diff --git a/.eslintrc.js b/.eslintrc.js
index fc82e75ce2..bc2a142c2d 100644
--- a/.eslintrc.js
+++ b/.eslintrc.js
@@ -19,7 +19,7 @@ module.exports = {
},
overrides: [{
- "files": ["src/**/*.{ts, tsx}"],
+ "files": ["src/**/*.{ts,tsx}"],
"extends": ["matrix-org/ts"],
"rules": {
// We disable this while we're transitioning
diff --git a/.stylelintrc.js b/.stylelintrc.js
index 1690f2186f..313102ea83 100644
--- a/.stylelintrc.js
+++ b/.stylelintrc.js
@@ -17,7 +17,7 @@ module.exports = {
"at-rule-no-unknown": null,
"no-descending-specificity": null,
"scss/at-rule-no-unknown": [true, {
- // https://github.com/vector-im/riot-web/issues/10544
+ // https://github.com/vector-im/element-web/issues/10544
"ignoreAtRules": ["define-mixin"],
}],
}
diff --git a/CHANGELOG.md b/CHANGELOG.md
index d944d58f36..47bffe432f 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,206 @@
+Changes in [3.3.0](https://github.com/matrix-org/matrix-react-sdk/releases/tag/v3.3.0) (2020-09-01)
+===================================================================================================
+[Full Changelog](https://github.com/matrix-org/matrix-react-sdk/compare/v3.3.0-rc.1...v3.3.0)
+
+ * Upgrade to JS SDK 8.2.0
+
+Changes in [3.3.0-rc.1](https://github.com/matrix-org/matrix-react-sdk/releases/tag/v3.3.0-rc.1) (2020-08-26)
+=============================================================================================================
+[Full Changelog](https://github.com/matrix-org/matrix-react-sdk/compare/v3.2.0...v3.3.0-rc.1)
+
+ * Upgrade to JS SDK 8.2.0-rc.1
+ * Update from Weblate
+ [\#5146](https://github.com/matrix-org/matrix-react-sdk/pull/5146)
+ * BaseAvatar avoid initial render with default avatar
+ [\#5142](https://github.com/matrix-org/matrix-react-sdk/pull/5142)
+ * Enforce Secure Backup completion when requested by HS
+ [\#5130](https://github.com/matrix-org/matrix-react-sdk/pull/5130)
+ * Communities v2 prototype: Explore rooms, global state, and default room
+ [\#5139](https://github.com/matrix-org/matrix-react-sdk/pull/5139)
+ * Add communities v2 prototyping feature flag + initial tag panel prototypes
+ [\#5133](https://github.com/matrix-org/matrix-react-sdk/pull/5133)
+ * Remove some unused components
+ [\#5134](https://github.com/matrix-org/matrix-react-sdk/pull/5134)
+ * Allow avatar image view for 1:1 rooms
+ [\#5137](https://github.com/matrix-org/matrix-react-sdk/pull/5137)
+ * Send mx_local_settings in rageshake
+ [\#5136](https://github.com/matrix-org/matrix-react-sdk/pull/5136)
+ * Run all room leaving behaviour through a single function
+ [\#5132](https://github.com/matrix-org/matrix-react-sdk/pull/5132)
+ * Add clarifying comment in media device selection
+ [\#5131](https://github.com/matrix-org/matrix-react-sdk/pull/5131)
+ * Settings v3: Feature flag changes
+ [\#5124](https://github.com/matrix-org/matrix-react-sdk/pull/5124)
+ * Clear url previews if they all get edited out of the event
+ [\#5129](https://github.com/matrix-org/matrix-react-sdk/pull/5129)
+ * Consider tab completions as modifications for editing purposes to unlock
+ sending
+ [\#5128](https://github.com/matrix-org/matrix-react-sdk/pull/5128)
+ * Use matrix-doc for SAS emoji translations
+ [\#5125](https://github.com/matrix-org/matrix-react-sdk/pull/5125)
+ * Add a rageshake function to download the logs locally
+ [\#3849](https://github.com/matrix-org/matrix-react-sdk/pull/3849)
+ * Room List filtering visual tweaks
+ [\#5123](https://github.com/matrix-org/matrix-react-sdk/pull/5123)
+ * Make reply preview not an overlay so you can see new messages
+ [\#5072](https://github.com/matrix-org/matrix-react-sdk/pull/5072)
+ * Allow room tile context menu when minimized using right click
+ [\#5113](https://github.com/matrix-org/matrix-react-sdk/pull/5113)
+ * Add null guard to group inviter for corrupted groups
+ [\#5121](https://github.com/matrix-org/matrix-react-sdk/pull/5121)
+ * Room List styling tweaks
+ [\#5118](https://github.com/matrix-org/matrix-react-sdk/pull/5118)
+ * Fix corner rounding on images not always affecting right side
+ [\#5120](https://github.com/matrix-org/matrix-react-sdk/pull/5120)
+ * Change add room action for rooms to context menu
+ [\#5108](https://github.com/matrix-org/matrix-react-sdk/pull/5108)
+ * Switch out the globe icon and colour it depending on theme
+ [\#5106](https://github.com/matrix-org/matrix-react-sdk/pull/5106)
+ * Message Action Bar watch for event send changes
+ [\#5115](https://github.com/matrix-org/matrix-react-sdk/pull/5115)
+ * Put message previews for Emoji behind Labs
+ [\#5110](https://github.com/matrix-org/matrix-react-sdk/pull/5110)
+ * Fix styling for selected community marker
+ [\#5107](https://github.com/matrix-org/matrix-react-sdk/pull/5107)
+ * Fix action bar safe area regression
+ [\#5111](https://github.com/matrix-org/matrix-react-sdk/pull/5111)
+ * Fix /op slash command
+ [\#5109](https://github.com/matrix-org/matrix-react-sdk/pull/5109)
+
+Changes in [3.2.0](https://github.com/matrix-org/matrix-react-sdk/releases/tag/v3.2.0) (2020-08-17)
+===================================================================================================
+[Full Changelog](https://github.com/matrix-org/matrix-react-sdk/compare/v3.2.0-rc.1...v3.2.0)
+
+ * Upgrade to JS SDK 8.1.0
+ * [Release] Fix corner rounding on images not always affecting right side
+ [\#5122](https://github.com/matrix-org/matrix-react-sdk/pull/5122)
+ * [Release] Message Action Bar watch for event send changes
+ [\#5116](https://github.com/matrix-org/matrix-react-sdk/pull/5116)
+ * Fix /op slash command to release
+ [\#5114](https://github.com/matrix-org/matrix-react-sdk/pull/5114)
+ * Fix action bar safe area regression
+ [\#5112](https://github.com/matrix-org/matrix-react-sdk/pull/5112)
+
+Changes in [3.2.0-rc.1](https://github.com/matrix-org/matrix-react-sdk/releases/tag/v3.2.0-rc.1) (2020-08-13)
+=============================================================================================================
+[Full Changelog](https://github.com/matrix-org/matrix-react-sdk/compare/v3.1.0...v3.2.0-rc.1)
+
+ * Upgrade to JS SDK 8.1.0-rc.1
+ * Update from Weblate
+ [\#5105](https://github.com/matrix-org/matrix-react-sdk/pull/5105)
+ * padding the timeline so that its scrollbar has its own space from the
+ resizer
+ [\#5103](https://github.com/matrix-org/matrix-react-sdk/pull/5103)
+ * Try to close notification on all platforms which support it, not just
+ electron
+ [\#5102](https://github.com/matrix-org/matrix-react-sdk/pull/5102)
+ * Fix exception when stripping replies from an event with a non-string body
+ [\#5101](https://github.com/matrix-org/matrix-react-sdk/pull/5101)
+ * Quick win session 24/07/2020
+ [\#5056](https://github.com/matrix-org/matrix-react-sdk/pull/5056)
+ * Remove rebranding toast
+ [\#5100](https://github.com/matrix-org/matrix-react-sdk/pull/5100)
+ * Generate previews for rooms when the option changes
+ [\#5098](https://github.com/matrix-org/matrix-react-sdk/pull/5098)
+ * Fix Bridge Settings tab
+ [\#5095](https://github.com/matrix-org/matrix-react-sdk/pull/5095)
+ * get screen type from app prop
+ [\#5081](https://github.com/matrix-org/matrix-react-sdk/pull/5081)
+ * Update rageshake app name
+ [\#5093](https://github.com/matrix-org/matrix-react-sdk/pull/5093)
+ * Factor out Iconized Context menu for reusability
+ [\#5085](https://github.com/matrix-org/matrix-react-sdk/pull/5085)
+ * Decouple Audible notifications from Desktop notifications
+ [\#5088](https://github.com/matrix-org/matrix-react-sdk/pull/5088)
+ * Make the room sublist show more/less buttons treeitems
+ [\#5087](https://github.com/matrix-org/matrix-react-sdk/pull/5087)
+ * Share and debug master cross-signing key
+ [\#5092](https://github.com/matrix-org/matrix-react-sdk/pull/5092)
+ * Create Map comparison utilities and convert Hooks to Typescript
+ [\#5086](https://github.com/matrix-org/matrix-react-sdk/pull/5086)
+ * Fix room list scrolling in Safari
+ [\#5090](https://github.com/matrix-org/matrix-react-sdk/pull/5090)
+ * Replace Riot with Element in docs and comments
+ [\#5083](https://github.com/matrix-org/matrix-react-sdk/pull/5083)
+ * When the room view isn't active don't highlight it in room list
+ [\#5027](https://github.com/matrix-org/matrix-react-sdk/pull/5027)
+ * remove emoji icons in autocomplete/reply by designer request
+ [\#5073](https://github.com/matrix-org/matrix-react-sdk/pull/5073)
+ * Add title and icon to empty state of file and notification panel
+ [\#5079](https://github.com/matrix-org/matrix-react-sdk/pull/5079)
+ * Mass redact ignore room creation events
+ [\#5045](https://github.com/matrix-org/matrix-react-sdk/pull/5045)
+ * Replace all chevrons with a single icon
+ [\#5067](https://github.com/matrix-org/matrix-react-sdk/pull/5067)
+ * Replace i18n generation script with something matching our project
+ [\#5077](https://github.com/matrix-org/matrix-react-sdk/pull/5077)
+ * Handle tag changes in sticky room updates
+ [\#5078](https://github.com/matrix-org/matrix-react-sdk/pull/5078)
+ * Remove leftover bits of TSLint
+ [\#5075](https://github.com/matrix-org/matrix-react-sdk/pull/5075)
+ * Clean up documentation of Whenable + fix other code concerns
+ [\#5076](https://github.com/matrix-org/matrix-react-sdk/pull/5076)
+ * Center the jump down/up icon, looks misaligned
+ [\#5074](https://github.com/matrix-org/matrix-react-sdk/pull/5074)
+ * [WIP] Support a new settings structure
+ [\#5058](https://github.com/matrix-org/matrix-react-sdk/pull/5058)
+ * Convert SettingsStore to TypeScript
+ [\#5062](https://github.com/matrix-org/matrix-react-sdk/pull/5062)
+
+Changes in [3.1.0](https://github.com/matrix-org/matrix-react-sdk/releases/tag/v3.1.0) (2020-08-05)
+===================================================================================================
+[Full Changelog](https://github.com/matrix-org/matrix-react-sdk/compare/v3.1.0-rc.1...v3.1.0)
+
+ * Upgrade JS SDK to 8.0.1
+ * Fix room list scrolling in Safari
+ [\#5091](https://github.com/matrix-org/matrix-react-sdk/pull/5091)
+ * Add null guard in InviteDialog
+ [\#5084](https://github.com/matrix-org/matrix-react-sdk/pull/5084)
+ * Add null guard in InviteDialog
+ [\#5082](https://github.com/matrix-org/matrix-react-sdk/pull/5082)
+ * Handle tag changes in sticky room updates
+ [\#5080](https://github.com/matrix-org/matrix-react-sdk/pull/5080)
+
+Changes in [3.1.0-rc.1](https://github.com/matrix-org/matrix-react-sdk/releases/tag/v3.1.0-rc.1) (2020-07-31)
+=============================================================================================================
+[Full Changelog](https://github.com/matrix-org/matrix-react-sdk/compare/v3.0.0...v3.1.0-rc.1)
+
+ * Upgrade JS SDK to 8.0.1-rc.1
+ * Update from Weblate
+ [\#5071](https://github.com/matrix-org/matrix-react-sdk/pull/5071)
+ * Add local echo for notifications in the new room list
+ [\#5065](https://github.com/matrix-org/matrix-react-sdk/pull/5065)
+ * Fix various small regressions in the room list's behaviour
+ [\#5070](https://github.com/matrix-org/matrix-react-sdk/pull/5070)
+ * Remove redundant lint dependencies
+ [\#5059](https://github.com/matrix-org/matrix-react-sdk/pull/5059)
+ * Fix key backup warning on soft logout page
+ [\#5069](https://github.com/matrix-org/matrix-react-sdk/pull/5069)
+ * Bump elliptic from 6.5.2 to 6.5.3
+ [\#5066](https://github.com/matrix-org/matrix-react-sdk/pull/5066)
+ * Fix crash on logging in again after soft logout
+ [\#5068](https://github.com/matrix-org/matrix-react-sdk/pull/5068)
+ * Convert right_panel to TS
+ [\#5036](https://github.com/matrix-org/matrix-react-sdk/pull/5036)
+ * Remove all unreferenced images
+ [\#5063](https://github.com/matrix-org/matrix-react-sdk/pull/5063)
+ * Provide nicer error for no known servers error when accepting an invite
+ [\#5061](https://github.com/matrix-org/matrix-react-sdk/pull/5061)
+ * add logging for keytar/pickle key
+ [\#5057](https://github.com/matrix-org/matrix-react-sdk/pull/5057)
+ * Don't speak the outgoing message if it is in the Sending state.
+ [\#4075](https://github.com/matrix-org/matrix-react-sdk/pull/4075)
+ * Remove poorly contrasted "dark style" heading in Room Preview Bar
+ [\#5052](https://github.com/matrix-org/matrix-react-sdk/pull/5052)
+ * Fix Query Matcher regression with certain unhomoglyph'd characters
+ [\#5050](https://github.com/matrix-org/matrix-react-sdk/pull/5050)
+ * Fix handlebar interaction
+ [\#4989](https://github.com/matrix-org/matrix-react-sdk/pull/4989)
+ * Minor improvements to filtering performance
+ [\#5054](https://github.com/matrix-org/matrix-react-sdk/pull/5054)
+ * Fix TextWithTooltip "leaking" tooltip wrappers
+ [\#5055](https://github.com/matrix-org/matrix-react-sdk/pull/5055)
+
Changes in [3.0.0](https://github.com/matrix-org/matrix-react-sdk/releases/tag/v3.0.0) (2020-07-27)
===================================================================================================
[Full Changelog](https://github.com/matrix-org/matrix-react-sdk/compare/v2.10.1...v3.0.0)
diff --git a/README.md b/README.md
index 5f5da9a40d..e468d272d0 100644
--- a/README.md
+++ b/README.md
@@ -11,14 +11,14 @@ a 'skin'. A skin provides:
* The containing application
* Zero or more 'modules' containing non-UI functionality
-As of Aug 2018, the only skin that exists is `vector-im/riot-web`; it and
+As of Aug 2018, the only skin that exists is `vector-im/element-web`; it and
`matrix-org/matrix-react-sdk` should effectively
be considered as a single project (for instance, matrix-react-sdk bugs
-are currently filed against vector-im/riot-web rather than this project).
+are currently filed against vector-im/element-web rather than this project).
Translation Status
==================
-[](https://translate.riot.im/engage/riot-web/?utm_source=widget)
+[](https://translate.riot.im/engage/element-web/?utm_source=widget)
Developer Guide
===============
@@ -41,10 +41,10 @@ https://github.com/matrix-org/matrix-react-sdk/blob/master/code_style.md
Code should be committed as follows:
* All new components: https://github.com/matrix-org/matrix-react-sdk/tree/master/src/components
- * Riot-specific components: https://github.com/vector-im/riot-web/tree/master/src/components
+ * Element-specific components: https://github.com/vector-im/element-web/tree/master/src/components
* In practice, `matrix-react-sdk` is still evolving so fast that the maintenance
- burden of customising and overriding these components for Riot can seriously
- impede development. So right now, there should be very few (if any) customisations for Riot.
+ burden of customising and overriding these components for Element can seriously
+ impede development. So right now, there should be very few (if any) customisations for Element.
* CSS: https://github.com/matrix-org/matrix-react-sdk/tree/master/res/css
* Theme specific CSS & resources: https://github.com/matrix-org/matrix-react-sdk/tree/master/res/themes
@@ -71,7 +71,7 @@ practices that anyone working with the SDK needs to be be aware of and uphold:
* The view's CSS file MUST have the same name (e.g. view/rooms/MessageTile.css).
CSS for matrix-react-sdk currently resides in
- https://github.com/vector-im/riot-web/tree/master/src/skins/vector/css/matrix-react-sdk.
+ https://github.com/vector-im/element-web/tree/master/src/skins/vector/css/matrix-react-sdk.
* Per-view CSS is optional - it could choose to inherit all its styling from
the context of the rest of the app, although this is unusual for any but
@@ -125,7 +125,7 @@ from it.
Github Issues
=============
-All issues should be filed under https://github.com/vector-im/riot-web/issues
+All issues should be filed under https://github.com/vector-im/element-web/issues
for now.
Development
@@ -174,5 +174,5 @@ yarn test
## End-to-End tests
-Make sure you've got your Riot development server running (by doing `yarn start` in riot-web), and then in this project, run `yarn run e2etests`.
+Make sure you've got your Element development server running (by doing `yarn start` in element-web), and then in this project, run `yarn run e2etests`.
See `test/end-to-end-tests/README.md` for more information.
diff --git a/docs/ciderEditor.md b/docs/ciderEditor.md
index 00033b5b8c..f522dc2fc4 100644
--- a/docs/ciderEditor.md
+++ b/docs/ciderEditor.md
@@ -1,6 +1,6 @@
# The CIDER (Contenteditable-Input-Diff-Error-Reconcile) editor
-The CIDER editor is a custom editor written for Riot.
+The CIDER editor is a custom editor written for Element.
Most of the code can be found in the `/editor/` directory of the `matrix-react-sdk` project.
It is used to power the composer main composer (both to send and edit messages), and might be used for other usecases where autocomplete is desired (invite box, ...).
diff --git a/docs/jitsi.md b/docs/jitsi.md
index 779ef79d3a..2b63ce0f72 100644
--- a/docs/jitsi.md
+++ b/docs/jitsi.md
@@ -25,7 +25,7 @@ which takes several parameters:
be null.
The react-sdk will assume that `jitsi.html` is at the path of wherever it is currently
-being served. For example, `https://riot.im/develop/jitsi.html` or `vector://webapp/jitsi.html`.
+being served. For example, `https://develop.element.io/jitsi.html` or `vector://webapp/jitsi.html`.
The `jitsi.html` wrapper can use the react-sdk's `WidgetApi` to communicate, making
it easier to actually implement the feature.
diff --git a/docs/room-list-store.md b/docs/room-list-store.md
index 53f0527209..fa849e2505 100644
--- a/docs/room-list-store.md
+++ b/docs/room-list-store.md
@@ -55,7 +55,7 @@ timestamp contained within the event (generated server-side by the sender's serv
This is the easiest of the algorithms to understand because it does essentially nothing. It imposes no
behavioural changes over the tag sorting algorithm and is by far the simplest way to order a room list.
-Historically, it's been the only option in Riot and extremely common in most chat applications due to
+Historically, it's been the only option in Element and extremely common in most chat applications due to
its relative deterministic behaviour.
### List ordering algorithm: Importance
diff --git a/docs/scrolling.md b/docs/scrolling.md
index 71329e5c32..a5232359a7 100644
--- a/docs/scrolling.md
+++ b/docs/scrolling.md
@@ -13,7 +13,7 @@ ScrollPanel supports a mode to prevent it shrinking. This is used to prevent a j
BACAT scrolling implements a different way of restoring the scroll position in the timeline while tiles out of view are changing height or tiles are being added or removed. It was added in https://github.com/matrix-org/matrix-react-sdk/pull/2842.
-The motivation for the changes is having noticed that setting scrollTop while scrolling tends to not work well, with it interrupting ongoing scrolling and also querying scrollTop reporting outdated values and consecutive scroll adjustments cancelling each out previous ones. This seems to be worse on macOS than other platforms, presumably because of a higher resolution in scroll events there. Also see https://github.com/vector-im/riot-web/issues/528. The BACAT approach allows to only have to change the scroll offset when adding or removing tiles.
+The motivation for the changes is having noticed that setting scrollTop while scrolling tends to not work well, with it interrupting ongoing scrolling and also querying scrollTop reporting outdated values and consecutive scroll adjustments cancelling each out previous ones. This seems to be worse on macOS than other platforms, presumably because of a higher resolution in scroll events there. Also see https://github.com/vector-im/element-web/issues/528. The BACAT approach allows to only have to change the scroll offset when adding or removing tiles.
The approach taken instead is to vertically align the timeline tiles to the bottom of the scroll container (using flexbox) and give the timeline inside the scroll container an explicit height, initially set to a multiple of the PAGE_SIZE (400px at time of writing) as needed by the content. When scrolled up, we can compensate for anything that grew below the viewport by changing the height of the timeline to maintain what's currently visible in the viewport without adjusting the scrollTop and hence without jumping.
diff --git a/docs/settings.md b/docs/settings.md
index 46e4a68fdb..4172c72c15 100644
--- a/docs/settings.md
+++ b/docs/settings.md
@@ -9,7 +9,7 @@ of dealing with the different levels and exposes easy to use getters and setters
## Levels
Granular Settings rely on a series of known levels in order to use the correct value for the scenario. These levels, in
-order of prioirty, are:
+order of priority, are:
* `device` - The current user's device
* `room-device` - The current user's device, but only when in a specific room
* `room-account` - The current user's account, but only when in a specific room
@@ -25,33 +25,10 @@ that room administrators cannot force account-only settings upon participants.
## Settings
Settings are the different options a user may set or experience in the application. These are pre-defined in
-`src/settings/Settings.js` under the `SETTINGS` constant and have the following minimum requirements:
-```
-// The ID is used to reference the setting throughout the application. This must be unique.
-"theSettingId": {
- // The levels this setting supports is required. In `src/settings/Settings.js` there are various pre-set arrays
- // for this option - they should be used where possible to avoid copy/pasting arrays across settings.
- supportedLevels: [...],
+`src/settings/Settings.ts` under the `SETTINGS` constant, and match the `ISetting` interface as defined there.
- // The default for this setting serves two purposes: It provides a value if the setting is not defined at other
- // levels, and it serves to demonstrate the expected type to other developers. The value isn't enforced, but it
- // should be respected throughout the code. The default may be any data type.
- default: false,
-
- // The display name has two notations: string and object. The object notation allows for different translatable
- // strings to be used for different levels, while the string notation represents the string for all levels.
-
- displayName: _td("Change something"), // effectively `displayName: { "default": _td("Change something") }`
- displayName: {
- "room": _td("Change something for participants of this room"),
-
- // Note: the default will be used if the level requested (such as `device`) does not have a string defined here.
- "default": _td("Change something"),
- }
-}
-```
-
-Settings that support the config level can be set in the config file under the `settingDefaults` key (note that some settings, like the "theme" setting, are special cased in the config file):
+Settings that support the config level can be set in the config file under the `settingDefaults` key (note that some
+settings, like the "theme" setting, are special cased in the config file):
```json
{
...
@@ -119,38 +96,29 @@ for you. If a display name cannot be found, it will return `null`.
## Features
-Occasionally some parts of the application may be undergoing testing and are not quite production ready. These are
-commonly known to be behind a "labs flag". Features behind lab flags must go through the granular settings system, and
-look and act very much normal settings. The exception is that they must supply `isFeature: true` as part of the setting
-definition and should go through the helper functions on `SettingsStore`.
+Feature flags are just like regular settings with some underlying semantics for how they are meant to be used. Usually
+a feature flag is used when a portion of the application is under development or not ready for full release yet, such
+as new functionality or experimental ideas. In these cases, the feature name *should* be named with the `feature_*`
+convention and must be tagged with `isFeature: true` in the setting definition. By doing so, the feature will automatically
+appear in the "labs" section of the user's settings.
-Although features have levels and a default value, the calculation of those options is blocked by the feature's state.
-A feature's state is determined from the `SdkConfig` and is a little complex. If `enableLabs` (a legacy flag) is `true`
-then the feature's state is `labs`, if it is `false`, the state is `disable`. If `enableLabs` is not set then the state
-is determined from the `features` config, such as in the following:
+Features can be controlled at the config level using the following structure:
```json
"features": {
- "feature_lazyloading": "labs"
+ "feature_lazyloading": true
}
```
-In this example, `feature_lazyloading` is in the `labs` state. It may also be in the `enable` or `disable` state with a
-similar approach. If the state is invalid, the feature is in the `disable` state. A feature's levels are only calculated
-if it is in the `labs` state, therefore the default only applies in that scenario. If the state is `enable`, the feature
-is always-on.
-Once a feature flag has served its purpose, it is generally recommended to remove it and the associated feature flag
-checks. This would enable the feature implicitly as it is part of the application now.
+When `true`, the user will see the feature as enabled. Similarly, when `false` the user will see the feature as disabled.
+The user will only be able to change/see these states if `showLabsSettings: true` is in the config.
### Determining if a feature is enabled
-A simple call to `SettingsStore.isFeatureEnabled` will tell you if the feature is enabled. This will perform all the
-required calculations to determine if the feature is enabled based upon the configuration and user selection.
+Call `SettingsStore.getValue()` as you would for any other setting.
### Enabling a feature
-Features can only be enabled if the feature is in the `labs` state, otherwise this is a no-op. To find the current set
-of features in the `labs` state, call `SettingsStore.getLabsFeatures`. To set the value, call
-`SettingsStore.setFeatureEnabled`.
+Call `SettingsStore.setValue("feature_name", null, SettingLevel.DEVICE, true)`.
## Setting controllers
@@ -162,7 +130,7 @@ kept up to date with the setting where it is otherwise not possible. An example
they can only be considered enabled if the platform supports notifications, and enabling notifications requires
additional steps to actually enable notifications.
-For more information, see `src/settings/controllers/SettingController.js`.
+For more information, see `src/settings/controllers/SettingController.ts`.
## Local echo
@@ -222,7 +190,7 @@ The `SettingsStore` uses the hardcoded `LEVEL_ORDER` constant to ensure that it
The array is checked from left to right, simulating the behaviour of overriding values from the higher levels. Each
level should be defined in this array, including `default`.
-Handlers (`src/settings/handlers/SettingsHandler.js`) represent a single level and are responsible for getting and
+Handlers (`src/settings/handlers/SettingsHandler.ts`) represent a single level and are responsible for getting and
setting values at that level. Handlers also provide additional information to the `SettingsStore` such as if the level
is supported or if the current user may set values at the level. The `SettingsStore` will use the handler to enforce
checks and manipulate settings. Handlers are also responsible for dealing with migration patterns or legacy settings for
@@ -230,7 +198,7 @@ their level (for example, a setting being renamed or using a different key from
Handlers are provided to the `SettingsStore` via the `LEVEL_HANDLERS` constant. `SettingsStore` will optimize lookups by
only considering handlers that are supported on the platform.
-Local echo is achieved through `src/settings/handlers/LocalEchoWrapper.js` which acts as a wrapper around a given
+Local echo is achieved through `src/settings/handlers/LocalEchoWrapper.ts` which acts as a wrapper around a given
handler. This is automatically applied to all defined `LEVEL_HANDLERS` and proxies the calls to the wrapped handler
where possible. The echo is achieved by a simple object cache stored within the class itself. The cache is invalidated
immediately upon the proxied save call succeeding or failing.
@@ -240,20 +208,7 @@ Controllers are notified of changes by the `SettingsStore`, and are given the op
### Features
-Features automatically get considered as `disabled` if they are not listed in the `SdkConfig` or `enableLabs` is
-false/not set. Features are always checked against the configuration before going through the level order as they have
-the option of being forced-on or forced-off for the application. This is done by the `features` section and looks
-something like this:
-
-```
-"features": {
- "feature_groups": "enable",
- "feature_pinning": "disable", // the default
- "feature_presence": "labs"
-}
-```
-
-If `enableLabs` is true in the configuration, the default for features becomes `"labs"`.
+See above for feature reference.
### Watchers
diff --git a/docs/usercontent.md b/docs/usercontent.md
index e54851dd0d..db0e34e5fa 100644
--- a/docs/usercontent.md
+++ b/docs/usercontent.md
@@ -5,9 +5,9 @@ letting the browser and user interact with the resulting data may be dangerous,
previously `usercontent.riot.im` was used to act as a sandbox on a different origin to close the attack surface,
it is now possible to do by using a combination of a sandboxed iframe and some code written into the app which consumes this SDK.
-Usercontent is an iframe sandbox target for allowing a user to safely download a decrypted attachment from a sandboxed origin where it cannot be used to XSS your riot session out from under you.
+Usercontent is an iframe sandbox target for allowing a user to safely download a decrypted attachment from a sandboxed origin where it cannot be used to XSS your Element session out from under you.
-Its function is to create an Object URL for the user/browser to use but bound to an origin different to that of the riot instance to protect against XSS.
+Its function is to create an Object URL for the user/browser to use but bound to an origin different to that of the Element instance to protect against XSS.
It exposes a function over a postMessage API, when sent an object with the matching fields to render a download link with the Object URL:
@@ -24,4 +24,4 @@ It exposes a function over a postMessage API, when sent an object with the match
If only imgSrc, imgStyle and style are passed then just update the existing link without overwriting other things about it.
-It is expected that this target be available at `usercontent/` relative to the root of the app, this can be seen in riot-web's webpack config.
+It is expected that this target be available at `usercontent/` relative to the root of the app, this can be seen in element-web's webpack config.
diff --git a/package.json b/package.json
index 61a9a21815..9b7d80ca73 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "matrix-react-sdk",
- "version": "3.0.0",
+ "version": "3.3.0",
"description": "SDK for matrix.org using React",
"author": "matrix.org",
"repository": {
@@ -61,7 +61,6 @@
"classnames": "^2.2.6",
"commonmark": "^0.29.1",
"counterpart": "^0.18.6",
- "create-react-class": "^15.6.3",
"diff-dom": "^4.1.6",
"diff-match-patch": "^1.0.5",
"emojibase-data": "^5.0.1",
@@ -96,6 +95,7 @@
"react-transition-group": "^4.4.1",
"resize-observer-polyfill": "^1.5.1",
"sanitize-html": "^1.27.1",
+ "tar-js": "^0.3.0",
"text-encoding-utf-8": "^1.0.2",
"url": "^0.11.0",
"velocity-animate": "^1.5.2",
@@ -127,6 +127,7 @@
"@types/lodash": "^4.14.158",
"@types/modernizr": "^3.5.3",
"@types/node": "^12.12.51",
+ "@types/pako": "^1.0.1",
"@types/qrcode": "^1.3.4",
"@types/react": "^16.9",
"@types/react-dom": "^16.9.8",
@@ -161,9 +162,7 @@
"stylelint-config-standard": "^18.3.0",
"stylelint-scss": "^3.18.0",
"typescript": "^3.9.7",
- "walk": "^2.3.14",
- "webpack": "^4.43.0",
- "webpack-cli": "^3.3.12"
+ "walk": "^2.3.14"
},
"jest": {
"testMatch": [
diff --git a/res/css/_common.scss b/res/css/_common.scss
index f2d3a0e54b..a22d77f3d3 100644
--- a/res/css/_common.scss
+++ b/res/css/_common.scss
@@ -38,7 +38,7 @@ body {
margin: 0px;
// needed to match the designs correctly on macOS
- // see https://github.com/vector-im/riot-web/issues/11425
+ // see https://github.com/vector-im/element-web/issues/11425
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
@@ -436,7 +436,7 @@ input[type=text]:focus, input[type=password]:focus, textarea:focus {
// TODO: Review mx_GeneralButton usage to see if it can use a different class
// These classes were brought in from the old UserSettings and are included here to avoid
// breaking the app.
-// Ref: https://github.com/vector-im/riot-web/issues/8420
+// Ref: https://github.com/vector-im/element-web/issues/8420
.mx_GeneralButton {
@mixin mx_DialogButton;
display: inline;
@@ -585,93 +585,6 @@ input[type=text]:focus, input[type=password]:focus, textarea:focus {
max-width: 120px;
}
-// A context menu that largely fits the | [icon] [label] | format.
-.mx_IconizedContextMenu {
- min-width: 146px;
-
- .mx_IconizedContextMenu_optionList {
- & > * {
- padding-left: 20px;
- padding-right: 20px;
- }
-
- // the notFirst class is for cases where the optionList might be under a header of sorts.
- &:nth-child(n + 2), .mx_IconizedContextMenu_optionList_notFirst {
- // This is a bit of a hack when we could just use a simple border-top property,
- // however we have a (kinda) good reason for doing it this way: we need opacity.
- // To get the right color, we need an opacity modifier which means we have to work
- // around the problem. PostCSS doesn't support the opacity() function, and if we
- // use something like postcss-functions we quickly run into an issue where the
- // function we would define gets passed a CSS variable for custom themes, which
- // can't be converted easily even when considering https://stackoverflow.com/a/41265350/7037379
- //
- // Therefore, we just hack in a line and border the thing ourselves
- &::before {
- border-top: 1px solid $primary-fg-color;
- opacity: 0.1;
- content: '';
-
- // Counteract the padding problems (width: 100% ignores the 40px padding,
- // unless we position it absolutely then it does the right thing).
- width: 100%;
- position: absolute;
- left: 0;
- }
- }
-
- // round the top corners of the top button for the hover effect to be bounded
- &:first-child .mx_AccessibleButton:first-child {
- border-radius: 8px 8px 0 0; // radius matches .mx_ContextualMenu
- }
-
- // round the bottom corners of the bottom button for the hover effect to be bounded
- &:last-child .mx_AccessibleButton:last-child {
- border-radius: 0 0 8px 8px; // radius matches .mx_ContextualMenu
- }
-
- .mx_AccessibleButton {
- // pad the inside of the button so that the hover background is padded too
- padding-top: 12px;
- padding-bottom: 12px;
- text-decoration: none;
- color: $primary-fg-color;
- font-size: $font-15px;
- line-height: $font-24px;
-
- // Create a flexbox to more easily define the list items
- display: flex;
- align-items: center;
-
- &:hover {
- background-color: $menu-selected-color;
- }
-
- img, .mx_IconizedContextMenu_icon { // icons
- width: 16px;
- min-width: 16px;
- max-width: 16px;
- }
-
- span.mx_IconizedContextMenu_label { // labels
- padding-left: 14px;
- width: 100%;
- flex: 1;
-
- // Ellipsize any text overflow
- text-overflow: ellipsis;
- overflow: hidden;
- white-space: nowrap;
- }
- }
- }
-
- &.mx_IconizedContextMenu_compact {
- .mx_IconizedContextMenu_optionList > * {
- padding: 8px 16px 8px 11px;
- }
- }
-}
-
@define-mixin ProgressBarColour $colour {
color: $colour;
&::-moz-progress-bar {
@@ -692,3 +605,15 @@ input[type=text]:focus, input[type=password]:focus, textarea:focus {
border-radius: $radius;
}
}
+
+@define-mixin unreal-focus {
+ outline-width: 2px;
+ outline-style: solid;
+ outline-color: Highlight;
+
+ /* WebKit gets its native focus styles. */
+ @media (-webkit-min-device-pixel-ratio: 0) {
+ outline-color: -webkit-focus-ring-color;
+ outline-style: auto;
+ }
+}
diff --git a/res/css/_components.scss b/res/css/_components.scss
index 1f86bb67a6..a4873090f5 100644
--- a/res/css/_components.scss
+++ b/res/css/_components.scss
@@ -1,6 +1,7 @@
// autogenerated by rethemendex.sh
@import "./_common.scss";
@import "./_font-sizes.scss";
+@import "./_font-weights.scss";
@import "./structures/_AutoHideScrollbar.scss";
@import "./structures/_CompatibilityPage.scss";
@import "./structures/_ContextualMenu.scss";
@@ -50,28 +51,30 @@
@import "./views/avatars/_DecoratedRoomAvatar.scss";
@import "./views/avatars/_MemberStatusMessageAvatar.scss";
@import "./views/avatars/_PulsedAvatar.scss";
+@import "./views/context_menus/_IconizedContextMenu.scss";
@import "./views/context_menus/_MessageContextMenu.scss";
-@import "./views/context_menus/_RoomTileContextMenu.scss";
@import "./views/context_menus/_StatusMessageContextMenu.scss";
@import "./views/context_menus/_TagTileContextMenu.scss";
-@import "./views/context_menus/_TopLeftMenu.scss";
@import "./views/context_menus/_WidgetContextMenu.scss";
@import "./views/dialogs/_AddressPickerDialog.scss";
@import "./views/dialogs/_Analytics.scss";
+@import "./views/dialogs/_BugReportDialog.scss";
@import "./views/dialogs/_ChangelogDialog.scss";
@import "./views/dialogs/_ChatCreateOrReuseChatDialog.scss";
+@import "./views/dialogs/_CommunityPrototypeInviteDialog.scss";
@import "./views/dialogs/_ConfirmUserActionDialog.scss";
+@import "./views/dialogs/_CreateCommunityPrototypeDialog.scss";
@import "./views/dialogs/_CreateGroupDialog.scss";
@import "./views/dialogs/_CreateRoomDialog.scss";
@import "./views/dialogs/_DeactivateAccountDialog.scss";
@import "./views/dialogs/_DevtoolsDialog.scss";
+@import "./views/dialogs/_EditCommunityPrototypeDialog.scss";
@import "./views/dialogs/_GroupAddressPicker.scss";
@import "./views/dialogs/_IncomingSasDialog.scss";
@import "./views/dialogs/_InviteDialog.scss";
@import "./views/dialogs/_KeyboardShortcutsDialog.scss";
@import "./views/dialogs/_MessageEditHistoryDialog.scss";
@import "./views/dialogs/_NewSessionReviewDialog.scss";
-@import "./views/dialogs/_RebrandDialog.scss";
@import "./views/dialogs/_RoomSettingsDialog.scss";
@import "./views/dialogs/_RoomSettingsDialogBridges.scss";
@import "./views/dialogs/_RoomUpgradeDialog.scss";
@@ -106,6 +109,7 @@
@import "./views/elements/_FormButton.scss";
@import "./views/elements/_IconButton.scss";
@import "./views/elements/_ImageView.scss";
+@import "./views/elements/_InfoTooltip.scss";
@import "./views/elements/_InlineSpinner.scss";
@import "./views/elements/_ManageIntegsButton.scss";
@import "./views/elements/_PowerSelector.scss";
@@ -156,7 +160,6 @@
@import "./views/right_panel/_UserInfo.scss";
@import "./views/right_panel/_VerificationPanel.scss";
@import "./views/room_settings/_AliasSettings.scss";
-@import "./views/room_settings/_ColorSettings.scss";
@import "./views/rooms/_AppsDrawer.scss";
@import "./views/rooms/_Autocomplete.scss";
@import "./views/rooms/_AuxPanel.scss";
@@ -186,7 +189,6 @@
@import "./views/rooms/_RoomRecoveryReminder.scss";
@import "./views/rooms/_RoomSublist.scss";
@import "./views/rooms/_RoomTile.scss";
-@import "./views/rooms/_RoomTileIcon.scss";
@import "./views/rooms/_RoomUpgradeWarningBar.scss";
@import "./views/rooms/_SearchBar.scss";
@import "./views/rooms/_SendMessageComposer.scss";
diff --git a/res/css/_font-weights.scss b/res/css/_font-weights.scss
new file mode 100644
index 0000000000..3e2b19d516
--- /dev/null
+++ b/res/css/_font-weights.scss
@@ -0,0 +1,17 @@
+/*
+Copyright 2020 The Matrix.org Foundation C.I.C.
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+$font-semi-bold: 600;
diff --git a/res/css/structures/_FilePanel.scss b/res/css/structures/_FilePanel.scss
index 50b01b4a14..21b30d804a 100644
--- a/res/css/structures/_FilePanel.scss
+++ b/res/css/structures/_FilePanel.scss
@@ -41,13 +41,19 @@ limitations under the License.
.mx_FilePanel .mx_EventTile {
word-break: break-word;
+ margin-top: 32px;
}
.mx_FilePanel .mx_EventTile .mx_MImageBody {
margin-right: 0px;
}
+.mx_FilePanel .mx_EventTile .mx_MFileBody {
+ line-height: 2.4rem;
+}
+
.mx_FilePanel .mx_EventTile .mx_MFileBody_download {
+ padding-top: 8px;
display: flex;
font-size: $font-14px;
color: $event-timestamp-color;
@@ -60,7 +66,7 @@ limitations under the License.
.mx_FilePanel .mx_EventTile .mx_MImageBody_size {
flex: 1 0 0;
- font-size: $font-11px;
+ font-size: $font-14px;
text-align: right;
white-space: nowrap;
}
@@ -80,7 +86,7 @@ limitations under the License.
flex: 1 1 auto;
line-height: initial;
padding: 0px;
- font-size: $font-11px;
+ font-size: $font-14px;
opacity: 1.0;
color: $event-timestamp-color;
}
@@ -90,7 +96,7 @@ limitations under the License.
text-align: right;
visibility: visible;
position: initial;
- font-size: $font-11px;
+ font-size: $font-14px;
opacity: 1.0;
color: $event-timestamp-color;
}
diff --git a/res/css/structures/_LeftPanel.scss b/res/css/structures/_LeftPanel.scss
index db531cf088..5112d07c46 100644
--- a/res/css/structures/_LeftPanel.scss
+++ b/res/css/structures/_LeftPanel.scss
@@ -97,23 +97,25 @@ $tagPanelWidth: 56px; // only applies in this file, used for calculations
display: flex;
align-items: center;
- .mx_RoomSearch_expanded + .mx_LeftPanel_exploreButton {
- // Cheaty way to return the occupied space to the filter input
- flex-basis: 0;
- margin: 0;
- width: 0;
+ .mx_RoomSearch_focused, .mx_RoomSearch_hasQuery {
+ & + .mx_LeftPanel_exploreButton {
+ // Cheaty way to return the occupied space to the filter input
+ flex-basis: 0;
+ margin: 0;
+ width: 0;
- // Don't forget to hide the masked ::before icon,
- // using display:none or visibility:hidden would break accessibility
- &::before {
- content: none;
+ // Don't forget to hide the masked ::before icon,
+ // using display:none or visibility:hidden would break accessibility
+ &::before {
+ content: none;
+ }
}
}
.mx_LeftPanel_exploreButton {
- width: 28px;
- height: 28px;
- border-radius: 20px;
+ width: 32px;
+ height: 32px;
+ border-radius: 8px;
background-color: $roomlist-button-bg-color;
position: relative;
margin-left: 8px;
@@ -121,22 +123,31 @@ $tagPanelWidth: 56px; // only applies in this file, used for calculations
&::before {
content: '';
position: absolute;
- top: 6px;
- left: 6px;
+ top: 8px;
+ left: 8px;
width: 16px;
height: 16px;
- mask-image: url('$(res)/img/feather-customised/compass.svg');
+ mask-image: url('$(res)/img/element-icons/roomlist/explore.svg');
mask-position: center;
mask-size: contain;
mask-repeat: no-repeat;
- background: $primary-fg-color;
+ background: $secondary-fg-color;
}
}
}
+ .mx_LeftPanel_roomListFilterCount {
+ font-size: $font-13px;
+ font-weight: $font-semi-bold;
+ margin-left: 12px;
+ margin-top: 14px;
+ margin-bottom: -4px; // to counteract the normal roomListWrapper margin-top
+ }
+
.mx_LeftPanel_roomListWrapper {
overflow: hidden;
margin-top: 10px; // so we're not up against the search/filter
+ flex: 1 0 0; // needed in Safari to properly set flex-basis
&.mx_LeftPanel_roomListWrapper_stickyBottom {
padding-bottom: 32px;
diff --git a/res/css/structures/_MainSplit.scss b/res/css/structures/_MainSplit.scss
index aee7b5a154..dc62cb8218 100644
--- a/res/css/structures/_MainSplit.scss
+++ b/res/css/structures/_MainSplit.scss
@@ -23,6 +23,8 @@ limitations under the License.
.mx_MainSplit > .mx_RightPanel_ResizeWrapper {
padding: 5px;
+ // margin left to not allow the handle to not encroach on the space for the scrollbar
+ margin-left: 8px;
&:hover .mx_RightPanel_ResizeHandle {
// Need to use important to override element style attributes
diff --git a/res/css/structures/_MatrixChat.scss b/res/css/structures/_MatrixChat.scss
index af6f6c79e9..f4e46a8e94 100644
--- a/res/css/structures/_MatrixChat.scss
+++ b/res/css/structures/_MatrixChat.scss
@@ -72,7 +72,7 @@ limitations under the License.
flex: 1 1 0;
min-width: 0;
- /* To fix https://github.com/vector-im/riot-web/issues/3298 where Safari
+ /* To fix https://github.com/vector-im/element-web/issues/3298 where Safari
needed height 100% all the way down to the HomePage. Height does not
have to be auto, empirically.
*/
diff --git a/res/css/structures/_RightPanel.scss b/res/css/structures/_RightPanel.scss
index 120f44db90..c7c0d6fac4 100644
--- a/res/css/structures/_RightPanel.scss
+++ b/res/css/structures/_RightPanel.scss
@@ -64,7 +64,7 @@ limitations under the License.
left: 4px; // center with parent of 32px
height: 24px;
width: 24px;
- background-color: $rightpanel-button-color;
+ background-color: $icon-button-color;
mask-repeat: no-repeat;
mask-size: contain;
}
@@ -99,7 +99,7 @@ limitations under the License.
background: rgba($accent-color, 0.25);
// make the icon the accent color too
&::before {
- background-color: $accent-color;
+ background-color: $accent-color !important;
}
}
diff --git a/res/css/structures/_RoomSearch.scss b/res/css/structures/_RoomSearch.scss
index 39a3dee30b..c33a3c0ff9 100644
--- a/res/css/structures/_RoomSearch.scss
+++ b/res/css/structures/_RoomSearch.scss
@@ -17,8 +17,10 @@ limitations under the License.
// Note: this component expects to be contained within a flexbox
.mx_RoomSearch {
flex: 1;
- border-radius: 20px;
+ border-radius: 8px;
background-color: $roomlist-button-bg-color;
+ // keep border thickness consistent to prevent movement
+ border: 1px solid transparent;
height: 28px;
padding: 2px;
@@ -29,9 +31,9 @@ limitations under the License.
.mx_RoomSearch_icon {
width: 16px;
height: 16px;
- mask: url('$(res)/img/feather-customised/search-input.svg');
+ mask: url('$(res)/img/element-icons/roomlist/search.svg');
mask-repeat: no-repeat;
- background: $primary-fg-color;
+ background-color: $secondary-fg-color;
margin-left: 7px;
}
@@ -46,19 +48,30 @@ limitations under the License.
line-height: $font-16px;
&:not(.mx_RoomSearch_inputExpanded)::placeholder {
- color: $primary-fg-color !important; // !important to override default app-wide styles
+ color: $tertiary-fg-color !important; // !important to override default app-wide styles
}
}
- &.mx_RoomSearch_expanded {
+ &.mx_RoomSearch_hasQuery {
+ border-color: $secondary-fg-color;
+ }
+
+ &.mx_RoomSearch_focused {
+ box-shadow: 0 0 4px 4px rgba(0, 132, 255, 0.5);
+ border-color: transparent;
+ }
+
+ &.mx_RoomSearch_focused, &.mx_RoomSearch_hasQuery {
+ background-color: $roomlist-filter-active-bg-color;
+
.mx_RoomSearch_clearButton {
width: 16px;
height: 16px;
- mask-image: url('$(res)/img/feather-customised/x.svg');
+ mask-image: url('$(res)/img/element-icons/roomlist/search-clear.svg');
mask-position: center;
mask-size: contain;
mask-repeat: no-repeat;
- background: $primary-fg-color;
+ background-color: $secondary-fg-color;
margin-right: 8px;
}
}
diff --git a/res/css/structures/_TagPanel.scss b/res/css/structures/_TagPanel.scss
index 78e8326772..cdca1f0764 100644
--- a/res/css/structures/_TagPanel.scss
+++ b/res/css/structures/_TagPanel.scss
@@ -30,30 +30,11 @@ limitations under the License.
cursor: pointer;
}
-.mx_TagPanel .mx_TagPanel_clearButton_container {
- /* Constant height within flex mx_TagPanel */
- height: 70px;
- width: 56px;
-
- flex: none;
-
- justify-content: center;
- align-items: flex-start;
-
- display: none;
-}
-
-.mx_TagPanel .mx_TagPanel_clearButton object {
- /* Same as .mx_SearchBox padding-top */
- margin-top: 24px;
- pointer-events: none;
-}
-
.mx_TagPanel .mx_TagPanel_divider {
height: 0px;
- width: 34px;
- border-bottom: 1px solid $panel-divider-color;
- display: none;
+ width: 90%;
+ border: none;
+ border-bottom: 1px solid $tagpanel-divider-color;
}
.mx_TagPanel .mx_TagPanel_scroller {
@@ -76,12 +57,57 @@ limitations under the License.
// opacity: 0.5;
position: relative;
}
+
+.mx_TagPanel .mx_TagTile.mx_TagTile_prototype {
+ padding: 3px;
+}
+
.mx_TagPanel .mx_TagTile:focus,
.mx_TagPanel .mx_TagTile:hover,
.mx_TagPanel .mx_TagTile.mx_TagTile_selected {
// opacity: 1;
}
+.mx_TagPanel .mx_TagTile.mx_TagTile_selected_prototype {
+ background-color: $primary-bg-color;
+ border-radius: 6px;
+}
+
+.mx_TagTile_selected_prototype {
+ .mx_TagTile_homeIcon::before {
+ background-color: $primary-fg-color; // dark-on-light
+ }
+}
+
+.mx_TagTile:not(.mx_TagTile_selected_prototype) .mx_TagTile_homeIcon {
+ background-color: $roomheader-addroom-bg-color;
+ border-radius: 48px;
+
+ &::before {
+ background-color: $roomheader-addroom-fg-color;
+ }
+}
+
+.mx_TagTile_homeIcon {
+ width: 32px;
+ height: 32px;
+ position: relative;
+
+ &::before {
+ mask-image: url('$(res)/img/element-icons/home.svg');
+ mask-position: center;
+ mask-repeat: no-repeat;
+ mask-size: 21px;
+ content: '';
+ display: inline-block;
+ width: 32px;
+ height: 32px;
+ position: absolute;
+ top: calc(50% - 16px);
+ left: calc(50% - 16px);
+ }
+}
+
.mx_TagPanel .mx_TagTile_plus {
margin-bottom: 12px;
height: 32px;
@@ -108,13 +134,12 @@ limitations under the License.
.mx_TagPanel .mx_TagTile.mx_TagTile_selected::before {
content: '';
- height: calc(100% + 16px);
+ height: 100%;
background-color: $accent-color;
- width: 5px;
+ width: 4px;
position: absolute;
- left: -15px;
+ left: -12px;
border-radius: 0 3px 3px 0;
- top: -8px; // (16px from height / 2)
}
.mx_TagPanel .mx_TagTile.mx_AccessibleButton:focus {
diff --git a/res/css/structures/_ToastContainer.scss b/res/css/structures/_ToastContainer.scss
index e798e4ac52..544dcbc180 100644
--- a/res/css/structures/_ToastContainer.scss
+++ b/res/css/structures/_ToastContainer.scss
@@ -80,10 +80,6 @@ limitations under the License.
}
}
- &.mx_Toast_icon_element_logo::after {
- background-image: url("$(res)/img/element-logo.svg");
- }
-
.mx_Toast_title, .mx_Toast_body {
grid-column: 2;
}
diff --git a/res/css/structures/_UserMenu.scss b/res/css/structures/_UserMenu.scss
index 81a10ee1d0..6fa2f2578e 100644
--- a/res/css/structures/_UserMenu.scss
+++ b/res/css/structures/_UserMenu.scss
@@ -16,9 +16,33 @@ limitations under the License.
.mx_UserMenu {
- // to make the ... button sort of aligned with the explore button below
+ // to make the menu button sort of aligned with the explore button below
padding-right: 6px;
+ &.mx_UserMenu_prototype {
+ // The margin & padding combination between here and the ::after is to
+ // align the border line with the tag panel.
+ margin-bottom: 6px;
+
+ padding-right: 0; // make the right edge line up with the explore button
+
+ .mx_UserMenu_headerButtons {
+ // considering we've eliminated right padding on the menu itself, we need to
+ // push the chevron in slightly (roughly lining up with the center of the
+ // plus buttons)
+ margin-right: 2px;
+ }
+
+ // we cheat opacity on the theme colour with an after selector here
+ &::after {
+ content: '';
+ border-bottom: 1px solid $primary-fg-color; // XXX: Variable abuse
+ opacity: 0.2;
+ display: block;
+ padding-top: 8px;
+ }
+ }
+
.mx_UserMenu_headerButtons {
width: 16px;
height: 16px;
@@ -36,7 +60,7 @@ limitations under the License.
mask-size: contain;
mask-repeat: no-repeat;
background: $primary-fg-color;
- mask-image: url('$(res)/img/element-icons/context-menu.svg');
+ mask-image: url('$(res)/img/feather-customised/chevron-down.svg');
}
}
@@ -56,6 +80,28 @@ limitations under the License.
}
}
+ .mx_UserMenu_doubleName {
+ flex: 1;
+ min-width: 0; // make flexbox aware that it can crush this to a tiny width
+
+ .mx_UserMenu_userName,
+ .mx_UserMenu_subUserName {
+ display: block;
+ }
+
+ .mx_UserMenu_subUserName {
+ color: $muted-fg-color;
+ font-size: $font-13px;
+ line-height: $font-18px;
+ flex: 1;
+
+ // Ellipsize any text overflow
+ text-overflow: ellipsis;
+ overflow: hidden;
+ white-space: nowrap;
+ }
+ }
+
.mx_UserMenu_userName {
font-weight: 600;
font-size: $font-15px;
@@ -89,15 +135,48 @@ limitations under the License.
.mx_UserMenu_contextMenu {
width: 247px;
- .mx_UserMenu_contextMenu_redRow {
+ // These override the styles already present on the user menu rather than try to
+ // define a new menu. They are specifically for the stacked menu when a community
+ // is being represented as a prototype.
+ &.mx_UserMenu_contextMenu_prototype {
+ padding-bottom: 16px;
+
+ .mx_UserMenu_contextMenu_header {
+ padding-bottom: 0;
+ padding-top: 16px;
+
+ &:nth-child(n + 2) {
+ padding-top: 8px;
+ }
+ }
+
+ hr {
+ width: 85%;
+ opacity: 0.2;
+ border: none;
+ border-bottom: 1px solid $primary-fg-color; // XXX: Variable abuse
+ }
+
+ &.mx_IconizedContextMenu {
+ > .mx_IconizedContextMenu_optionList {
+ margin-top: 4px;
+
+ &::before {
+ border: none;
+ }
+
+ > .mx_AccessibleButton {
+ padding-top: 2px;
+ padding-bottom: 2px;
+ }
+ }
+ }
+ }
+
+ &.mx_IconizedContextMenu .mx_IconizedContextMenu_optionList_red {
.mx_AccessibleButton {
padding-top: 16px;
padding-bottom: 16px;
- color: $warning-color !important; // !important to override styles from context menu
- }
-
- .mx_IconizedContextMenu_icon::before {
- background-color: $warning-color;
}
}
@@ -198,4 +277,12 @@ limitations under the License.
.mx_UserMenu_iconSignOut::before {
mask-image: url('$(res)/img/element-icons/leave.svg');
}
+
+ .mx_UserMenu_iconMembers::before {
+ mask-image: url('$(res)/img/element-icons/room/members.svg');
+ }
+
+ .mx_UserMenu_iconInvite::before {
+ mask-image: url('$(res)/img/element-icons/room/invite.svg');
+ }
}
diff --git a/res/css/views/avatars/_BaseAvatar.scss b/res/css/views/avatars/_BaseAvatar.scss
index e59598278f..1a1e14e7ac 100644
--- a/res/css/views/avatars/_BaseAvatar.scss
+++ b/res/css/views/avatars/_BaseAvatar.scss
@@ -22,7 +22,7 @@ limitations under the License.
// different results during full reflow of the page vs. incremental reflow
// of small portions. While that's surely a browser bug, we can avoid it by
// using `inline-block` instead of the default `inline`.
- // https://github.com/vector-im/riot-web/issues/5594
+ // https://github.com/vector-im/element-web/issues/5594
// https://bugzilla.mozilla.org/show_bug.cgi?id=1535053
// https://bugzilla.mozilla.org/show_bug.cgi?id=255139
display: inline-block;
diff --git a/res/css/views/avatars/_DecoratedRoomAvatar.scss b/res/css/views/avatars/_DecoratedRoomAvatar.scss
index 48d72131b5..e0afd9de66 100644
--- a/res/css/views/avatars/_DecoratedRoomAvatar.scss
+++ b/res/css/views/avatars/_DecoratedRoomAvatar.scss
@@ -18,10 +18,49 @@ limitations under the License.
.mx_DecoratedRoomAvatar, .mx_TemporaryTile {
position: relative;
- .mx_RoomTileIcon {
+ &.mx_DecoratedRoomAvatar_cutout .mx_BaseAvatar {
+ mask-image: url('$(res)/img/element-icons/roomlist/decorated-avatar-mask.svg');
+ mask-position: center;
+ mask-size: contain;
+ mask-repeat: no-repeat;
+ }
+
+ .mx_DecoratedRoomAvatar_icon {
position: absolute;
- bottom: 0;
- right: 0;
+ bottom: -2px;
+ right: -2px;
+ margin: 4px;
+ width: 8px;
+ height: 8px;
+ border-radius: 50%;
+ }
+
+ .mx_DecoratedRoomAvatar_icon::before {
+ content: '';
+ width: 8px;
+ height: 8px;
+ position: absolute;
+ border-radius: 8px;
+ }
+
+ .mx_DecoratedRoomAvatar_icon_globe::before {
+ mask-position: center;
+ mask-size: contain;
+ mask-repeat: no-repeat;
+ background: $secondary-fg-color;
+ mask-image: url('$(res)/img/globe.svg');
+ }
+
+ .mx_DecoratedRoomAvatar_icon_offline::before {
+ background-color: $presence-offline;
+ }
+
+ .mx_DecoratedRoomAvatar_icon_online::before {
+ background-color: $presence-online;
+ }
+
+ .mx_DecoratedRoomAvatar_icon_away::before {
+ background-color: $presence-away;
}
.mx_NotificationBadge, .mx_RoomTile_badgeContainer {
diff --git a/res/css/views/context_menus/_IconizedContextMenu.scss b/res/css/views/context_menus/_IconizedContextMenu.scss
new file mode 100644
index 0000000000..7913058995
--- /dev/null
+++ b/res/css/views/context_menus/_IconizedContextMenu.scss
@@ -0,0 +1,148 @@
+/*
+Copyright 2020 The Matrix.org Foundation C.I.C.
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+// A context menu that largely fits the | [icon] [label] | format.
+.mx_IconizedContextMenu {
+ min-width: 146px;
+
+ .mx_IconizedContextMenu_optionList {
+ & > * {
+ padding-left: 20px;
+ padding-right: 20px;
+ }
+
+ // the notFirst class is for cases where the optionList might be under a header of sorts.
+ &:nth-child(n + 2), .mx_IconizedContextMenu_optionList_notFirst {
+ // This is a bit of a hack when we could just use a simple border-top property,
+ // however we have a (kinda) good reason for doing it this way: we need opacity.
+ // To get the right color, we need an opacity modifier which means we have to work
+ // around the problem. PostCSS doesn't support the opacity() function, and if we
+ // use something like postcss-functions we quickly run into an issue where the
+ // function we would define gets passed a CSS variable for custom themes, which
+ // can't be converted easily even when considering https://stackoverflow.com/a/41265350/7037379
+ //
+ // Therefore, we just hack in a line and border the thing ourselves
+ &::before {
+ border-top: 1px solid $primary-fg-color;
+ opacity: 0.1;
+ content: '';
+
+ // Counteract the padding problems (width: 100% ignores the 40px padding,
+ // unless we position it absolutely then it does the right thing).
+ width: 100%;
+ position: absolute;
+ left: 0;
+ }
+ }
+
+ // round the top corners of the top button for the hover effect to be bounded
+ &:first-child .mx_AccessibleButton:first-child {
+ border-radius: 8px 8px 0 0; // radius matches .mx_ContextualMenu
+ }
+
+ // round the bottom corners of the bottom button for the hover effect to be bounded
+ &:last-child .mx_AccessibleButton:last-child {
+ border-radius: 0 0 8px 8px; // radius matches .mx_ContextualMenu
+ }
+
+ .mx_AccessibleButton {
+ // pad the inside of the button so that the hover background is padded too
+ padding-top: 12px;
+ padding-bottom: 12px;
+ text-decoration: none;
+ color: $primary-fg-color;
+ font-size: $font-15px;
+ line-height: $font-24px;
+
+ // Create a flexbox to more easily define the list items
+ display: flex;
+ align-items: center;
+
+ &:hover {
+ background-color: $menu-selected-color;
+ }
+
+ img, .mx_IconizedContextMenu_icon { // icons
+ width: 16px;
+ min-width: 16px;
+ max-width: 16px;
+ }
+
+ span.mx_IconizedContextMenu_label { // labels
+ padding-left: 14px;
+ width: 100%;
+ flex: 1;
+
+ // Ellipsize any text overflow
+ text-overflow: ellipsis;
+ overflow: hidden;
+ white-space: nowrap;
+ }
+ }
+ }
+
+ .mx_IconizedContextMenu_icon {
+ position: relative;
+ width: 16px;
+ height: 16px;
+
+ &::before {
+ content: '';
+ width: 16px;
+ height: 16px;
+ position: absolute;
+ mask-position: center;
+ mask-size: contain;
+ mask-repeat: no-repeat;
+ background: $primary-fg-color;
+ }
+ }
+
+ .mx_IconizedContextMenu_optionList_red {
+ .mx_AccessibleButton {
+ color: $warning-color !important;
+ }
+
+ .mx_IconizedContextMenu_icon::before {
+ background-color: $warning-color;
+ }
+ }
+
+ .mx_IconizedContextMenu_active {
+ &.mx_AccessibleButton, .mx_AccessibleButton {
+ color: $accent-color !important;
+ }
+
+ .mx_IconizedContextMenu_icon::before {
+ background-color: $accent-color;
+ }
+ }
+
+ &.mx_IconizedContextMenu_compact {
+ .mx_IconizedContextMenu_optionList > * {
+ padding: 8px 16px 8px 11px;
+ }
+ }
+
+ .mx_IconizedContextMenu_checked {
+ margin-left: 16px;
+ margin-right: -5px;
+
+ &::before {
+ mask-image: url('$(res)/img/element-icons/roomlist/checkmark.svg');
+ }
+ }
+}
diff --git a/res/css/views/context_menus/_RoomTileContextMenu.scss b/res/css/views/context_menus/_RoomTileContextMenu.scss
deleted file mode 100644
index 9697ac9bef..0000000000
--- a/res/css/views/context_menus/_RoomTileContextMenu.scss
+++ /dev/null
@@ -1,114 +0,0 @@
-/*
-Copyright 2015, 2016 OpenMarket Ltd
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
-*/
-
-.mx_RoomTileContextMenu {
- padding: 6px;
-}
-
-.mx_RoomTileContextMenu_tag_icon {
- padding-right: 8px;
- padding-left: 4px;
- display: inline-block;
-}
-
-.mx_RoomTileContextMenu_tag_icon_set {
- padding-right: 8px;
- padding-left: 4px;
- display: none;
-}
-
-.mx_RoomTileContextMenu_tag_field, .mx_RoomTileContextMenu_leave {
- padding-top: 8px;
- padding-right: 20px;
- padding-bottom: 8px;
- cursor: pointer;
- white-space: nowrap;
- display: flex;
- align-items: center;
- line-height: $font-16px;
-}
-
-.mx_RoomTileContextMenu_tag_field.mx_RoomTileContextMenu_tag_fieldSet {
- font-weight: bold;
-}
-
-.mx_RoomTileContextMenu_tag_field.mx_RoomTileContextMenu_tag_fieldSet .mx_RoomTileContextMenu_tag_icon {
- display: none;
-}
-
-.mx_RoomTileContextMenu_tag_field.mx_RoomTileContextMenu_tag_fieldSet .mx_RoomTileContextMenu_tag_icon_set {
- display: inline-block;
-}
-
-.mx_RoomTileContextMenu_tag_field.mx_RoomTileContextMenu_tag_fieldDisabled {
- color: rgba(0, 0, 0, 0.2);
-}
-
-.mx_RoomTileContextMenu_separator {
- margin-top: 0;
- margin-bottom: 0;
- border-bottom-style: none;
- border-left-style: none;
- border-right-style: none;
- border-top-style: solid;
- border-top-width: 1px;
- border-color: $menu-border-color;
-}
-
-.mx_RoomTileContextMenu_leave {
- color: $warning-color;
-}
-
-.mx_RoomTileContextMenu_notif_picker {
- position: absolute;
- top: 16px;
- left: 5px;
-}
-
-.mx_RoomTileContextMenu_notif_field {
- padding-top: 4px;
- padding-right: 6px;
- padding-bottom: 10px;
- padding-left: 8px; /* 20px */
- cursor: pointer;
- white-space: nowrap;
- display: flex;
- align-items: center;
-}
-
-.mx_RoomTileContextMenu_notif_field.mx_RoomTileContextMenu_notif_fieldSet {
- font-weight: bold;
-}
-
-.mx_RoomTileContextMenu_notif_field.mx_RoomTileContextMenu_notif_fieldDisabled {
- color: rgba(0, 0, 0, 0.2);
-}
-
-.mx_RoomTileContextMenu_notif_icon {
- padding-right: 4px;
- padding-left: 4px;
-}
-
-.mx_RoomTileContextMenu_notif_activeIcon {
- display: inline-block;
- opacity: 0;
- position: relative;
- left: -5px;
-}
-
-.mx_RoomTileContextMenu_notif_fieldSet .mx_RoomTileContextMenu_notif_activeIcon {
- opacity: 1;
-}
diff --git a/res/css/views/context_menus/_TopLeftMenu.scss b/res/css/views/context_menus/_TopLeftMenu.scss
deleted file mode 100644
index e0f5dd47bd..0000000000
--- a/res/css/views/context_menus/_TopLeftMenu.scss
+++ /dev/null
@@ -1,96 +0,0 @@
-/*
-Copyright 2018 New Vector Ltd
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
-*/
-
-.mx_TopLeftMenu {
- min-width: 210px;
- border-radius: 4px;
-
- .mx_TopLeftMenu_greyedText {
- font-size: $font-12px;
- opacity: 0.5;
- }
-
- .mx_TopLeftMenu_upgradeLink {
- font-size: $font-12px;
-
- img {
- margin-left: 5px;
- }
- }
-
- .mx_TopLeftMenu_section:not(:last-child) {
- border-bottom: 1px solid $menu-border-color;
- }
-
- .mx_TopLeftMenu_section_noIcon {
- margin: 5px 0;
- padding: 5px 20px 5px 15px;
-
- div:not(:first-child) {
- margin-top: 5px;
- }
- }
-
- .mx_TopLeftMenu_section_withIcon {
- margin: 5px 0;
- padding: 0;
- list-style: none;
-
- .mx_TopLeftMenu_icon_home::after {
- mask-image: url('$(res)/img/feather-customised/home.svg');
- }
-
- .mx_TopLeftMenu_icon_help::after {
- mask-image: url('$(res)/img/feather-customised/life-buoy.svg');
- }
-
- .mx_TopLeftMenu_icon_settings::after {
- mask-image: url('$(res)/img/feather-customised/settings.svg');
- }
-
- .mx_TopLeftMenu_icon_signin::after {
- mask-image: url('$(res)/img/feather-customised/sign-in.svg');
- }
-
- .mx_TopLeftMenu_icon_signout::after {
- mask-image: url('$(res)/img/feather-customised/sign-out.svg');
- }
-
- .mx_AccessibleButton::after {
- mask-repeat: no-repeat;
- mask-position: 0 center;
- mask-size: $font-16px;
- position: absolute;
- width: $font-16px;
- height: $font-16px;
- content: "";
- top: 5px;
- left: 14px;
- background-color: $primary-fg-color;
- }
-
- .mx_AccessibleButton {
- position: relative;
- cursor: pointer;
- white-space: nowrap;
- padding: 5px 20px 5px 43px;
- }
-
- .mx_AccessibleButton:hover {
- background-color: $menu-selected-color;
- }
- }
-}
diff --git a/res/css/views/dialogs/_BugReportDialog.scss b/res/css/views/dialogs/_BugReportDialog.scss
new file mode 100644
index 0000000000..1920ac33ea
--- /dev/null
+++ b/res/css/views/dialogs/_BugReportDialog.scss
@@ -0,0 +1,23 @@
+/*
+Copyright 2020 The Matrix.org Foundation C.I.C.
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+.mx_BugReportDialog {
+ .mx_BugReportDialog_download {
+ .mx_AccessibleButton_kind_link {
+ padding-left: 0;
+ }
+ }
+}
diff --git a/res/css/views/dialogs/_CommunityPrototypeInviteDialog.scss b/res/css/views/dialogs/_CommunityPrototypeInviteDialog.scss
new file mode 100644
index 0000000000..beae03f00f
--- /dev/null
+++ b/res/css/views/dialogs/_CommunityPrototypeInviteDialog.scss
@@ -0,0 +1,88 @@
+/*
+Copyright 2020 The Matrix.org Foundation C.I.C.
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+.mx_CommunityPrototypeInviteDialog {
+ &.mx_Dialog_fixedWidth {
+ width: 360px;
+ }
+
+ .mx_Dialog_content {
+ margin-bottom: 0;
+
+ .mx_CommunityPrototypeInviteDialog_people {
+ position: relative;
+ margin-bottom: 4px;
+
+ .mx_AccessibleButton {
+ display: inline-block;
+ background-color: $focus-bg-color; // XXX: Abuse of variables
+ border-radius: 4px;
+ padding: 3px 5px;
+ font-size: $font-12px;
+ float: right;
+ }
+ }
+
+ .mx_CommunityPrototypeInviteDialog_morePeople {
+ margin-top: 8px;
+ }
+
+ .mx_CommunityPrototypeInviteDialog_person {
+ position: relative;
+ margin-top: 4px;
+
+ & > * {
+ vertical-align: middle;
+ }
+
+ .mx_Checkbox {
+ position: absolute;
+ right: 0;
+ top: calc(50% - 8px); // checkbox is 16px high
+ width: 16px; // to force a square
+ }
+
+ .mx_CommunityPrototypeInviteDialog_personIdentifiers {
+ display: inline-block;
+
+ & > * {
+ display: block;
+ }
+
+ .mx_CommunityPrototypeInviteDialog_personName {
+ font-weight: 600;
+ font-size: $font-14px;
+ color: $primary-fg-color;
+ margin-left: 7px;
+ }
+
+ .mx_CommunityPrototypeInviteDialog_personId {
+ font-size: $font-12px;
+ color: $muted-fg-color;
+ margin-left: 7px;
+ }
+ }
+ }
+
+ .mx_CommunityPrototypeInviteDialog_primaryButton {
+ display: block;
+ font-size: $font-13px;
+ line-height: 20px;
+ height: 20px;
+ margin-top: 24px;
+ }
+ }
+}
diff --git a/res/css/views/dialogs/_CreateCommunityPrototypeDialog.scss b/res/css/views/dialogs/_CreateCommunityPrototypeDialog.scss
new file mode 100644
index 0000000000..81babc4c38
--- /dev/null
+++ b/res/css/views/dialogs/_CreateCommunityPrototypeDialog.scss
@@ -0,0 +1,102 @@
+/*
+Copyright 2020 The Matrix.org Foundation C.I.C.
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+.mx_CreateCommunityPrototypeDialog {
+ .mx_Dialog_content {
+ display: flex;
+ flex-direction: row;
+ margin-bottom: 12px;
+
+ .mx_CreateCommunityPrototypeDialog_colName {
+ flex-basis: 66.66%;
+ padding-right: 100px;
+
+ .mx_Field input {
+ font-size: $font-16px;
+ line-height: $font-20px;
+ }
+
+ .mx_CreateCommunityPrototypeDialog_subtext {
+ display: block;
+ color: $muted-fg-color;
+ margin-bottom: 16px;
+
+ &:last-child {
+ margin-top: 16px;
+ }
+
+ &.mx_CreateCommunityPrototypeDialog_subtext_error {
+ color: $warning-color;
+ }
+ }
+
+ .mx_CreateCommunityPrototypeDialog_communityId {
+ position: relative;
+
+ .mx_InfoTooltip {
+ float: right;
+ }
+ }
+
+ .mx_AccessibleButton {
+ display: block;
+ height: 32px;
+ font-size: $font-16px;
+ line-height: 32px;
+ }
+ }
+
+ .mx_CreateCommunityPrototypeDialog_colAvatar {
+ flex-basis: 33.33%;
+
+ .mx_CreateCommunityPrototypeDialog_avatarContainer {
+ margin-top: 12px;
+ margin-bottom: 20px;
+
+ .mx_CreateCommunityPrototypeDialog_avatar,
+ .mx_CreateCommunityPrototypeDialog_placeholderAvatar {
+ width: 96px;
+ height: 96px;
+ border-radius: 96px;
+ }
+
+ .mx_CreateCommunityPrototypeDialog_placeholderAvatar {
+ background-color: #368bd6; // hardcoded for both themes
+
+ &::before {
+ display: inline-block;
+ background-color: #fff; // hardcoded because the background is
+ mask-repeat: no-repeat;
+ mask-size: 96px;
+ width: 96px;
+ height: 96px;
+ mask-position: center;
+ content: '';
+ vertical-align: middle;
+ mask-image: url('$(res)/img/element-icons/add-photo.svg');
+ }
+ }
+ }
+
+ .mx_CreateCommunityPrototypeDialog_tip {
+ & > b, & > span {
+ display: block;
+ color: $muted-fg-color;
+ }
+ }
+ }
+ }
+}
diff --git a/res/css/views/dialogs/_EditCommunityPrototypeDialog.scss b/res/css/views/dialogs/_EditCommunityPrototypeDialog.scss
new file mode 100644
index 0000000000..75a56bf6b3
--- /dev/null
+++ b/res/css/views/dialogs/_EditCommunityPrototypeDialog.scss
@@ -0,0 +1,77 @@
+/*
+Copyright 2020 The Matrix.org Foundation C.I.C.
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+// XXX: many of these styles are shared with the create dialog
+.mx_EditCommunityPrototypeDialog {
+ &.mx_Dialog_fixedWidth {
+ width: 360px;
+ }
+
+ .mx_Dialog_content {
+ margin-bottom: 12px;
+
+ .mx_AccessibleButton.mx_AccessibleButton_kind_primary {
+ display: block;
+ height: 32px;
+ font-size: $font-16px;
+ line-height: 32px;
+ }
+
+ .mx_EditCommunityPrototypeDialog_rowAvatar {
+ display: flex;
+ flex-direction: row;
+ align-items: center;
+ }
+
+ .mx_EditCommunityPrototypeDialog_avatarContainer {
+ margin-top: 20px;
+ margin-bottom: 20px;
+
+ .mx_EditCommunityPrototypeDialog_avatar,
+ .mx_EditCommunityPrototypeDialog_placeholderAvatar {
+ width: 96px;
+ height: 96px;
+ border-radius: 96px;
+ }
+
+ .mx_EditCommunityPrototypeDialog_placeholderAvatar {
+ background-color: #368bd6; // hardcoded for both themes
+
+ &::before {
+ display: inline-block;
+ background-color: #fff; // hardcoded because the background is
+ mask-repeat: no-repeat;
+ mask-size: 96px;
+ width: 96px;
+ height: 96px;
+ mask-position: center;
+ content: '';
+ vertical-align: middle;
+ mask-image: url('$(res)/img/element-icons/add-photo.svg');
+ }
+ }
+ }
+
+ .mx_EditCommunityPrototypeDialog_tip {
+ margin-left: 20px;
+
+ & > b, & > span {
+ display: block;
+ color: $muted-fg-color;
+ }
+ }
+ }
+}
diff --git a/res/css/views/dialogs/_InviteDialog.scss b/res/css/views/dialogs/_InviteDialog.scss
index a77d0bfbba..b9063f46b9 100644
--- a/res/css/views/dialogs/_InviteDialog.scss
+++ b/res/css/views/dialogs/_InviteDialog.scss
@@ -89,6 +89,13 @@ limitations under the License.
font-weight: bold;
text-transform: uppercase;
}
+
+ .mx_InviteDialog_subname {
+ margin-bottom: 10px;
+ margin-top: -10px; // HACK: Positioning with margins is bad
+ font-size: $font-12px;
+ color: $muted-fg-color;
+ }
}
.mx_InviteDialog_roomTile {
@@ -226,3 +233,7 @@ limitations under the License.
.mx_InviteDialog_addressBar {
margin-right: 45px;
}
+
+.mx_InviteDialog_helpText .mx_AccessibleButton_kind_link {
+ padding: 0;
+}
diff --git a/res/css/views/dialogs/_RebrandDialog.scss b/res/css/views/dialogs/_RebrandDialog.scss
deleted file mode 100644
index 534584ae2a..0000000000
--- a/res/css/views/dialogs/_RebrandDialog.scss
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
-Copyright 2020 The Matrix.org Foundation C.I.C.
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
-*/
-
-.mx_RebrandDialog {
- text-align: center;
-
- a:link,
- a:hover,
- a:visited {
- @mixin mx_Dialog_link;
- }
-
- .mx_Dialog_buttons {
- margin-top: 43px;
- text-align: center;
- }
-}
-
-.mx_RebrandDialog_body {
- width: 550px;
- margin-left: auto;
- margin-right: auto;
-}
-
-.mx_RebrandDialog_logoContainer {
- margin-top: 35px;
- margin-bottom: 20px;
- display: flex;
- align-items: center;
- justify-content: center;
-}
-
-.mx_RebrandDialog_logo {
- margin-left: 28px;
- margin-right: 28px;
- width: 64px;
- height: 64px;
-}
-
-.mx_RebrandDialog_chevron::after {
- content: '';
- display: inline-block;
- width: 30px;
- height: 30px;
- mask-position: center;
- mask-size: contain;
- mask-repeat: no-repeat;
- background-color: $muted-fg-color;
- mask-image: url('$(res)/img/feather-customised/chevron-down.svg');
- transform: rotate(-90deg);
-}
diff --git a/res/css/views/dialogs/_ShareDialog.scss b/res/css/views/dialogs/_ShareDialog.scss
index d2fe98e8f9..c343b872fd 100644
--- a/res/css/views/dialogs/_ShareDialog.scss
+++ b/res/css/views/dialogs/_ShareDialog.scss
@@ -51,7 +51,8 @@ limitations under the License.
display: inherit;
}
.mx_ShareDialog_matrixto_copy > div {
- background-image: url($copy-button-url);
+ mask-image: url($copy-button-url);
+ background-color: $message-action-bar-fg-color;
margin-left: 5px;
width: 20px;
height: 20px;
diff --git a/res/css/views/room_settings/_ColorSettings.scss b/res/css/views/elements/_InfoTooltip.scss
similarity index 56%
rename from res/css/views/room_settings/_ColorSettings.scss
rename to res/css/views/elements/_InfoTooltip.scss
index fc6a4443ad..5858a60629 100644
--- a/res/css/views/room_settings/_ColorSettings.scss
+++ b/res/css/views/elements/_InfoTooltip.scss
@@ -1,5 +1,5 @@
/*
-Copyright 2019 New Vector Ltd.
+Copyright 2020 The Matrix.org Foundation C.I.C.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -14,26 +14,21 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
-.mx_ColorSettings_roomColor {
+.mx_InfoTooltip_icon {
+ width: 16px;
+ height: 16px;
display: inline-block;
- position: relative;
- width: 37px;
- height: 37px;
- border: 1px solid #979797;
- margin-right: 13px;
- cursor: pointer;
}
-.mx_ColorSettings_roomColor_selected {
- position: absolute;
- left: 10px;
- top: 4px;
- cursor: default !important;
-}
-
-.mx_ColorSettings_roomColorPrimary {
- height: 10px;
- position: absolute;
- bottom: 0px;
- width: 100%;
+.mx_InfoTooltip_icon::before {
+ display: inline-block;
+ background-color: $muted-fg-color;
+ mask-repeat: no-repeat;
+ mask-size: 16px;
+ width: 16px;
+ height: 16px;
+ mask-position: center;
+ content: '';
+ vertical-align: middle;
+ mask-image: url('$(res)/img/element-icons/info.svg');
}
diff --git a/res/css/views/elements/_StyledCheckbox.scss b/res/css/views/elements/_StyledCheckbox.scss
index 60f1bf0277..e2d61c033b 100644
--- a/res/css/views/elements/_StyledCheckbox.scss
+++ b/res/css/views/elements/_StyledCheckbox.scss
@@ -80,5 +80,11 @@ limitations under the License.
background-color: $accent-color;
border-color: $accent-color;
}
+
+ &.focus-visible {
+ & + label .mx_Checkbox_background {
+ @mixin unreal-focus;
+ }
+ }
}
}
diff --git a/res/css/views/elements/_StyledRadioButton.scss b/res/css/views/elements/_StyledRadioButton.scss
index ffa1337ebb..62fb5c5512 100644
--- a/res/css/views/elements/_StyledRadioButton.scss
+++ b/res/css/views/elements/_StyledRadioButton.scss
@@ -63,6 +63,7 @@ limitations under the License.
box-sizing: border-box;
height: $font-16px;
width: $font-16px;
+ margin-left: 2px; // For the highlight on focus
border: $font-1-5px solid $radio-circle-color;
border-radius: $font-16px;
@@ -77,6 +78,12 @@ limitations under the License.
}
}
+ &.focus-visible {
+ & + div {
+ @mixin unreal-focus;
+ }
+ }
+
&:checked {
& + div {
border-color: $active-radio-circle-color;
diff --git a/res/css/views/messages/_MImageBody.scss b/res/css/views/messages/_MImageBody.scss
index 547b16e9ad..1c773c2f06 100644
--- a/res/css/views/messages/_MImageBody.scss
+++ b/res/css/views/messages/_MImageBody.scss
@@ -25,6 +25,7 @@ limitations under the License.
height: 100%;
left: 0;
top: 0;
+ border-radius: 4px;
}
.mx_MImageBody_thumbnail_container {
diff --git a/res/css/views/messages/_MessageActionBar.scss b/res/css/views/messages/_MessageActionBar.scss
index e3ccd99611..1254b496b5 100644
--- a/res/css/views/messages/_MessageActionBar.scss
+++ b/res/css/views/messages/_MessageActionBar.scss
@@ -24,7 +24,7 @@ limitations under the License.
line-height: $font-24px;
border-radius: 4px;
background: $message-action-bar-bg-color;
- top: -18px;
+ top: -26px;
right: 8px;
user-select: none;
// Ensure the action bar appears above over things, like the read marker.
@@ -41,7 +41,7 @@ limitations under the License.
width: calc(10px + 48px + 100% + 8px);
// safe area + action bar
height: calc(20px + 100%);
- top: -20px;
+ top: -12px;
left: -58px;
z-index: -1;
cursor: initial;
diff --git a/res/css/views/rooms/_EventTile.scss b/res/css/views/rooms/_EventTile.scss
index 2a2191b799..eb0e1dd7b0 100644
--- a/res/css/views/rooms/_EventTile.scss
+++ b/res/css/views/rooms/_EventTile.scss
@@ -536,11 +536,12 @@ $left-gutter: 64px;
display: inline-block;
visibility: hidden;
cursor: pointer;
- top: 8px;
+ top: 6px;
right: 6px;
width: 19px;
height: 19px;
- background-image: url($copy-button-url);
+ mask-image: url($copy-button-url);
+ background-color: $message-action-bar-fg-color;
}
.mx_EventTile_body .mx_EventTile_pre_container:focus-within .mx_EventTile_copyButton,
diff --git a/res/css/views/rooms/_IRCLayout.scss b/res/css/views/rooms/_IRCLayout.scss
index ed60c220e7..958d718b11 100644
--- a/res/css/views/rooms/_IRCLayout.scss
+++ b/res/css/views/rooms/_IRCLayout.scss
@@ -54,7 +54,7 @@ $irc-line-height: $font-18px;
flex-shrink: 0;
width: var(--name-width);
text-overflow: ellipsis;
- text-align: right;
+ text-align: left;
display: flex;
align-items: center;
overflow: visible;
diff --git a/res/css/views/rooms/_MessageComposer.scss b/res/css/views/rooms/_MessageComposer.scss
index ec95403262..a403a8dc4c 100644
--- a/res/css/views/rooms/_MessageComposer.scss
+++ b/res/css/views/rooms/_MessageComposer.scss
@@ -21,6 +21,7 @@ limitations under the License.
border-top: 1px solid $primary-hairline-color;
position: relative;
padding-left: 82px;
+ padding-right: 6px;
}
.mx_MessageComposer_replaced_wrapper {
@@ -178,25 +179,44 @@ limitations under the License.
color: $accent-color;
}
+.mx_MessageComposer_button_highlight {
+ background: rgba($accent-color, 0.25);
+ // make the icon the accent color too
+ &::before {
+ background-color: $accent-color !important;
+ }
+}
+
.mx_MessageComposer_button {
position: relative;
- margin-right: 12px;
+ margin-right: 6px;
cursor: pointer;
- height: 20px;
- width: 20px;
+ height: 26px;
+ width: 26px;
+ border-radius: 100%;
&::before {
content: '';
position: absolute;
+ top: 3px;
+ left: 3px;
height: 20px;
width: 20px;
- background-color: $composer-button-color;
+ background-color: $icon-button-color;
mask-repeat: no-repeat;
mask-size: contain;
mask-position: center;
}
+ &:hover {
+ background: rgba($accent-color, 0.1);
+
+ &::before {
+ background-color: $accent-color;
+ }
+ }
+
&.mx_MessageComposer_hangup::before {
background-color: $warning-color;
}
@@ -288,7 +308,7 @@ limitations under the License.
mask-size: contain;
mask-position: center;
mask-repeat: no-repeat;
- background-color: $composer-button-color;
+ background-color: $icon-button-color;
&.mx_MessageComposer_markdownDisabled {
opacity: 0.2;
diff --git a/res/css/views/rooms/_ReplyPreview.scss b/res/css/views/rooms/_ReplyPreview.scss
index 229b4291db..c1fe1d9a8b 100644
--- a/res/css/views/rooms/_ReplyPreview.scss
+++ b/res/css/views/rooms/_ReplyPreview.scss
@@ -15,10 +15,6 @@ limitations under the License.
*/
.mx_ReplyPreview {
- position: absolute;
- bottom: 0;
- z-index: 1000;
- width: 100%;
border: 1px solid $primary-hairline-color;
background: $primary-bg-color;
border-bottom: none;
diff --git a/res/css/views/rooms/_RoomHeader.scss b/res/css/views/rooms/_RoomHeader.scss
index ba46100ea6..a880a7bee2 100644
--- a/res/css/views/rooms/_RoomHeader.scss
+++ b/res/css/views/rooms/_RoomHeader.scss
@@ -222,7 +222,7 @@ limitations under the License.
left: 4px; // center with parent of 32px
height: 24px;
width: 24px;
- background-color: $roomheader-button-color;
+ background-color: $icon-button-color;
mask-repeat: no-repeat;
mask-size: contain;
}
diff --git a/res/css/views/rooms/_RoomList.scss b/res/css/views/rooms/_RoomList.scss
index 89ab85e146..78e7307bc0 100644
--- a/res/css/views/rooms/_RoomList.scss
+++ b/res/css/views/rooms/_RoomList.scss
@@ -17,3 +17,43 @@ limitations under the License.
.mx_RoomList {
padding-right: 7px; // width of the scrollbar, to line things up
}
+
+.mx_RoomList_iconPlus::before {
+ mask-image: url('$(res)/img/element-icons/roomlist/plus.svg');
+}
+.mx_RoomList_iconExplore::before {
+ mask-image: url('$(res)/img/element-icons/roomlist/explore.svg');
+}
+
+.mx_RoomList_explorePrompt {
+ margin: 4px 12px 4px;
+ padding-top: 12px;
+ border-top: 1px solid $tertiary-fg-color;
+ font-size: $font-13px;
+
+ div:first-child {
+ font-weight: $font-semi-bold;
+ margin-bottom: 8px;
+ }
+
+ .mx_AccessibleButton {
+ color: $secondary-fg-color;
+ position: relative;
+ padding: 0 0 0 24px;
+ font-size: inherit;
+
+ &::before {
+ content: '';
+ width: 16px;
+ height: 16px;
+ position: absolute;
+ top: 0;
+ left: 0;
+ background: $secondary-fg-color;
+ mask-position: center;
+ mask-size: contain;
+ mask-repeat: no-repeat;
+ mask-image: url('$(res)/img/element-icons/roomlist/explore.svg');
+ }
+ }
+}
diff --git a/res/css/views/rooms/_RoomSublist.scss b/res/css/views/rooms/_RoomSublist.scss
index d3c9b79c69..543940fb78 100644
--- a/res/css/views/rooms/_RoomSublist.scss
+++ b/res/css/views/rooms/_RoomSublist.scss
@@ -120,7 +120,7 @@ limitations under the License.
}
.mx_RoomSublist_auxButton::before {
- mask-image: url('$(res)/img/feather-customised/plus.svg');
+ mask-image: url('$(res)/img/element-icons/roomlist/plus.svg');
}
.mx_RoomSublist_menuButton::before {
@@ -169,7 +169,7 @@ limitations under the License.
// that the sublists below them do not jump. However, that leaves a gap
// when scrolled to the top above the first sublist (whose header can only
// ever stick to top), so we force height to 0 for only that first header.
- // See also https://github.com/vector-im/riot-web/issues/14429.
+ // See also https://github.com/vector-im/element-web/issues/14429.
&:first-child .mx_RoomSublist_headerContainer {
height: 0;
padding-bottom: 4px;
diff --git a/res/css/views/rooms/_RoomTile.scss b/res/css/views/rooms/_RoomTile.scss
index f22228602d..8eca3f1efa 100644
--- a/res/css/views/rooms/_RoomTile.scss
+++ b/res/css/views/rooms/_RoomTile.scss
@@ -175,48 +175,8 @@ limitations under the License.
.mx_RoomTile_iconBellMentions::before {
mask-image: url('$(res)/img/element-icons/roomlist/notifications-dm.svg');
}
-.mx_RoomTile_iconCheck::before {
- mask-image: url('$(res)/img/element-icons/roomlist/checkmark.svg');
-}
.mx_RoomTile_contextMenu {
- .mx_RoomTile_contextMenu_redRow {
- .mx_AccessibleButton {
- color: $warning-color !important; // !important to override styles from context menu
- }
-
- .mx_IconizedContextMenu_icon::before {
- background-color: $warning-color;
- }
- }
-
- .mx_RoomTile_contextMenu_activeRow {
- &.mx_AccessibleButton, .mx_AccessibleButton {
- color: $accent-color !important; // !important to override styles from context menu
- }
-
- .mx_IconizedContextMenu_icon::before {
- background-color: $accent-color;
- }
- }
-
- .mx_IconizedContextMenu_icon {
- position: relative;
- width: 16px;
- height: 16px;
-
- &::before {
- content: '';
- width: 16px;
- height: 16px;
- position: absolute;
- mask-position: center;
- mask-size: contain;
- mask-repeat: no-repeat;
- background: $primary-fg-color;
- }
- }
-
.mx_RoomTile_iconStar::before {
mask-image: url('$(res)/img/element-icons/roomlist/favorite.svg');
}
diff --git a/res/css/views/rooms/_RoomTileIcon.scss b/res/css/views/rooms/_RoomTileIcon.scss
deleted file mode 100644
index 2f3afdd446..0000000000
--- a/res/css/views/rooms/_RoomTileIcon.scss
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
-Copyright 2020 The Matrix.org Foundation C.I.C.
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
-*/
-
-.mx_RoomTileIcon {
- width: 12px;
- height: 12px;
- border-radius: 12px;
- background-color: $roomlist-bg-color; // to match the room list itself
-}
-
-.mx_RoomTileIcon_globe::before {
- content: '';
- width: 8px;
- height: 8px;
- top: 2px;
- left: 2px;
- position: absolute;
- mask-position: center;
- mask-size: contain;
- mask-repeat: no-repeat;
- background: $primary-fg-color;
- mask-image: url('$(res)/img/globe.svg');
-}
-
-.mx_RoomTileIcon_offline::before {
- content: '';
- width: 8px;
- height: 8px;
- top: 2px;
- left: 2px;
- position: absolute;
- border-radius: 8px;
- background-color: $presence-offline;
-}
-
-.mx_RoomTileIcon_online::before {
- content: '';
- width: 8px;
- height: 8px;
- top: 2px;
- left: 2px;
- position: absolute;
- border-radius: 8px;
- background-color: $presence-online;
-}
-
-.mx_RoomTileIcon_away::before {
- content: '';
- width: 8px;
- height: 8px;
- top: 2px;
- left: 2px;
- position: absolute;
- border-radius: 8px;
- background-color: $presence-away;
-}
diff --git a/res/css/views/rooms/_SendMessageComposer.scss b/res/css/views/rooms/_SendMessageComposer.scss
index 0b646666e7..9f6a8d52ce 100644
--- a/res/css/views/rooms/_SendMessageComposer.scss
+++ b/res/css/views/rooms/_SendMessageComposer.scss
@@ -44,10 +44,5 @@ limitations under the License.
overflow-y: auto;
}
}
-
- .mx_SendMessageComposer_overlayWrapper {
- position: relative;
- height: 0;
- }
}
diff --git a/res/css/views/settings/tabs/room/_SecurityRoomSettingsTab.scss b/res/css/views/settings/tabs/room/_SecurityRoomSettingsTab.scss
index b5a57dfefb..23dcc532b2 100644
--- a/res/css/views/settings/tabs/room/_SecurityRoomSettingsTab.scss
+++ b/res/css/views/settings/tabs/room/_SecurityRoomSettingsTab.scss
@@ -14,10 +14,6 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
-.mx_SecurityRoomSettingsTab label {
- display: block;
-}
-
.mx_SecurityRoomSettingsTab_warning {
display: block;
diff --git a/res/img/element-icons/add-photo.svg b/res/img/element-icons/add-photo.svg
new file mode 100644
index 0000000000..bde5253bea
--- /dev/null
+++ b/res/img/element-icons/add-photo.svg
@@ -0,0 +1,5 @@
+
diff --git a/res/img/element-icons/home.svg b/res/img/element-icons/home.svg
new file mode 100644
index 0000000000..a6c15456ff
--- /dev/null
+++ b/res/img/element-icons/home.svg
@@ -0,0 +1,3 @@
+
diff --git a/res/img/element-icons/info.svg b/res/img/element-icons/info.svg
new file mode 100644
index 0000000000..b5769074ab
--- /dev/null
+++ b/res/img/element-icons/info.svg
@@ -0,0 +1,4 @@
+
diff --git a/res/img/element-icons/roomlist/decorated-avatar-mask.svg b/res/img/element-icons/roomlist/decorated-avatar-mask.svg
new file mode 100644
index 0000000000..fb09c16bba
--- /dev/null
+++ b/res/img/element-icons/roomlist/decorated-avatar-mask.svg
@@ -0,0 +1,3 @@
+
diff --git a/res/img/element-icons/roomlist/explore.svg b/res/img/element-icons/roomlist/explore.svg
new file mode 100644
index 0000000000..3786ce1153
--- /dev/null
+++ b/res/img/element-icons/roomlist/explore.svg
@@ -0,0 +1,4 @@
+
diff --git a/res/img/element-icons/roomlist/plus.svg b/res/img/element-icons/roomlist/plus.svg
new file mode 100644
index 0000000000..f6d80ac7ef
--- /dev/null
+++ b/res/img/element-icons/roomlist/plus.svg
@@ -0,0 +1,3 @@
+
diff --git a/res/img/element-icons/roomlist/search-clear.svg b/res/img/element-icons/roomlist/search-clear.svg
new file mode 100644
index 0000000000..29fc097600
--- /dev/null
+++ b/res/img/element-icons/roomlist/search-clear.svg
@@ -0,0 +1,3 @@
+
diff --git a/res/img/element-icons/roomlist/search.svg b/res/img/element-icons/roomlist/search.svg
new file mode 100644
index 0000000000..b706092a5c
--- /dev/null
+++ b/res/img/element-icons/roomlist/search.svg
@@ -0,0 +1,3 @@
+
diff --git a/res/img/element-logo.svg b/res/img/element-logo.svg
deleted file mode 100644
index 2cd11ed193..0000000000
--- a/res/img/element-logo.svg
+++ /dev/null
@@ -1,6 +0,0 @@
-
diff --git a/res/img/feather-customised/clipboard.svg b/res/img/feather-customised/clipboard.svg
new file mode 100644
index 0000000000..b25b97176c
--- /dev/null
+++ b/res/img/feather-customised/clipboard.svg
@@ -0,0 +1,4 @@
+
diff --git a/res/img/feather-customised/compass.svg b/res/img/feather-customised/compass.svg
deleted file mode 100644
index 3296260803..0000000000
--- a/res/img/feather-customised/compass.svg
+++ /dev/null
@@ -1 +0,0 @@
-
\ No newline at end of file
diff --git a/res/img/globe.svg b/res/img/globe.svg
index cc22bc6e66..635fa91cce 100644
--- a/res/img/globe.svg
+++ b/res/img/globe.svg
@@ -1,6 +1,3 @@
diff --git a/res/img/icon_copy_message.svg b/res/img/icon_copy_message.svg
deleted file mode 100644
index 8d8887bb22..0000000000
--- a/res/img/icon_copy_message.svg
+++ /dev/null
@@ -1,86 +0,0 @@
-
-
diff --git a/res/img/riot-logo.svg b/res/img/riot-logo.svg
deleted file mode 100644
index ac1e547234..0000000000
--- a/res/img/riot-logo.svg
+++ /dev/null
@@ -1,6 +0,0 @@
-
diff --git a/res/themes/dark/css/_dark.scss b/res/themes/dark/css/_dark.scss
index e39bb29044..a3b03c777e 100644
--- a/res/themes/dark/css/_dark.scss
+++ b/res/themes/dark/css/_dark.scss
@@ -46,7 +46,7 @@ $inverted-bg-color: $base-color;
$selected-color: $room-highlight-color;
// selected for hoverover & selected event tiles
-$event-selected-color: $header-panel-bg-color;
+$event-selected-color: #21262c;
// used for the hairline dividers in RoomView
$primary-hairline-color: transparent;
@@ -100,10 +100,9 @@ $roomheader-bg-color: $bg-color;
$roomheader-addroom-bg-color: rgba(92, 100, 112, 0.3);
$roomheader-addroom-fg-color: $text-primary-color;
$tagpanel-button-color: $header-panel-text-primary-color;
-$roomheader-button-color: $header-panel-text-primary-color;
$groupheader-button-color: $header-panel-text-primary-color;
$rightpanel-button-color: $header-panel-text-primary-color;
-$composer-button-color: $header-panel-text-primary-color;
+$icon-button-color: #8E99A4;
$roomtopic-color: $text-secondary-color;
$eventtile-meta-color: $roomtopic-color;
@@ -115,10 +114,13 @@ $composer-e2e-icon-color: $header-panel-text-primary-color;
$theme-button-bg-color: #e3e8f0;
$roomlist-button-bg-color: rgba(141, 151, 165, 0.2); // Buttons include the filter box, explore button, and sublist buttons
+$roomlist-filter-active-bg-color: $bg-color;
$roomlist-bg-color: rgba(33, 38, 44, 0.90);
$roomlist-header-color: $tertiary-fg-color;
$roomsublist-divider-color: $primary-fg-color;
+$tagpanel-divider-color: $roomlist-header-color;
+
$roomtile-preview-color: $secondary-fg-color;
$roomtile-default-badge-bg-color: #61708b;
$roomtile-selected-bg-color: rgba(141, 151, 165, 0.2);
diff --git a/res/themes/legacy-dark/css/_legacy-dark.scss b/res/themes/legacy-dark/css/_legacy-dark.scss
index 7ecfcf13d9..2741dcebf8 100644
--- a/res/themes/legacy-dark/css/_legacy-dark.scss
+++ b/res/themes/legacy-dark/css/_legacy-dark.scss
@@ -15,6 +15,8 @@ $room-highlight-color: #343a46;
// typical text (dark-on-white in light skin)
$primary-fg-color: $text-primary-color;
+$secondary-fg-color: $primary-fg-color;
+$tertiary-fg-color: $primary-fg-color;
$primary-bg-color: $bg-color;
$muted-fg-color: $header-panel-text-primary-color;
@@ -95,10 +97,9 @@ $roomheader-color: $text-primary-color;
$roomheader-addroom-bg-color: #3c4556; // $search-placeholder-color at 0.5 opacity
$roomheader-addroom-fg-color: $text-primary-color;
$tagpanel-button-color: $header-panel-text-primary-color;
-$roomheader-button-color: $header-panel-text-primary-color;
$groupheader-button-color: $header-panel-text-primary-color;
$rightpanel-button-color: $header-panel-text-primary-color;
-$composer-button-color: $header-panel-text-primary-color;
+$icon-button-color: $header-panel-text-primary-color;
$roomtopic-color: $text-secondary-color;
$eventtile-meta-color: $roomtopic-color;
@@ -110,10 +111,13 @@ $composer-e2e-icon-color: $header-panel-text-primary-color;
$theme-button-bg-color: #e3e8f0;
$roomlist-button-bg-color: #1A1D23; // Buttons include the filter box, explore button, and sublist buttons
+$roomlist-filter-active-bg-color: $roomlist-button-bg-color;
$roomlist-bg-color: $header-panel-bg-color;
$roomsublist-divider-color: $primary-fg-color;
+$tagpanel-divider-color: $roomlist-header-color;
+
$roomtile-preview-color: #9e9e9e;
$roomtile-default-badge-bg-color: #61708b;
$roomtile-selected-bg-color: #1A1D23;
diff --git a/res/themes/legacy-light/css/_legacy-light.scss b/res/themes/legacy-light/css/_legacy-light.scss
index 3465aa307e..4fd2a3615b 100644
--- a/res/themes/legacy-light/css/_legacy-light.scss
+++ b/res/themes/legacy-light/css/_legacy-light.scss
@@ -23,6 +23,8 @@ $header-panel-bg-color: #f3f8fd;
// typical text (dark-on-white in light skin)
$primary-fg-color: #2e2f32;
+$secondary-fg-color: $primary-fg-color;
+$tertiary-fg-color: $primary-fg-color;
$primary-bg-color: #ffffff;
$muted-fg-color: #61708b; // Commonly used in headings and relevant alt text
@@ -162,10 +164,9 @@ $roomheader-bg-color: $primary-bg-color;
$roomheader-addroom-bg-color: #91a1c0;
$roomheader-addroom-fg-color: $accent-fg-color;
$tagpanel-button-color: #91a1c0;
-$roomheader-button-color: #91a1c0;
$groupheader-button-color: #91a1c0;
$rightpanel-button-color: #91a1c0;
-$composer-button-color: #91a1c0;
+$icon-button-color: #91a1c0;
$roomtopic-color: #9e9e9e;
$eventtile-meta-color: $roomtopic-color;
@@ -177,10 +178,13 @@ $header-divider-color: #91a1c0;
$theme-button-bg-color: #e3e8f0;
$roomlist-button-bg-color: #fff; // Buttons include the filter box, explore button, and sublist buttons
+$roomlist-filter-active-bg-color: $roomlist-button-bg-color;
$roomlist-bg-color: $header-panel-bg-color;
$roomlist-header-color: $primary-fg-color;
$roomsublist-divider-color: $primary-fg-color;
+$tagpanel-divider-color: $roomlist-header-color;
+
$roomtile-preview-color: #9e9e9e;
$roomtile-default-badge-bg-color: #61708b;
$roomtile-selected-bg-color: #fff;
@@ -228,7 +232,8 @@ $event-redacted-border-color: #cccccc;
// event timestamp
$event-timestamp-color: #acacac;
-$copy-button-url: "$(res)/img/icon_copy_message.svg";
+$copy-button-url: "$(res)/img/feather-customised/clipboard.svg";
+
// e2e
$e2e-verified-color: #76cfa5; // N.B. *NOT* the same as $accent-color
diff --git a/res/themes/legacy-light/css/_paths.scss b/res/themes/legacy-light/css/_paths.scss
index 0744347826..3944076004 100644
--- a/res/themes/legacy-light/css/_paths.scss
+++ b/res/themes/legacy-light/css/_paths.scss
@@ -1,3 +1,3 @@
// Path from root SCSS file (such as `light.scss`) to `res` dir in the source tree
-// This value is overridden by external themes in `riot-web`.
+// This value is overridden by external themes in `element-web`.
$res: ../../..;
diff --git a/res/themes/light/css/_light.scss b/res/themes/light/css/_light.scss
index e67bcdf89a..05302a2a80 100644
--- a/res/themes/light/css/_light.scss
+++ b/res/themes/light/css/_light.scss
@@ -74,7 +74,7 @@ $droptarget-bg-color: rgba(255,255,255,0.5);
$selected-color: $secondary-accent-color;
// selected for hoverover & selected event tiles
-$event-selected-color: $header-panel-bg-color;
+$event-selected-color: #f6f7f8;
// used for the hairline dividers in RoomView
$primary-hairline-color: transparent;
@@ -158,10 +158,9 @@ $roomheader-bg-color: $primary-bg-color;
$roomheader-addroom-bg-color: rgba(92, 100, 112, 0.2);
$roomheader-addroom-fg-color: #5c6470;
$tagpanel-button-color: #91A1C0;
-$roomheader-button-color: #91A1C0;
$groupheader-button-color: #91A1C0;
$rightpanel-button-color: #91A1C0;
-$composer-button-color: #91A1C0;
+$icon-button-color: #C1C6CD;
$roomtopic-color: #9e9e9e;
$eventtile-meta-color: $roomtopic-color;
@@ -172,11 +171,14 @@ $header-divider-color: #91A1C0;
$theme-button-bg-color: #e3e8f0;
-$roomlist-button-bg-color: #fff; // Buttons include the filter box, explore button, and sublist buttons
+$roomlist-button-bg-color: rgba(141, 151, 165, 0.2); // Buttons include the filter box, explore button, and sublist buttons
+$roomlist-filter-active-bg-color: #ffffff;
$roomlist-bg-color: rgba(245, 245, 245, 0.90);
$roomlist-header-color: $tertiary-fg-color;
$roomsublist-divider-color: $primary-fg-color;
+$tagpanel-divider-color: $roomlist-header-color;
+
$roomtile-preview-color: $secondary-fg-color;
$roomtile-default-badge-bg-color: #61708b;
$roomtile-selected-bg-color: #FFF;
@@ -230,7 +232,7 @@ $event-redacted-border-color: #cccccc;
// event timestamp
$event-timestamp-color: #acacac;
-$copy-button-url: "$(res)/img/icon_copy_message.svg";
+$copy-button-url: "$(res)/img/feather-customised/clipboard.svg";
// e2e
$e2e-verified-color: #76cfa5; // N.B. *NOT* the same as $accent-color
diff --git a/res/themes/light/css/_paths.scss b/res/themes/light/css/_paths.scss
index 0744347826..3944076004 100644
--- a/res/themes/light/css/_paths.scss
+++ b/res/themes/light/css/_paths.scss
@@ -1,3 +1,3 @@
// Path from root SCSS file (such as `light.scss`) to `res` dir in the source tree
-// This value is overridden by external themes in `riot-web`.
+// This value is overridden by external themes in `element-web`.
$res: ../../..;
diff --git a/scripts/ci/end-to-end-tests.sh b/scripts/ci/end-to-end-tests.sh
index 1233677db4..7a62c03b12 100755
--- a/scripts/ci/end-to-end-tests.sh
+++ b/scripts/ci/end-to-end-tests.sh
@@ -13,7 +13,7 @@ handle_error() {
trap 'handle_error' ERR
-echo "--- Building Riot"
+echo "--- Building Element"
scripts/ci/layered-riot-web.sh
cd ../riot-web
riot_web_dir=`pwd`
diff --git a/scripts/gen-i18n.js b/scripts/gen-i18n.js
index c30ac62e3b..91733469f7 100755
--- a/scripts/gen-i18n.js
+++ b/scripts/gen-i18n.js
@@ -217,7 +217,7 @@ function getTranslationsOther(file) {
const trs = new Set();
- // Taken from riot-web src/components/structures/HomePage.js
+ // Taken from element-web src/components/structures/HomePage.js
const translationsRegex = /_t\(['"]([\s\S]*?)['"]\)/mg;
let matches;
while (matches = translationsRegex.exec(contents)) {
diff --git a/src/@types/global.d.ts b/src/@types/global.d.ts
index 6510c02160..84340d8219 100644
--- a/src/@types/global.d.ts
+++ b/src/@types/global.d.ts
@@ -19,17 +19,20 @@ import ContentMessages from "../ContentMessages";
import { IMatrixClientPeg } from "../MatrixClientPeg";
import ToastStore from "../stores/ToastStore";
import DeviceListener from "../DeviceListener";
-import RebrandListener from "../RebrandListener";
import { RoomListStoreClass } from "../stores/room-list/RoomListStore";
import { PlatformPeg } from "../PlatformPeg";
import RoomListLayoutStore from "../stores/room-list/RoomListLayoutStore";
import {IntegrationManagers} from "../integrations/IntegrationManagers";
import {ModalManager} from "../Modal";
import SettingsStore from "../settings/SettingsStore";
+import {ActiveRoomObserver} from "../ActiveRoomObserver";
+import {Notifier} from "../Notifier";
+import type {Renderer} from "react-dom";
declare global {
interface Window {
Modernizr: ModernizrStatic;
+ matrixChat: ReturnType;
mxMatrixClientPeg: IMatrixClientPeg;
Olm: {
init: () => Promise;
@@ -38,18 +41,14 @@ declare global {
mxContentMessages: ContentMessages;
mxToastStore: ToastStore;
mxDeviceListener: DeviceListener;
- mxRebrandListener: RebrandListener;
mxRoomListStore: RoomListStoreClass;
mxRoomListLayoutStore: RoomListLayoutStore;
+ mxActiveRoomObserver: ActiveRoomObserver;
mxPlatformPeg: PlatformPeg;
mxIntegrationManagers: typeof IntegrationManagers;
singletonModalManager: ModalManager;
mxSettingsStore: SettingsStore;
- }
-
- // workaround for https://github.com/microsoft/TypeScript/issues/30933
- interface ObjectConstructor {
- fromEntries?(xs: [string|number|symbol, any][]): object;
+ mxNotifier: typeof Notifier;
}
interface Document {
@@ -77,4 +76,8 @@ declare global {
interface PromiseConstructor {
allSettled(promises: Promise[]): Promise | ISettledRejected>>;
}
+
+ interface HTMLAudioElement {
+ type?: string;
+ }
}
diff --git a/src/ActiveRoomObserver.js b/src/ActiveRoomObserver.ts
similarity index 54%
rename from src/ActiveRoomObserver.js
rename to src/ActiveRoomObserver.ts
index b7695d401d..1126dc9496 100644
--- a/src/ActiveRoomObserver.js
+++ b/src/ActiveRoomObserver.ts
@@ -16,6 +16,8 @@ limitations under the License.
import RoomViewStore from './stores/RoomViewStore';
+type Listener = (isActive: boolean) => void;
+
/**
* Consumes changes from the RoomViewStore and notifies specific things
* about when the active room changes. Unlike listening for RoomViewStore
@@ -25,57 +27,57 @@ import RoomViewStore from './stores/RoomViewStore';
* TODO: If we introduce an observer for something else, factor out
* the adding / removing of listeners & emitting into a common class.
*/
-class ActiveRoomObserver {
- constructor() {
- this._listeners = {}; // key=roomId, value=function(isActive:boolean)
+export class ActiveRoomObserver {
+ private listeners: {[key: string]: Listener[]} = {};
+ private _activeRoomId = RoomViewStore.getRoomId();
+ private readonly roomStoreToken: string;
- this._activeRoomId = RoomViewStore.getRoomId();
- // TODO: We could self-destruct when the last listener goes away, or at least
- // stop listening.
- this._roomStoreToken = RoomViewStore.addListener(this._onRoomViewStoreUpdate.bind(this));
+ constructor() {
+ // TODO: We could self-destruct when the last listener goes away, or at least stop listening.
+ this.roomStoreToken = RoomViewStore.addListener(this.onRoomViewStoreUpdate);
}
- get activeRoomId(): string {
+ public get activeRoomId(): string {
return this._activeRoomId;
}
- addListener(roomId, listener) {
- if (!this._listeners[roomId]) this._listeners[roomId] = [];
- this._listeners[roomId].push(listener);
+ public addListener(roomId, listener) {
+ if (!this.listeners[roomId]) this.listeners[roomId] = [];
+ this.listeners[roomId].push(listener);
}
- removeListener(roomId, listener) {
- if (this._listeners[roomId]) {
- const i = this._listeners[roomId].indexOf(listener);
+ public removeListener(roomId, listener) {
+ if (this.listeners[roomId]) {
+ const i = this.listeners[roomId].indexOf(listener);
if (i > -1) {
- this._listeners[roomId].splice(i, 1);
+ this.listeners[roomId].splice(i, 1);
}
} else {
console.warn("Unregistering unrecognised listener (roomId=" + roomId + ")");
}
}
- _emit(roomId, isActive: boolean) {
- if (!this._listeners[roomId]) return;
+ private emit(roomId, isActive: boolean) {
+ if (!this.listeners[roomId]) return;
- for (const l of this._listeners[roomId]) {
+ for (const l of this.listeners[roomId]) {
l.call(null, isActive);
}
}
- _onRoomViewStoreUpdate() {
+ private onRoomViewStoreUpdate = () => {
// emit for the old room ID
- if (this._activeRoomId) this._emit(this._activeRoomId, false);
+ if (this._activeRoomId) this.emit(this._activeRoomId, false);
// update our cache
this._activeRoomId = RoomViewStore.getRoomId();
// and emit for the new one
- if (this._activeRoomId) this._emit(this._activeRoomId, true);
- }
+ if (this._activeRoomId) this.emit(this._activeRoomId, true);
+ };
}
-if (global.mx_ActiveRoomObserver === undefined) {
- global.mx_ActiveRoomObserver = new ActiveRoomObserver();
+if (window.mxActiveRoomObserver === undefined) {
+ window.mxActiveRoomObserver = new ActiveRoomObserver();
}
-export default global.mx_ActiveRoomObserver;
+export default window.mxActiveRoomObserver;
diff --git a/src/AsyncWrapper.js b/src/AsyncWrapper.js
index 05054cf63a..359828b312 100644
--- a/src/AsyncWrapper.js
+++ b/src/AsyncWrapper.js
@@ -15,7 +15,7 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
-import createReactClass from 'create-react-class';
+import React from "react";
import * as sdk from './index';
import PropTypes from 'prop-types';
import { _t } from './languageHandler';
@@ -24,24 +24,22 @@ import { _t } from './languageHandler';
* Wrap an asynchronous loader function with a react component which shows a
* spinner until the real component loads.
*/
-export default createReactClass({
- propTypes: {
+export default class AsyncWrapper extends React.Component {
+ static propTypes = {
/** A promise which resolves with the real component
*/
prom: PropTypes.object.isRequired,
- },
+ };
- getInitialState: function() {
- return {
- component: null,
- error: null,
- };
- },
+ state = {
+ component: null,
+ error: null,
+ };
- componentDidMount: function() {
+ componentDidMount() {
this._unmounted = false;
// XXX: temporary logging to try to diagnose
- // https://github.com/vector-im/riot-web/issues/3148
+ // https://github.com/vector-im/element-web/issues/3148
console.log('Starting load of AsyncWrapper for modal');
this.props.prom.then((result) => {
if (this._unmounted) {
@@ -56,17 +54,17 @@ export default createReactClass({
console.warn('AsyncWrapper promise failed', e);
this.setState({error: e});
});
- },
+ }
- componentWillUnmount: function() {
+ componentWillUnmount() {
this._unmounted = true;
- },
+ }
- _onWrapperCancelClick: function() {
+ _onWrapperCancelClick = () => {
this.props.onFinished(false);
- },
+ };
- render: function() {
+ render() {
if (this.state.component) {
const Component = this.state.component;
return ;
@@ -87,6 +85,6 @@ export default createReactClass({
const Spinner = sdk.getComponent("elements.Spinner");
return ;
}
- },
-});
+ }
+}
diff --git a/src/BasePlatform.ts b/src/BasePlatform.ts
index acf72a986c..4d06c5df73 100644
--- a/src/BasePlatform.ts
+++ b/src/BasePlatform.ts
@@ -156,6 +156,14 @@ export default abstract class BasePlatform {
loudNotification(ev: Event, room: Object) {
}
+ clearNotification(notif: Notification) {
+ // Some browsers don't support this, e.g Safari on iOS
+ // https://developer.mozilla.org/en-US/docs/Web/API/Notification/close
+ if (notif.close) {
+ notif.close();
+ }
+ }
+
/**
* Returns a promise that resolves to a string representing the current version of the application.
*/
diff --git a/src/CallHandler.js b/src/CallHandler.js
index d5e058ef1e..18f6aeb98a 100644
--- a/src/CallHandler.js
+++ b/src/CallHandler.js
@@ -90,7 +90,7 @@ function play(audioId) {
// This is usually because the user hasn't interacted with the document,
// or chrome doesn't think so and is denying the request. Not sure what
// we can really do here...
- // https://github.com/vector-im/riot-web/issues/7657
+ // https://github.com/vector-im/element-web/issues/7657
console.log("Unable to play audio clip", e);
}
};
@@ -474,15 +474,15 @@ const callHandler = {
/**
* The conference handler is a module that deals with implementation-specific
- * multi-party calling implementations. Riot passes in its own which creates
+ * multi-party calling implementations. Element passes in its own which creates
* a one-to-one call with a freeswitch conference bridge. As of July 2018,
* the de-facto way of conference calling is a Jitsi widget, so this is
* deprecated. It reamins here for two reasons:
- * 1. So Riot still supports joining existing freeswitch conference calls
+ * 1. So Element still supports joining existing freeswitch conference calls
* (but doesn't support creating them). After a transition period, we can
* remove support for joining them too.
* 2. To hide the one-to-one rooms that old-style conferencing creates. This
- * is much harder to remove: probably either we make Riot leave & forget these
+ * is much harder to remove: probably either we make Element leave & forget these
* rooms after we remove support for joining freeswitch conferences, or we
* accept that random rooms with cryptic users will suddently appear for
* anyone who's ever used conference calling, or we are stuck with this
diff --git a/src/ContentMessages.tsx b/src/ContentMessages.tsx
index 6f55a75d0c..eb8fff0eb1 100644
--- a/src/ContentMessages.tsx
+++ b/src/ContentMessages.tsx
@@ -70,6 +70,7 @@ interface IContent {
interface IThumbnail {
info: {
+ // eslint-disable-next-line camelcase
thumbnail_info: {
w: number;
h: number;
@@ -104,7 +105,12 @@ interface IAbortablePromise extends Promise {
* @return {Promise} A promise that resolves with an object with an info key
* and a thumbnail key.
*/
-function createThumbnail(element: ThumbnailableElement, inputWidth: number, inputHeight: number, mimeType: string): Promise {
+function createThumbnail(
+ element: ThumbnailableElement,
+ inputWidth: number,
+ inputHeight: number,
+ mimeType: string,
+): Promise {
return new Promise((resolve) => {
let targetWidth = inputWidth;
let targetHeight = inputHeight;
@@ -437,11 +443,13 @@ export default class ContentMessages {
for (let i = 0; i < okFiles.length; ++i) {
const file = okFiles[i];
if (!uploadAll) {
- const {finished} = Modal.createTrackedDialog<[boolean, boolean]>('Upload Files confirmation', '', UploadConfirmDialog, {
- file,
- currentIndex: i,
- totalFiles: okFiles.length,
- });
+ const {finished} = Modal.createTrackedDialog<[boolean, boolean]>('Upload Files confirmation',
+ '', UploadConfirmDialog, {
+ file,
+ currentIndex: i,
+ totalFiles: okFiles.length,
+ },
+ );
const [shouldContinue, shouldUploadAll] = await finished;
if (!shouldContinue) break;
if (shouldUploadAll) {
diff --git a/src/CrossSigningManager.js b/src/CrossSigningManager.js
index a584a69d35..0353bfc5ae 100644
--- a/src/CrossSigningManager.js
+++ b/src/CrossSigningManager.js
@@ -21,6 +21,7 @@ import { deriveKey } from 'matrix-js-sdk/src/crypto/key_passphrase';
import { decodeRecoveryKey } from 'matrix-js-sdk/src/crypto/recoverykey';
import { _t } from './languageHandler';
import {encodeBase64} from "matrix-js-sdk/src/crypto/olmlib";
+import { isSecureBackupRequired } from './utils/WellKnownUtils';
// This stores the secret storage private keys in memory for the JS SDK. This is
// only meant to act as a cache to avoid prompting the user multiple times
@@ -34,6 +35,17 @@ function isCachingAllowed() {
return secretStorageBeingAccessed;
}
+/**
+ * This can be used by other components to check if secret storage access is in
+ * progress, so that we can e.g. avoid intermittently showing toasts during
+ * secret storage setup.
+ *
+ * @returns {bool}
+ */
+export function isSecretStorageBeingAccessed() {
+ return secretStorageBeingAccessed;
+}
+
export class AccessCancelledError extends Error {
constructor() {
super("Secret storage access canceled");
@@ -57,19 +69,19 @@ async function getSecretStorageKey({ keys: keyInfos }, ssssItemName) {
if (keyInfoEntries.length > 1) {
throw new Error("Multiple storage key requests not implemented");
}
- const [name, info] = keyInfoEntries[0];
+ const [keyId, keyInfo] = keyInfoEntries[0];
// Check the in-memory cache
- if (isCachingAllowed() && secretStorageKeys[name]) {
- return [name, secretStorageKeys[name]];
+ if (isCachingAllowed() && secretStorageKeys[keyId]) {
+ return [keyId, secretStorageKeys[keyId]];
}
const inputToKey = async ({ passphrase, recoveryKey }) => {
if (passphrase) {
return deriveKey(
passphrase,
- info.passphrase.salt,
- info.passphrase.iterations,
+ keyInfo.passphrase.salt,
+ keyInfo.passphrase.iterations,
);
} else {
return decodeRecoveryKey(recoveryKey);
@@ -81,10 +93,10 @@ async function getSecretStorageKey({ keys: keyInfos }, ssssItemName) {
AccessSecretStorageDialog,
/* props= */
{
- keyInfo: info,
+ keyInfo,
checkPrivateKey: async (input) => {
const key = await inputToKey(input);
- return await MatrixClientPeg.get().checkSecretStorageKey(key, info);
+ return await MatrixClientPeg.get().checkSecretStorageKey(key, keyInfo);
},
},
/* className= */ null,
@@ -106,11 +118,15 @@ async function getSecretStorageKey({ keys: keyInfos }, ssssItemName) {
const key = await inputToKey(input);
// Save to cache to avoid future prompts in the current session
- if (isCachingAllowed()) {
- secretStorageKeys[name] = key;
- }
+ cacheSecretStorageKey(keyId, key);
- return [name, key];
+ return [keyId, key];
+}
+
+function cacheSecretStorageKey(keyId, key) {
+ if (isCachingAllowed()) {
+ secretStorageKeys[keyId] = key;
+ }
}
const onSecretRequested = async function({
@@ -129,27 +145,21 @@ const onSecretRequested = async function({
console.log(`CrossSigningManager: Ignoring request from untrusted device ${deviceId}`);
return;
}
- if (name.startsWith("m.cross_signing")) {
+ if (
+ name === "m.cross_signing.master" ||
+ name === "m.cross_signing.self_signing" ||
+ name === "m.cross_signing.user_signing"
+ ) {
const callbacks = client.getCrossSigningCacheCallbacks();
if (!callbacks.getCrossSigningKeyCache) return;
- /* Explicit enumeration here is deliberate – never share the master key! */
- if (name === "m.cross_signing.self_signing") {
- const key = await callbacks.getCrossSigningKeyCache("self_signing");
- if (!key) {
- console.log(
- `self_signing requested by ${deviceId}, but not found in cache`,
- );
- }
- return key && encodeBase64(key);
- } else if (name === "m.cross_signing.user_signing") {
- const key = await callbacks.getCrossSigningKeyCache("user_signing");
- if (!key) {
- console.log(
- `user_signing requested by ${deviceId}, but not found in cache`,
- );
- }
- return key && encodeBase64(key);
+ const keyId = name.replace("m.cross_signing.", "");
+ const key = await callbacks.getCrossSigningKeyCache(keyId);
+ if (!key) {
+ console.log(
+ `${keyId} requested by ${deviceId}, but not found in cache`,
+ );
}
+ return key && encodeBase64(key);
} else if (name === "m.megolm_backup.v1") {
const key = await client._crypto.getSessionBackupPrivateKey();
if (!key) {
@@ -164,6 +174,7 @@ const onSecretRequested = async function({
export const crossSigningCallbacks = {
getSecretStorageKey,
+ cacheSecretStorageKey,
onSecretRequested,
};
@@ -212,9 +223,20 @@ export async function accessSecretStorage(func = async () => { }, forceReset = f
const { finished } = Modal.createTrackedDialogAsync('Create Secret Storage dialog', '',
import("./async-components/views/dialogs/secretstorage/CreateSecretStorageDialog"),
{
- force: forceReset,
+ forceReset,
+ },
+ null,
+ /* priority = */ false,
+ /* static = */ true,
+ /* options = */ {
+ onBeforeClose(reason) {
+ // If Secure Backup is required, you cannot leave the modal.
+ if (reason === "backgroundClick") {
+ return !isSecureBackupRequired();
+ }
+ return true;
+ },
},
- null, /* priority = */ false, /* static = */ true,
);
const [confirmed] = await finished;
if (!confirmed) {
@@ -222,7 +244,7 @@ export async function accessSecretStorage(func = async () => { }, forceReset = f
}
} else {
const InteractiveAuthDialog = sdk.getComponent("dialogs.InteractiveAuthDialog");
- await cli.bootstrapSecretStorage({
+ await cli.bootstrapCrossSigning({
authUploadDeviceSigningKeys: async (makeRequest) => {
const { finished } = Modal.createTrackedDialog(
'Cross-signing keys dialog', '', InteractiveAuthDialog,
@@ -237,7 +259,9 @@ export async function accessSecretStorage(func = async () => { }, forceReset = f
throw new Error("Cross-signing key upload auth canceled");
}
},
- getBackupPassphrase: promptForBackupPassphrase,
+ });
+ await cli.bootstrapSecretStorage({
+ getKeyBackupPassphrase: promptForBackupPassphrase,
});
}
diff --git a/src/DeviceListener.ts b/src/DeviceListener.ts
index a37521118f..156d8db61b 100644
--- a/src/DeviceListener.ts
+++ b/src/DeviceListener.ts
@@ -15,6 +15,7 @@ limitations under the License.
*/
import {MatrixClientPeg} from './MatrixClientPeg';
+import dis from "./dispatcher/dispatcher";
import {
hideToast as hideBulkUnverifiedSessionsToast,
showToast as showBulkUnverifiedSessionsToast,
@@ -28,11 +29,16 @@ import {
hideToast as hideUnverifiedSessionsToast,
showToast as showUnverifiedSessionsToast,
} from "./toasts/UnverifiedSessionToast";
-import {privateShouldBeEncrypted} from "./createRoom";
+import { privateShouldBeEncrypted } from "./createRoom";
+import { isSecretStorageBeingAccessed, accessSecretStorage } from "./CrossSigningManager";
+import { isSecureBackupRequired } from './utils/WellKnownUtils';
+import { isLoggedIn } from './components/structures/MatrixChat';
+
const KEY_BACKUP_POLL_INTERVAL = 5 * 60 * 1000;
export default class DeviceListener {
+ private dispatcherRef: string;
// device IDs for which the user has dismissed the verify toast ('Later')
private dismissed = new Set();
// has the user dismissed any of the various nag toasts to setup encryption on this device?
@@ -60,6 +66,7 @@ export default class DeviceListener {
MatrixClientPeg.get().on('crossSigning.keysChanged', this._onCrossSingingKeysChanged);
MatrixClientPeg.get().on('accountData', this._onAccountData);
MatrixClientPeg.get().on('sync', this._onSync);
+ this.dispatcherRef = dis.register(this._onAction);
this._recheck();
}
@@ -73,6 +80,10 @@ export default class DeviceListener {
MatrixClientPeg.get().removeListener('accountData', this._onAccountData);
MatrixClientPeg.get().removeListener('sync', this._onSync);
}
+ if (this.dispatcherRef) {
+ dis.unregister(this.dispatcherRef);
+ this.dispatcherRef = null;
+ }
this.dismissed.clear();
this.dismissedThisDeviceToast = false;
this.keyBackupInfo = null;
@@ -158,6 +169,11 @@ export default class DeviceListener {
if (state === 'PREPARED' && prevState === null) this._recheck();
};
+ _onAction = ({ action }) => {
+ if (action !== "on_logged_in") return;
+ this._recheck();
+ };
+
// The server doesn't tell us when key backup is set up, so we poll
// & cache the result
async _getKeyBackupInfo() {
@@ -170,6 +186,9 @@ export default class DeviceListener {
}
private shouldShowSetupEncryptionToast() {
+ // If we're in the middle of a secret storage operation, we're likely
+ // modifying the state involved here, so don't add new toasts to setup.
+ if (isSecretStorageBeingAccessed()) return false;
// In a default configuration, show the toasts. If the well-known config causes e2ee default to be false
// then do not show the toasts until user is in at least one encrypted room.
if (privateShouldBeEncrypted()) return true;
@@ -188,16 +207,23 @@ export default class DeviceListener {
// (we add a listener on sync to do once check after the initial sync is done)
if (!cli.isInitialSyncComplete()) return;
+ // JRS: This will change again in the next PR which moves secret storage
+ // later in the process.
const crossSigningReady = await cli.isCrossSigningReady();
+ const secretStorageReady = await cli.isSecretStorageReady();
+ const allSystemsReady = crossSigningReady && secretStorageReady;
- if (this.dismissedThisDeviceToast || crossSigningReady) {
+ if (this.dismissedThisDeviceToast || allSystemsReady) {
hideSetupEncryptionToast();
} else if (this.shouldShowSetupEncryptionToast()) {
// make sure our keys are finished downloading
await cli.downloadKeys([cli.getUserId()]);
// cross signing isn't enabled - nag to enable it
// There are 3 different toasts for:
- if (cli.getStoredCrossSigningForUser(cli.getUserId())) {
+ if (
+ !cli.getCrossSigningId() &&
+ cli.getStoredCrossSigningForUser(cli.getUserId())
+ ) {
// Cross-signing on account but this device doesn't trust the master key (verify this session)
showSetupEncryptionToast(SetupKind.VERIFY_THIS_SESSION);
} else {
@@ -207,7 +233,15 @@ export default class DeviceListener {
showSetupEncryptionToast(SetupKind.UPGRADE_ENCRYPTION);
} else {
// No cross-signing or key backup on account (set up encryption)
- showSetupEncryptionToast(SetupKind.SET_UP_ENCRYPTION);
+ await cli.waitForClientWellKnown();
+ if (isSecureBackupRequired() && isLoggedIn()) {
+ // If we're meant to set up, and Secure Backup is required,
+ // trigger the flow directly without a toast once logged in.
+ hideSetupEncryptionToast();
+ accessSecretStorage();
+ } else {
+ showSetupEncryptionToast(SetupKind.SET_UP_ENCRYPTION);
+ }
}
}
}
diff --git a/src/FromWidgetPostMessageApi.js b/src/FromWidgetPostMessageApi.js
index 1b4aa19ebf..d5d7c08d50 100644
--- a/src/FromWidgetPostMessageApi.js
+++ b/src/FromWidgetPostMessageApi.js
@@ -197,7 +197,7 @@ export default class FromWidgetPostMessageApi {
const integId = (data && data.integId) ? data.integId : null;
// TODO: Open the right integration manager for the widget
- if (SettingsStore.isFeatureEnabled("feature_many_integration_managers")) {
+ if (SettingsStore.getValue("feature_many_integration_managers")) {
IntegrationManagers.sharedInstance().openAll(
MatrixClientPeg.get().getRoom(RoomViewStore.getRoomId()),
`type_${integType}`,
diff --git a/src/HtmlUtils.tsx b/src/HtmlUtils.tsx
index 77a9579f2c..bd314c2e5f 100644
--- a/src/HtmlUtils.tsx
+++ b/src/HtmlUtils.tsx
@@ -339,33 +339,9 @@ class HtmlHighlighter extends BaseHighlighter {
}
}
-class TextHighlighter extends BaseHighlighter {
- private key = 0;
-
- /* create a node to hold the given content
- *
- * snippet: content of the span
- * highlight: true to highlight as a search match
- *
- * returns a React node
- */
- protected processSnippet(snippet: string, highlight: boolean): React.ReactNode {
- const key = this.key++;
-
- let node =
- { snippet }
- ;
-
- if (highlight && this.highlightLink) {
- node = { node };
- }
-
- return node;
- }
-}
-
interface IContent {
format?: string;
+ // eslint-disable-next-line camelcase
formatted_body?: string;
body: string;
}
@@ -421,7 +397,7 @@ export function bodyToHtml(content: IContent, highlights: string[], opts: IOpts
}
let formattedBody = typeof content.formatted_body === 'string' ? content.formatted_body : null;
- const plainBody = typeof content.body === 'string' ? content.body : null;
+ const plainBody = typeof content.body === 'string' ? content.body : "";
if (opts.stripReplyFallback && formattedBody) formattedBody = ReplyThread.stripHTMLReply(formattedBody);
strippedBody = opts.stripReplyFallback ? ReplyThread.stripPlainReply(plainBody) : plainBody;
@@ -474,8 +450,13 @@ export function bodyToHtml(content: IContent, highlights: string[], opts: IOpts
});
return isDisplayedWithHtml ?
- :
- { strippedBody };
+ : { strippedBody };
}
/**
diff --git a/src/IdentityAuthClient.js b/src/IdentityAuthClient.js
index 4a830d6506..fbdb6812ee 100644
--- a/src/IdentityAuthClient.js
+++ b/src/IdentityAuthClient.js
@@ -177,7 +177,7 @@ export default class IdentityAuthClient {
// appropriately. We already clear storage on sign out, but we'll need
// additional clearing when changing ISes in settings as part of future
// privacy work.
- // See also https://github.com/vector-im/riot-web/issues/10455.
+ // See also https://github.com/vector-im/element-web/issues/10455.
}
async registerForToken(check=true) {
diff --git a/src/Lifecycle.js b/src/Lifecycle.js
index 2bebe22f14..d2de31eb80 100644
--- a/src/Lifecycle.js
+++ b/src/Lifecycle.js
@@ -40,7 +40,6 @@ import ToastStore from "./stores/ToastStore";
import {IntegrationManagers} from "./integrations/IntegrationManagers";
import {Mjolnir} from "./mjolnir/Mjolnir";
import DeviceListener from "./DeviceListener";
-import RebrandListener from "./RebrandListener";
import {Jitsi} from "./widgets/Jitsi";
import {SSO_HOMESERVER_URL_KEY, SSO_ID_SERVER_URL_KEY} from "./BasePlatform";
@@ -647,8 +646,6 @@ async function startMatrixClient(startSyncing=true) {
// Now that we have a MatrixClientPeg, update the Jitsi info
await Jitsi.getInstance().start();
- RebrandListener.sharedInstance().start();
-
// dispatch that we finished starting up to wire up any other bits
// of the matrix client that cannot be set prior to starting up.
dis.dispatch({action: 'client_started'});
@@ -710,7 +707,6 @@ export function stopMatrixClient(unsetClient=true) {
IntegrationManagers.sharedInstance().stopWatching();
Mjolnir.sharedInstance().stop();
DeviceListener.sharedInstance().stop();
- RebrandListener.sharedInstance().stop();
if (DMRoomMap.shared()) DMRoomMap.shared().stop();
EventIndexPeg.stop();
const cli = MatrixClientPeg.get();
diff --git a/src/Markdown.js b/src/Markdown.js
index d312b7c5bd..492450e87d 100644
--- a/src/Markdown.js
+++ b/src/Markdown.js
@@ -15,7 +15,7 @@ limitations under the License.
*/
import commonmark from 'commonmark';
-import escape from 'lodash/escape';
+import {escape} from "lodash";
const ALLOWED_HTML_TAGS = ['sub', 'sup', 'del', 'u'];
@@ -99,7 +99,7 @@ export default class Markdown {
// puts softbreaks in for multiple lines in a blockquote,
// so if these are just newline characters then the
// block quote ends up all on one line
- // (https://github.com/vector-im/riot-web/issues/3154)
+ // (https://github.com/vector-im/element-web/issues/3154)
softbreak: ' ',
});
@@ -166,7 +166,7 @@ export default class Markdown {
* Render the markdown message to plain text. That is, essentially
* just remove any backslashes escaping what would otherwise be
* markdown syntax
- * (to fix https://github.com/vector-im/riot-web/issues/2870).
+ * (to fix https://github.com/vector-im/element-web/issues/2870).
*
* N.B. this does **NOT** render arbitrary MD to plain text - only MD
* which has no formatting. Otherwise it emits HTML(!).
diff --git a/src/Modal.tsx b/src/Modal.tsx
index b744dbacf4..0a36813961 100644
--- a/src/Modal.tsx
+++ b/src/Modal.tsx
@@ -151,7 +151,7 @@ export class ModalManager {
prom: Promise,
props?: IProps,
className?: string,
- options?: IOptions
+ options?: IOptions,
) {
const modal: IModal = {
onFinished: props ? props.onFinished : null,
@@ -182,7 +182,7 @@ export class ModalManager {
private getCloseFn(
modal: IModal,
- props: IProps
+ props: IProps,
): [IHandle["close"], IHandle["finished"]] {
const deferred = defer();
return [async (...args: T) => {
@@ -264,7 +264,7 @@ export class ModalManager {
className?: string,
isPriorityModal = false,
isStaticModal = false,
- options: IOptions = {}
+ options: IOptions = {},
): IHandle {
const {modal, closeDialog, onFinishedProm} = this.buildModal(prom, props, className, options);
if (isPriorityModal) {
@@ -287,7 +287,7 @@ export class ModalManager {
private appendDialogAsync(
prom: Promise,
props?: IProps,
- className?: string
+ className?: string,
): IHandle {
const {modal, closeDialog, onFinishedProm} = this.buildModal(prom, props, className, {});
@@ -319,7 +319,7 @@ export class ModalManager {
private reRender() {
if (this.modals.length === 0 && !this.priorityModal && !this.staticModal) {
- // If there is no modal to render, make all of Riot available
+ // If there is no modal to render, make all of Element available
// to screen reader users again
dis.dispatch({
action: 'aria_unhide_main_app',
diff --git a/src/Notifier.js b/src/Notifier.ts
similarity index 91%
rename from src/Notifier.js
rename to src/Notifier.ts
index 2ed302267e..473de6c161 100644
--- a/src/Notifier.js
+++ b/src/Notifier.ts
@@ -17,6 +17,9 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
+import { MatrixEvent } from "matrix-js-sdk/src/models/event";
+import { Room } from "matrix-js-sdk/src/models/room";
+
import { MatrixClientPeg } from './MatrixClientPeg';
import SdkConfig from './SdkConfig';
import PlatformPeg from './PlatformPeg';
@@ -28,9 +31,7 @@ import * as sdk from './index';
import { _t } from './languageHandler';
import Modal from './Modal';
import SettingsStore from "./settings/SettingsStore";
-import {
- hideToast as hideNotificationsToast,
-} from "./toasts/DesktopNotificationsToast";
+import { hideToast as hideNotificationsToast } from "./toasts/DesktopNotificationsToast";
import {SettingLevel} from "./settings/SettingLevel";
/*
@@ -55,7 +56,7 @@ const typehandlers = {
},
};
-const Notifier = {
+export const Notifier = {
notifsByRoom: {},
// A list of event IDs that we've received but need to wait until
@@ -63,14 +64,14 @@ const Notifier = {
// or not
pendingEncryptedEventIds: [],
- notificationMessageForEvent: function(ev) {
+ notificationMessageForEvent: function(ev: MatrixEvent) {
if (typehandlers.hasOwnProperty(ev.getContent().msgtype)) {
return typehandlers[ev.getContent().msgtype](ev);
}
return TextForEvent.textForEvent(ev);
},
- _displayPopupNotification: function(ev, room) {
+ _displayPopupNotification: function(ev: MatrixEvent, room: Room) {
const plaf = PlatformPeg.get();
if (!plaf) {
return;
@@ -125,7 +126,7 @@ const Notifier = {
}
},
- getSoundForRoom: function(roomId) {
+ getSoundForRoom: function(roomId: string) {
// We do no caching here because the SDK caches setting
// and the browser will cache the sound.
const content = SettingsStore.getValue("notificationSound", roomId);
@@ -153,12 +154,13 @@ const Notifier = {
};
},
- _playAudioNotification: async function(ev, room) {
+ _playAudioNotification: async function(ev: MatrixEvent, room: Room) {
const sound = this.getSoundForRoom(room.roomId);
console.log(`Got sound ${sound && sound.name || "default"} for ${room.roomId}`);
try {
- const selector = document.querySelector(sound ? `audio[src='${sound.url}']` : "#messageAudio");
+ const selector =
+ document.querySelector(sound ? `audio[src='${sound.url}']` : "#messageAudio");
let audioElement = selector;
if (!selector) {
if (!sound) {
@@ -207,7 +209,7 @@ const Notifier = {
return plaf && plaf.supportsNotifications();
},
- setEnabled: function(enable, callback) {
+ setEnabled: function(enable: boolean, callback?: () => void) {
const plaf = PlatformPeg.get();
if (!plaf) return;
@@ -277,10 +279,11 @@ const Notifier = {
},
isAudioEnabled: function() {
- return this.isEnabled() && SettingsStore.getValue("audioNotificationsEnabled");
+ // We don't route Audio via the HTML Notifications API so it is possible regardless of other things
+ return SettingsStore.getValue("audioNotificationsEnabled");
},
- setToolbarHidden: function(hidden, persistent = true) {
+ setToolbarHidden: function(hidden: boolean, persistent = true) {
this.toolbarHidden = hidden;
Analytics.trackEvent('Notifier', 'Set Toolbar Hidden', hidden);
@@ -289,7 +292,7 @@ const Notifier = {
// update the info to localStorage for persistent settings
if (persistent && global.localStorage) {
- global.localStorage.setItem("notifications_hidden", hidden);
+ global.localStorage.setItem("notifications_hidden", String(hidden));
}
},
@@ -312,7 +315,7 @@ const Notifier = {
return this.toolbarHidden;
},
- onSyncStateChange: function(state) {
+ onSyncStateChange: function(state: string) {
if (state === "SYNCING") {
this.isSyncing = true;
} else if (state === "STOPPED" || state === "ERROR") {
@@ -320,7 +323,7 @@ const Notifier = {
}
},
- onEvent: function(ev) {
+ onEvent: function(ev: MatrixEvent) {
if (!this.isSyncing) return; // don't alert for any messages initially
if (ev.sender && ev.sender.userId === MatrixClientPeg.get().credentials.userId) return;
@@ -338,7 +341,7 @@ const Notifier = {
this._evaluateEvent(ev);
},
- onEventDecrypted: function(ev) {
+ onEventDecrypted: function(ev: MatrixEvent) {
// 'decrypted' means the decryption process has finished: it may have failed,
// in which case it might decrypt soon if the keys arrive
if (ev.isDecryptionFailure()) return;
@@ -350,7 +353,7 @@ const Notifier = {
this._evaluateEvent(ev);
},
- onRoomReceipt: function(ev, room) {
+ onRoomReceipt: function(ev: MatrixEvent, room: Room) {
if (room.getUnreadNotificationCount() === 0) {
// ideally we would clear each notification when it was read,
// but we have no way, given a read receipt, to know whether
@@ -383,8 +386,8 @@ const Notifier = {
},
};
-if (!global.mxNotifier) {
- global.mxNotifier = Notifier;
+if (!window.mxNotifier) {
+ window.mxNotifier = Notifier;
}
-export default global.mxNotifier;
+export default window.mxNotifier;
diff --git a/src/RebrandListener.tsx b/src/RebrandListener.tsx
deleted file mode 100644
index 47b883cf35..0000000000
--- a/src/RebrandListener.tsx
+++ /dev/null
@@ -1,184 +0,0 @@
-/*
-Copyright 2020 The Matrix.org Foundation C.I.C.
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
-*/
-
-import SdkConfig from "./SdkConfig";
-import ToastStore from "./stores/ToastStore";
-import GenericToast from "./components/views/toasts/GenericToast";
-import RebrandDialog from "./components/views/dialogs/RebrandDialog";
-import { RebrandDialogKind } from "./components/views/dialogs/RebrandDialog";
-import Modal from './Modal';
-import { _t } from './languageHandler';
-
-const TOAST_KEY = 'rebrand';
-const NAG_INTERVAL = 24 * 60 * 60 * 1000;
-
-function getRedirectUrl(url): string {
- const redirectUrl = new URL(url);
- redirectUrl.hash = '';
-
- if (SdkConfig.get()['redirectToNewBrandUrl']) {
- const newUrl = new URL(SdkConfig.get()['redirectToNewBrandUrl']);
- if (url.hostname !== newUrl.hostname || url.pathname !== newUrl.pathname) {
- redirectUrl.hostname = newUrl.hostname;
- redirectUrl.pathname = newUrl.pathname;
- return redirectUrl.toString();
- }
- return null;
- } else if (url.hostname === 'riot.im') {
- if (url.pathname.startsWith('/app')) {
- redirectUrl.hostname = 'app.element.io';
- redirectUrl.pathname = '/';
- } else if (url.pathname.startsWith('/staging')) {
- redirectUrl.hostname = 'staging.element.io';
- redirectUrl.pathname = '/';
- } else if (url.pathname.startsWith('/develop')) {
- redirectUrl.hostname = 'develop.element.io';
- redirectUrl.pathname = '/';
- }
-
- return redirectUrl.href;
- } else if (url.hostname.endsWith('.riot.im')) {
- redirectUrl.hostname = url.hostname.substr(0, url.hostname.length - '.riot.im'.length) + '.element.io';
- return redirectUrl.href;
- } else {
- return null;
- }
-}
-
-/**
- * Shows toasts informing the user that the name of the app has changed and,
- * potentially, that they should head to a different URL and log in there
- */
-export default class RebrandListener {
- private _reshowTimer?: number;
- private nagAgainAt?: number = null;
-
- static sharedInstance() {
- if (!window.mxRebrandListener) window.mxRebrandListener = new RebrandListener();
- return window.mxRebrandListener;
- }
-
- constructor() {
- this._reshowTimer = null;
- }
-
- start() {
- this.recheck();
- }
-
- stop() {
- if (this._reshowTimer) {
- clearTimeout(this._reshowTimer);
- this._reshowTimer = null;
- }
- }
-
- onNagToastLearnMore = async () => {
- const [doneClicked] = await Modal.createDialog(RebrandDialog, {
- kind: RebrandDialogKind.NAG,
- targetUrl: getRedirectUrl(window.location),
- }).finished;
- if (doneClicked) {
- // open in new tab: they should come back here & log out
- window.open(getRedirectUrl(window.location), '_blank');
- }
-
- // whatever the user clicks, we go away & nag again after however long:
- // If they went to the new URL, we want to nag them to log out if they
- // come back to this tab, and if they clicked, 'remind me later' we want
- // to, well, remind them later.
- this.nagAgainAt = Date.now() + NAG_INTERVAL;
- this.recheck();
- };
-
- onOneTimeToastLearnMore = async () => {
- const [doneClicked] = await Modal.createDialog(RebrandDialog, {
- kind: RebrandDialogKind.ONE_TIME,
- }).finished;
- if (doneClicked) {
- localStorage.setItem('mx_rename_dialog_dismissed', 'true');
- this.recheck();
- }
- };
-
- onOneTimeToastDismiss = async () => {
- localStorage.setItem('mx_rename_dialog_dismissed', 'true');
- this.recheck();
- };
-
- onNagTimerFired = () => {
- this._reshowTimer = null;
- this.nagAgainAt = null;
- this.recheck();
- };
-
- private async recheck() {
- // There are two types of toast/dialog we show: a 'one time' informing the user that
- // the app is now called a different thing but no action is required from them (they
- // may need to look for a different name name/icon to launch the app but don't need to
- // log in again) and a nag toast where they need to log in to the app on a different domain.
- let nagToast = false;
- let oneTimeToast = false;
-
- if (getRedirectUrl(window.location)) {
- if (!this.nagAgainAt) {
- // if we have redirectUrl, show the nag toast
- nagToast = true;
- }
- } else {
- // otherwise we show the 'one time' toast / dialog
- const renameDialogDismissed = localStorage.getItem('mx_rename_dialog_dismissed');
- if (renameDialogDismissed !== 'true') {
- oneTimeToast = true;
- }
- }
-
- if (nagToast || oneTimeToast) {
- let description;
- let rejectLabel = null;
- let onReject = null;
- if (nagToast) {
- description = _t("Use your account to sign in to the latest version");
- } else {
- description = _t("We’re excited to announce Riot is now Element");
- rejectLabel = _t("Dismiss");
- onReject = this.onOneTimeToastDismiss;
- }
-
- ToastStore.sharedInstance().addOrReplaceToast({
- key: TOAST_KEY,
- title: _t("Riot is now Element!"),
- icon: 'element_logo',
- props: {
- description,
- acceptLabel: _t("Learn More"),
- onAccept: nagToast ? this.onNagToastLearnMore : this.onOneTimeToastLearnMore,
- rejectLabel,
- onReject,
- },
- component: GenericToast,
- priority: 20,
- });
- } else {
- ToastStore.sharedInstance().dismissToast(TOAST_KEY);
- }
-
- if (!this._reshowTimer && this.nagAgainAt) {
- // XXX: Our build system picks up NodeJS bindings when we need browser bindings.
- this._reshowTimer = setTimeout(this.onNagTimerFired, (this.nagAgainAt - Date.now()) + 100) as any as number;
- }
- }
-}
diff --git a/src/Registration.js b/src/Registration.js
index 32c3d9cc35..9c0264c067 100644
--- a/src/Registration.js
+++ b/src/Registration.js
@@ -52,7 +52,7 @@ export async function startAnyRegistrationFlow(options) {
// caution though.
// XXX: ILAG is disabled for now,
- // see https://github.com/vector-im/riot-web/issues/8222
+ // see https://github.com/vector-im/element-web/issues/8222
// const flows = await _getRegistrationFlows();
// const hasIlagFlow = flows.some((flow) => {
diff --git a/src/Resend.js b/src/Resend.js
index f5f24bffa5..5638313306 100644
--- a/src/Resend.js
+++ b/src/Resend.js
@@ -45,7 +45,7 @@ export default class Resend {
});
}, function(err) {
// XXX: temporary logging to try to diagnose
- // https://github.com/vector-im/riot-web/issues/3148
+ // https://github.com/vector-im/element-web/issues/3148
console.log('Resend got send failure: ' + err.name + '(' + err + ')');
dis.dispatch({
diff --git a/src/RoomInvite.js b/src/RoomInvite.js
index 839d677069..7eb7f5dbb2 100644
--- a/src/RoomInvite.js
+++ b/src/RoomInvite.js
@@ -23,6 +23,8 @@ import Modal from './Modal';
import * as sdk from './';
import { _t } from './languageHandler';
import {KIND_DM, KIND_INVITE} from "./components/views/dialogs/InviteDialog";
+import CommunityPrototypeInviteDialog from "./components/views/dialogs/CommunityPrototypeInviteDialog";
+import {CommunityPrototypeStore} from "./stores/CommunityPrototypeStore";
/**
* Invites multiple addresses to a room
@@ -56,6 +58,23 @@ export function showRoomInviteDialog(roomId) {
);
}
+export function showCommunityRoomInviteDialog(roomId, communityName) {
+ Modal.createTrackedDialog(
+ 'Invite Users to Community', '', CommunityPrototypeInviteDialog, {communityName, roomId},
+ /*className=*/null, /*isPriority=*/false, /*isStatic=*/true,
+ );
+}
+
+export function showCommunityInviteDialog(communityId) {
+ const chat = CommunityPrototypeStore.instance.getGeneralChat(communityId);
+ if (chat) {
+ const name = CommunityPrototypeStore.instance.getCommunityName(communityId);
+ showCommunityRoomInviteDialog(chat.roomId, name);
+ } else {
+ throw new Error("Failed to locate appropriate room to start an invite in");
+ }
+}
+
/**
* Checks if the given MatrixEvent is a valid 3rd party user invite.
* @param {MatrixEvent} event The event to check
@@ -77,7 +96,7 @@ export function isValid3pidInvite(event) {
export function inviteUsersToRoom(roomId, userIds) {
return inviteMultipleToRoom(roomId, userIds).then((result) => {
const room = MatrixClientPeg.get().getRoom(roomId);
- return _showAnyInviteErrors(result.states, room, result.inviter);
+ showAnyInviteErrors(result.states, room, result.inviter);
}).catch((err) => {
console.error(err.stack);
const ErrorDialog = sdk.getComponent("dialogs.ErrorDialog");
@@ -88,7 +107,7 @@ export function inviteUsersToRoom(roomId, userIds) {
});
}
-function _showAnyInviteErrors(addrs, room, inviter) {
+export function showAnyInviteErrors(addrs, room, inviter) {
// Show user any errors
const failedUsers = Object.keys(addrs).filter(a => addrs[a] === 'error');
if (failedUsers.length === 1 && inviter.fatal) {
@@ -100,6 +119,7 @@ function _showAnyInviteErrors(addrs, room, inviter) {
title: _t("Failed to invite users to the room:", {roomName: room.name}),
description: inviter.getErrorText(failedUsers[0]),
});
+ return false;
} else {
const errorList = [];
for (const addr of failedUsers) {
@@ -118,8 +138,9 @@ function _showAnyInviteErrors(addrs, room, inviter) {
title: _t("Failed to invite the following users to the %(roomName)s room:", {roomName: room.name}),
description,
});
+ return false;
}
}
- return addrs;
+ return true;
}
diff --git a/src/ScalarMessaging.js b/src/ScalarMessaging.js
index b33aa57359..896e27d92c 100644
--- a/src/ScalarMessaging.js
+++ b/src/ScalarMessaging.js
@@ -174,7 +174,7 @@ Request:
Response:
[
{
- // TODO: Enable support for m.widget event type (https://github.com/vector-im/riot-web/issues/13111)
+ // TODO: Enable support for m.widget event type (https://github.com/vector-im/element-web/issues/13111)
type: "im.vector.modular.widgets",
state_key: "wid1",
content: {
@@ -193,7 +193,7 @@ Example:
room_id: "!foo:bar",
response: [
{
- // TODO: Enable support for m.widget event type (https://github.com/vector-im/riot-web/issues/13111)
+ // TODO: Enable support for m.widget event type (https://github.com/vector-im/element-web/issues/13111)
type: "im.vector.modular.widgets",
state_key: "wid1",
content: {
diff --git a/src/SendHistoryManager.js b/src/SendHistoryManager.js
index 794a58ad6f..d9955727a4 100644
--- a/src/SendHistoryManager.js
+++ b/src/SendHistoryManager.js
@@ -15,7 +15,7 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
-import _clamp from 'lodash/clamp';
+import {clamp} from "lodash";
export default class SendHistoryManager {
history: Array = [];
@@ -54,7 +54,7 @@ export default class SendHistoryManager {
}
getItem(offset: number): ?HistoryItem {
- this.currentIndex = _clamp(this.currentIndex + offset, 0, this.history.length - 1);
+ this.currentIndex = clamp(this.currentIndex + offset, 0, this.history.length - 1);
return this.history[this.currentIndex];
}
}
diff --git a/src/SlashCommands.tsx b/src/SlashCommands.tsx
index ad3dc7002a..661ab74e6f 100644
--- a/src/SlashCommands.tsx
+++ b/src/SlashCommands.tsx
@@ -43,7 +43,7 @@ import SdkConfig from "./SdkConfig";
import { ensureDMExists } from "./createRoom";
import { ViewUserPayload } from "./dispatcher/payloads/ViewUserPayload";
import { Action } from "./dispatcher/actions";
-import { EffectiveMembership, getEffectiveMembership } from "./utils/membership";
+import { EffectiveMembership, getEffectiveMembership, leaveRoomBehaviour } from "./utils/membership";
// XXX: workaround for https://github.com/microsoft/TypeScript/issues/31816
interface HTMLInputEvent extends Event {
@@ -479,7 +479,7 @@ export const Commands = [
const parsedUrl = new URL(params[0]);
const hostname = parsedUrl.host || parsedUrl.hostname; // takes first non-falsey value
- // if we're using a Riot permalink handler, this will catch it before we get much further.
+ // if we're using a Element permalink handler, this will catch it before we get much further.
// see below where we make assumptions about parsing the URL.
if (isPermalinkHost(hostname)) {
isPermalink = true;
@@ -601,11 +601,7 @@ export const Commands = [
}
if (!targetRoomId) targetRoomId = roomId;
- return success(
- cli.leaveRoomChain(targetRoomId).then(function() {
- dis.dispatch({action: 'view_next_room'});
- }),
- );
+ return success(leaveRoomBehaviour(targetRoomId));
},
category: CommandCategories.actions,
}),
@@ -733,7 +729,7 @@ export const Commands = [
const cli = MatrixClientPeg.get();
const room = cli.getRoom(roomId);
if (!room) return reject(_t("Command failed"));
- const member = room.getMember(args);
+ const member = room.getMember(userId);
if (!member || getEffectiveMembership(member.membership) === EffectiveMembership.Leave) {
return reject(_t("Could not find user in room"));
}
@@ -864,12 +860,12 @@ export const Commands = [
_t('WARNING: KEY VERIFICATION FAILED! The signing key for %(userId)s and session' +
' %(deviceId)s is "%(fprint)s" which does not match the provided key ' +
'"%(fingerprint)s". This could mean your communications are being intercepted!',
- {
- fprint,
- userId,
- deviceId,
- fingerprint,
- }));
+ {
+ fprint,
+ userId,
+ deviceId,
+ fingerprint,
+ }));
}
await cli.setDeviceVerified(userId, deviceId, true);
@@ -883,7 +879,7 @@ export const Commands = [
{
_t('The signing key you provided matches the signing key you received ' +
'from %(userId)s\'s session %(deviceId)s. Session marked as verified.',
- {userId, deviceId})
+ {userId, deviceId})
}
,
diff --git a/src/TextForEvent.js b/src/TextForEvent.js
index 3607d7a676..c55380bd9b 100644
--- a/src/TextForEvent.js
+++ b/src/TextForEvent.js
@@ -345,7 +345,7 @@ function textForCallHangupEvent(event) {
} else if (eventContent.reason === "invite_timeout") {
reason = _t('(no answer)');
} else if (eventContent.reason === "user hangup") {
- // workaround for https://github.com/vector-im/riot-web/issues/5178
+ // workaround for https://github.com/vector-im/element-web/issues/5178
// it seems Android randomly sets a reason of "user hangup" which is
// interpreted as an error code :(
// https://github.com/vector-im/riot-android/issues/2623
@@ -603,7 +603,7 @@ const stateHandlers = {
'm.room.guest_access': textForGuestAccessEvent,
'm.room.related_groups': textForRelatedGroupsEvent,
- // TODO: Enable support for m.widget event type (https://github.com/vector-im/riot-web/issues/13111)
+ // TODO: Enable support for m.widget event type (https://github.com/vector-im/element-web/issues/13111)
'im.vector.modular.widgets': textForWidgetEvent,
};
diff --git a/src/Tinter.js b/src/Tinter.js
index 24a4d25a00..ca5a460e16 100644
--- a/src/Tinter.js
+++ b/src/Tinter.js
@@ -327,7 +327,7 @@ class Tinter {
// Vector Green as its primary color?
// --richvdh
- // Yes, tinting assumes that you are using the Riot skin for now.
+ // Yes, tinting assumes that you are using the Element skin for now.
// The right solution will be to move the CSS over to react-sdk.
// And yes, the default assets for the base skin might as well use
// Vector Green as any other colour.
diff --git a/src/Unread.js b/src/Unread.js
index ca713b05e4..cf131cac00 100644
--- a/src/Unread.js
+++ b/src/Unread.js
@@ -52,10 +52,10 @@ export function doesRoomHaveUnreadMessages(room) {
// as we don't send RRs for our own messages, make sure we special case that
// if *we* sent the last message into the room, we consider it not unread!
- // Should fix: https://github.com/vector-im/riot-web/issues/3263
- // https://github.com/vector-im/riot-web/issues/2427
+ // Should fix: https://github.com/vector-im/element-web/issues/3263
+ // https://github.com/vector-im/element-web/issues/2427
// ...and possibly some of the others at
- // https://github.com/vector-im/riot-web/issues/3363
+ // https://github.com/vector-im/element-web/issues/3363
if (room.timeline.length &&
room.timeline[room.timeline.length - 1].sender &&
room.timeline[room.timeline.length - 1].sender.userId === myUserId) {
diff --git a/src/VectorConferenceHandler.js b/src/VectorConferenceHandler.js
index 180dad876b..c10bc659ae 100644
--- a/src/VectorConferenceHandler.js
+++ b/src/VectorConferenceHandler.js
@@ -19,13 +19,13 @@ import {createNewMatrixCall as jsCreateNewMatrixCall, Room} from "matrix-js-sdk"
import CallHandler from './CallHandler';
import {MatrixClientPeg} from "./MatrixClientPeg";
-// FIXME: this is Riot (Vector) specific code, but will be removed shortly when
-// we switch over to jitsi entirely for video conferencing.
+// FIXME: this is Element specific code, but will be removed shortly when we
+// switch over to Jitsi entirely for video conferencing.
-// FIXME: This currently forces Vector to try to hit the matrix.org AS for conferencing.
-// This is bad because it prevents people running their own ASes from being used.
-// This isn't permanent and will be customisable in the future: see the proposal
-// at docs/conferencing.md for more info.
+// FIXME: This currently forces Element to try to hit the matrix.org AS for
+// conferencing. This is bad because it prevents people running their own ASes
+// from being used. This isn't permanent and will be customisable in the future:
+// see the proposal at docs/conferencing.md for more info.
const USER_PREFIX = "fs_";
const DOMAIN = "matrix.org";
diff --git a/src/WidgetMessaging.js b/src/WidgetMessaging.js
index c89a0ceeeb..6aed08c39d 100644
--- a/src/WidgetMessaging.js
+++ b/src/WidgetMessaging.js
@@ -76,7 +76,7 @@ export default class WidgetMessaging {
console.error(err._error);
}
// Potential XSS attack if 'msg' is not appropriately sanitized,
- // as it is untrusted input by our parent window (which we assume is Riot).
+ // as it is untrusted input by our parent window (which we assume is Element).
// We can't aggressively sanitize [A-z0-9] since it might be a translation.
throw new Error(msg);
}
diff --git a/src/accessibility/KeyboardShortcuts.tsx b/src/accessibility/KeyboardShortcuts.tsx
index f527ab4a14..58d8124122 100644
--- a/src/accessibility/KeyboardShortcuts.tsx
+++ b/src/accessibility/KeyboardShortcuts.tsx
@@ -168,7 +168,7 @@ const shortcuts: Record = {
key: Key.U,
}],
description: _td("Upload a file"),
- }
+ },
],
[Categories.ROOM_LIST]: [
diff --git a/src/accessibility/RovingTabIndex.tsx b/src/accessibility/RovingTabIndex.tsx
index 5a650d4b6e..b1dbb56a01 100644
--- a/src/accessibility/RovingTabIndex.tsx
+++ b/src/accessibility/RovingTabIndex.tsx
@@ -190,7 +190,7 @@ export const RovingTabIndexProvider: React.FC = ({children, handleHomeEn
ev.preventDefault();
ev.stopPropagation();
} else if (onKeyDown) {
- return onKeyDown(ev, state);
+ return onKeyDown(ev, context.state);
}
}, [context.state, onKeyDown, handleHomeEnd]);
diff --git a/src/accessibility/Toolbar.tsx b/src/accessibility/Toolbar.tsx
index 0e968461a8..cc2a1769c7 100644
--- a/src/accessibility/Toolbar.tsx
+++ b/src/accessibility/Toolbar.tsx
@@ -30,6 +30,7 @@ const Toolbar: React.FC = ({children, ...props}) => {
const target = ev.target as HTMLElement;
let handled = true;
+ // HOME and END are handled by RovingTabIndexProvider
switch (ev.key) {
case Key.ARROW_UP:
case Key.ARROW_DOWN:
@@ -47,8 +48,6 @@ const Toolbar: React.FC = ({children, ...props}) => {
}
break;
- // HOME and END are handled by RovingTabIndexProvider
-
default:
handled = false;
}
diff --git a/src/accessibility/context_menu/ContextMenuTooltipButton.tsx b/src/accessibility/context_menu/ContextMenuTooltipButton.tsx
index abc5412100..49f57ca7b6 100644
--- a/src/accessibility/context_menu/ContextMenuTooltipButton.tsx
+++ b/src/accessibility/context_menu/ContextMenuTooltipButton.tsx
@@ -20,7 +20,7 @@ import React from "react";
import AccessibleTooltipButton from "../../components/views/elements/AccessibleTooltipButton";
-interface IProps extends React.ComponentProps {
+interface IProps extends React.ComponentProps {
// whether or not the context menu is currently open
isExpanded: boolean;
}
diff --git a/src/accessibility/context_menu/MenuItem.tsx b/src/accessibility/context_menu/MenuItem.tsx
index 64233e51ad..0bb169abf8 100644
--- a/src/accessibility/context_menu/MenuItem.tsx
+++ b/src/accessibility/context_menu/MenuItem.tsx
@@ -26,8 +26,9 @@ interface IProps extends React.ComponentProps {
// Semantic component for representing a role=menuitem
export const MenuItem: React.FC = ({children, label, ...props}) => {
+ const ariaLabel = props["aria-label"] || label;
return (
-
+
{ children }
);
diff --git a/src/accessibility/roving/RovingAccessibleTooltipButton.tsx b/src/accessibility/roving/RovingAccessibleTooltipButton.tsx
index cc824fef22..2cb974d60e 100644
--- a/src/accessibility/roving/RovingAccessibleTooltipButton.tsx
+++ b/src/accessibility/roving/RovingAccessibleTooltipButton.tsx
@@ -20,7 +20,8 @@ import AccessibleTooltipButton from "../../components/views/elements/AccessibleT
import {useRovingTabIndex} from "../RovingTabIndex";
import {Ref} from "./types";
-interface IProps extends Omit, "onFocus" | "inputRef" | "tabIndex"> {
+type ATBProps = React.ComponentProps;
+interface IProps extends Omit {
inputRef?: Ref;
}
diff --git a/src/accessibility/roving/RovingTabIndexWrapper.tsx b/src/accessibility/roving/RovingTabIndexWrapper.tsx
index c826b74497..5211f30215 100644
--- a/src/accessibility/roving/RovingTabIndexWrapper.tsx
+++ b/src/accessibility/roving/RovingTabIndexWrapper.tsx
@@ -16,7 +16,6 @@ limitations under the License.
import React from "react";
-import AccessibleButton from "../../components/views/elements/AccessibleButton";
import {useRovingTabIndex} from "../RovingTabIndex";
import {FocusHandler, Ref} from "./types";
diff --git a/src/async-components/views/dialogs/ExportE2eKeysDialog.js b/src/async-components/views/dialogs/ExportE2eKeysDialog.js
index 7ec9da39de..406ffd8749 100644
--- a/src/async-components/views/dialogs/ExportE2eKeysDialog.js
+++ b/src/async-components/views/dialogs/ExportE2eKeysDialog.js
@@ -17,7 +17,6 @@ limitations under the License.
import FileSaver from 'file-saver';
import React, {createRef} from 'react';
import PropTypes from 'prop-types';
-import createReactClass from 'create-react-class';
import { _t } from '../../../languageHandler';
import { MatrixClient } from 'matrix-js-sdk';
@@ -27,34 +26,31 @@ import * as sdk from '../../../index';
const PHASE_EDIT = 1;
const PHASE_EXPORTING = 2;
-export default createReactClass({
- displayName: 'ExportE2eKeysDialog',
-
- propTypes: {
+export default class ExportE2eKeysDialog extends React.Component {
+ static propTypes = {
matrixClient: PropTypes.instanceOf(MatrixClient).isRequired,
onFinished: PropTypes.func.isRequired,
- },
+ };
- getInitialState: function() {
- return {
- phase: PHASE_EDIT,
- errStr: null,
- };
- },
+ constructor(props) {
+ super(props);
- // TODO: [REACT-WARNING] Replace component with real class, use constructor for refs
- UNSAFE_componentWillMount: function() {
this._unmounted = false;
this._passphrase1 = createRef();
this._passphrase2 = createRef();
- },
- componentWillUnmount: function() {
+ this.state = {
+ phase: PHASE_EDIT,
+ errStr: null,
+ };
+ }
+
+ componentWillUnmount() {
this._unmounted = true;
- },
+ }
- _onPassphraseFormSubmit: function(ev) {
+ _onPassphraseFormSubmit = (ev) => {
ev.preventDefault();
const passphrase = this._passphrase1.current.value;
@@ -69,9 +65,9 @@ export default createReactClass({
this._startExport(passphrase);
return false;
- },
+ };
- _startExport: function(passphrase) {
+ _startExport(passphrase) {
// extra Promise.resolve() to turn synchronous exceptions into
// asynchronous ones.
Promise.resolve().then(() => {
@@ -84,7 +80,7 @@ export default createReactClass({
const blob = new Blob([f], {
type: 'text/plain;charset=us-ascii',
});
- FileSaver.saveAs(blob, 'riot-keys.txt');
+ FileSaver.saveAs(blob, 'element-keys.txt');
this.props.onFinished(true);
}).catch((e) => {
console.error("Error exporting e2e keys:", e);
@@ -102,15 +98,15 @@ export default createReactClass({
errStr: null,
phase: PHASE_EXPORTING,
});
- },
+ }
- _onCancelClick: function(ev) {
+ _onCancelClick = (ev) => {
ev.preventDefault();
this.props.onFinished(false);
return false;
- },
+ };
- render: function() {
+ render() {
const BaseDialog = sdk.getComponent('views.dialogs.BaseDialog');
const disableForm = (this.state.phase === PHASE_EXPORTING);
@@ -184,5 +180,5 @@ export default createReactClass({
);
- },
-});
+ }
+}
diff --git a/src/async-components/views/dialogs/ImportE2eKeysDialog.js b/src/async-components/views/dialogs/ImportE2eKeysDialog.js
index 6b9d2c7e45..c2d17f681d 100644
--- a/src/async-components/views/dialogs/ImportE2eKeysDialog.js
+++ b/src/async-components/views/dialogs/ImportE2eKeysDialog.js
@@ -16,7 +16,6 @@ limitations under the License.
import React, {createRef} from 'react';
import PropTypes from 'prop-types';
-import createReactClass from 'create-react-class';
import { MatrixClient } from 'matrix-js-sdk';
import * as MegolmExportEncryption from '../../../utils/MegolmExportEncryption';
@@ -38,48 +37,45 @@ function readFileAsArrayBuffer(file) {
const PHASE_EDIT = 1;
const PHASE_IMPORTING = 2;
-export default createReactClass({
- displayName: 'ImportE2eKeysDialog',
-
- propTypes: {
+export default class ImportE2eKeysDialog extends React.Component {
+ static propTypes = {
matrixClient: PropTypes.instanceOf(MatrixClient).isRequired,
onFinished: PropTypes.func.isRequired,
- },
+ };
- getInitialState: function() {
- return {
- enableSubmit: false,
- phase: PHASE_EDIT,
- errStr: null,
- };
- },
+ constructor(props) {
+ super(props);
- // TODO: [REACT-WARNING] Replace component with real class, use constructor for refs
- UNSAFE_componentWillMount: function() {
this._unmounted = false;
this._file = createRef();
this._passphrase = createRef();
- },
- componentWillUnmount: function() {
+ this.state = {
+ enableSubmit: false,
+ phase: PHASE_EDIT,
+ errStr: null,
+ };
+ }
+
+ componentWillUnmount() {
this._unmounted = true;
- },
+ }
- _onFormChange: function(ev) {
+ _onFormChange = (ev) => {
const files = this._file.current.files || [];
this.setState({
enableSubmit: (this._passphrase.current.value !== "" && files.length > 0),
});
- },
+ };
- _onFormSubmit: function(ev) {
+ _onFormSubmit = (ev) => {
ev.preventDefault();
this._startImport(this._file.current.files[0], this._passphrase.current.value);
return false;
- },
+ };
- _startImport: function(file, passphrase) {
+ _startImport(file, passphrase) {
this.setState({
errStr: null,
phase: PHASE_IMPORTING,
@@ -105,15 +101,15 @@ export default createReactClass({
phase: PHASE_EDIT,
});
});
- },
+ }
- _onCancelClick: function(ev) {
+ _onCancelClick = (ev) => {
ev.preventDefault();
this.props.onFinished(false);
return false;
- },
+ };
- render: function() {
+ render() {
const BaseDialog = sdk.getComponent('views.dialogs.BaseDialog');
const disableForm = (this.state.phase !== PHASE_EDIT);
@@ -188,5 +184,5 @@ export default createReactClass({
);
- },
-});
+ }
+}
diff --git a/src/async-components/views/dialogs/keybackup/CreateKeyBackupDialog.js b/src/async-components/views/dialogs/keybackup/CreateKeyBackupDialog.js
index 79fbb98c7b..c3aef9109a 100644
--- a/src/async-components/views/dialogs/keybackup/CreateKeyBackupDialog.js
+++ b/src/async-components/views/dialogs/keybackup/CreateKeyBackupDialog.js
@@ -286,7 +286,7 @@ export default class CreateKeyBackupDialog extends React.PureComponent {
changeText = _t("Use a different passphrase?");
} else if (!this.state.passPhrase.startsWith(this.state.passPhraseConfirm)) {
// only tell them they're wrong if they've actually gone wrong.
- // Security concious readers will note that if you left riot-web unattended
+ // Security concious readers will note that if you left element-web unattended
// on this screen, this would make it easy for a malicious person to guess
// your passphrase one letter at a time, but they could get this faster by
// just opening the browser's developer tools and reading it.
diff --git a/src/async-components/views/dialogs/secretstorage/CreateSecretStorageDialog.js b/src/async-components/views/dialogs/secretstorage/CreateSecretStorageDialog.js
index 4cef817a38..0a1a0b02b3 100644
--- a/src/async-components/views/dialogs/secretstorage/CreateSecretStorageDialog.js
+++ b/src/async-components/views/dialogs/secretstorage/CreateSecretStorageDialog.js
@@ -30,6 +30,7 @@ import StyledRadioButton from '../../../../components/views/elements/StyledRadio
import AccessibleButton from "../../../../components/views/elements/AccessibleButton";
import DialogButtons from "../../../../components/views/elements/DialogButtons";
import InlineSpinner from "../../../../components/views/elements/InlineSpinner";
+import { isSecureBackupRequired } from '../../../../utils/WellKnownUtils';
const PHASE_LOADING = 0;
const PHASE_LOADERROR = 1;
@@ -55,12 +56,12 @@ export default class CreateSecretStorageDialog extends React.PureComponent {
static propTypes = {
hasCancel: PropTypes.bool,
accountPassword: PropTypes.string,
- force: PropTypes.bool,
+ forceReset: PropTypes.bool,
};
static defaultProps = {
hasCancel: true,
- force: false,
+ forceReset: false,
};
constructor(props) {
@@ -85,8 +86,8 @@ export default class CreateSecretStorageDialog extends React.PureComponent {
canUploadKeysWithPasswordOnly: null,
accountPassword: props.accountPassword || "",
accountPasswordCorrect: null,
-
passPhraseKeySelected: CREATE_STORAGE_OPTION_KEY,
+ canSkip: !isSecureBackupRequired(),
};
this._passphraseField = createRef();
@@ -117,8 +118,8 @@ export default class CreateSecretStorageDialog extends React.PureComponent {
MatrixClientPeg.get().isCryptoEnabled() && await MatrixClientPeg.get().isKeyBackupTrusted(backupInfo)
);
- const { force } = this.props;
- const phase = (backupInfo && !force) ? PHASE_MIGRATE : PHASE_CHOOSE_KEY_PASSPHRASE;
+ const { forceReset } = this.props;
+ const phase = (backupInfo && !forceReset) ? PHASE_MIGRATE : PHASE_CHOOSE_KEY_PASSPHRASE;
this.setState({
phase,
@@ -276,20 +277,25 @@ export default class CreateSecretStorageDialog extends React.PureComponent {
const cli = MatrixClientPeg.get();
- const { force } = this.props;
+ const { forceReset } = this.props;
try {
- if (force) {
- console.log("Forcing secret storage reset"); // log something so we can debug this later
+ if (forceReset) {
+ console.log("Forcing cross-signing and secret storage reset");
await cli.bootstrapSecretStorage({
- authUploadDeviceSigningKeys: this._doBootstrapUIAuth,
createSecretStorageKey: async () => this._recoveryKey,
setupNewKeyBackup: true,
setupNewSecretStorage: true,
});
- } else {
- await cli.bootstrapSecretStorage({
+ await cli.bootstrapCrossSigning({
authUploadDeviceSigningKeys: this._doBootstrapUIAuth,
+ setupNewCrossSigning: true,
+ });
+ } else {
+ await cli.bootstrapCrossSigning({
+ authUploadDeviceSigningKeys: this._doBootstrapUIAuth,
+ });
+ await cli.bootstrapSecretStorage({
createSecretStorageKey: async () => this._recoveryKey,
keyBackupInfo: this.state.backupInfo,
setupNewKeyBackup: !this.state.backupInfo,
@@ -470,7 +476,7 @@ export default class CreateSecretStorageDialog extends React.PureComponent {
primaryButton={_t("Continue")}
onPrimaryButtonClick={this._onChooseKeyPassphraseFormSubmit}
onCancel={this._onCancelClick}
- hasCancel={true}
+ hasCancel={this.state.canSkip}
/>
;
}
@@ -480,7 +486,7 @@ export default class CreateSecretStorageDialog extends React.PureComponent {
// click the button are aware they're making a change to their account.
// Once we're confident enough in this (and it's supported enough) we can do
// it automatically.
- // https://github.com/vector-im/riot-web/issues/11696
+ // https://github.com/vector-im/element-web/issues/11696
const Field = sdk.getComponent('views.elements.Field');
let authPrompt;
@@ -575,7 +581,7 @@ export default class CreateSecretStorageDialog extends React.PureComponent {
changeText = _t("Use a different passphrase?");
} else if (!this.state.passPhrase.startsWith(this.state.passPhraseConfirm)) {
// only tell them they're wrong if they've actually gone wrong.
- // Security concious readers will note that if you left riot-web unattended
+ // Security concious readers will note that if you left element-web unattended
// on this screen, this would make it easy for a malicious person to guess
// your passphrase one letter at a time, but they could get this faster by
// just opening the browser's developer tools and reading it.
@@ -687,7 +693,7 @@ export default class CreateSecretStorageDialog extends React.PureComponent {
@@ -714,7 +720,7 @@ export default class CreateSecretStorageDialog extends React.PureComponent {
_titleForPhase(phase) {
switch (phase) {
case PHASE_CHOOSE_KEY_PASSPHRASE:
- return _t('Set up Secure backup');
+ return _t('Set up Secure Backup');
case PHASE_MIGRATE:
return _t('Upgrade your encryption');
case PHASE_PASSPHRASE:
@@ -742,7 +748,7 @@ export default class CreateSecretStorageDialog extends React.PureComponent {
{ children }
{ title }
diff --git a/src/autocomplete/EmojiProvider.tsx b/src/autocomplete/EmojiProvider.tsx
index 147d68f5ff..705474f8d0 100644
--- a/src/autocomplete/EmojiProvider.tsx
+++ b/src/autocomplete/EmojiProvider.tsx
@@ -23,8 +23,7 @@ import AutocompleteProvider from './AutocompleteProvider';
import QueryMatcher from './QueryMatcher';
import {PillCompletion} from './Components';
import {ICompletion, ISelectionRange} from './Autocompleter';
-import _uniq from 'lodash/uniq';
-import _sortBy from 'lodash/sortBy';
+import {uniq, sortBy} from 'lodash';
import SettingsStore from "../settings/SettingsStore";
import { shortcodeToUnicode } from '../HtmlUtils';
import { EMOJI, IEmoji } from '../emoji';
@@ -115,7 +114,7 @@ export default class EmojiProvider extends AutocompleteProvider {
}
// Finally, sort by original ordering
sorters.push((c) => c._orderBy);
- completions = _sortBy(_uniq(completions), sorters);
+ completions = sortBy(uniq(completions), sorters);
completions = completions.map(({shortname}) => {
const unicode = shortcodeToUnicode(shortname);
@@ -139,7 +138,11 @@ export default class EmojiProvider extends AutocompleteProvider {
renderCompletions(completions: React.ReactNode[]): React.ReactNode {
return (
-
+
{ completions }
);
diff --git a/src/autocomplete/QueryMatcher.ts b/src/autocomplete/QueryMatcher.ts
index 9c91414556..a07ed29c7e 100644
--- a/src/autocomplete/QueryMatcher.ts
+++ b/src/autocomplete/QueryMatcher.ts
@@ -16,8 +16,7 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
-import _at from 'lodash/at';
-import _uniq from 'lodash/uniq';
+import {at, uniq} from 'lodash';
import {removeHiddenChars} from "matrix-js-sdk/src/utils";
interface IOptions {
@@ -73,7 +72,7 @@ export default class QueryMatcher {
// type for their values. We assume that those values who's keys have
// been specified will be string. Also, we cannot infer all the
// types of the keys of the objects at compile.
- const keyValues = _at(object, this._options.keys);
+ const keyValues = at(object, this._options.keys);
if (this._options.funcs) {
for (const f of this._options.funcs) {
@@ -137,7 +136,7 @@ export default class QueryMatcher {
});
// Now map the keys to the result objects. Also remove any duplicates.
- return _uniq(matches.map((match) => match.object));
+ return uniq(matches.map((match) => match.object));
}
private processQuery(query: string): string {
diff --git a/src/autocomplete/RoomProvider.tsx b/src/autocomplete/RoomProvider.tsx
index f14fa3bbfa..74deacf61f 100644
--- a/src/autocomplete/RoomProvider.tsx
+++ b/src/autocomplete/RoomProvider.tsx
@@ -27,7 +27,7 @@ import {PillCompletion} from './Components';
import * as sdk from '../index';
import {makeRoomPermalink} from "../utils/permalinks/Permalinks";
import {ICompletion, ISelectionRange} from "./Autocompleter";
-import { uniqBy, sortBy } from 'lodash';
+import {uniqBy, sortBy} from "lodash";
const ROOM_REGEX = /\B#\S*/g;
@@ -110,15 +110,13 @@ export default class RoomProvider extends AutocompleteProvider {
),
range,
};
- })
- .filter((completion) => !!completion.completion && completion.completion.length > 0)
- .slice(0, 4);
+ }).filter((completion) => !!completion.completion && completion.completion.length > 0).slice(0, 4);
}
return completions;
}
getName() {
- return '💬 ' + _t('Rooms');
+ return _t('Rooms');
}
renderCompletions(completions: React.ReactNode[]): React.ReactNode {
diff --git a/src/autocomplete/UserProvider.tsx b/src/autocomplete/UserProvider.tsx
index eeb6c7a522..32eea55b0b 100644
--- a/src/autocomplete/UserProvider.tsx
+++ b/src/autocomplete/UserProvider.tsx
@@ -23,7 +23,7 @@ import AutocompleteProvider from './AutocompleteProvider';
import {PillCompletion} from './Components';
import * as sdk from '../index';
import QueryMatcher from './QueryMatcher';
-import _sortBy from 'lodash/sortBy';
+import {sortBy} from 'lodash';
import {MatrixClientPeg} from '../MatrixClientPeg';
import MatrixEvent from "matrix-js-sdk/src/models/event";
@@ -71,8 +71,13 @@ export default class UserProvider extends AutocompleteProvider {
}
}
- private onRoomTimeline = (ev: MatrixEvent, room: Room, toStartOfTimeline: boolean, removed: boolean,
- data: IRoomTimelineData) => {
+ private onRoomTimeline = (
+ ev: MatrixEvent,
+ room: Room,
+ toStartOfTimeline: boolean,
+ removed: boolean,
+ data: IRoomTimelineData,
+ ) => {
if (!room) return;
if (removed) return;
if (room.roomId !== this.room.roomId) return;
@@ -137,7 +142,7 @@ export default class UserProvider extends AutocompleteProvider {
}
getName(): string {
- return '👥 ' + _t('Users');
+ return _t('Users');
}
_makeUsers() {
@@ -151,7 +156,7 @@ export default class UserProvider extends AutocompleteProvider {
const currentUserId = MatrixClientPeg.get().credentials.userId;
this.users = this.room.getJoinedMembers().filter(({userId}) => userId !== currentUserId);
- this.users = _sortBy(this.users, (member) => 1E20 - lastSpoken[member.userId] || 1E20);
+ this.users = sortBy(this.users, (member) => 1E20 - lastSpoken[member.userId] || 1E20);
this.matcher.setObjects(this.users);
}
@@ -171,7 +176,11 @@ export default class UserProvider extends AutocompleteProvider {
renderCompletions(completions: React.ReactNode[]): React.ReactNode {
return (
-
+
{ completions }
);
diff --git a/src/components/structures/CompatibilityPage.js b/src/components/structures/CompatibilityPage.js
deleted file mode 100644
index 1fa6068675..0000000000
--- a/src/components/structures/CompatibilityPage.js
+++ /dev/null
@@ -1,90 +0,0 @@
-/*
-Copyright 2015, 2016 OpenMarket Ltd
-Copyright 2019 Michael Telatynski <7t3chguy@gmail.com>
-Copyright 2019, 2020 The Matrix.org Foundation C.I.C.
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
-*/
-
-import React from 'react';
-import createReactClass from 'create-react-class';
-import PropTypes from 'prop-types';
-import { _t } from '../../languageHandler';
-import SdkConfig from '../../SdkConfig';
-
-export default createReactClass({
- displayName: 'CompatibilityPage',
- propTypes: {
- onAccept: PropTypes.func,
- },
-
- getDefaultProps: function() {
- return {
- onAccept: function() {}, // NOP
- };
- },
-
- onAccept: function() {
- this.props.onAccept();
- },
-
- render: function() {
- const brand = SdkConfig.get().brand;
-
- return (
-
-
-
{_t(
- "Sorry, your browser is not able to run %(brand)s.",
- {
- brand,
- },
- {
- 'b': (sub) => {sub},
- })
- }
-
- { _t(
- "%(brand)s uses many advanced browser features, some of which are not available " +
- "or experimental in your current browser.",
- { brand },
- ) }
-
- { _t(
- "With your current browser, the look and feel of the application may be " +
- "completely incorrect, and some or all features may not function. " +
- "If you want to try it anyway you can continue, but you are on your own in terms " +
- "of any issues you may encounter!",
- ) }
-
-
-
-
- );
- },
-});
diff --git a/src/components/structures/ContextMenu.tsx b/src/components/structures/ContextMenu.tsx
index f1bd297730..64e0160d83 100644
--- a/src/components/structures/ContextMenu.tsx
+++ b/src/components/structures/ContextMenu.tsx
@@ -58,7 +58,7 @@ export enum ChevronFace {
None = "none",
}
-interface IProps extends IPosition {
+export interface IProps extends IPosition {
menuWidth?: number;
menuHeight?: number;
@@ -233,8 +233,7 @@ export class ContextMenu extends React.PureComponent {
switch (ev.key) {
case Key.TAB:
case Key.ESCAPE:
- // close on left and right arrows too for when it is a context menu on a
- case Key.ARROW_LEFT:
+ case Key.ARROW_LEFT: // close on left and right arrows too for when it is a context menu on a
case Key.ARROW_RIGHT:
this.props.onFinished();
break;
diff --git a/src/components/structures/EmbeddedPage.js b/src/components/structures/EmbeddedPage.js
index 49ba3d1227..cbfeff7582 100644
--- a/src/components/structures/EmbeddedPage.js
+++ b/src/components/structures/EmbeddedPage.js
@@ -43,8 +43,8 @@ export default class EmbeddedPage extends React.PureComponent {
static contextType = MatrixClientContext;
- constructor(props) {
- super(props);
+ constructor(props, context) {
+ super(props, context);
this._dispatcherRef = null;
diff --git a/src/components/structures/FilePanel.js b/src/components/structures/FilePanel.js
index d873dd4094..8aa1192458 100644
--- a/src/components/structures/FilePanel.js
+++ b/src/components/structures/FilePanel.js
@@ -16,7 +16,6 @@ limitations under the License.
*/
import React from 'react';
-import createReactClass from 'create-react-class';
import PropTypes from 'prop-types';
import {Filter} from 'matrix-js-sdk';
@@ -28,23 +27,20 @@ import { _t } from '../../languageHandler';
/*
* Component which shows the filtered file using a TimelinePanel
*/
-const FilePanel = createReactClass({
- displayName: 'FilePanel',
+class FilePanel extends React.Component {
+ static propTypes = {
+ roomId: PropTypes.string.isRequired,
+ };
+
// This is used to track if a decrypted event was a live event and should be
// added to the timeline.
- decryptingEvents: new Set(),
+ decryptingEvents = new Set();
- propTypes: {
- roomId: PropTypes.string.isRequired,
- },
+ state = {
+ timelineSet: null,
+ };
- getInitialState: function() {
- return {
- timelineSet: null,
- };
- },
-
- onRoomTimeline(ev, room, toStartOfTimeline, removed, data) {
+ onRoomTimeline = (ev, room, toStartOfTimeline, removed, data) => {
if (room.roomId !== this.props.roomId) return;
if (toStartOfTimeline || !data || !data.liveEvent || ev.isRedacted()) return;
@@ -53,9 +49,9 @@ const FilePanel = createReactClass({
} else {
this.addEncryptedLiveEvent(ev);
}
- },
+ };
- onEventDecrypted(ev, err) {
+ onEventDecrypted = (ev, err) => {
if (ev.getRoomId() !== this.props.roomId) return;
const eventId = ev.getId();
@@ -63,7 +59,7 @@ const FilePanel = createReactClass({
if (err) return;
this.addEncryptedLiveEvent(ev);
- },
+ };
addEncryptedLiveEvent(ev, toStartOfTimeline) {
if (!this.state.timelineSet) return;
@@ -77,7 +73,7 @@ const FilePanel = createReactClass({
if (!this.state.timelineSet.eventIdToTimeline(ev.getId())) {
this.state.timelineSet.addEventToTimeline(ev, timeline, false);
}
- },
+ }
async componentDidMount() {
const client = MatrixClientPeg.get();
@@ -98,7 +94,7 @@ const FilePanel = createReactClass({
client.on('Room.timeline', this.onRoomTimeline);
client.on('Event.decrypted', this.onEventDecrypted);
}
- },
+ }
componentWillUnmount() {
const client = MatrixClientPeg.get();
@@ -110,7 +106,7 @@ const FilePanel = createReactClass({
client.removeListener('Room.timeline', this.onRoomTimeline);
client.removeListener('Event.decrypted', this.onEventDecrypted);
}
- },
+ }
async fetchFileEventsServer(room) {
const client = MatrixClientPeg.get();
@@ -134,9 +130,9 @@ const FilePanel = createReactClass({
const timelineSet = room.getOrCreateFilteredTimelineSet(filter);
return timelineSet;
- },
+ }
- onPaginationRequest(timelineWindow, direction, limit) {
+ onPaginationRequest = (timelineWindow, direction, limit) => {
const client = MatrixClientPeg.get();
const eventIndex = EventIndexPeg.get();
const roomId = this.props.roomId;
@@ -152,7 +148,7 @@ const FilePanel = createReactClass({
} else {
return timelineWindow.paginate(direction, limit);
}
- },
+ };
async updateTimelineSet(roomId: string) {
const client = MatrixClientPeg.get();
@@ -188,9 +184,9 @@ const FilePanel = createReactClass({
} else {
console.error("Failed to add filtered timelineSet for FilePanel as no room!");
}
- },
+ }
- render: function() {
+ render() {
if (MatrixClientPeg.get().isGuest()) {
return
{
}
};
- _calculateServerLimitToast(syncErrorData: IState["syncErrorData"], usageLimitEventContent?: IUsageLimit) {
- const error = syncErrorData && syncErrorData.error && syncErrorData.error.errcode === "M_RESOURCE_LIMIT_EXCEEDED";
+ _calculateServerLimitToast(syncError: IState["syncErrorData"], usageLimitEventContent?: IUsageLimit) {
+ const error = syncError && syncError.error && syncError.error.errcode === "M_RESOURCE_LIMIT_EXCEEDED";
if (error) {
- usageLimitEventContent = syncErrorData.error.data;
+ usageLimitEventContent = syncError.error.data;
}
if (usageLimitEventContent) {
@@ -596,7 +599,7 @@ class LoggedInView extends React.Component {
const maxRadius = 5; // People shouldn't be straying too far, hopefully
// Note: we track how far the user moved their mouse to help
- // combat against https://github.com/vector-im/riot-web/issues/7158
+ // combat against https://github.com/vector-im/element-web/issues/7158
if (distance < maxRadius) {
// This is probably a real click, and not a drag
@@ -620,18 +623,18 @@ class LoggedInView extends React.Component {
switch (this.props.page_type) {
case PageTypes.RoomView:
pageElement = ;
+ ref={this._roomView}
+ autoJoin={this.props.autoJoin}
+ onRegistered={this.props.onRegistered}
+ thirdPartyInvite={this.props.thirdPartyInvite}
+ oobData={this.props.roomOobData}
+ viaServers={this.props.viaServers}
+ eventPixelOffset={this.props.initialEventPixelOffset}
+ key={this.props.currentRoomId || 'roomview'}
+ disabled={this.props.middleDisabled}
+ ConferenceHandler={this.props.ConferenceHandler}
+ resizeNotifier={this.props.resizeNotifier}
+ />;
break;
case PageTypes.MyGroups:
diff --git a/src/components/structures/MatrixChat.tsx b/src/components/structures/MatrixChat.tsx
index a66d4c043f..176aaf95a3 100644
--- a/src/components/structures/MatrixChat.tsx
+++ b/src/components/structures/MatrixChat.tsx
@@ -69,13 +69,15 @@ import { ViewUserPayload } from "../../dispatcher/payloads/ViewUserPayload";
import { Action } from "../../dispatcher/actions";
import {
showToast as showAnalyticsToast,
- hideToast as hideAnalyticsToast
+ hideToast as hideAnalyticsToast,
} from "../../toasts/AnalyticsToast";
import {showToast as showNotificationsToast} from "../../toasts/DesktopNotificationsToast";
import { OpenToTabPayload } from "../../dispatcher/payloads/OpenToTabPayload";
import ErrorDialog from "../views/dialogs/ErrorDialog";
import { RoomNotificationStateStore } from "../../stores/notifications/RoomNotificationStateStore";
import { SettingLevel } from "../../settings/SettingLevel";
+import { leaveRoomBehaviour } from "../../utils/membership";
+import CreateCommunityPrototypeDialog from "../views/dialogs/CreateCommunityPrototypeDialog";
/** constants for MatrixChat.state.view */
export enum Views {
@@ -127,6 +129,7 @@ interface IScreen {
params?: object;
}
+/* eslint-disable camelcase */
interface IRoomInfo {
room_id?: string;
room_alias?: string;
@@ -138,6 +141,7 @@ interface IRoomInfo {
oob_data?: object;
via_servers?: string[];
}
+/* eslint-enable camelcase */
interface IProps { // TODO type things better
config: Record;
@@ -163,6 +167,7 @@ interface IState {
// the master view we are showing.
view: Views;
// What the LoggedInView would be showing if visible
+ // eslint-disable-next-line camelcase
page_type?: PageTypes;
// The ID of the room we're viewing. This is either populated directly
// in the case where we view a room by ID or by RoomView when it resolves
@@ -178,8 +183,11 @@ interface IState {
middleDisabled: boolean;
// the right panel's disabled state is tracked in its store.
// Parameters used in the registration dance with the IS
+ // eslint-disable-next-line camelcase
register_client_secret?: string;
+ // eslint-disable-next-line camelcase
register_session_id?: string;
+ // eslint-disable-next-line camelcase
register_id_sid?: string;
// When showing Modal dialogs we need to set aria-hidden on the root app element
// and disable it when there are no dialogs
@@ -339,6 +347,7 @@ export default class MatrixChat extends React.PureComponent {
}
// TODO: [REACT-WARNING] Replace with appropriate lifecycle stage
+ // eslint-disable-next-line camelcase
UNSAFE_componentWillUpdate(props, state) {
if (this.shouldTrackPageChange(this.state, state)) {
this.startPageChangeTimer();
@@ -415,7 +424,7 @@ export default class MatrixChat extends React.PureComponent {
return;
}
this.pageChanging = true;
- performance.mark('riot_MatrixChat_page_change_start');
+ performance.mark('element_MatrixChat_page_change_start');
}
stopPageChangeTimer() {
@@ -427,15 +436,15 @@ export default class MatrixChat extends React.PureComponent {
return;
}
this.pageChanging = false;
- performance.mark('riot_MatrixChat_page_change_stop');
+ performance.mark('element_MatrixChat_page_change_stop');
performance.measure(
- 'riot_MatrixChat_page_change_delta',
- 'riot_MatrixChat_page_change_start',
- 'riot_MatrixChat_page_change_stop',
+ 'element_MatrixChat_page_change_delta',
+ 'element_MatrixChat_page_change_start',
+ 'element_MatrixChat_page_change_stop',
);
- performance.clearMarks('riot_MatrixChat_page_change_start');
- performance.clearMarks('riot_MatrixChat_page_change_stop');
- const measurement = performance.getEntriesByName('riot_MatrixChat_page_change_delta').pop();
+ performance.clearMarks('element_MatrixChat_page_change_start');
+ performance.clearMarks('element_MatrixChat_page_change_stop');
+ const measurement = performance.getEntriesByName('element_MatrixChat_page_change_delta').pop();
// In practice, sometimes the entries list is empty, so we get no measurement
if (!measurement) return null;
@@ -608,8 +617,7 @@ export default class MatrixChat extends React.PureComponent {
const UserSettingsDialog = sdk.getComponent("dialogs.UserSettingsDialog");
Modal.createTrackedDialog('User settings', '', UserSettingsDialog,
{initialTabId: tabPayload.initialTabId},
- /*className=*/null, /*isPriority=*/false, /*isStatic=*/true
- );
+ /*className=*/null, /*isPriority=*/false, /*isStatic=*/true);
// View the welcome or home page if we need something to look at
this.viewSomethingBehindModal();
@@ -619,7 +627,10 @@ export default class MatrixChat extends React.PureComponent {
this.createRoom(payload.public);
break;
case 'view_create_group': {
- const CreateGroupDialog = sdk.getComponent("dialogs.CreateGroupDialog");
+ let CreateGroupDialog = sdk.getComponent("dialogs.CreateGroupDialog")
+ if (SettingsStore.getValue("feature_communities_v2_prototypes")) {
+ CreateGroupDialog = CreateCommunityPrototypeDialog;
+ }
Modal.createTrackedDialog('Create Community', '', CreateGroupDialog);
break;
}
@@ -1075,57 +1086,20 @@ export default class MatrixChat extends React.PureComponent {
title: _t("Leave room"),
description: (
- { _t("Are you sure you want to leave the room '%(roomName)s'?", {roomName: roomToLeave.name}) }
+ { _t("Are you sure you want to leave the room '%(roomName)s'?", {roomName: roomToLeave.name}) }
{ warnings }
),
button: _t("Leave"),
onFinished: (shouldLeave) => {
if (shouldLeave) {
- const d = MatrixClientPeg.get().leaveRoomChain(roomId);
+ const d = leaveRoomBehaviour(roomId);
// FIXME: controller shouldn't be loading a view :(
const Loader = sdk.getComponent("elements.Spinner");
const modal = Modal.createDialog(Loader, null, 'mx_Dialog_spinner');
- d.then((errors) => {
- modal.close();
-
- for (const leftRoomId of Object.keys(errors)) {
- const err = errors[leftRoomId];
- if (!err) continue;
-
- console.error("Failed to leave room " + leftRoomId + " " + err);
- let title = _t("Failed to leave room");
- let message = _t("Server may be unavailable, overloaded, or you hit a bug.");
- if (err.errcode === 'M_CANNOT_LEAVE_SERVER_NOTICE_ROOM') {
- title = _t("Can't leave Server Notices room");
- message = _t(
- "This room is used for important messages from the Homeserver, " +
- "so you cannot leave it.",
- );
- } else if (err && err.message) {
- message = err.message;
- }
- Modal.createTrackedDialog('Failed to leave room', '', ErrorDialog, {
- title: title,
- description: message,
- });
- return;
- }
-
- if (this.state.currentRoomId === roomId) {
- dis.dispatch({action: 'view_next_room'});
- }
- }, (err) => {
- // This should only happen if something went seriously wrong with leaving the chain.
- modal.close();
- console.error("Failed to leave room " + roomId + " " + err);
- Modal.createTrackedDialog('Failed to leave room', '', ErrorDialog, {
- title: _t("Failed to leave room"),
- description: _t("Unknown error"),
- });
- });
+ d.finally(() => modal.close());
}
},
});
@@ -1323,7 +1297,7 @@ export default class MatrixChat extends React.PureComponent {
// state (each of which can be 10s of MBs) for each DISJOINT timeline. This is
// particularly noticeable when there are lots of 'limited' /sync responses
// such as when laptops unsleep.
- // https://github.com/vector-im/riot-web/issues/3307#issuecomment-282895568
+ // https://github.com/vector-im/element-web/issues/3307#issuecomment-282895568
cli.setCanResetTimelineCallback((roomId) => {
console.log("Request to reset timeline in room ", roomId, " viewing:", this.state.currentRoomId);
if (roomId !== this.state.currentRoomId) {
@@ -1465,7 +1439,6 @@ export default class MatrixChat extends React.PureComponent {
cli.on("crypto.warning", (type) => {
switch (type) {
case 'CRYPTO_WARNING_OLD_VERSION_DETECTED':
- const brand = SdkConfig.get().brand;
Modal.createTrackedDialog('Crypto migrated', '', ErrorDialog, {
title: _t('Old cryptography data detected'),
description: _t(
@@ -1476,7 +1449,7 @@ export default class MatrixChat extends React.PureComponent {
"in this version. This may also cause messages exchanged with this " +
"version to fail. If you experience problems, log out and back in " +
"again. To retain message history, export and re-import your keys.",
- { brand },
+ { brand: SdkConfig.get().brand },
),
});
break;
@@ -1661,7 +1634,7 @@ export default class MatrixChat extends React.PureComponent {
// of the app, we coerce the eventId to be undefined where applicable.
if (!eventId) eventId = undefined;
- // TODO: Handle encoded room/event IDs: https://github.com/vector-im/riot-web/issues/9149
+ // TODO: Handle encoded room/event IDs: https://github.com/vector-im/element-web/issues/9149
// FIXME: sort_out caseConsistency
const thirdPartyInvite = {
@@ -1935,7 +1908,7 @@ export default class MatrixChat extends React.PureComponent {
let fragmentAfterLogin = "";
const initialScreenAfterLogin = this.props.initialScreenAfterLogin;
if (initialScreenAfterLogin &&
- // XXX: workaround for https://github.com/vector-im/riot-web/issues/11643 causing a login-loop
+ // XXX: workaround for https://github.com/vector-im/element-web/issues/11643 causing a login-loop
!["welcome", "login", "register", "start_sso", "start_cas"].includes(initialScreenAfterLogin.screen)
) {
fragmentAfterLogin = `/${initialScreenAfterLogin.screen}`;
@@ -2085,3 +2058,12 @@ export default class MatrixChat extends React.PureComponent {
;
}
}
+
+export function isLoggedIn(): boolean {
+ // JRS: Maybe we should move the step that writes this to the window out of
+ // `element-web` and into this file? Better yet, we should probably create a
+ // store to hold this state.
+ // See also https://github.com/vector-im/element-web/issues/15034.
+ const app = window.matrixChat;
+ return app && (app as MatrixChat).state.view === Views.LOGGED_IN;
+}
diff --git a/src/components/structures/MyGroups.js b/src/components/structures/MyGroups.js
index 7043c7f38a..e0551eecdb 100644
--- a/src/components/structures/MyGroups.js
+++ b/src/components/structures/MyGroups.js
@@ -17,7 +17,6 @@ limitations under the License.
*/
import React from 'react';
-import createReactClass from 'create-react-class';
import * as sdk from '../../index';
import { _t } from '../../languageHandler';
import SdkConfig from '../../SdkConfig';
@@ -26,29 +25,23 @@ import AccessibleButton from '../views/elements/AccessibleButton';
import MatrixClientContext from "../../contexts/MatrixClientContext";
import AutoHideScrollbar from "./AutoHideScrollbar";
-export default createReactClass({
- displayName: 'MyGroups',
+export default class MyGroups extends React.Component {
+ static contextType = MatrixClientContext;
- getInitialState: function() {
- return {
- groups: null,
- error: null,
- };
- },
+ state = {
+ groups: null,
+ error: null,
+ };
- statics: {
- contextType: MatrixClientContext,
- },
-
- componentDidMount: function() {
+ componentDidMount() {
this._fetch();
- },
+ }
- _onCreateGroupClick: function() {
+ _onCreateGroupClick = () => {
dis.dispatch({action: 'view_create_group'});
- },
+ };
- _fetch: function() {
+ _fetch() {
this.context.getJoinedGroups().then((result) => {
this.setState({groups: result.groups, error: null});
}, (err) => {
@@ -59,9 +52,9 @@ export default createReactClass({
}
this.setState({groups: null, error: err});
});
- },
+ }
- render: function() {
+ render() {
const brand = SdkConfig.get().brand;
const Loader = sdk.getComponent("elements.Spinner");
const SimpleRoomHeader = sdk.getComponent('rooms.SimpleRoomHeader');
@@ -149,5 +142,5 @@ export default createReactClass({
{ content }
;
- },
-});
+ }
+}
diff --git a/src/components/structures/NotificationPanel.js b/src/components/structures/NotificationPanel.js
index c1f78cffda..6ae7f91142 100644
--- a/src/components/structures/NotificationPanel.js
+++ b/src/components/structures/NotificationPanel.js
@@ -17,7 +17,6 @@ limitations under the License.
*/
import React from 'react';
-import createReactClass from 'create-react-class';
import { _t } from '../../languageHandler';
import {MatrixClientPeg} from "../../MatrixClientPeg";
import * as sdk from "../../index";
@@ -25,13 +24,8 @@ import * as sdk from "../../index";
/*
* Component which shows the global notification list using a TimelinePanel
*/
-const NotificationPanel = createReactClass({
- displayName: 'NotificationPanel',
-
- propTypes: {
- },
-
- render: function() {
+class NotificationPanel extends React.Component {
+ render() {
// wrap a TimelinePanel with the jump-to-event bits turned off.
const TimelinePanel = sdk.getComponent("structures.TimelinePanel");
const Loader = sdk.getComponent("elements.Spinner");
@@ -45,7 +39,7 @@ const NotificationPanel = createReactClass({
if (timelineSet) {
return (
-
);
}
- },
-});
+ }
+}
export default NotificationPanel;
diff --git a/src/components/structures/RightPanel.js b/src/components/structures/RightPanel.js
index a4e3254e4c..24fee80c2a 100644
--- a/src/components/structures/RightPanel.js
+++ b/src/components/structures/RightPanel.js
@@ -42,8 +42,8 @@ export default class RightPanel extends React.Component {
static contextType = MatrixClientContext;
- constructor(props) {
- super(props);
+ constructor(props, context) {
+ super(props, context);
this.state = {
phase: this._getPhaseFromProps(),
isUserPrivilegedInGroup: null,
diff --git a/src/components/structures/RoomDirectory.js b/src/components/structures/RoomDirectory.js
index 5b12dae7df..16ab8edbed 100644
--- a/src/components/structures/RoomDirectory.js
+++ b/src/components/structures/RoomDirectory.js
@@ -17,7 +17,6 @@ limitations under the License.
*/
import React from 'react';
-import createReactClass from 'create-react-class';
import {MatrixClientPeg} from "../../MatrixClientPeg";
import * as sdk from "../../index";
import dis from "../../dispatcher/dispatcher";
@@ -30,6 +29,10 @@ import { instanceForInstanceId, protocolNameForInstanceId } from '../../utils/Di
import Analytics from '../../Analytics';
import {getHttpUriForMxc} from "matrix-js-sdk/src/content-repo";
import {ALL_ROOMS} from "../views/directory/NetworkDropdown";
+import SettingsStore from "../../settings/SettingsStore";
+import TagOrderStore from "../../stores/TagOrderStore";
+import GroupStore from "../../stores/GroupStore";
+import FlairStore from "../../stores/FlairStore";
const MAX_NAME_LENGTH = 80;
const MAX_TOPIC_LENGTH = 160;
@@ -38,15 +41,16 @@ function track(action) {
Analytics.trackEvent('RoomDirectory', action);
}
-export default createReactClass({
- displayName: 'RoomDirectory',
-
- propTypes: {
+export default class RoomDirectory extends React.Component {
+ static propTypes = {
onFinished: PropTypes.func.isRequired,
- },
+ };
- getInitialState: function() {
- return {
+ constructor(props) {
+ super(props);
+
+ const selectedCommunityId = TagOrderStore.getSelectedTags()[0];
+ this.state = {
publicRooms: [],
loading: true,
protocolsLoading: true,
@@ -54,11 +58,12 @@ export default createReactClass({
instanceId: undefined,
roomServer: MatrixClientPeg.getHomeserverName(),
filterString: null,
+ selectedCommunityId: SettingsStore.getValue("feature_communities_v2_prototypes")
+ ? selectedCommunityId
+ : null,
+ communityName: null,
};
- },
- // TODO: [REACT-WARNING] Move this to constructor
- UNSAFE_componentWillMount: function() {
this._unmounted = false;
this.nextBatch = null;
this.filterTimeout = null;
@@ -71,49 +76,88 @@ export default createReactClass({
this.setState({protocolsLoading: false});
return;
}
- MatrixClientPeg.get().getThirdpartyProtocols().then((response) => {
- this.protocols = response;
- this.setState({protocolsLoading: false});
- }, (err) => {
- console.warn(`error loading third party protocols: ${err}`);
- this.setState({protocolsLoading: false});
- if (MatrixClientPeg.get().isGuest()) {
- // Guests currently aren't allowed to use this API, so
- // ignore this as otherwise this error is literally the
- // thing you see when loading the client!
- return;
- }
- track('Failed to get protocol list from homeserver');
- const brand = SdkConfig.get().brand;
- this.setState({
- error: _t(
- '%(brand)s failed to get the protocol list from the homeserver. ' +
- 'The homeserver may be too old to support third party networks.',
- { brand },
- ),
+
+ if (!this.state.selectedCommunityId) {
+ MatrixClientPeg.get().getThirdpartyProtocols().then((response) => {
+ this.protocols = response;
+ this.setState({protocolsLoading: false});
+ }, (err) => {
+ console.warn(`error loading third party protocols: ${err}`);
+ this.setState({protocolsLoading: false});
+ if (MatrixClientPeg.get().isGuest()) {
+ // Guests currently aren't allowed to use this API, so
+ // ignore this as otherwise this error is literally the
+ // thing you see when loading the client!
+ return;
+ }
+ track('Failed to get protocol list from homeserver');
+ const brand = SdkConfig.get().brand;
+ this.setState({
+ error: _t(
+ '%(brand)s failed to get the protocol list from the homeserver. ' +
+ 'The homeserver may be too old to support third party networks.',
+ {brand},
+ ),
+ });
});
- });
+ } else {
+ // We don't use the protocols in the communities v2 prototype experience
+ this.setState({protocolsLoading: false});
+
+ // Grab the profile info async
+ FlairStore.getGroupProfileCached(MatrixClientPeg.get(), this.state.selectedCommunityId).then(profile => {
+ this.setState({communityName: profile.name});
+ });
+ }
this.refreshRoomList();
- },
+ }
- componentWillUnmount: function() {
+ componentWillUnmount() {
if (this.filterTimeout) {
clearTimeout(this.filterTimeout);
}
this._unmounted = true;
- },
+ }
+
+ refreshRoomList = () => {
+ if (this.state.selectedCommunityId) {
+ this.setState({
+ publicRooms: GroupStore.getGroupRooms(this.state.selectedCommunityId).map(r => {
+ return {
+ // Translate all the group properties to the directory format
+ room_id: r.roomId,
+ name: r.name,
+ topic: r.topic,
+ canonical_alias: r.canonicalAlias,
+ num_joined_members: r.numJoinedMembers,
+ avatarUrl: r.avatarUrl,
+ world_readable: r.worldReadable,
+ guest_can_join: r.guestsCanJoin,
+ };
+ }).filter(r => {
+ const filterString = this.state.filterString;
+ if (filterString) {
+ const containedIn = (s: string) => (s || "").toLowerCase().includes(filterString.toLowerCase());
+ return containedIn(r.name) || containedIn(r.topic) || containedIn(r.canonical_alias);
+ }
+ return true;
+ }),
+ loading: false,
+ });
+ return;
+ }
- refreshRoomList: function() {
this.nextBatch = null;
this.setState({
publicRooms: [],
loading: true,
});
this.getMoreRooms();
- },
+ };
- getMoreRooms: function() {
+ getMoreRooms() {
+ if (this.state.selectedCommunityId) return Promise.resolve(); // no more rooms
if (!MatrixClientPeg.get()) return Promise.resolve();
this.setState({
@@ -185,7 +229,7 @@ export default createReactClass({
),
});
});
- },
+ }
/**
* A limited interface for removing rooms from the directory.
@@ -194,7 +238,7 @@ export default createReactClass({
* HS admins to do this through the RoomSettings interface, but
* this needs SPEC-417.
*/
- removeFromDirectory: function(room) {
+ removeFromDirectory(room) {
const alias = get_display_alias_for_room(room);
const name = room.name || alias || _t('Unnamed room');
@@ -236,18 +280,18 @@ export default createReactClass({
});
},
});
- },
+ }
- onRoomClicked: function(room, ev) {
- if (ev.shiftKey) {
+ onRoomClicked = (room, ev) => {
+ if (ev.shiftKey && !this.state.selectedCommunityId) {
ev.preventDefault();
this.removeFromDirectory(room);
} else {
this.showRoom(room);
}
- },
+ };
- onOptionChange: function(server, instanceId) {
+ onOptionChange = (server, instanceId) => {
// clear next batch so we don't try to load more rooms
this.nextBatch = null;
this.setState({
@@ -265,15 +309,15 @@ export default createReactClass({
// find the five gitter ones, at which point we do not want
// to render all those rooms when switching back to 'all networks'.
// Easiest to just blow away the state & re-fetch.
- },
+ };
- onFillRequest: function(backwards) {
+ onFillRequest = (backwards) => {
if (backwards || !this.nextBatch) return Promise.resolve(false);
return this.getMoreRooms();
- },
+ };
- onFilterChange: function(alias) {
+ onFilterChange = (alias) => {
this.setState({
filterString: alias || null,
});
@@ -289,9 +333,9 @@ export default createReactClass({
this.filterTimeout = null;
this.refreshRoomList();
}, 700);
- },
+ };
- onFilterClear: function() {
+ onFilterClear = () => {
// update immediately
this.setState({
filterString: null,
@@ -300,9 +344,9 @@ export default createReactClass({
if (this.filterTimeout) {
clearTimeout(this.filterTimeout);
}
- },
+ };
- onJoinFromSearchClick: function(alias) {
+ onJoinFromSearchClick = (alias) => {
// If we don't have a particular instance id selected, just show that rooms alias
if (!this.state.instanceId || this.state.instanceId === ALL_ROOMS) {
// If the user specified an alias without a domain, add on whichever server is selected
@@ -343,9 +387,9 @@ export default createReactClass({
});
});
}
- },
+ };
- onPreviewClick: function(ev, room) {
+ onPreviewClick = (ev, room) => {
this.props.onFinished();
dis.dispatch({
action: 'view_room',
@@ -353,9 +397,9 @@ export default createReactClass({
should_peek: true,
});
ev.stopPropagation();
- },
+ };
- onViewClick: function(ev, room) {
+ onViewClick = (ev, room) => {
this.props.onFinished();
dis.dispatch({
action: 'view_room',
@@ -363,26 +407,26 @@ export default createReactClass({
should_peek: false,
});
ev.stopPropagation();
- },
+ };
- onJoinClick: function(ev, room) {
+ onJoinClick = (ev, room) => {
this.showRoom(room, null, true);
ev.stopPropagation();
- },
+ };
- onCreateRoomClick: function(room) {
+ onCreateRoomClick = room => {
this.props.onFinished();
dis.dispatch({
action: 'view_create_room',
public: true,
});
- },
+ };
- showRoomAlias: function(alias, autoJoin=false) {
+ showRoomAlias(alias, autoJoin=false) {
this.showRoom(null, alias, autoJoin);
- },
+ }
- showRoom: function(room, room_alias, autoJoin=false) {
+ showRoom(room, room_alias, autoJoin=false) {
this.props.onFinished();
const payload = {
action: 'view_room',
@@ -426,7 +470,7 @@ export default createReactClass({
payload.room_id = room.room_id;
}
dis.dispatch(payload);
- },
+ }
getRow(room) {
const client = MatrixClientPeg.get();
@@ -492,22 +536,22 @@ export default createReactClass({
{joinOrViewButton}
);
- },
+ }
- collectScrollPanel: function(element) {
+ collectScrollPanel = (element) => {
this.scrollPanel = element;
- },
+ };
- _stringLooksLikeId: function(s, field_type) {
+ _stringLooksLikeId(s, field_type) {
let pat = /^#[^\s]+:[^\s]/;
if (field_type && field_type.regexp) {
pat = new RegExp(field_type.regexp);
}
return pat.test(s);
- },
+ }
- _getFieldsForThirdPartyLocation: function(userInput, protocol, instance) {
+ _getFieldsForThirdPartyLocation(userInput, protocol, instance) {
// make an object with the fields specified by that protocol. We
// require that the values of all but the last field come from the
// instance. The last is the user input.
@@ -521,20 +565,20 @@ export default createReactClass({
}
fields[requiredFields[requiredFields.length - 1]] = userInput;
return fields;
- },
+ }
/**
* called by the parent component when PageUp/Down/etc is pressed.
*
* We pass it down to the scroll panel.
*/
- handleScrollKey: function(ev) {
+ handleScrollKey = ev => {
if (this.scrollPanel) {
this.scrollPanel.handleScrollKey(ev);
}
- },
+ };
- render: function() {
+ render() {
const Loader = sdk.getComponent("elements.Spinner");
const BaseDialog = sdk.getComponent('views.dialogs.BaseDialog');
const AccessibleButton = sdk.getComponent('elements.AccessibleButton');
@@ -610,6 +654,18 @@ export default createReactClass({
}
}
+ let dropdown = (
+
+ );
+ if (this.state.selectedCommunityId) {
+ dropdown = null;
+ }
+
listHeader =
);
- },
-});
+ }
+}
// Similar to matrix-react-sdk's MatrixTools.getDisplayAliasForRoom
// but works with the objects we get from the public room list
diff --git a/src/components/structures/RoomSearch.tsx b/src/components/structures/RoomSearch.tsx
index 69504e9ab8..768bc38d23 100644
--- a/src/components/structures/RoomSearch.tsx
+++ b/src/components/structures/RoomSearch.tsx
@@ -20,7 +20,6 @@ import classNames from "classnames";
import defaultDispatcher from "../../dispatcher/dispatcher";
import { _t } from "../../languageHandler";
import { ActionPayload } from "../../dispatcher/payloads";
-import { throttle } from 'lodash';
import { Key } from "../../Keyboard";
import AccessibleButton from "../views/elements/AccessibleButton";
import { Action } from "../../dispatcher/actions";
@@ -126,7 +125,8 @@ export default class RoomSearch extends React.PureComponent {
public render(): React.ReactNode {
const classes = classNames({
'mx_RoomSearch': true,
- 'mx_RoomSearch_expanded': this.state.query || this.state.focused,
+ 'mx_RoomSearch_hasQuery': this.state.query,
+ 'mx_RoomSearch_focused': this.state.focused,
'mx_RoomSearch_minimized': this.props.isMinimized,
});
@@ -136,7 +136,7 @@ export default class RoomSearch extends React.PureComponent {
});
let icon = (
-
+
);
let input = (
{
if (state === "SYNCING" && prevState === "SYNCING") {
return;
}
@@ -124,39 +119,39 @@ export default createReactClass({
syncState: state,
syncStateData: data,
});
- },
+ };
- _onResendAllClick: function() {
+ _onResendAllClick = () => {
Resend.resendUnsentEvents(this.props.room);
dis.fire(Action.FocusComposer);
- },
+ };
- _onCancelAllClick: function() {
+ _onCancelAllClick = () => {
Resend.cancelUnsentEvents(this.props.room);
dis.fire(Action.FocusComposer);
- },
+ };
- _onRoomLocalEchoUpdated: function(event, room, oldEventId, oldStatus) {
+ _onRoomLocalEchoUpdated = (event, room, oldEventId, oldStatus) => {
if (room.roomId !== this.props.room.roomId) return;
this.setState({
unsentMessages: getUnsentMessages(this.props.room),
});
- },
+ };
// Check whether current size is greater than 0, if yes call props.onVisible
- _checkSize: function() {
+ _checkSize() {
if (this._getSize()) {
if (this.props.onVisible) this.props.onVisible();
} else {
if (this.props.onHidden) this.props.onHidden();
}
- },
+ }
// We don't need the actual height - just whether it is likely to have
// changed - so we use '0' to indicate normal size, and other values to
// indicate other sizes.
- _getSize: function() {
+ _getSize() {
if (this._shouldShowConnectionError() ||
this.props.hasActiveCall ||
this.props.sentMessageAndIsAlone
@@ -166,10 +161,10 @@ export default createReactClass({
return STATUS_BAR_EXPANDED_LARGE;
}
return STATUS_BAR_HIDDEN;
- },
+ }
// return suitable content for the image on the left of the status bar.
- _getIndicator: function() {
+ _getIndicator() {
if (this.props.hasActiveCall) {
const TintableSvg = sdk.getComponent("elements.TintableSvg");
return (
@@ -182,9 +177,9 @@ export default createReactClass({
}
return null;
- },
+ }
- _shouldShowConnectionError: function() {
+ _shouldShowConnectionError() {
// no conn bar trumps the "some not sent" msg since you can't resend without
// a connection!
// There's one situation in which we don't show this 'no connection' bar, and that's
@@ -195,9 +190,9 @@ export default createReactClass({
this.state.syncStateData.error.errcode === 'M_RESOURCE_LIMIT_EXCEEDED',
);
return this.state.syncState === "ERROR" && !errorIsMauError;
- },
+ }
- _getUnsentMessageContent: function() {
+ _getUnsentMessageContent() {
const unsentMessages = this.state.unsentMessages;
if (!unsentMessages.length) return null;
@@ -272,10 +267,10 @@ export default createReactClass({
;
- },
+ }
// return suitable content for the main (text) part of the status bar.
- _getContent: function() {
+ _getContent() {
if (this._shouldShowConnectionError()) {
return (
;
- }
- },
-});
diff --git a/src/components/views/context_menus/TopLeftMenu.js b/src/components/views/context_menus/TopLeftMenu.js
deleted file mode 100644
index ec99c63724..0000000000
--- a/src/components/views/context_menus/TopLeftMenu.js
+++ /dev/null
@@ -1,155 +0,0 @@
-/*
-Copyright 2018, 2019 New Vector Ltd
-Copyright 2019 The Matrix.org Foundation C.I.C.
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
-*/
-
-import React from 'react';
-import PropTypes from 'prop-types';
-import dis from '../../../dispatcher/dispatcher';
-import { _t } from '../../../languageHandler';
-import LogoutDialog from "../dialogs/LogoutDialog";
-import Modal from "../../../Modal";
-import SdkConfig from '../../../SdkConfig';
-import { getHostingLink } from '../../../utils/HostingLink';
-import {MatrixClientPeg} from '../../../MatrixClientPeg';
-import {MenuItem} from "../../structures/ContextMenu";
-import * as sdk from "../../../index";
-import {getHomePageUrl} from "../../../utils/pages";
-import {Action} from "../../../dispatcher/actions";
-
-export default class TopLeftMenu extends React.Component {
- static propTypes = {
- displayName: PropTypes.string.isRequired,
- userId: PropTypes.string.isRequired,
- onFinished: PropTypes.func,
-
- // Optional function to collect a reference to the container
- // of this component directly.
- containerRef: PropTypes.func,
- };
-
- constructor() {
- super();
- this.viewHomePage = this.viewHomePage.bind(this);
- this.openSettings = this.openSettings.bind(this);
- this.signIn = this.signIn.bind(this);
- this.signOut = this.signOut.bind(this);
- }
-
- hasHomePage() {
- return !!getHomePageUrl(SdkConfig.get());
- }
-
- render() {
- const isGuest = MatrixClientPeg.get().isGuest();
-
- const hostingSignupLink = getHostingLink('user-context-menu');
- let hostingSignup = null;
- if (hostingSignupLink) {
- hostingSignup =
- {_t(
- "Upgrade to your own domain", {},
- {
- a: sub =>
- {sub},
- },
- )}
-
-
-
-
{_t("This room is private, and can only be joined by invitation.")}
);
+ }
+
+ let publicPrivateLabel =
{_t(
+ "Private rooms can be found and joined by invitation only. Public rooms can be " +
+ "found and joined by anyone.",
+ )}
;
+ if (CommunityPrototypeStore.instance.getSelectedCommunityId()) {
+ publicPrivateLabel =
{_t(
+ "Private rooms can be found and joined by invitation only. Public rooms can be " +
+ "found and joined by anyone in this community.",
+ )}
;
}
let e2eeSection;
@@ -212,7 +224,24 @@ export default createReactClass({
;
}
- const title = this.state.isPublic ? _t('Create a public room') : _t('Create a private room');
+ let federateLabel = _t(
+ "You might enable this if the room will only be used for collaborating with internal " +
+ "teams on your homeserver. This cannot be changed later.",
+ );
+ if (SdkConfig.get().default_federate === false) {
+ // We only change the label if the default setting is different to avoid jarring text changes to the
+ // user. They will have read the implications of turning this off/on, so no need to rephrase for them.
+ federateLabel = _t(
+ "You might disable this if the room will be used for collaborating with external " +
+ "teams who have their own homeserver. This cannot be changed later.",
+ );
+ }
+
+ let title = this.state.isPublic ? _t('Create a public room') : _t('Create a private room');
+ if (CommunityPrototypeStore.instance.getSelectedCommunityId()) {
+ const name = CommunityPrototypeStore.instance.getSelectedCommunityName();
+ title = _t("Create a room in %(communityName)s", {communityName: name});
+ }
return (
{ this.state.detailsOpen ? _t('Hide advanced') : _t('Show advanced') }
-
+
+
{federateLabel}
@@ -236,5 +273,5 @@ export default createReactClass({
onCancel={this.onCancel} />
);
- },
-});
+ }
+}
diff --git a/src/components/views/dialogs/EditCommunityPrototypeDialog.tsx b/src/components/views/dialogs/EditCommunityPrototypeDialog.tsx
new file mode 100644
index 0000000000..3071854b3e
--- /dev/null
+++ b/src/components/views/dialogs/EditCommunityPrototypeDialog.tsx
@@ -0,0 +1,167 @@
+/*
+Copyright 2020 The Matrix.org Foundation C.I.C.
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+import React, { ChangeEvent } from 'react';
+import BaseDialog from "./BaseDialog";
+import { _t } from "../../../languageHandler";
+import { IDialogProps } from "./IDialogProps";
+import Field from "../elements/Field";
+import AccessibleButton from "../elements/AccessibleButton";
+import { MatrixClientPeg } from "../../../MatrixClientPeg";
+import { CommunityPrototypeStore } from "../../../stores/CommunityPrototypeStore";
+import FlairStore from "../../../stores/FlairStore";
+
+interface IProps extends IDialogProps {
+ communityId: string;
+}
+
+interface IState {
+ name: string;
+ error: string;
+ busy: boolean;
+ currentAvatarUrl: string;
+ avatarFile: File;
+ avatarPreview: string;
+}
+
+// XXX: This is a lot of duplication from the create dialog, just in a different shape
+export default class EditCommunityPrototypeDialog extends React.PureComponent {
+ private avatarUploadRef: React.RefObject = React.createRef();
+
+ constructor(props: IProps) {
+ super(props);
+
+ const profile = CommunityPrototypeStore.instance.getCommunityProfile(props.communityId);
+
+ this.state = {
+ name: profile?.name || "",
+ error: null,
+ busy: false,
+ avatarFile: null,
+ avatarPreview: null,
+ currentAvatarUrl: profile?.avatarUrl,
+ };
+ }
+
+ private onNameChange = (ev: ChangeEvent) => {
+ this.setState({name: ev.target.value});
+ };
+
+ private onSubmit = async (ev) => {
+ ev.preventDefault();
+ ev.stopPropagation();
+
+ if (this.state.busy) return;
+
+ // We'll create the community now to see if it's taken, leaving it active in
+ // the background for the user to look at while they invite people.
+ this.setState({busy: true});
+ try {
+ let avatarUrl = this.state.currentAvatarUrl || ""; // must be a string for synapse to accept it
+ if (this.state.avatarFile) {
+ avatarUrl = await MatrixClientPeg.get().uploadContent(this.state.avatarFile);
+ }
+
+ await MatrixClientPeg.get().setGroupProfile(this.props.communityId, {
+ name: this.state.name,
+ avatar_url: avatarUrl,
+ });
+
+ // ask the flair store to update the profile too
+ await FlairStore.refreshGroupProfile(MatrixClientPeg.get(), this.props.communityId);
+
+ // we did it, so close the dialog
+ this.props.onFinished(true);
+ } catch (e) {
+ console.error(e);
+ this.setState({
+ busy: false,
+ error: _t("There was an error updating your community. The server is unable to process your request."),
+ });
+ }
+ };
+
+ private onAvatarChanged = (e: ChangeEvent) => {
+ if (!e.target.files || !e.target.files.length) {
+ this.setState({avatarFile: null});
+ } else {
+ this.setState({busy: true});
+ const file = e.target.files[0];
+ const reader = new FileReader();
+ reader.onload = (ev: ProgressEvent) => {
+ this.setState({avatarFile: file, busy: false, avatarPreview: ev.target.result as string});
+ };
+ reader.readAsDataURL(file);
+ }
+ };
+
+ private onChangeAvatar = () => {
+ if (this.avatarUploadRef.current) this.avatarUploadRef.current.click();
+ };
+
+ public render() {
+ let preview = ;
+ if (!this.state.avatarPreview) {
+ if (this.state.currentAvatarUrl) {
+ const url = MatrixClientPeg.get().mxcUrlToHttp(this.state.currentAvatarUrl);
+ preview = ;
+ } else {
+ preview =
+ }
+ }
+
+ return (
+
+
+
+ );
+ }
+}
diff --git a/src/components/views/dialogs/ErrorDialog.js b/src/components/views/dialogs/ErrorDialog.js
index fbc5509457..acebdcd854 100644
--- a/src/components/views/dialogs/ErrorDialog.js
+++ b/src/components/views/dialogs/ErrorDialog.js
@@ -26,14 +26,12 @@ limitations under the License.
*/
import React from 'react';
-import createReactClass from 'create-react-class';
import PropTypes from 'prop-types';
import * as sdk from '../../../index';
import { _t } from '../../../languageHandler';
-export default createReactClass({
- displayName: 'ErrorDialog',
- propTypes: {
+export default class ErrorDialog extends React.Component {
+ static propTypes = {
title: PropTypes.string,
description: PropTypes.oneOfType([
PropTypes.element,
@@ -43,18 +41,16 @@ export default createReactClass({
focus: PropTypes.bool,
onFinished: PropTypes.func.isRequired,
headerImage: PropTypes.string,
- },
+ };
- getDefaultProps: function() {
- return {
- focus: true,
- title: null,
- description: null,
- button: null,
- };
- },
+ static defaultProps = {
+ focus: true,
+ title: null,
+ description: null,
+ button: null,
+ };
- render: function() {
+ render() {
const BaseDialog = sdk.getComponent('views.dialogs.BaseDialog');
return (
);
- },
-});
+ }
+}
diff --git a/src/components/views/dialogs/IDialogProps.ts b/src/components/views/dialogs/IDialogProps.ts
new file mode 100644
index 0000000000..1027ca7607
--- /dev/null
+++ b/src/components/views/dialogs/IDialogProps.ts
@@ -0,0 +1,19 @@
+/*
+Copyright 2020 The Matrix.org Foundation C.I.C.
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+export interface IDialogProps {
+ onFinished: (bool) => void;
+}
diff --git a/src/components/views/dialogs/InfoDialog.js b/src/components/views/dialogs/InfoDialog.js
index b63f6ba9c6..8125bc3edd 100644
--- a/src/components/views/dialogs/InfoDialog.js
+++ b/src/components/views/dialogs/InfoDialog.js
@@ -17,15 +17,13 @@ limitations under the License.
*/
import React from 'react';
-import createReactClass from 'create-react-class';
import PropTypes from 'prop-types';
import * as sdk from '../../../index';
import { _t } from '../../../languageHandler';
import classNames from "classnames";
-export default createReactClass({
- displayName: 'InfoDialog',
- propTypes: {
+export default class InfoDialog extends React.Component {
+ static propTypes = {
className: PropTypes.string,
title: PropTypes.string,
description: PropTypes.node,
@@ -33,21 +31,19 @@ export default createReactClass({
onFinished: PropTypes.func,
hasCloseButton: PropTypes.bool,
onKeyDown: PropTypes.func,
- },
+ };
- getDefaultProps: function() {
- return {
- title: '',
- description: '',
- hasCloseButton: false,
- };
- },
+ static defaultProps = {
+ title: '',
+ description: '',
+ hasCloseButton: false,
+ };
- onFinished: function() {
+ onFinished = () => {
this.props.onFinished();
- },
+ };
- render: function() {
+ render() {
const BaseDialog = sdk.getComponent('views.dialogs.BaseDialog');
const DialogButtons = sdk.getComponent('views.elements.DialogButtons');
return (
@@ -69,5 +65,5 @@ export default createReactClass({
);
- },
-});
+ }
+}
diff --git a/src/components/views/dialogs/InteractiveAuthDialog.js b/src/components/views/dialogs/InteractiveAuthDialog.js
index b06ce63ecd..22291225ad 100644
--- a/src/components/views/dialogs/InteractiveAuthDialog.js
+++ b/src/components/views/dialogs/InteractiveAuthDialog.js
@@ -17,7 +17,6 @@ limitations under the License.
*/
import React from 'react';
-import createReactClass from 'create-react-class';
import PropTypes from 'prop-types';
import * as sdk from '../../../index';
@@ -27,10 +26,8 @@ import AccessibleButton from '../elements/AccessibleButton';
import {ERROR_USER_CANCELLED} from "../../structures/InteractiveAuth";
import {SSOAuthEntry} from "../auth/InteractiveAuthEntryComponents";
-export default createReactClass({
- displayName: 'InteractiveAuthDialog',
-
- propTypes: {
+export default class InteractiveAuthDialog extends React.Component {
+ static propTypes = {
// matrix client to use for UI auth requests
matrixClient: PropTypes.object.isRequired,
@@ -70,19 +67,17 @@ export default createReactClass({
//
// Default is defined in _getDefaultDialogAesthetics()
aestheticsForStagePhases: PropTypes.object,
- },
+ };
- getInitialState: function() {
- return {
- authError: null,
+ state = {
+ authError: null,
- // See _onUpdateStagePhase()
- uiaStage: null,
- uiaStagePhase: null,
- };
- },
+ // See _onUpdateStagePhase()
+ uiaStage: null,
+ uiaStagePhase: null,
+ };
- _getDefaultDialogAesthetics: function() {
+ _getDefaultDialogAesthetics() {
const ssoAesthetics = {
[SSOAuthEntry.PHASE_PREAUTH]: {
title: _t("Use Single Sign On to continue"),
@@ -102,9 +97,9 @@ export default createReactClass({
[SSOAuthEntry.LOGIN_TYPE]: ssoAesthetics,
[SSOAuthEntry.UNSTABLE_LOGIN_TYPE]: ssoAesthetics,
};
- },
+ }
- _onAuthFinished: function(success, result) {
+ _onAuthFinished = (success, result) => {
if (success) {
this.props.onFinished(true, result);
} else {
@@ -116,18 +111,18 @@ export default createReactClass({
});
}
}
- },
+ };
- _onUpdateStagePhase: function(newStage, newPhase) {
+ _onUpdateStagePhase = (newStage, newPhase) => {
// We copy the stage and stage phase params into state for title selection in render()
this.setState({uiaStage: newStage, uiaStagePhase: newPhase});
- },
+ };
- _onDismissClick: function() {
+ _onDismissClick = () => {
this.props.onFinished(false);
- },
+ };
- render: function() {
+ render() {
const InteractiveAuth = sdk.getComponent("structures.InteractiveAuth");
const BaseDialog = sdk.getComponent('views.dialogs.BaseDialog');
@@ -190,5 +185,5 @@ export default createReactClass({
{ content }
);
- },
-});
+ }
+}
diff --git a/src/components/views/dialogs/InviteDialog.js b/src/components/views/dialogs/InviteDialog.js
index 4d7a66e957..80d8f1fc2c 100644
--- a/src/components/views/dialogs/InviteDialog.js
+++ b/src/components/views/dialogs/InviteDialog.js
@@ -32,11 +32,12 @@ import IdentityAuthClient from "../../../IdentityAuthClient";
import Modal from "../../../Modal";
import {humanizeTime} from "../../../utils/humanize";
import createRoom, {canEncryptToAllUsers, privateShouldBeEncrypted} from "../../../createRoom";
-import {inviteMultipleToRoom} from "../../../RoomInvite";
+import {inviteMultipleToRoom, showCommunityInviteDialog} from "../../../RoomInvite";
import {Key} from "../../../Keyboard";
import {Action} from "../../../dispatcher/actions";
import {DefaultTagID} from "../../../stores/room-list/models";
import RoomListStore from "../../../stores/room-list/RoomListStore";
+import {CommunityPrototypeStore} from "../../../stores/CommunityPrototypeStore";
// we have a number of types defined from the Matrix spec which can't reasonably be altered here.
/* eslint-disable camelcase */
@@ -327,7 +328,7 @@ export default class InviteDialog extends React.PureComponent {
this.state = {
targets: [], // array of Member objects (see interface above)
filterText: "",
- recents: this._buildRecents(alreadyInvited),
+ recents: InviteDialog.buildRecents(alreadyInvited),
numRecentsShown: INITIAL_ROOMS_SHOWN,
suggestions: this._buildSuggestions(alreadyInvited),
numSuggestionsShown: INITIAL_ROOMS_SHOWN,
@@ -344,12 +345,12 @@ export default class InviteDialog extends React.PureComponent {
this._editorRef = createRef();
}
- _buildRecents(excludedTargetIds: Set): {userId: string, user: RoomMember, lastActive: number} {
+ static buildRecents(excludedTargetIds: Set): {userId: string, user: RoomMember, lastActive: number} {
const rooms = DMRoomMap.shared().getUniqueRoomsWithIndividuals(); // map of userId => js-sdk Room
// Also pull in all the rooms tagged as DefaultTagID.DM so we don't miss anything. Sometimes the
// room list doesn't tag the room for the DMRoomMap, but does for the room list.
- const dmTaggedRooms = RoomListStore.instance.orderedLists[DefaultTagID.DM];
+ const dmTaggedRooms = RoomListStore.instance.orderedLists[DefaultTagID.DM] || [];
const myUserId = MatrixClientPeg.get().getUserId();
for (const dmRoom of dmTaggedRooms) {
const otherMembers = dmRoom.getJoinedMembers().filter(u => u.userId !== myUserId);
@@ -909,12 +910,23 @@ export default class InviteDialog extends React.PureComponent {
this.props.onFinished();
};
+ _onCommunityInviteClick = (e) => {
+ this.props.onFinished();
+ showCommunityInviteDialog(CommunityPrototypeStore.instance.getSelectedCommunityId());
+ };
+
_renderSection(kind: "recents"|"suggestions") {
let sourceMembers = kind === 'recents' ? this.state.recents : this.state.suggestions;
let showNum = kind === 'recents' ? this.state.numRecentsShown : this.state.numSuggestionsShown;
const showMoreFn = kind === 'recents' ? this._showMoreRecents.bind(this) : this._showMoreSuggestions.bind(this);
const lastActive = (m) => kind === 'recents' ? m.lastActive : null;
let sectionName = kind === 'recents' ? _t("Recent Conversations") : _t("Suggestions");
+ let sectionSubname = null;
+
+ if (kind === 'suggestions' && CommunityPrototypeStore.instance.getSelectedCommunityId()) {
+ const communityName = CommunityPrototypeStore.instance.getSelectedCommunityName();
+ sectionSubname = _t("May include members not in %(communityName)s", {communityName});
+ }
if (this.props.kind === KIND_INVITE) {
sectionName = kind === 'recents' ? _t("Recently Direct Messaged") : _t("Suggestions");
@@ -993,6 +1005,7 @@ export default class InviteDialog extends React.PureComponent {
return (
{sectionName}
+ {sectionSubname ?
{sectionSubname}
: null}
{tiles}
{showMore}
@@ -1083,6 +1096,33 @@ export default class InviteDialog extends React.PureComponent {
return {userId};
}},
);
+ if (CommunityPrototypeStore.instance.getSelectedCommunityId()) {
+ const communityName = CommunityPrototypeStore.instance.getSelectedCommunityName();
+ helpText = _t(
+ "Start a conversation with someone using their name, username (like ) or email address. " +
+ "This won't invite them to %(communityName)s. To invite someone to %(communityName)s, click " +
+ "here.",
+ {communityName}, {
+ userId: () => {
+ return (
+ {userId}
+ );
+ },
+ a: (sub) => {
+ return (
+ {sub}
+ );
+ },
+ },
+ );
+ }
buttonText = _t("Go");
goButtonFn = this._startDm;
} else { // KIND_INVITE
diff --git a/src/components/views/dialogs/QuestionDialog.js b/src/components/views/dialogs/QuestionDialog.js
index 07a1eae5d5..d6de60195f 100644
--- a/src/components/views/dialogs/QuestionDialog.js
+++ b/src/components/views/dialogs/QuestionDialog.js
@@ -16,14 +16,12 @@ limitations under the License.
*/
import React from 'react';
-import createReactClass from 'create-react-class';
import PropTypes from 'prop-types';
import * as sdk from '../../../index';
import { _t } from '../../../languageHandler';
-export default createReactClass({
- displayName: 'QuestionDialog',
- propTypes: {
+export default class QuestionDialog extends React.Component {
+ static propTypes = {
title: PropTypes.string,
description: PropTypes.node,
extraButtons: PropTypes.node,
@@ -34,29 +32,27 @@ export default createReactClass({
headerImage: PropTypes.string,
quitOnly: PropTypes.bool, // quitOnly doesn't show the cancel button just the quit [x].
fixedWidth: PropTypes.bool,
- },
+ };
- getDefaultProps: function() {
- return {
- title: "",
- description: "",
- extraButtons: null,
- focus: true,
- hasCancelButton: true,
- danger: false,
- quitOnly: false,
- };
- },
+ static defaultProps = {
+ title: "",
+ description: "",
+ extraButtons: null,
+ focus: true,
+ hasCancelButton: true,
+ danger: false,
+ quitOnly: false,
+ };
- onOk: function() {
+ onOk = () => {
this.props.onFinished(true);
- },
+ };
- onCancel: function() {
+ onCancel = () => {
this.props.onFinished(false);
- },
+ };
- render: function() {
+ render() {
const BaseDialog = sdk.getComponent('views.dialogs.BaseDialog');
const DialogButtons = sdk.getComponent('views.elements.DialogButtons');
let primaryButtonClass = "";
@@ -88,5 +84,5 @@ export default createReactClass({
);
- },
-});
+ }
+}
diff --git a/src/components/views/dialogs/RebrandDialog.tsx b/src/components/views/dialogs/RebrandDialog.tsx
deleted file mode 100644
index 79b4b69a4a..0000000000
--- a/src/components/views/dialogs/RebrandDialog.tsx
+++ /dev/null
@@ -1,116 +0,0 @@
-/*
-Copyright 2020 The Matrix.org Foundation C.I.C.
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
-*/
-
-import * as React from 'react';
-import * as PropTypes from 'prop-types';
-import BaseDialog from './BaseDialog';
-import { _t } from '../../../languageHandler';
-import DialogButtons from '../elements/DialogButtons';
-
-export enum RebrandDialogKind {
- NAG,
- ONE_TIME,
-}
-
-interface IProps {
- onFinished: (bool) => void;
- kind: RebrandDialogKind;
- targetUrl?: string;
-}
-
-export default class RebrandDialog extends React.PureComponent {
- private onDoneClick = () => {
- this.props.onFinished(true);
- };
-
- private onGoToElementClick = () => {
- this.props.onFinished(true);
- };
-
- private onRemindMeLaterClick = () => {
- this.props.onFinished(false);
- };
-
- private getPrettyTargetUrl() {
- const u = new URL(this.props.targetUrl);
- let ret = u.host;
- if (u.pathname !== '/') ret += u.pathname;
- return ret;
- }
-
- getBodyText() {
- if (this.props.kind === RebrandDialogKind.NAG) {
- return _t(
- "Use your account to sign in to the latest version of the app at ", {},
- {
- a: sub => {this.getPrettyTargetUrl()},
- },
- );
- } else {
- return _t(
- "You’re already signed in and good to go here, but you can also grab the latest " +
- "versions of the app on all platforms at element.io/get-started.", {},
- {
- a: sub => {sub},
- },
- );
- }
- }
-
- getDialogButtons() {
- if (this.props.kind === RebrandDialogKind.NAG) {
- return ;
- } else {
- return ;
- }
- }
-
- render() {
- return
-
diff --git a/src/components/views/elements/Field.tsx b/src/components/views/elements/Field.tsx
index d9fd59dc11..7fd154047d 100644
--- a/src/components/views/elements/Field.tsx
+++ b/src/components/views/elements/Field.tsx
@@ -17,7 +17,7 @@ limitations under the License.
import React, {InputHTMLAttributes, SelectHTMLAttributes, TextareaHTMLAttributes} from 'react';
import classNames from 'classnames';
import * as sdk from '../../../index';
-import { debounce } from 'lodash';
+import {debounce} from "lodash";
import {IFieldState, IValidationResult} from "./Validation";
// Invoke validation from user input (when typing, etc.) at most once every N ms.
@@ -198,11 +198,9 @@ export default class Field extends React.PureComponent {
}
}
-
-
public render() {
- const {
- element, prefixComponent, postfixComponent, className, onValidate, children,
+ /* eslint @typescript-eslint/no-unused-vars: ["error", { "ignoreRestSiblings": true }] */
+ const { element, prefixComponent, postfixComponent, className, onValidate, children,
tooltipContent, forceValidity, tooltipClassName, list, ...inputProps} = this.props;
// Set some defaults for the element
diff --git a/src/components/views/elements/IRCTimelineProfileResizer.tsx b/src/components/views/elements/IRCTimelineProfileResizer.tsx
index 1098d0293e..ecd63816de 100644
--- a/src/components/views/elements/IRCTimelineProfileResizer.tsx
+++ b/src/components/views/elements/IRCTimelineProfileResizer.tsx
@@ -78,7 +78,12 @@ export default class IRCTimelineProfileResizer extends React.Component
+Copyright 2019 The Matrix.org Foundation C.I.C.
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+import React from 'react';
+import classNames from 'classnames';
+
+import Tooltip from './Tooltip';
+import { _t } from "../../../languageHandler";
+
+interface ITooltipProps {
+ tooltip?: React.ReactNode;
+ tooltipClassName?: string;
+}
+
+interface IState {
+ hover: boolean;
+}
+
+export default class InfoTooltip extends React.PureComponent {
+ constructor(props: ITooltipProps) {
+ super(props);
+ this.state = {
+ hover: false,
+ };
+ }
+
+ onMouseOver = () => {
+ this.setState({
+ hover: true,
+ });
+ };
+
+ onMouseLeave = () => {
+ this.setState({
+ hover: false,
+ });
+ };
+
+ render() {
+ const {tooltip, children, tooltipClassName} = this.props;
+ const title = _t("Information");
+
+ // Tooltip are forced on the right for a more natural feel to them on info icons
+ const tip = this.state.hover ? : ;
+ return (
+
+
+ {children}
+ {tip}
+
+ );
+ }
+}
diff --git a/src/components/views/elements/InlineSpinner.js b/src/components/views/elements/InlineSpinner.js
index 89b5e6f19d..73316157f4 100644
--- a/src/components/views/elements/InlineSpinner.js
+++ b/src/components/views/elements/InlineSpinner.js
@@ -15,20 +15,17 @@ limitations under the License.
*/
import React from "react";
-import createReactClass from 'create-react-class';
import {_t} from "../../../languageHandler";
import SettingsStore from "../../../settings/SettingsStore";
-export default createReactClass({
- displayName: 'InlineSpinner',
-
- render: function() {
+export default class InlineSpinner extends React.Component {
+ render() {
const w = this.props.w || 16;
const h = this.props.h || 16;
const imgClass = this.props.imgClassName || "";
let imageSource;
- if (SettingsStore.isFeatureEnabled('feature_new_spinner')) {
+ if (SettingsStore.getValue('feature_new_spinner')) {
imageSource = require("../../../../res/img/spinner.svg");
} else {
imageSource = require("../../../../res/img/spinner.gif");
@@ -45,5 +42,5 @@ export default createReactClass({
/>
);
- },
-});
+ }
+}
diff --git a/src/components/views/elements/ManageIntegsButton.js b/src/components/views/elements/ManageIntegsButton.js
index ac8a98a94a..0990218c65 100644
--- a/src/components/views/elements/ManageIntegsButton.js
+++ b/src/components/views/elements/ManageIntegsButton.js
@@ -34,7 +34,7 @@ export default class ManageIntegsButton extends React.Component {
if (!managers.hasManager()) {
managers.openNoManagerDialog();
} else {
- if (SettingsStore.isFeatureEnabled("feature_many_integration_managers")) {
+ if (SettingsStore.getValue("feature_many_integration_managers")) {
managers.openAll(this.props.room);
} else {
managers.getPrimaryManager().open(this.props.room);
diff --git a/src/components/views/elements/MemberEventListSummary.js b/src/components/views/elements/MemberEventListSummary.js
index 956b69ca7b..e16b52c8a2 100644
--- a/src/components/views/elements/MemberEventListSummary.js
+++ b/src/components/views/elements/MemberEventListSummary.js
@@ -18,17 +18,14 @@ limitations under the License.
import React from 'react';
import PropTypes from 'prop-types';
-import createReactClass from 'create-react-class';
import { _t } from '../../../languageHandler';
import { formatCommaSeparatedList } from '../../../utils/FormattingUtils';
import * as sdk from "../../../index";
import {MatrixEvent} from "matrix-js-sdk";
import {isValid3pidInvite} from "../../../RoomInvite";
-export default createReactClass({
- displayName: 'MemberEventListSummary',
-
- propTypes: {
+export default class MemberEventListSummary extends React.Component {
+ static propTypes = {
// An array of member events to summarise
events: PropTypes.arrayOf(PropTypes.instanceOf(MatrixEvent)).isRequired,
// An array of EventTiles to render when expanded
@@ -43,17 +40,15 @@ export default createReactClass({
onToggle: PropTypes.func,
// Whether or not to begin with state.expanded=true
startExpanded: PropTypes.bool,
- },
+ };
- getDefaultProps: function() {
- return {
- summaryLength: 1,
- threshold: 3,
- avatarsMaxLength: 5,
- };
- },
+ static defaultProps = {
+ summaryLength: 1,
+ threshold: 3,
+ avatarsMaxLength: 5,
+ };
- shouldComponentUpdate: function(nextProps) {
+ shouldComponentUpdate(nextProps) {
// Update if
// - The number of summarised events has changed
// - or if the summary is about to toggle to become collapsed
@@ -62,7 +57,7 @@ export default createReactClass({
nextProps.events.length !== this.props.events.length ||
nextProps.events.length < this.props.threshold
);
- },
+ }
/**
* Generate the text for users aggregated by their transition sequences (`eventAggregates`) where
@@ -73,7 +68,7 @@ export default createReactClass({
* `Object.keys(eventAggregates)`.
* @returns {string} the textual summary of the aggregated events that occurred.
*/
- _generateSummary: function(eventAggregates, orderedTransitionSequences) {
+ _generateSummary(eventAggregates, orderedTransitionSequences) {
const summaries = orderedTransitionSequences.map((transitions) => {
const userNames = eventAggregates[transitions];
const nameList = this._renderNameList(userNames);
@@ -105,7 +100,7 @@ export default createReactClass({
}
return summaries.join(", ");
- },
+ }
/**
* @param {string[]} users an array of user display names or user IDs.
@@ -113,9 +108,9 @@ export default createReactClass({
* more items in `users` than `this.props.summaryLength`, which is the number of names
* included before "and [n] others".
*/
- _renderNameList: function(users) {
+ _renderNameList(users) {
return formatCommaSeparatedList(users, this.props.summaryLength);
- },
+ }
/**
* Canonicalise an array of transitions such that some pairs of transitions become
@@ -124,7 +119,7 @@ export default createReactClass({
* @param {string[]} transitions an array of transitions.
* @returns {string[]} an array of transitions.
*/
- _getCanonicalTransitions: function(transitions) {
+ _getCanonicalTransitions(transitions) {
const modMap = {
'joined': {
'after': 'left',
@@ -155,7 +150,7 @@ export default createReactClass({
res.push(transition);
}
return res;
- },
+ }
/**
* Transform an array of transitions into an array of transitions and how many times
@@ -171,7 +166,7 @@ export default createReactClass({
* @param {string[]} transitions the array of transitions to transform.
* @returns {object[]} an array of coalesced transitions.
*/
- _coalesceRepeatedTransitions: function(transitions) {
+ _coalesceRepeatedTransitions(transitions) {
const res = [];
for (let i = 0; i < transitions.length; i++) {
if (res.length > 0 && res[res.length - 1].transitionType === transitions[i]) {
@@ -184,7 +179,7 @@ export default createReactClass({
}
}
return res;
- },
+ }
/**
* For a certain transition, t, describe what happened to the users that
@@ -268,11 +263,11 @@ export default createReactClass({
}
return res;
- },
+ }
- _getTransitionSequence: function(events) {
+ _getTransitionSequence(events) {
return events.map(this._getTransition);
- },
+ }
/**
* Label a given membership event, `e`, where `getContent().membership` has
@@ -282,7 +277,7 @@ export default createReactClass({
* @returns {string?} the transition type given to this event. This defaults to `null`
* if a transition is not recognised.
*/
- _getTransition: function(e) {
+ _getTransition(e) {
if (e.mxEvent.getType() === 'm.room.third_party_invite') {
// Handle 3pid invites the same as invites so they get bundled together
if (!isValid3pidInvite(e.mxEvent)) {
@@ -323,9 +318,9 @@ export default createReactClass({
}
default: return null;
}
- },
+ }
- _getAggregate: function(userEvents) {
+ _getAggregate(userEvents) {
// A map of aggregate type to arrays of display names. Each aggregate type
// is a comma-delimited string of transitions, e.g. "joined,left,kicked".
// The array of display names is the array of users who went through that
@@ -364,9 +359,9 @@ export default createReactClass({
names: aggregate,
indices: aggregateIndices,
};
- },
+ }
- render: function() {
+ render() {
const eventsToRender = this.props.events;
// Map user IDs to an array of objects:
@@ -420,5 +415,5 @@ export default createReactClass({
children={this.props.children}
summaryMembers={avatarMembers}
summaryText={this._generateSummary(aggregate.names, orderedTransitionSequences)} />;
- },
-});
+ }
+}
diff --git a/src/components/views/elements/PersistentApp.js b/src/components/views/elements/PersistentApp.js
index a146debc45..bdf5f60234 100644
--- a/src/components/views/elements/PersistentApp.js
+++ b/src/components/views/elements/PersistentApp.js
@@ -16,49 +16,44 @@ limitations under the License.
*/
import React from 'react';
-import createReactClass from 'create-react-class';
import RoomViewStore from '../../../stores/RoomViewStore';
import ActiveWidgetStore from '../../../stores/ActiveWidgetStore';
import WidgetUtils from '../../../utils/WidgetUtils';
import * as sdk from '../../../index';
import {MatrixClientPeg} from '../../../MatrixClientPeg';
-export default createReactClass({
- displayName: 'PersistentApp',
+export default class PersistentApp extends React.Component {
+ state = {
+ roomId: RoomViewStore.getRoomId(),
+ persistentWidgetId: ActiveWidgetStore.getPersistentWidgetId(),
+ };
- getInitialState: function() {
- return {
- roomId: RoomViewStore.getRoomId(),
- persistentWidgetId: ActiveWidgetStore.getPersistentWidgetId(),
- };
- },
-
- componentDidMount: function() {
+ componentDidMount() {
this._roomStoreToken = RoomViewStore.addListener(this._onRoomViewStoreUpdate);
ActiveWidgetStore.on('update', this._onActiveWidgetStoreUpdate);
- },
+ }
- componentWillUnmount: function() {
+ componentWillUnmount() {
if (this._roomStoreToken) {
this._roomStoreToken.remove();
}
ActiveWidgetStore.removeListener('update', this._onActiveWidgetStoreUpdate);
- },
+ }
- _onRoomViewStoreUpdate: function(payload) {
+ _onRoomViewStoreUpdate = payload => {
if (RoomViewStore.getRoomId() === this.state.roomId) return;
this.setState({
roomId: RoomViewStore.getRoomId(),
});
- },
+ };
- _onActiveWidgetStoreUpdate: function() {
+ _onActiveWidgetStoreUpdate = () => {
this.setState({
persistentWidgetId: ActiveWidgetStore.getPersistentWidgetId(),
});
- },
+ };
- render: function() {
+ render() {
if (this.state.persistentWidgetId) {
const persistentWidgetInRoomId = ActiveWidgetStore.getRoomId(this.state.persistentWidgetId);
if (this.state.roomId !== persistentWidgetInRoomId) {
@@ -91,6 +86,6 @@ export default createReactClass({
}
}
return null;
- },
-});
+ }
+}
diff --git a/src/components/views/elements/Pill.js b/src/components/views/elements/Pill.js
index 03a1aeed85..8247225a2b 100644
--- a/src/components/views/elements/Pill.js
+++ b/src/components/views/elements/Pill.js
@@ -16,7 +16,6 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
import React from 'react';
-import createReactClass from 'create-react-class';
import * as sdk from '../../../index';
import dis from '../../../dispatcher/dispatcher';
import classNames from 'classnames';
@@ -32,27 +31,29 @@ import {Action} from "../../../dispatcher/actions";
// HttpUtils transformTags to relative links. This excludes event URLs (with `[^\/]*`)
const REGEX_LOCAL_PERMALINK = /^#\/(?:user|room|group)\/(([#!@+])[^/]*)$/;
-const Pill = createReactClass({
- statics: {
- isPillUrl: (url) => {
- return !!getPrimaryPermalinkEntity(url);
- },
- isMessagePillUrl: (url) => {
- return !!REGEX_LOCAL_PERMALINK.exec(url);
- },
- roomNotifPos: (text) => {
- return text.indexOf("@room");
- },
- roomNotifLen: () => {
- return "@room".length;
- },
- TYPE_USER_MENTION: 'TYPE_USER_MENTION',
- TYPE_ROOM_MENTION: 'TYPE_ROOM_MENTION',
- TYPE_GROUP_MENTION: 'TYPE_GROUP_MENTION',
- TYPE_AT_ROOM_MENTION: 'TYPE_AT_ROOM_MENTION', // '@room' mention
- },
+class Pill extends React.Component {
+ static isPillUrl(url) {
+ return !!getPrimaryPermalinkEntity(url);
+ }
- props: {
+ static isMessagePillUrl(url) {
+ return !!REGEX_LOCAL_PERMALINK.exec(url);
+ }
+
+ static roomNotifPos(text) {
+ return text.indexOf("@room");
+ }
+
+ static roomNotifLen() {
+ return "@room".length;
+ }
+
+ static TYPE_USER_MENTION = 'TYPE_USER_MENTION';
+ static TYPE_ROOM_MENTION = 'TYPE_ROOM_MENTION';
+ static TYPE_GROUP_MENTION = 'TYPE_GROUP_MENTION';
+ static TYPE_AT_ROOM_MENTION = 'TYPE_AT_ROOM_MENTION'; // '@room' mention
+
+ static propTypes = {
// The Type of this Pill. If url is given, this is auto-detected.
type: PropTypes.string,
// The URL to pillify (no validation is done, see isPillUrl and isMessagePillUrl)
@@ -65,25 +66,24 @@ const Pill = createReactClass({
shouldShowPillAvatar: PropTypes.bool,
// Whether to render this pill as if it were highlit by a selection
isSelected: PropTypes.bool,
- },
+ };
- getInitialState() {
- return {
- // ID/alias of the room/user
- resourceId: null,
- // Type of pill
- pillType: null,
+ state = {
+ // ID/alias of the room/user
+ resourceId: null,
+ // Type of pill
+ pillType: null,
- // The member related to the user pill
- member: null,
- // The group related to the group pill
- group: null,
- // The room related to the room pill
- room: null,
- };
- },
+ // The member related to the user pill
+ member: null,
+ // The group related to the group pill
+ group: null,
+ // The room related to the room pill
+ room: null,
+ };
// TODO: [REACT-WARNING] Replace with appropriate lifecycle event
+ // eslint-disable-next-line camelcase
async UNSAFE_componentWillReceiveProps(nextProps) {
let resourceId;
let prefix;
@@ -155,7 +155,7 @@ const Pill = createReactClass({
}
}
this.setState({resourceId, pillType, member, group, room});
- },
+ }
componentDidMount() {
this._unmounted = false;
@@ -163,13 +163,13 @@ const Pill = createReactClass({
// eslint-disable-next-line new-cap
this.UNSAFE_componentWillReceiveProps(this.props); // HACK: We shouldn't be calling lifecycle functions ourselves.
- },
+ }
componentWillUnmount() {
this._unmounted = true;
- },
+ }
- doProfileLookup: function(userId, member) {
+ doProfileLookup(userId, member) {
MatrixClientPeg.get().getProfileInfo(userId).then((resp) => {
if (this._unmounted) {
return;
@@ -188,15 +188,16 @@ const Pill = createReactClass({
}).catch((err) => {
console.error('Could not retrieve profile data for ' + userId + ':', err);
});
- },
+ }
- onUserPillClicked: function() {
+ onUserPillClicked = () => {
dis.dispatch({
action: Action.ViewUser,
member: this.state.member,
});
- },
- render: function() {
+ };
+
+ render() {
const BaseAvatar = sdk.getComponent('views.avatars.BaseAvatar');
const MemberAvatar = sdk.getComponent('avatars.MemberAvatar');
const RoomAvatar = sdk.getComponent('avatars.RoomAvatar');
@@ -285,7 +286,7 @@ const Pill = createReactClass({
// Deliberately render nothing if the URL isn't recognised
return null;
}
- },
-});
+ }
+}
export default Pill;
diff --git a/src/components/views/elements/PowerSelector.js b/src/components/views/elements/PowerSelector.js
index 948b4835d5..e5f217dd90 100644
--- a/src/components/views/elements/PowerSelector.js
+++ b/src/components/views/elements/PowerSelector.js
@@ -16,16 +16,13 @@ limitations under the License.
import React from 'react';
import PropTypes from 'prop-types';
-import createReactClass from 'create-react-class';
import * as Roles from '../../../Roles';
import { _t } from '../../../languageHandler';
import Field from "./Field";
import {Key} from "../../../Keyboard";
-export default createReactClass({
- displayName: 'PowerSelector',
-
- propTypes: {
+export default class PowerSelector extends React.Component {
+ static propTypes = {
value: PropTypes.number.isRequired,
// The maximum value that can be set with the power selector
maxValue: PropTypes.number.isRequired,
@@ -42,10 +39,17 @@ export default createReactClass({
// The name to annotate the selector with
label: PropTypes.string,
- },
+ }
- getInitialState: function() {
- return {
+ static defaultProps = {
+ maxValue: Infinity,
+ usersDefault: 0,
+ };
+
+ constructor(props) {
+ super(props);
+
+ this.state = {
levelRoleMap: {},
// List of power levels to show in the drop-down
options: [],
@@ -53,26 +57,17 @@ export default createReactClass({
customValue: this.props.value,
selectValue: 0,
};
- },
- getDefaultProps: function() {
- return {
- maxValue: Infinity,
- usersDefault: 0,
- };
- },
-
- componentDidMount: function() {
- // TODO: [REACT-WARNING] Move this to class constructor
this._initStateFromProps(this.props);
- },
+ }
// TODO: [REACT-WARNING] Replace with appropriate lifecycle event
- UNSAFE_componentWillReceiveProps: function(newProps) {
+ // eslint-disable-next-line camelcase
+ UNSAFE_componentWillReceiveProps(newProps) {
this._initStateFromProps(newProps);
- },
+ }
- _initStateFromProps: function(newProps) {
+ _initStateFromProps(newProps) {
// This needs to be done now because levelRoleMap has translated strings
const levelRoleMap = Roles.levelRoleMap(newProps.usersDefault);
const options = Object.keys(levelRoleMap).filter(level => {
@@ -92,9 +87,9 @@ export default createReactClass({
customLevel: newProps.value,
selectValue: isCustom ? "SELECT_VALUE_CUSTOM" : newProps.value,
});
- },
+ }
- onSelectChange: function(event) {
+ onSelectChange = event => {
const isCustom = event.target.value === "SELECT_VALUE_CUSTOM";
if (isCustom) {
this.setState({custom: true});
@@ -102,20 +97,20 @@ export default createReactClass({
this.props.onChange(event.target.value, this.props.powerLevelKey);
this.setState({selectValue: event.target.value});
}
- },
+ };
- onCustomChange: function(event) {
+ onCustomChange = event => {
this.setState({customValue: event.target.value});
- },
+ };
- onCustomBlur: function(event) {
+ onCustomBlur = event => {
event.preventDefault();
event.stopPropagation();
this.props.onChange(parseInt(this.state.customValue), this.props.powerLevelKey);
- },
+ };
- onCustomKeyDown: function(event) {
+ onCustomKeyDown = event => {
if (event.key === Key.ENTER) {
event.preventDefault();
event.stopPropagation();
@@ -127,9 +122,9 @@ export default createReactClass({
// handle the onBlur safely.
event.target.blur();
}
- },
+ };
- render: function() {
+ render() {
let picker;
const label = typeof this.props.label === "undefined" ? _t("Power level") : this.props.label;
if (this.state.custom) {
@@ -166,5 +161,5 @@ export default createReactClass({
{ picker }
- );
- },
-});
diff --git a/src/components/views/elements/UserTagTile.tsx b/src/components/views/elements/UserTagTile.tsx
new file mode 100644
index 0000000000..912f54edc7
--- /dev/null
+++ b/src/components/views/elements/UserTagTile.tsx
@@ -0,0 +1,85 @@
+/*
+Copyright 2020 The Matrix.org Foundation C.I.C.
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+import React from "react";
+import defaultDispatcher from "../../../dispatcher/dispatcher";
+import * as fbEmitter from "fbemitter";
+import TagOrderStore from "../../../stores/TagOrderStore";
+import AccessibleTooltipButton from "./AccessibleTooltipButton";
+import classNames from "classnames";
+import { _t } from "../../../languageHandler";
+
+interface IProps {
+}
+
+interface IState {
+ selected: boolean;
+}
+
+export default class UserTagTile extends React.PureComponent {
+ private tagStoreRef: fbEmitter.EventSubscription;
+
+ constructor(props: IProps) {
+ super(props);
+
+ this.state = {
+ selected: TagOrderStore.getSelectedTags().length === 0,
+ };
+ }
+
+ public componentDidMount() {
+ this.tagStoreRef = TagOrderStore.addListener(this.onTagStoreUpdate);
+ }
+
+ public componentWillUnmount() {
+ this.tagStoreRef.remove();
+ }
+
+ private onTagStoreUpdate = () => {
+ const selected = TagOrderStore.getSelectedTags().length === 0;
+ this.setState({selected});
+ };
+
+ private onTileClick = (ev) => {
+ ev.preventDefault();
+ ev.stopPropagation();
+
+ // Deselect all tags
+ defaultDispatcher.dispatch({action: "deselect_tags"});
+ };
+
+ public render() {
+ // XXX: We reuse TagTile classes for ease of demonstration - we should probably generify
+ // TagTile instead if we continue to use this component.
+ const className = classNames({
+ mx_TagTile: true,
+ mx_TagTile_prototype: true,
+ mx_TagTile_selected_prototype: this.state.selected,
+ mx_TagTile_home: true,
+ });
+ return (
+
+
+
+
+
+ );
+ }
+}
diff --git a/src/components/views/groups/GroupInviteTile.js b/src/components/views/groups/GroupInviteTile.js
index bc5334f2de..0c09b6ed05 100644
--- a/src/components/views/groups/GroupInviteTile.js
+++ b/src/components/views/groups/GroupInviteTile.js
@@ -18,7 +18,6 @@ limitations under the License.
import React from 'react';
import PropTypes from 'prop-types';
-import createReactClass from 'create-react-class';
import * as sdk from '../../../index';
import dis from '../../../dispatcher/dispatcher';
import {_t} from '../../../languageHandler';
@@ -29,50 +28,48 @@ import MatrixClientContext from "../../../contexts/MatrixClientContext";
import {RovingTabIndexWrapper} from "../../../accessibility/RovingTabIndex";
// XXX this class copies a lot from RoomTile.js
-export default createReactClass({
- displayName: 'GroupInviteTile',
-
- propTypes: {
+export default class GroupInviteTile extends React.Component {
+ static propTypes: {
group: PropTypes.object.isRequired,
- },
+ };
- statics: {
- contextType: MatrixClientContext,
- },
+ static contextType = MatrixClientContext;
- getInitialState: function() {
- return ({
+ constructor(props, context) {
+ super(props, context);
+
+ this.state = {
hover: false,
badgeHover: false,
menuDisplayed: false,
selected: this.props.group.groupId === null, // XXX: this needs linking to LoggedInView/GroupView state
- });
- },
+ };
+ }
- onClick: function(e) {
+ onClick = e => {
dis.dispatch({
action: 'view_group',
group_id: this.props.group.groupId,
});
- },
+ };
- onMouseEnter: function() {
+ onMouseEnter = () => {
const state = {hover: true};
// Only allow non-guests to access the context menu
if (!this.context.isGuest()) {
state.badgeHover = true;
}
this.setState(state);
- },
+ };
- onMouseLeave: function() {
+ onMouseLeave = () => {
this.setState({
badgeHover: false,
hover: false,
});
- },
+ };
- _showContextMenu: function(boundingClientRect) {
+ _showContextMenu(boundingClientRect) {
// Only allow non-guests to access the context menu
if (MatrixClientPeg.get().isGuest()) return;
@@ -86,17 +83,17 @@ export default createReactClass({
}
this.setState(state);
- },
+ }
- onContextMenuButtonClick: function(e) {
+ onContextMenuButtonClick = e => {
// Prevent the RoomTile onClick event firing as well
e.stopPropagation();
e.preventDefault();
this._showContextMenu(e.target.getBoundingClientRect());
- },
+ };
- onContextMenu: function(e) {
+ onContextMenu = e => {
// Prevent the native context menu
e.preventDefault();
@@ -105,15 +102,15 @@ export default createReactClass({
top: e.clientY,
height: 0,
});
- },
+ };
- closeMenu: function() {
+ closeMenu = () => {
this.setState({
contextMenuPosition: null,
});
- },
+ };
- render: function() {
+ render() {
const AccessibleButton = sdk.getComponent('elements.AccessibleButton');
const BaseAvatar = sdk.getComponent('avatars.BaseAvatar');
@@ -197,5 +194,5 @@ export default createReactClass({
{ contextMenu }
;
- },
-});
+ }
+}
diff --git a/src/components/views/groups/GroupMemberList.js b/src/components/views/groups/GroupMemberList.js
index 031b875409..600a466601 100644
--- a/src/components/views/groups/GroupMemberList.js
+++ b/src/components/views/groups/GroupMemberList.js
@@ -16,7 +16,6 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
import React from 'react';
-import createReactClass from 'create-react-class';
import { _t } from '../../../languageHandler';
import * as sdk from '../../../index';
import dis from '../../../dispatcher/dispatcher';
@@ -30,33 +29,29 @@ import {Action} from "../../../dispatcher/actions";
const INITIAL_LOAD_NUM_MEMBERS = 30;
-export default createReactClass({
- displayName: 'GroupMemberList',
-
- propTypes: {
+export default class GroupMemberList extends React.Component {
+ static propTypes = {
groupId: PropTypes.string.isRequired,
- },
+ };
- getInitialState: function() {
- return {
- members: null,
- membersError: null,
- invitedMembers: null,
- invitedMembersError: null,
- truncateAt: INITIAL_LOAD_NUM_MEMBERS,
- };
- },
+ state = {
+ members: null,
+ membersError: null,
+ invitedMembers: null,
+ invitedMembersError: null,
+ truncateAt: INITIAL_LOAD_NUM_MEMBERS,
+ };
- componentDidMount: function() {
+ componentDidMount() {
this._unmounted = false;
this._initGroupStore(this.props.groupId);
- },
+ }
- componentWillUnmount: function() {
+ componentWillUnmount() {
this._unmounted = true;
- },
+ }
- _initGroupStore: function(groupId) {
+ _initGroupStore(groupId) {
GroupStore.registerListener(groupId, () => {
this._fetchMembers();
});
@@ -73,17 +68,17 @@ export default createReactClass({
});
}
});
- },
+ }
- _fetchMembers: function() {
+ _fetchMembers() {
if (this._unmounted) return;
this.setState({
members: GroupStore.getGroupMembers(this.props.groupId),
invitedMembers: GroupStore.getGroupInvitedMembers(this.props.groupId),
});
- },
+ }
- _createOverflowTile: function(overflowCount, totalCount) {
+ _createOverflowTile = (overflowCount, totalCount) => {
// For now we'll pretend this is any entity. It should probably be a separate tile.
const EntityTile = sdk.getComponent("rooms.EntityTile");
const BaseAvatar = sdk.getComponent("avatars.BaseAvatar");
@@ -94,19 +89,19 @@ export default createReactClass({
} name={text} presenceState="online" suppressOnHover={true}
onClick={this._showFullMemberList} />
);
- },
+ };
- _showFullMemberList: function() {
+ _showFullMemberList = () => {
this.setState({
truncateAt: -1,
});
- },
+ };
- onSearchQueryChanged: function(ev) {
+ onSearchQueryChanged = ev => {
this.setState({ searchQuery: ev.target.value });
- },
+ };
- makeGroupMemberTiles: function(query, memberList, memberListError) {
+ makeGroupMemberTiles(query, memberList, memberListError) {
if (memberListError) {
return
:
+ null;
// TODO: add way to open camera to scan a QR code
return
@@ -208,7 +207,7 @@ export default class VerificationPanel extends React.PureComponent {
const alias = this.state.localAliases[index];
// TODO: In future, we should probably be making sure that the alias actually belongs
- // to this room. See https://github.com/vector-im/riot-web/issues/7353
+ // to this room. See https://github.com/vector-im/element-web/issues/7353
MatrixClientPeg.get().deleteAlias(alias).then(() => {
const localAliases = this.state.localAliases.filter(a => a !== alias);
this.setState({localAliases});
diff --git a/src/components/views/room_settings/ColorSettings.js b/src/components/views/room_settings/ColorSettings.js
deleted file mode 100644
index 4e8b6ba42f..0000000000
--- a/src/components/views/room_settings/ColorSettings.js
+++ /dev/null
@@ -1,154 +0,0 @@
-/*
-Copyright 2016 OpenMarket Ltd
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
-*/
-
-import React from 'react';
-import PropTypes from 'prop-types';
-import createReactClass from 'create-react-class';
-
-import Tinter from '../../../Tinter';
-import dis from '../../../dispatcher/dispatcher';
-import SettingsStore from "../../../settings/SettingsStore";
-import {SettingLevel} from "../../../settings/SettingLevel";
-
-const ROOM_COLORS = [
- // magic room default values courtesy of Ribot
- [Tinter.getKeyRgb()[0], Tinter.getKeyRgb()[1]],
- ["#81bddb", "#eaf1f4"],
- ["#bd79cb", "#f3eaf5"],
- ["#c65d94", "#f5eaef"],
- ["#e55e5e", "#f5eaea"],
- ["#eca46f", "#f5eeea"],
- ["#dad658", "#f5f4ea"],
- ["#80c553", "#eef5ea"],
- ["#bb814e", "#eee8e3"],
- //["#595959", "#ececec"], // Grey makes everything appear disabled, so remove it for now
-];
-
-// Dev note: this component is not attached anywhere, but is left here as it
-// has a high possibility of being used in the nearish future.
-// Ref: https://github.com/vector-im/riot-web/issues/8421
-
-export default createReactClass({
- displayName: 'ColorSettings',
-
- propTypes: {
- room: PropTypes.object.isRequired,
- },
-
- getInitialState: function() {
- const data = {
- index: 0,
- primary_color: ROOM_COLORS[0][0],
- secondary_color: ROOM_COLORS[0][1],
- hasChanged: false,
- };
- const scheme = SettingsStore.getValueAt(SettingLevel.ROOM_ACCOUNT, "roomColor", this.props.room.roomId);
-
- if (scheme.primary_color && scheme.secondary_color) {
- // We only use the user's scheme if the scheme is valid.
- data.primary_color = scheme.primary_color;
- data.secondary_color = scheme.secondary_color;
- }
- data.index = this._getColorIndex(data);
-
- if (data.index === -1) {
- // append the unrecognised colours to our palette
- data.index = ROOM_COLORS.length;
- ROOM_COLORS.push([
- scheme.primary_color, scheme.secondary_color,
- ]);
- }
- return data;
- },
-
- saveSettings: function() { // : Promise
- if (!this.state.hasChanged) {
- return Promise.resolve(); // They didn't explicitly give a color to save.
- }
- const originalState = this.getInitialState();
- if (originalState.primary_color !== this.state.primary_color ||
- originalState.secondary_color !== this.state.secondary_color) {
- console.log("ColorSettings: Saving new color");
- // We would like guests to be able to set room colour but currently
- // they can't, so we still send the request but display a sensible
- // error if it fails.
- // TODO: Support guests for room color. Technically this is possible via granular settings
- // Granular settings would mean the guest is forced to use the DEVICE level though.
- SettingsStore.setValue("roomColor", this.props.room.roomId, SettingLevel.ROOM_ACCOUNT, {
- primary_color: this.state.primary_color,
- secondary_color: this.state.secondary_color,
- }).catch(function(err) {
- if (err.errcode === 'M_GUEST_ACCESS_FORBIDDEN') {
- dis.dispatch({action: 'require_registration'});
- }
- });
- }
- return Promise.resolve(); // no color diff
- },
-
- _getColorIndex: function(scheme) {
- if (!scheme || !scheme.primary_color || !scheme.secondary_color) {
- return -1;
- }
- // XXX: we should validate these values
- for (let i = 0; i < ROOM_COLORS.length; i++) {
- const room_color = ROOM_COLORS[i];
- if (room_color[0] === String(scheme.primary_color).toLowerCase() &&
- room_color[1] === String(scheme.secondary_color).toLowerCase()) {
- return i;
- }
- }
- return -1;
- },
-
- _onColorSchemeChanged: function(index) {
- // preview what the user just changed the scheme to.
- Tinter.tint(ROOM_COLORS[index][0], ROOM_COLORS[index][1]);
- this.setState({
- index: index,
- primary_color: ROOM_COLORS[index][0],
- secondary_color: ROOM_COLORS[index][1],
- hasChanged: true,
- });
- },
-
- render: function() {
- return (
-
- { ROOM_COLORS.map((room_color, i) => {
- let selected;
- if (i === this.state.index) {
- selected = (
-
);
- },
-});
+ }
+}
diff --git a/src/components/views/rooms/ReadReceiptMarker.js b/src/components/views/rooms/ReadReceiptMarker.js
index 1c490f019e..c19247ef5a 100644
--- a/src/components/views/rooms/ReadReceiptMarker.js
+++ b/src/components/views/rooms/ReadReceiptMarker.js
@@ -17,7 +17,6 @@ limitations under the License.
import React, {createRef} from 'react';
import PropTypes from 'prop-types';
-import createReactClass from 'create-react-class';
import '../../../VelocityBounce';
import { _t } from '../../../languageHandler';
import {formatDate} from '../../../DateUtils';
@@ -33,10 +32,8 @@ try {
} catch (e) {
}
-export default createReactClass({
- displayName: 'ReadReceiptMarker',
-
- propTypes: {
+export default class ReadReceiptMarker extends React.Component {
+ static propTypes = {
// the RoomMember to show the RR for
member: PropTypes.object,
// userId to fallback the avatar to
@@ -70,30 +67,27 @@ export default createReactClass({
// True to show twelve hour format, false otherwise
showTwelveHour: PropTypes.bool,
- },
+ };
- getDefaultProps: function() {
- return {
- leftOffset: 0,
- };
- },
+ static defaultProps = {
+ leftOffset: 0,
+ };
- getInitialState: function() {
- // if we are going to animate the RR, we don't show it on first render,
- // and instead just add a placeholder to the DOM; once we've been
- // mounted, we start an animation which moves the RR from its old
- // position.
- return {
+ constructor(props) {
+ super(props);
+
+ this._avatar = createRef();
+
+ this.state = {
+ // if we are going to animate the RR, we don't show it on first render,
+ // and instead just add a placeholder to the DOM; once we've been
+ // mounted, we start an animation which moves the RR from its old
+ // position.
suppressDisplay: !this.props.suppressAnimation,
};
- },
+ }
- // TODO: [REACT-WARNING] Replace component with real class, use constructor for refs
- UNSAFE_componentWillMount: function() {
- this._avatar = createRef();
- },
-
- componentWillUnmount: function() {
+ componentWillUnmount() {
// before we remove the rr, store its location in the map, so that if
// it reappears, it can be animated from the right place.
const rrInfo = this.props.readReceiptInfo;
@@ -112,9 +106,9 @@ export default createReactClass({
rrInfo.top = avatarNode.offsetTop;
rrInfo.left = avatarNode.offsetLeft;
rrInfo.parent = avatarNode.offsetParent;
- },
+ }
- componentDidMount: function() {
+ componentDidMount() {
if (!this.state.suppressDisplay) {
// we've already done our display - nothing more to do.
return;
@@ -172,10 +166,9 @@ export default createReactClass({
startStyles: startStyles,
enterTransitionOpts: enterTransitionOpts,
});
- },
+ }
-
- render: function() {
+ render() {
const MemberAvatar = sdk.getComponent('avatars.MemberAvatar');
if (this.state.suppressDisplay) {
return ;
@@ -222,5 +215,5 @@ export default createReactClass({
/>
);
- },
-});
+ }
+}
diff --git a/src/components/views/rooms/ReplyPreview.js b/src/components/views/rooms/ReplyPreview.js
index 7656c3ee52..2c86b9b770 100644
--- a/src/components/views/rooms/ReplyPreview.js
+++ b/src/components/views/rooms/ReplyPreview.js
@@ -72,7 +72,7 @@ export default class ReplyPreview extends React.Component {
return
+ >
+ {sublists}
+ {explorePrompt}
+
)}
);
diff --git a/src/components/views/rooms/RoomListNumResults.tsx b/src/components/views/rooms/RoomListNumResults.tsx
new file mode 100644
index 0000000000..fcac91a56a
--- /dev/null
+++ b/src/components/views/rooms/RoomListNumResults.tsx
@@ -0,0 +1,41 @@
+/*
+Copyright 2020 The Matrix.org Foundation C.I.C.
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+import React, {useState} from "react";
+
+import { _t } from "../../../languageHandler";
+import RoomListStore, { LISTS_UPDATE_EVENT } from "../../../stores/room-list/RoomListStore";
+import {useEventEmitter} from "../../../hooks/useEventEmitter";
+
+const RoomListNumResults: React.FC = () => {
+ const [count, setCount] = useState(null);
+ useEventEmitter(RoomListStore.instance, LISTS_UPDATE_EVENT, () => {
+ if (RoomListStore.instance.getFirstNameFilterCondition()) {
+ const numRooms = Object.values(RoomListStore.instance.orderedLists).flat(1).length;
+ setCount(numRooms);
+ } else {
+ setCount(null);
+ }
+ });
+
+ if (typeof count !== "number") return null;
+
+ return
+ {_t("%(count)s results", { count })}
+
;
+};
+
+export default RoomListNumResults;
diff --git a/src/components/views/rooms/RoomNameEditor.js b/src/components/views/rooms/RoomNameEditor.js
deleted file mode 100644
index e0c31321c3..0000000000
--- a/src/components/views/rooms/RoomNameEditor.js
+++ /dev/null
@@ -1,80 +0,0 @@
-/*
-Copyright 2016 OpenMarket Ltd
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
-*/
-
-import React from 'react';
-import PropTypes from 'prop-types';
-import createReactClass from 'create-react-class';
-import {MatrixClientPeg} from "../../../MatrixClientPeg";
-import * as sdk from "../../../index";
-import { _t } from '../../../languageHandler';
-
-export default createReactClass({
- displayName: 'RoomNameEditor',
-
- propTypes: {
- room: PropTypes.object.isRequired,
- },
-
- getInitialState: function() {
- return {
- name: null,
- };
- },
-
- // TODO: [REACT-WARNING] Move this to constructor
- UNSAFE_componentWillMount: function() {
- const room = this.props.room;
- const name = room.currentState.getStateEvents('m.room.name', '');
- const myId = MatrixClientPeg.get().credentials.userId;
- const defaultName = room.getDefaultRoomName(myId);
-
- this.setState({
- name: name ? name.getContent().name : '',
- });
-
- this._placeholderName = _t("Unnamed Room");
- if (defaultName && defaultName !== 'Empty room') { // default name from JS SDK, needs no translation as we don't ever show it.
- this._placeholderName += " (" + defaultName + ")";
- }
- },
-
- getRoomName: function() {
- return this.state.name;
- },
-
- _onValueChanged: function(value, shouldSubmit) {
- this.setState({
- name: value,
- });
- },
-
- render: function() {
- const EditableText = sdk.getComponent("elements.EditableText");
-
- return (
-
-
-
- );
- },
-});
diff --git a/src/components/views/rooms/RoomPreviewBar.js b/src/components/views/rooms/RoomPreviewBar.js
index 9aa78fbbfd..f42e18372a 100644
--- a/src/components/views/rooms/RoomPreviewBar.js
+++ b/src/components/views/rooms/RoomPreviewBar.js
@@ -18,7 +18,6 @@ limitations under the License.
import React from 'react';
import PropTypes from 'prop-types';
-import createReactClass from 'create-react-class';
import * as sdk from '../../../index';
import {MatrixClientPeg} from '../../../MatrixClientPeg';
import dis from '../../../dispatcher/dispatcher';
@@ -26,6 +25,8 @@ import classNames from 'classnames';
import { _t } from '../../../languageHandler';
import SdkConfig from "../../../SdkConfig";
import IdentityAuthClient from '../../../IdentityAuthClient';
+import {CommunityPrototypeStore} from "../../../stores/CommunityPrototypeStore";
+import {UPDATE_EVENT} from "../../../stores/AsyncStore";
const MessageCase = Object.freeze({
NotLoggedIn: "NotLoggedIn",
@@ -44,10 +45,8 @@ const MessageCase = Object.freeze({
OtherError: "OtherError",
});
-export default createReactClass({
- displayName: 'RoomPreviewBar',
-
- propTypes: {
+export default class RoomPreviewBar extends React.Component {
+ static propTypes = {
onJoinClick: PropTypes.func,
onRejectClick: PropTypes.func,
onRejectAndIgnoreClick: PropTypes.func,
@@ -84,31 +83,32 @@ export default createReactClass({
// If given, this will be how the room is referred to (eg.
// in error messages).
roomAlias: PropTypes.string,
- },
+ };
- getDefaultProps: function() {
- return {
- onJoinClick: function() {},
- };
- },
+ static defaultProps = {
+ onJoinClick() {},
+ };
- getInitialState: function() {
- return {
- busy: false,
- };
- },
+ state = {
+ busy: false,
+ };
- componentDidMount: function() {
+ componentDidMount() {
this._checkInvitedEmail();
- },
+ CommunityPrototypeStore.instance.on(UPDATE_EVENT, this._onCommunityUpdate);
+ }
- componentDidUpdate: function(prevProps, prevState) {
+ componentDidUpdate(prevProps, prevState) {
if (this.props.invitedEmail !== prevProps.invitedEmail || this.props.inviterName !== prevProps.inviterName) {
this._checkInvitedEmail();
}
- },
+ }
- _checkInvitedEmail: async function() {
+ componentWillUnmount() {
+ CommunityPrototypeStore.instance.off(UPDATE_EVENT, this._onCommunityUpdate);
+ }
+
+ async _checkInvitedEmail() {
// If this is an invite and we've been told what email address was
// invited, fetch the user's account emails and discovery bindings so we
// can check them against the email that was invited.
@@ -141,7 +141,14 @@ export default createReactClass({
}
this.setState({busy: false});
}
- },
+ }
+
+ _onCommunityUpdate = (roomId) => {
+ if (this.props.room && this.props.room.roomId !== roomId) {
+ return;
+ }
+ this.forceUpdate(); // we have nothing to update
+ };
_getMessageCase() {
const isGuest = MatrixClientPeg.get().isGuest();
@@ -193,7 +200,7 @@ export default createReactClass({
} else {
return MessageCase.ViewingRoom;
}
- },
+ }
_getKickOrBanInfo() {
const myMember = this._getMyMember();
@@ -207,9 +214,9 @@ export default createReactClass({
kickerMember.name : myMember.events.member.getSender();
const reason = myMember.events.member.getContent().reason;
return {memberName, reason};
- },
+ }
- _joinRule: function() {
+ _joinRule() {
const room = this.props.room;
if (room) {
const joinRules = room.currentState.getStateEvents('m.room.join_rules', '');
@@ -217,10 +224,17 @@ export default createReactClass({
return joinRules.getContent().join_rule;
}
}
- },
+ }
- _roomName: function(atStart = false) {
- const name = this.props.room ? this.props.room.name : this.props.roomAlias;
+ _communityProfile() {
+ if (this.props.room) return CommunityPrototypeStore.instance.getInviteProfile(this.props.room.roomId);
+ return {displayName: null, avatarMxc: null};
+ }
+
+ _roomName(atStart = false) {
+ let name = this.props.room ? this.props.room.name : this.props.roomAlias;
+ const profile = this._communityProfile();
+ if (profile.displayName) name = profile.displayName;
if (name) {
return name;
} else if (atStart) {
@@ -228,16 +242,16 @@ export default createReactClass({
} else {
return _t("this room");
}
- },
+ }
_getMyMember() {
return (
this.props.room &&
this.props.room.getMember(MatrixClientPeg.get().getUserId())
);
- },
+ }
- _getInviteMember: function() {
+ _getInviteMember() {
const {room} = this.props;
if (!room) {
return;
@@ -249,7 +263,7 @@ export default createReactClass({
}
const inviterUserId = inviteEvent.events.member.getSender();
return room.currentState.getMember(inviterUserId);
- },
+ }
_isDMInvite() {
const myMember = this._getMyMember();
@@ -259,7 +273,7 @@ export default createReactClass({
const memberEvent = myMember.events.member;
const memberContent = memberEvent.getContent();
return memberContent.membership === "invite" && memberContent.is_direct;
- },
+ }
_makeScreenAfterLogin() {
return {
@@ -272,17 +286,17 @@ export default createReactClass({
inviter_name: this.props.oobData ? this.props.oobData.inviterName : null,
}
};
- },
+ }
- onLoginClick: function() {
+ onLoginClick = () => {
dis.dispatch({ action: 'start_login', screenAfterLogin: this._makeScreenAfterLogin() });
- },
+ };
- onRegisterClick: function() {
+ onRegisterClick = () => {
dis.dispatch({ action: 'start_registration', screenAfterLogin: this._makeScreenAfterLogin() });
- },
+ };
- render: function() {
+ render() {
const brand = SdkConfig.get().brand;
const Spinner = sdk.getComponent('elements.Spinner');
const AccessibleButton = sdk.getComponent('elements.AccessibleButton');
@@ -439,7 +453,10 @@ export default createReactClass({
}
case MessageCase.Invite: {
const RoomAvatar = sdk.getComponent("views.avatars.RoomAvatar");
- const avatar = ;
+ const oobData = Object.assign({}, this.props.oobData, {
+ avatarUrl: this._communityProfile().avatarMxc,
+ });
+ const avatar = ;
const inviteMember = this._getInviteMember();
let inviterElement;
@@ -511,7 +528,7 @@ export default createReactClass({
"If you think you're seeing this message in error, please " +
"submit a bug report.",
{ errcode: this.props.error.errcode },
- { issueLink: label => { label } },
),
];
@@ -573,5 +590,5 @@ export default createReactClass({
);
- },
-});
+ }
+}
diff --git a/src/components/views/rooms/RoomSublist.tsx b/src/components/views/rooms/RoomSublist.tsx
index f6d0d1c22e..4056f2fbd4 100644
--- a/src/components/views/rooms/RoomSublist.tsx
+++ b/src/components/views/rooms/RoomSublist.tsx
@@ -50,6 +50,7 @@ import { arrayFastClone, arrayHasOrderChange } from "../../../utils/arrays";
import { objectExcluding, objectHasDiff } from "../../../utils/objects";
import TemporaryTile from "./TemporaryTile";
import { ListNotificationState } from "../../../stores/notifications/ListNotificationState";
+import IconizedContextMenu from "../context_menus/IconizedContextMenu";
const SHOW_N_BUTTON_HEIGHT = 28; // As defined by CSS
const RESIZE_HANDLE_HEIGHT = 4; // As defined by CSS
@@ -65,6 +66,7 @@ interface IProps {
startAsHidden: boolean;
label: string;
onAddRoom?: () => void;
+ addRoomContextMenu?: (onFinished: () => void) => React.ReactNode;
addRoomLabel: string;
isMinimized: boolean;
tagId: TagID;
@@ -74,7 +76,7 @@ interface IProps {
// You should feel bad if you use this.
extraBadTilesThatShouldntExist?: TemporaryTile[];
- // TODO: Account for https://github.com/vector-im/riot-web/issues/14179
+ // TODO: Account for https://github.com/vector-im/element-web/issues/14179
}
// TODO: Use re-resizer's NumberSize when it is exposed as the type
@@ -87,6 +89,7 @@ type PartialDOMRect = Pick;
interface IState {
contextMenuPosition: PartialDOMRect;
+ addRoomContextMenuPosition: PartialDOMRect;
isResizing: boolean;
isExpanded: boolean; // used for the for expand of the sublist when the room list is being filtered
height: number;
@@ -112,6 +115,7 @@ export default class RoomSublist extends React.Component {
this.notificationState = RoomNotificationStateStore.instance.getListState(this.props.tagId);
this.state = {
contextMenuPosition: null,
+ addRoomContextMenuPosition: null,
isResizing: false,
isExpanded: this.isBeingFiltered ? this.isBeingFiltered : !this.layout.isCollapsed,
height: 0, // to be fixed in a moment, we need `rooms` to calculate this.
@@ -376,10 +380,21 @@ export default class RoomSublist extends React.Component {
});
};
+ private onAddRoomContextMenu = (ev: React.MouseEvent) => {
+ ev.preventDefault();
+ ev.stopPropagation();
+ const target = ev.target as HTMLButtonElement;
+ this.setState({addRoomContextMenuPosition: target.getBoundingClientRect()});
+ };
+
private onCloseMenu = () => {
this.setState({contextMenuPosition: null});
};
+ private onCloseAddRoomMenu = () => {
+ this.setState({addRoomContextMenuPosition: null});
+ };
+
private onUnreadFirstChanged = async () => {
const isUnreadFirst = RoomListStore.instance.getListOrder(this.props.tagId) === ListAlgorithm.Importance;
const newAlgorithm = isUnreadFirst ? ListAlgorithm.Natural : ListAlgorithm.Importance;
@@ -502,15 +517,13 @@ export default class RoomSublist extends React.Component {
if (this.state.rooms) {
const visibleRooms = this.state.rooms.slice(0, this.numVisibleTiles);
for (const room of visibleRooms) {
- tiles.push(
-
- );
+ tiles.push();
}
}
@@ -594,6 +607,18 @@ export default class RoomSublist extends React.Component {
);
+ } else if (this.state.addRoomContextMenuPosition) {
+ contextMenu = (
+
+ {this.props.addRoomContextMenu(this.onCloseAddRoomMenu)}
+
+ );
}
return (
@@ -637,9 +662,21 @@ export default class RoomSublist extends React.Component {
tabIndex={tabIndex}
onClick={this.onAddRoom}
className="mx_RoomSublist_auxButton"
+ tooltipClassName="mx_RoomSublist_addRoomTooltip"
aria-label={this.props.addRoomLabel || _t("Add room")}
title={this.props.addRoomLabel}
- tooltipClassName={"mx_RoomSublist_addRoomTooltip"}
+ />
+ );
+ } else if (this.props.addRoomContextMenu) {
+ addRoomButton = (
+
);
}
@@ -671,7 +708,12 @@ export default class RoomSublist extends React.Component {
// doesn't become sticky.
// The same applies to the notification badge.
return (
-
✅ {_t(
+ "Cross-signing is ready for use, but secret storage is " +
+ "currently not being used to backup your keys.",
)}
;
} else if (crossSigningPrivateKeysInStorage) {
summarisedStatus =
{_t(
- "Your account has a cross-signing identity in secret storage, but it " +
- "is not yet trusted by this session.",
+ "Your account has a cross-signing identity in secret storage, " +
+ "but it is not yet trusted by this session.",
)}
;
} else {
diff --git a/src/components/views/settings/tabs/room/RolesRoomSettingsTab.js b/src/components/views/settings/tabs/room/RolesRoomSettingsTab.js
index b812bb6b68..99352a452e 100644
--- a/src/components/views/settings/tabs/room/RolesRoomSettingsTab.js
+++ b/src/components/views/settings/tabs/room/RolesRoomSettingsTab.js
@@ -33,7 +33,7 @@ const plEventsToLabels = {
"m.room.tombstone": _td("Upgrade the room"),
"m.room.encryption": _td("Enable room encryption"),
- // TODO: Enable support for m.widget event type (https://github.com/vector-im/riot-web/issues/13111)
+ // TODO: Enable support for m.widget event type (https://github.com/vector-im/element-web/issues/13111)
"im.vector.modular.widgets": _td("Modify widgets"),
};
@@ -48,7 +48,7 @@ const plEventsToShow = {
"m.room.tombstone": {isState: true},
"m.room.encryption": {isState: true},
- // TODO: Enable support for m.widget event type (https://github.com/vector-im/riot-web/issues/13111)
+ // TODO: Enable support for m.widget event type (https://github.com/vector-im/element-web/issues/13111)
"im.vector.modular.widgets": {isState: true},
};
diff --git a/src/components/views/settings/tabs/room/SecurityRoomSettingsTab.js b/src/components/views/settings/tabs/room/SecurityRoomSettingsTab.js
index 596344d7cd..48115146f1 100644
--- a/src/components/views/settings/tabs/room/SecurityRoomSettingsTab.js
+++ b/src/components/views/settings/tabs/room/SecurityRoomSettingsTab.js
@@ -22,6 +22,7 @@ import * as sdk from "../../../../..";
import LabelledToggleSwitch from "../../../elements/LabelledToggleSwitch";
import Modal from "../../../../../Modal";
import QuestionDialog from "../../../dialogs/QuestionDialog";
+import StyledRadioGroup from '../../../elements/StyledRadioGroup';
import {SettingLevel} from "../../../../../settings/SettingLevel";
export default class SecurityRoomSettingsTab extends React.Component {
@@ -99,7 +100,7 @@ export default class SecurityRoomSettingsTab extends React.Component {
{
'a': (sub) => {
return {sub};
+ href='https://element.io/help#encryption'>{sub};
},
},
),
@@ -144,7 +145,7 @@ export default class SecurityRoomSettingsTab extends React.Component {
});
};
- _onRoomAccessRadioToggle = (ev) => {
+ _onRoomAccessRadioToggle = (roomAccess) => {
// join_rule
// INVITE | PUBLIC
// ----------------------+----------------
@@ -161,7 +162,7 @@ export default class SecurityRoomSettingsTab extends React.Component {
let joinRule = "invite";
let guestAccess = "can_join";
- switch (ev.target.value) {
+ switch (roomAccess) {
case "invite_only":
// no change - use defaults above
break;
@@ -190,11 +191,11 @@ export default class SecurityRoomSettingsTab extends React.Component {
});
};
- _onHistoryRadioToggle = (ev) => {
+ _onHistoryRadioToggle = (history) => {
const beforeHistory = this.state.history;
- this.setState({history: ev.target.value});
+ this.setState({history: history});
MatrixClientPeg.get().sendStateEvent(this.props.roomId, "m.room.history_visibility", {
- history_visibility: ev.target.value,
+ history_visibility: history,
}, "").catch((e) => {
console.error(e);
this.setState({history: beforeHistory});
@@ -257,27 +258,31 @@ export default class SecurityRoomSettingsTab extends React.Component {
{guestWarning}
{aliasWarning}
-
-
-
+
);
}
@@ -294,34 +299,33 @@ export default class SecurityRoomSettingsTab extends React.Component {
{_t('Changes to who can read history will only apply to future messages in this room. ' +
'The visibility of existing history will be unchanged.')}
-
-
-
-
+
);
}
diff --git a/src/components/views/settings/tabs/user/AppearanceUserSettingsTab.tsx b/src/components/views/settings/tabs/user/AppearanceUserSettingsTab.tsx
index c646025bbe..b4c05a2ecb 100644
--- a/src/components/views/settings/tabs/user/AppearanceUserSettingsTab.tsx
+++ b/src/components/views/settings/tabs/user/AppearanceUserSettingsTab.tsx
@@ -170,7 +170,7 @@ export default class AppearanceUserSettingsTab extends React.Component
{customThemeForm}
-
+
);
}
diff --git a/src/components/views/settings/tabs/user/LabsUserSettingsTab.js b/src/components/views/settings/tabs/user/LabsUserSettingsTab.js
index 25dfd9e100..eba5c6586d 100644
--- a/src/components/views/settings/tabs/user/LabsUserSettingsTab.js
+++ b/src/components/views/settings/tabs/user/LabsUserSettingsTab.js
@@ -28,14 +28,15 @@ export class LabsSettingToggle extends React.Component {
};
_onChange = async (checked) => {
- await SettingsStore.setFeatureEnabled(this.props.featureId, checked);
+ await SettingsStore.setValue(this.props.featureId, null, SettingLevel.DEVICE, checked);
this.forceUpdate();
};
render() {
const label = SettingsStore.getDisplayName(this.props.featureId);
- const value = SettingsStore.isFeatureEnabled(this.props.featureId);
- return ;
+ const value = SettingsStore.getValue(this.props.featureId);
+ const canChange = SettingsStore.canSetValue(this.props.featureId, null, SettingLevel.DEVICE);
+ return ;
}
}
@@ -46,7 +47,7 @@ export default class LabsUserSettingsTab extends React.Component {
render() {
const SettingsFlag = sdk.getComponent("views.elements.SettingsFlag");
- const flags = SettingsStore.getLabsFeatures().map(f => );
+ const flags = SettingsStore.getFeatureSettingNames().map(f => );
return (
{_t("Labs")}
@@ -55,7 +56,7 @@ export default class LabsUserSettingsTab extends React.Component {
_t('Customise your experience with experimental labs features. ' +
'Learn more.', {}, {
'a': (sub) => {
- return {sub};
},
})
diff --git a/src/components/views/settings/tabs/user/VoiceUserSettingsTab.js b/src/components/views/settings/tabs/user/VoiceUserSettingsTab.js
index 4114f6bb22..a78cc10b92 100644
--- a/src/components/views/settings/tabs/user/VoiceUserSettingsTab.js
+++ b/src/components/views/settings/tabs/user/VoiceUserSettingsTab.js
@@ -157,6 +157,9 @@ export default class VoiceUserSettingsTab extends React.Component {
label: _t('Default Device'),
};
const getDefaultDevice = (devices) => {
+ // Note we're looking for a device with deviceId 'default' but adding a device
+ // with deviceId == the empty string: this is because Chrome gives us a device
+ // with deviceId 'default', so we're looking for this, not the one we are adding.
if (!devices.some((i) => i.deviceId === 'default')) {
devices.unshift(defaultOption);
return '';
diff --git a/src/components/views/toasts/GenericExpiringToast.tsx b/src/components/views/toasts/GenericExpiringToast.tsx
index 83f43208c4..e63edd8e79 100644
--- a/src/components/views/toasts/GenericExpiringToast.tsx
+++ b/src/components/views/toasts/GenericExpiringToast.tsx
@@ -29,7 +29,15 @@ interface IProps extends IGenericToastProps {
const SECOND = 1000;
-const GenericExpiringToast: React.FC = ({description, acceptLabel, dismissLabel, onAccept, onDismiss, toastKey, numSeconds}) => {
+const GenericExpiringToast: React.FC = ({
+ description,
+ acceptLabel,
+ dismissLabel,
+ onAccept,
+ onDismiss,
+ toastKey,
+ numSeconds,
+}) => {
const onReject = () => {
if (onDismiss) onDismiss();
ToastStore.sharedInstance().dismissToast(toastKey);
diff --git a/src/components/views/toasts/GenericToast.tsx b/src/components/views/toasts/GenericToast.tsx
index 6cd881b9eb..a9c64f1962 100644
--- a/src/components/views/toasts/GenericToast.tsx
+++ b/src/components/views/toasts/GenericToast.tsx
@@ -31,7 +31,13 @@ interface IPropsExtended extends IProps {
onReject();
}
-const GenericToast: React.FC> = ({description, acceptLabel, rejectLabel, onAccept, onReject}) => {
+const GenericToast: React.FC> = ({
+ description,
+ acceptLabel,
+ rejectLabel,
+ onAccept,
+ onReject,
+}) => {
return
{ description }
diff --git a/src/components/views/voip/CallView.tsx b/src/components/views/voip/CallView.tsx
index 8416f56fd9..1d3a62984a 100644
--- a/src/components/views/voip/CallView.tsx
+++ b/src/components/views/voip/CallView.tsx
@@ -97,10 +97,7 @@ export default class CallView extends React.Component {
if (this.props.room) {
const roomId = this.props.room.roomId;
call = CallHandler.getCallForRoom(roomId) ||
- (this.props.ConferenceHandler ?
- this.props.ConferenceHandler.getConferenceCallForRoom(roomId) :
- null
- );
+ (this.props.ConferenceHandler ? this.props.ConferenceHandler.getConferenceCallForRoom(roomId) : null);
if (this.call) {
this.setState({ call: call });
diff --git a/src/components/views/voip/IncomingCallBox.tsx b/src/components/views/voip/IncomingCallBox.tsx
index 00d49b20f5..b7cba7a70f 100644
--- a/src/components/views/voip/IncomingCallBox.tsx
+++ b/src/components/views/voip/IncomingCallBox.tsx
@@ -51,7 +51,7 @@ export default class IncomingCallBox extends React.Component {
private onAction = (payload: ActionPayload) => {
switch (payload.action) {
- case 'call_state':
+ case 'call_state': {
const call = CallHandler.getCall(payload.room_id);
if (call && call.call_state === 'ringing') {
this.setState({
@@ -62,6 +62,7 @@ export default class IncomingCallBox extends React.Component {
incomingCall: null,
});
}
+ }
}
};
diff --git a/src/components/views/voip/VideoFeed.js b/src/components/views/voip/VideoFeed.js
index 527b071942..a0330f8cb1 100644
--- a/src/components/views/voip/VideoFeed.js
+++ b/src/components/views/voip/VideoFeed.js
@@ -17,44 +17,42 @@ limitations under the License.
import React, {createRef} from 'react';
import PropTypes from 'prop-types';
-import createReactClass from 'create-react-class';
-export default createReactClass({
- displayName: 'VideoFeed',
-
- propTypes: {
+export default class VideoFeed extends React.Component {
+ static propTypes = {
// maxHeight style attribute for the video element
maxHeight: PropTypes.number,
// a callback which is called when the video element is resized
// due to a change in video metadata
onResize: PropTypes.func,
- },
+ };
+
+ constructor(props) {
+ super(props);
- // TODO: [REACT-WARNING] Replace component with real class, use constructor for refs
- UNSAFE_componentWillMount() {
this._vid = createRef();
- },
+ }
componentDidMount() {
this._vid.current.addEventListener('resize', this.onResize);
- },
+ }
componentWillUnmount() {
this._vid.current.removeEventListener('resize', this.onResize);
- },
+ }
- onResize: function(e) {
+ onResize = (e) => {
if (this.props.onResize) {
this.props.onResize(e);
}
- },
+ };
- render: function() {
+ render() {
return (
);
- },
-});
+ }
+}
diff --git a/src/components/views/voip/VideoView.js b/src/components/views/voip/VideoView.js
index a51ab70da9..374a12e82d 100644
--- a/src/components/views/voip/VideoView.js
+++ b/src/components/views/voip/VideoView.js
@@ -18,7 +18,6 @@ limitations under the License.
import React, {createRef} from 'react';
import ReactDOM from 'react-dom';
import PropTypes from 'prop-types';
-import createReactClass from 'create-react-class';
import classNames from 'classnames';
import * as sdk from '../../../index';
@@ -35,10 +34,8 @@ function getFullScreenElement() {
);
}
-export default createReactClass({
- displayName: 'VideoView',
-
- propTypes: {
+export default class VideoView extends React.Component {
+ static propTypes = {
// maxHeight style attribute for the video element
maxHeight: PropTypes.number,
@@ -48,27 +45,28 @@ export default createReactClass({
// a callback which is called when the video element is resized due to
// a change in video metadata
onResize: PropTypes.func,
- },
+ };
+
+ constructor(props) {
+ super(props);
- // TODO: [REACT-WARNING] Replace component with real class, use constructor for refs
- UNSAFE_componentWillMount: function() {
this._local = createRef();
this._remote = createRef();
- },
+ }
- componentDidMount: function() {
+ componentDidMount() {
this.dispatcherRef = dis.register(this.onAction);
- },
+ }
- componentWillUnmount: function() {
+ componentWillUnmount() {
dis.unregister(this.dispatcherRef);
- },
+ }
- getRemoteVideoElement: function() {
+ getRemoteVideoElement = () => {
return ReactDOM.findDOMNode(this._remote.current);
- },
+ };
- getRemoteAudioElement: function() {
+ getRemoteAudioElement = () => {
// this needs to be somewhere at the top of the DOM which
// always exists to avoid audio interruptions.
// Might as well just use DOM.
@@ -78,17 +76,17 @@ export default createReactClass({
+ "You need to add an to the DOM.");
}
return remoteAudioElement;
- },
+ };
- getLocalVideoElement: function() {
+ getLocalVideoElement = () => {
return ReactDOM.findDOMNode(this._local.current);
- },
+ };
- setContainer: function(c) {
+ setContainer = (c) => {
this.container = c;
- },
+ };
- onAction: function(payload) {
+ onAction = (payload) => {
switch (payload.action) {
case 'video_fullscreen': {
if (!this.container) {
@@ -117,9 +115,9 @@ export default createReactClass({
break;
}
}
- },
+ };
- render: function() {
+ render() {
const VideoFeed = sdk.getComponent('voip.VideoFeed');
// if we're fullscreen, we don't want to set a maxHeight on the video element.
@@ -140,5 +138,5 @@ export default createReactClass({
);
- },
-});
+ }
+}
diff --git a/src/createRoom.ts b/src/createRoom.ts
index 23a664a4c4..09de265ebc 100644
--- a/src/createRoom.ts
+++ b/src/createRoom.ts
@@ -26,8 +26,8 @@ import dis from "./dispatcher/dispatcher";
import * as Rooms from "./Rooms";
import DMRoomMap from "./utils/DMRoomMap";
import {getAddressType} from "./UserAddress";
-
-const E2EE_WK_KEY = "im.vector.riot.e2ee";
+import { getE2EEWellKnown } from "./utils/WellKnownUtils";
+import GroupStore from "./stores/GroupStore";
// we define a number of interfaces which take their names from the js-sdk
/* eslint-disable camelcase */
@@ -80,6 +80,7 @@ interface IOpts {
encryption?: boolean;
inlineErrors?: boolean;
andView?: boolean;
+ associatedWithCommunity?: string;
}
/**
@@ -182,6 +183,10 @@ export default function createRoom(opts: IOpts): Promise {
} else {
return Promise.resolve();
}
+ }).then(() => {
+ if (opts.associatedWithCommunity) {
+ return GroupStore.addRoomToGroup(opts.associatedWithCommunity, roomId, false);
+ }
}).then(function() {
// NB createRoom doesn't block on the client seeing the echo that the
// room has been created, so we race here with the client knowing that
@@ -294,12 +299,11 @@ export async function ensureDMExists(client: MatrixClient, userId: string): Prom
return roomId;
}
-export function privateShouldBeEncrypted() {
- const clientWellKnown = MatrixClientPeg.get().getClientWellKnown();
- if (clientWellKnown && clientWellKnown[E2EE_WK_KEY]) {
- const defaultDisabled = clientWellKnown[E2EE_WK_KEY]["default"] === false;
+export function privateShouldBeEncrypted(): boolean {
+ const e2eeWellKnown = getE2EEWellKnown();
+ if (e2eeWellKnown) {
+ const defaultDisabled = e2eeWellKnown["default"] === false;
return !defaultDisabled;
}
-
return true;
}
diff --git a/src/editor/caret.ts b/src/editor/caret.ts
index 4864f9aa95..cb4978caf4 100644
--- a/src/editor/caret.ts
+++ b/src/editor/caret.ts
@@ -59,7 +59,7 @@ export function setCaretPosition(editor: HTMLDivElement, model: EditorModel, car
// If the selection matches, it's important to leave it alone.
// Recreating the selection state in at least Chrome can cause
// strange side effects, like touch bar flickering on every key.
- // See https://github.com/vector-im/riot-web/issues/9299
+ // See https://github.com/vector-im/element-web/issues/9299
return;
}
}
diff --git a/src/editor/deserialize.ts b/src/editor/deserialize.ts
index 28543137be..ec697b193c 100644
--- a/src/editor/deserialize.ts
+++ b/src/editor/deserialize.ts
@@ -158,7 +158,7 @@ function checkDescendInto(node) {
function checkIgnored(n) {
if (n.nodeType === Node.TEXT_NODE) {
- // riot adds \n text nodes in a lot of places,
+ // Element adds \n text nodes in a lot of places,
// which should be ignored
return n.nodeValue === "\n";
} else if (n.nodeType === Node.ELEMENT_NODE) {
diff --git a/src/hooks/useAsyncMemo.js b/src/hooks/useAsyncMemo.ts
similarity index 81%
rename from src/hooks/useAsyncMemo.js
rename to src/hooks/useAsyncMemo.ts
index ef7d256b04..11c7aca7f1 100644
--- a/src/hooks/useAsyncMemo.js
+++ b/src/hooks/useAsyncMemo.ts
@@ -14,9 +14,11 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
-import { useState, useEffect } from 'react';
+import {useState, useEffect, DependencyList} from 'react';
-export const useAsyncMemo = (fn, deps, initialValue) => {
+type Fn = () => Promise;
+
+export const useAsyncMemo = (fn: Fn, deps: DependencyList, initialValue?: T) => {
const [value, setValue] = useState(initialValue);
useEffect(() => {
fn().then(setValue);
diff --git a/src/hooks/useEventEmitter.js b/src/hooks/useEventEmitter.ts
similarity index 86%
rename from src/hooks/useEventEmitter.js
rename to src/hooks/useEventEmitter.ts
index 6a758fb108..6b5693ef95 100644
--- a/src/hooks/useEventEmitter.js
+++ b/src/hooks/useEventEmitter.ts
@@ -15,11 +15,14 @@ limitations under the License.
*/
import {useRef, useEffect} from "react";
+import type {EventEmitter} from "events";
+
+type Handler = (...args: any[]) => void;
// Hook to wrap event emitter on and removeListener in hook lifecycle
-export const useEventEmitter = (emitter, eventName, handler) => {
+export const useEventEmitter = (emitter: EventEmitter, eventName: string | symbol, handler: Handler) => {
// Create a ref that stores handler
- const savedHandler = useRef();
+ const savedHandler = useRef(handler);
// Update ref.current value if handler changes.
useEffect(() => {
diff --git a/src/hooks/useSettings.js b/src/hooks/useSettings.ts
similarity index 82%
rename from src/hooks/useSettings.js
rename to src/hooks/useSettings.ts
index 151a6369de..9534fccc4c 100644
--- a/src/hooks/useSettings.js
+++ b/src/hooks/useSettings.ts
@@ -18,7 +18,7 @@ import {useEffect, useState} from "react";
import SettingsStore from '../settings/SettingsStore';
// Hook to fetch the value of a setting and dynamically update when it changes
-export const useSettingValue = (settingName, roomId = null, excludeDefault = false) => {
+export const useSettingValue = (settingName: string, roomId: string = null, excludeDefault = false) => {
const [value, setValue] = useState(SettingsStore.getValue(settingName, roomId, excludeDefault));
useEffect(() => {
@@ -35,12 +35,12 @@ export const useSettingValue = (settingName, roomId = null, excludeDefault = fal
};
// Hook to fetch whether a feature is enabled and dynamically update when that changes
-export const useFeatureEnabled = (featureName, roomId = null) => {
- const [enabled, setEnabled] = useState(SettingsStore.isFeatureEnabled(featureName, roomId));
+export const useFeatureEnabled = (featureName: string, roomId: string = null) => {
+ const [enabled, setEnabled] = useState(SettingsStore.getValue(featureName, roomId));
useEffect(() => {
const ref = SettingsStore.watchSetting(featureName, roomId, () => {
- setEnabled(SettingsStore.isFeatureEnabled(featureName, roomId));
+ setEnabled(SettingsStore.getValue(featureName, roomId));
});
// clean-up
return () => {
diff --git a/src/hooks/useStateToggle.js b/src/hooks/useStateToggle.ts
similarity index 85%
rename from src/hooks/useStateToggle.js
rename to src/hooks/useStateToggle.ts
index 58cf123bfb..85441df328 100644
--- a/src/hooks/useStateToggle.js
+++ b/src/hooks/useStateToggle.ts
@@ -14,12 +14,12 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
-import {useState} from 'react';
+import {useState} from "react";
// Hook to simplify toggling of a boolean state value
// Returns value, method to toggle boolean value and method to set the boolean value
-export const useStateToggle = (initialValue) => {
- const [value, setValue] = useState(Boolean(initialValue));
+export const useStateToggle = (initialValue: boolean) => {
+ const [value, setValue] = useState(initialValue);
const toggleValue = () => {
setValue(!value);
};
diff --git a/src/i18n/strings/cs.json b/src/i18n/strings/cs.json
index de80c4aa74..4d9d27363f 100644
--- a/src/i18n/strings/cs.json
+++ b/src/i18n/strings/cs.json
@@ -1610,7 +1610,7 @@
"%(senderName)s changed a rule that was banning rooms matching %(oldGlob)s to matching %(newGlob)s for %(reason)s": "%(senderName)s změnil pravidlo blokující místnosti odpovídající %(oldGlob)s na místnosti odpovídající %(newGlob)s z důvodu %(reason)s",
"%(senderName)s changed a rule that was banning servers matching %(oldGlob)s to matching %(newGlob)s for %(reason)s": "%(senderName)s změnil pravidlo blokující servery odpovídající %(oldGlob)s na servery odpovídající %(newGlob)s z důvodu %(reason)s",
"%(senderName)s updated a ban rule that was matching %(oldGlob)s to matching %(newGlob)s for %(reason)s": "%(senderName)s změnil blokovací pravidlo odpovídající %(oldGlob)s na odpovídající %(newGlob)s z důvodu %(reason)s",
- "Try out new ways to ignore people (experimental)": "Vyzkošejte nové metody ignorování lidí (experimentální)",
+ "Try out new ways to ignore people (experimental)": "Vyzkoušejte nové metody ignorování lidí (experimentální)",
"Match system theme": "Nastavit podle vzhledu systému",
"My Ban List": "Můj seznam zablokovaných",
"This is your list of users/servers you have blocked - don't leave the room!": "Toto je váš seznam blokovaných uživatelů/serverů - neopouštějte tuto místnost!",
@@ -2164,5 +2164,54 @@
"Add users and servers you want to ignore here. Use asterisks to have %(brand)s match any characters. For example, @bot:* would ignore all users that have the name 'bot' on any server.": "Sem přídejte servery a uživatele, které chcete ignorovat. Hvězdička pro %(brand)s zastupuje libovolný počet kterýchkoliv znaků. Např. @bot:* bude ignorovat všechny uživatele se jménem „bot“ na kterémkoliv serveru.",
"Signature upload success": "Podpis úspěšně nahrán",
"Signature upload failed": "Podpis se nepodařilo nahrát",
- "If the other version of %(brand)s is still open in another tab, please close it as using %(brand)s on the same host with both lazy loading enabled and disabled simultaneously will cause issues.": "Je-li jiná verze programu %(brand)s stále otevřená na jiné kartě, tak ji prosím zavřete, neboť užívání programu %(brand)s stejným hostitelem se zpožděným nahráváním současně povoleným i zakázaným bude působit problémy."
+ "If the other version of %(brand)s is still open in another tab, please close it as using %(brand)s on the same host with both lazy loading enabled and disabled simultaneously will cause issues.": "Je-li jiná verze programu %(brand)s stále otevřená na jiné kartě, tak ji prosím zavřete, neboť užívání programu %(brand)s stejným hostitelem se zpožděným nahráváním současně povoleným i zakázaným bude působit problémy.",
+ "Unexpected server error trying to leave the room": "Neočekávaná chyba serveru při odcházení z místnosti",
+ "The person who invited you already left the room.": "Uživatel který vás pozval už místnosti není.",
+ "The person who invited you already left the room, or their server is offline.": "Uživatel který vás pozvat už odešel z místnosti a nebo je jeho server offline.",
+ "You left the call": "Odešli jste z hovoru",
+ "%(senderName)s left the call": "%(senderName)s opustil/a hovor",
+ "Call ended": "Hovor skončil",
+ "You started a call": "Začali jste hovor",
+ "%(senderName)s started a call": "%(senderName)s začal/a hovor",
+ "Waiting for answer": "Čekání na odpověď",
+ "%(senderName)s is calling": "%(senderName)s volá",
+ "* %(senderName)s %(emote)s": "* %(senderName)s %(emote)s",
+ "%(senderName)s: %(message)s": "%(senderName)s: %(message)s",
+ "%(senderName)s: %(reaction)s": "%(senderName)s: %(reaction)s",
+ "%(senderName)s: %(stickerName)s": "%(senderName)s: %(stickerName)s",
+ "Change notification settings": "Upravit nastavení oznámení",
+ "Communities v2 prototypes. Requires compatible homeserver. Highly experimental - use with caution.": "Prototyp komunit verze 2. Vyžaduje kompatibilní domovský server. Experimentální - používejte opatrně.",
+ "Use custom size": "Použít vlastní velikost",
+ "Use a more compact ‘Modern’ layout": "Používat kompaktní ‘Moderní’ vzhled",
+ "Use a system font": "Používat systémové nastavení písma",
+ "System font name": "Jméno systémového písma",
+ "Uploading logs": "Nahrávání záznamů",
+ "Downloading logs": "Stahování záznamů",
+ "Unknown caller": "Neznámý volající",
+ "Incoming voice call": "Příchozí hovor",
+ "Incoming video call": "Příchozí videohovor",
+ "Incoming call": "Příchozí hovor",
+ "Your server isn't responding to some requests.": "Váš server neodpovídá na některé požadavky.",
+ "Master private key:": "Hlavní soukromý klíč:",
+ "%(brand)s can't securely cache encrypted messages locally while running in a web browser. Use %(brand)s Desktop for encrypted messages to appear in search results.": "%(brand)s nemůže v prohlížeči lokálně bezpečně uložit zprávy. Použijte %(brand)s Desktop aby fungovalo vyhledávání v šifrovaných zprávách.",
+ "Your server admin has disabled end-to-end encryption by default in private rooms & Direct Messages.": "Váš administrátor vypnul šifrování ve výchozím nastavení soukromých místností a přímých chatů.",
+ "To link to this room, please add an address.": "Přidejte prosím místnosti adresu aby na ní šlo odkazovat.",
+ "The authenticity of this encrypted message can't be guaranteed on this device.": "Pravost této šifrované zprávy nelze na tomto zařízení ověřit.",
+ "Emoji picker": "Výběr emoji",
+ "No recently visited rooms": "Žádné nedávno navštívené místnosti",
+ "People": "Lidé",
+ "Explore public rooms": "Prozkoumat veřejné místnosti",
+ "Custom Tag": "Vlastní štítek",
+ "Can't see what you’re looking for?": "Nikde nevidíte co hledáte?",
+ "Explore all public rooms": "Prozkoumat všechny veřejné místnosti",
+ "%(count)s results|other": "%(count)s výsledků",
+ "Preparing to download logs": "Příprava na stažení záznamů",
+ "Download logs": "Stáhnout záznamy",
+ "a new cross-signing key signature": "nový podpis klíče pro cross-signing",
+ "a key signature": "podpis klíče",
+ "%(brand)s encountered an error during upload of:": "%(brand)s narazil na chybu při nahrávání:",
+ "Upload completed": "Nahrávání dokončeno",
+ "Cancelled signature upload": "Nahrávání podpisu zrušeno",
+ "Unable to upload": "Nelze nahrát",
+ "Server isn't responding": "Server neodpovídá"
}
diff --git a/src/i18n/strings/de_DE.json b/src/i18n/strings/de_DE.json
index 09dbcb2e18..9515a57f8f 100644
--- a/src/i18n/strings/de_DE.json
+++ b/src/i18n/strings/de_DE.json
@@ -115,7 +115,7 @@
"You are already in a call.": "Du bist bereits in einem Gespräch.",
"You cannot place a call with yourself.": "Du kannst keinen Anruf mit dir selbst starten.",
"You cannot place VoIP calls in this browser.": "VoIP-Gespräche werden von diesem Browser nicht unterstützt.",
- "Your email address does not appear to be associated with a Matrix ID on this Homeserver.": "Deine E-Mail-Adresse scheint nicht mit einer Matrix-ID auf diesem Heimserver verbunden zu sein.",
+ "Your email address does not appear to be associated with a Matrix ID on this Homeserver.": "Deine E-Mail-Adresse scheint nicht mit einer Matrix-ID auf diesem Home-Server verbunden zu sein.",
"Sun": "So",
"Mon": "Mo",
"Tue": "Di",
@@ -274,7 +274,7 @@
"ex. @bob:example.com": "z. B. @bob:example.com",
"Add User": "Benutzer hinzufügen",
"Custom Server Options": "Benutzerdefinierte Server-Optionen",
- "Dismiss": "Ablehnen",
+ "Dismiss": "Ausblenden",
"Please check your email to continue registration.": "Bitte prüfe deine E-Mails, um mit der Registrierung fortzufahren.",
"Token incorrect": "Token fehlerhaft",
"Please enter the code it contains:": "Bitte gib den darin enthaltenen Code ein:",
@@ -285,11 +285,11 @@
"Error decrypting video": "Video-Entschlüsselung fehlgeschlagen",
"Import room keys": "Raum-Schlüssel importieren",
"File to import": "Zu importierende Datei",
- "Failed to invite the following users to the %(roomName)s room:": "Das Einladen der folgenden Benutzer in den Raum \"%(roomName)s\" ist fehlgeschlagen:",
+ "Failed to invite the following users to the %(roomName)s room:": "Folgende Benutzer konnten nicht in den Raum \"%(roomName)s\" eingeladen werden:",
"Are you sure you wish to remove (delete) this event? Note that if you delete a room name or topic change, it could undo the change.": "Bist du sicher, dass du dieses Ereignis entfernen (löschen) möchtest? Wenn du die Änderung eines Raum-Namens oder eines Raum-Themas löscht, kann dies dazu führen, dass die ursprüngliche Änderung rückgängig gemacht wird.",
"This process allows you to export the keys for messages you have received in encrypted rooms to a local file. You will then be able to import the file into another Matrix client in the future, so that client will also be able to decrypt these messages.": "Dieser Prozess erlaubt es dir, die Schlüssel für die in verschlüsselten Räumen empfangenen Nachrichten in eine lokale Datei zu exportieren. In Zukunft wird es möglich sein, diese Datei in einen anderen Matrix-Client zu importieren, sodass dieser Client diese Nachrichten ebenfalls entschlüsseln kann.",
"The exported file will allow anyone who can read it to decrypt any encrypted messages that you can see, so you should be careful to keep it secure. To help with this, you should enter a passphrase below, which will be used to encrypt the exported data. It will only be possible to import the data by using the same passphrase.": "Mit der exportierten Datei kann jeder, der diese Datei lesen kann, jede verschlüsselte Nachricht entschlüsseln, die für dich lesbar ist. Du solltest die Datei also unbedingt sicher verwahren. Um den Vorgang sicherer zu gestalten, solltest du unten eine Passphrase eingeben, die dazu verwendet wird, die exportierten Daten zu verschlüsseln. Anschließend wird es nur möglich sein, die Daten zu importieren, wenn dieselbe Passphrase verwendet wird.",
- "Analytics": "Anonymisierte Analysedaten",
+ "Analytics": "Datenverkehrsanalyse",
"%(brand)s collects anonymous analytics to allow us to improve the application.": "%(brand)s sammelt anonymisierte Analysedaten, um die Anwendung kontinuierlich verbessern zu können.",
"Add an Integration": "Eine Integration hinzufügen",
"URL Previews": "URL-Vorschau",
@@ -390,7 +390,7 @@
"Add a widget": "Widget hinzufügen",
"Allow": "Erlauben",
"Delete widget": "Widget entfernen",
- "Define the power level of a user": "Setze das Berechtigungslevel eines Benutzers",
+ "Define the power level of a user": "Berechtigungsstufe einer/s Benutzer!n setzen",
"Edit": "Bearbeiten",
"Enable automatic language detection for syntax highlighting": "Automatische Spracherkennung für die Syntax-Hervorhebung aktivieren",
"To get started, please pick a username!": "Um zu starten, wähle bitte einen Nutzernamen!",
@@ -403,8 +403,8 @@
"Featured Users:": "Hervorgehobene Benutzer:",
"Automatically replace plain text Emoji": "Klartext-Emoji automatisch ersetzen",
"Failed to upload image": "Bild-Hochladen fehlgeschlagen",
- "AM": "a.m.",
- "PM": "p.m.",
+ "AM": "a. m.",
+ "PM": "p. m.",
"The maximum permitted number of widgets have already been added to this room.": "Die maximal erlaubte Anzahl an hinzufügbaren Widgets für diesen Raum wurde erreicht.",
"Cannot add any more widgets": "Kann keine weiteren Widgets hinzufügen",
"%(widgetName)s widget added by %(senderName)s": "%(senderName)s hat das Widget %(widgetName)s hinzugefügt",
@@ -466,7 +466,7 @@
"Warning: any person you add to a community will be publicly visible to anyone who knows the community ID": "Warnung: Jede Person, die du einer Community hinzufügst, wird für alle, die die Community-ID kennen, öffentlich sichtbar sein",
"Invite new community members": "Neue Community-Mitglieder einladen",
"Invite to Community": "In die Community einladen",
- "Which rooms would you like to add to this community?": "Welche Räume möchtest du zu dieser Community hinzufügen?",
+ "Which rooms would you like to add to this community?": "Welche Räume sollen zu dieser Community hinzugefügt werden?",
"Add rooms to the community": "Räume zur Community hinzufügen",
"Add to community": "Zur Community hinzufügen",
"Failed to invite users to community": "Benutzer konnten nicht in die Community eingeladen werden",
@@ -572,7 +572,7 @@
"was unbanned %(count)s times|one": "wurde entbannt",
"%(oneUser)schanged their name %(count)s times|one": "%(oneUser)shat den Namen geändert",
"%(items)s and %(count)s others|other": "%(items)s und %(count)s andere",
- "%(items)s and %(count)s others|one": "%(items)s und noch jemand",
+ "%(items)s and %(count)s others|one": "%(items)s und ein weiteres Raummitglied",
"An email has been sent to %(emailAddress)s. Once you've followed the link it contains, click below.": "Eine E-Mail wurde an %(emailAddress)s gesendet. Folge dem in der E-Mail enthaltenen Link und klicke dann unten.",
"The visibility of '%(roomName)s' in %(groupId)s could not be updated.": "Die Sichtbarkeit von '%(roomName)s' in %(groupId)s konnte nicht aktualisiert werden.",
"Visibility in Room List": "Sichtbarkeit in Raum-Liste",
@@ -627,13 +627,13 @@
"The version of %(brand)s": "Die %(brand)s-Version",
"Your language of choice": "Deine ausgewählte Sprache",
"Whether or not you're using the Richtext mode of the Rich Text Editor": "Ob du den Richtext-Modus des Editors benutzt oder nicht",
- "Your homeserver's URL": "Die URL deines Homeservers",
+ "Your homeserver's URL": "Deine Homeserver-URL",
"%(weekDayName)s, %(monthName)s %(day)s %(fullYear)s": "%(weekDayName)s, %(monthName)s %(day)s %(fullYear)s",
"You will not be able to undo this change as you are demoting yourself, if you are the last privileged user in the room it will be impossible to regain privileges.": "Du wirst nicht in der Lage sein, die Änderung zurückzusetzen, da du dich degradierst. Wenn du der letze Nutzer mit Berechtigungen bist, wird es unmöglich sein die Privilegien zurückzubekommen.",
"Community IDs cannot be empty.": "Community-IDs können nicht leer sein.",
"Learn more about how we use analytics.": "Lerne mehr darüber, wie wir die Analysedaten nutzen.",
"Where this page includes identifiable information, such as a room, user or group ID, that data is removed before being sent to the server.": "Wenn diese Seite identifizierbare Informationen wie Raum-, Nutzer- oder Gruppen-ID enthält, werden diese Daten entfernt bevor sie an den Server gesendet werden.",
- "Which officially provided instance you are using, if any": "Welche offiziell angebotene Instanz du nutzt, wenn es der Fall ist",
+ "Which officially provided instance you are using, if any": "Welche offiziell angebotene Instanz du nutzt, wenn überhaupt eine",
"In reply to": "Als Antwort auf",
"This room is not public. You will not be able to rejoin without an invite.": "Dies ist kein öffentlicher Raum. Du wirst diesen nicht ohne Einladung wieder beitreten können.",
"%(oldDisplayName)s changed their display name to %(displayName)s.": "%(oldDisplayName)s änderte den Anzeigenamen auf %(displayName)s.",
@@ -726,7 +726,7 @@
"Failed to set Direct Message status of room": "Konnte den direkten Benachrichtigungsstatus nicht setzen",
"Monday": "Montag",
"Remove from Directory": "Aus dem Raum-Verzeichnis entfernen",
- "Enable them now": "Aktiviere diese jetzt",
+ "Enable them now": "Diese jetzt aktivieren",
"Toolbox": "Werkzeugkasten",
"Collecting logs": "Protokolle werden abgerufen",
"You must specify an event type!": "Du musst einen Event-Typ spezifizieren!",
@@ -784,7 +784,7 @@
"Checking for an update...": "Nach Updates suchen...",
"Missing roomId.": "Fehlende Raum-ID.",
"Every page you use in the app": "Jede Seite, die du in der App benutzt",
- "e.g. ": "z.B. ",
+ "e.g. ": "z. B. ",
"Your device resolution": "Deine Bildschirmauflösung",
"Popout widget": "Widget ausklinken",
"Always show encryption icons": "Immer Verschlüsselungssymbole zeigen",
@@ -1034,7 +1034,7 @@
"%(senderDisplayName)s made the room invite only.": "%(senderDisplayName)s hat den Raum auf eingeladene User beschränkt.",
"%(senderDisplayName)s changed the join rule to %(rule)s": "%(senderDisplayName)s änderte die Zutrittsregel auf '%(rule)s'",
"%(senderDisplayName)s has allowed guests to join the room.": "%(senderDisplayName)s erlaubte Gäste diesem Raum beizutreten.",
- "%(senderDisplayName)s has prevented guests from joining the room.": "%(senderDisplayName)s hat verboten, dass Gäste diesem Raum beitreten.",
+ "%(senderDisplayName)s has prevented guests from joining the room.": "%(senderDisplayName)s hat Gästen verboten diesem Raum beizutreten.",
"%(senderDisplayName)s changed guest access to %(rule)s": "%(senderDisplayName)s änderte den Gastzugriff auf '%(rule)s'",
"Group & filter rooms by custom tags (refresh to apply changes)": "Gruppiere & filtere Räume nach eigenen Tags (neu laden um Änderungen zu übernehmen)",
"Unable to find a supported verification method.": "Konnte kein unterstützte Verifikationsmethode finden.",
@@ -1296,8 +1296,8 @@
"Actions": "Aktionen",
"Displays list of commands with usages and descriptions": "Zeigt eine Liste von Befehlen mit Verwendungen und Beschreibungen an",
"Call failed due to misconfigured server": "Anruf aufgrund eines falsch konfigurierten Servers fehlgeschlagen",
- "Try using turn.matrix.org": "Versuchen Sie es mit turn.matrix.org",
- "You do not have the required permissions to use this command.": "Sie haben nicht die erforderlichen Berechtigungen, um diesen Befehl zu verwenden.",
+ "Try using turn.matrix.org": "Versuche es mit turn.matrix.org",
+ "You do not have the required permissions to use this command.": "Du hast nicht die erforderlichen Berechtigungen, um diesen Befehl zu verwenden.",
"Multiple integration managers": "Mehrere Integrationsmanager",
"Public Name": "Öffentlicher Name",
"Identity Server URL must be HTTPS": "Die Identity Server-URL muss HTTPS sein",
@@ -1328,7 +1328,7 @@
"Find a room…": "Suche einen Raum…",
"Find a room… (e.g. %(exampleRoom)s)": "Suche einen Raum… (z.B. %(exampleRoom)s)",
"If you can't find the room you're looking for, ask for an invite or Create a new room.": "Wenn du den gesuchten Raum nicht finden kannst, frage nach einer Einladung für den Raum oder Erstelle einen neuen Raum.",
- "Alternatively, you can try to use the public server at turn.matrix.org, but this will not be as reliable, and it will share your IP address with that server. You can also manage this in Settings.": "Alternativ kannst du versuchen, den öffentlichen Server unter turn.matrix.org zu verwenden. Allerdings wird dieser nicht so zuverlässig sein, und deine IP-Adresse mit diesem teilen. Du kannst dies auch in den Einstellungen konfigurieren.",
+ "Alternatively, you can try to use the public server at turn.matrix.org, but this will not be as reliable, and it will share your IP address with that server. You can also manage this in Settings.": "Alternativ kannst du versuchen, den öffentlichen Server unter turn.matrix.org zu verwenden. Allerdings wird dieser nicht so zuverlässig sein, und deine IP-Adresse mit diesem Server teilen. Du kannst dies auch in den Einstellungen konfigurieren.",
"This action requires accessing the default identity server to validate an email address or phone number, but the server does not have any terms of service.": "Diese Handlung erfordert es, auf den Standard-Identitätsserver zuzugreifen, um eine E-Mail Adresse oder Telefonnummer zu validieren, aber der Server hat keine Nutzungsbedingungen.",
"Only continue if you trust the owner of the server.": "Fahre nur fort, wenn du den Inhaber*innen des Servers vertraust.",
"Trust": "Vertrauen",
@@ -1337,7 +1337,7 @@
"Use an identity server to invite by email. Manage in Settings.": "Nutze einen Identitätsserver, um über E-Mail Einladungen zu verschicken. Verwalte es in den Einstellungen.",
"%(name)s (%(userId)s)": "%(name)s (%(userId)s)",
"Try out new ways to ignore people (experimental)": "Versuche neue Möglichkeiten, um Menschen zu ignorieren (experimentell)",
- "Send read receipts for messages (requires compatible homeserver to disable)": "Schicke Lesebestätigungen für Nachrichten (erfordert kompatiblen Heimserver zum Deaktivieren)",
+ "Send read receipts for messages (requires compatible homeserver to disable)": "Lesebestätigungen für Nachrichten senden (Deaktivieren erfordert einen kompatiblen Heimserver)",
"My Ban List": "Meine Bannliste",
"This is your list of users/servers you have blocked - don't leave the room!": "Dies ist die Liste von Benutzer*innen/Servern, die du blockiert hast - verlasse den Raum nicht!",
"Accept to continue:": "Akzeptiere , um fortzufahren:",
@@ -1353,7 +1353,7 @@
"%(senderName)s placed a video call. (not supported by this browser)": "%(senderName)s hat einen Videoanruf getätigt. (Nicht von diesem Browser unterstützt)",
"Verify this session": "Sitzung verifizieren",
"Set up encryption": "Verschlüsselung einrichten",
- "%(senderName)s updated an invalid ban rule": "%(senderName)s hat eine ungültige Bannregel aktualisiert",
+ "%(senderName)s updated an invalid ban rule": "%(senderName)s aktualisierte eine ungültige Ausschluss-Regel",
"The message you are trying to send is too large.": "Die Nachricht, die du versuchst zu senden, ist zu lang.",
"a few seconds ago": "vor ein paar Sekunden",
"about a minute ago": "vor etwa einer Minute",
@@ -1428,7 +1428,7 @@
"Unknown (user, session) pair:": "Unbekanntes (Nutzer-, Sitzungs-) Paar:",
"Session already verified!": "Sitzung bereits verifiziert!",
"WARNING: Session already verified, but keys do NOT MATCH!": "ACHTUNG: Sitzung bereits verifiziert, aber die Schlüssel passen NICHT ZUSAMMEN!",
- "WARNING: KEY VERIFICATION FAILED! The signing key for %(userId)s and session %(deviceId)s is \"%(fprint)s\" which does not match the provided key \"%(fingerprint)s\". This could mean your communications are being intercepted!": "ACHTUNG: SCHLÜSSEL-VERIFIZIERUNG FEHLGESCHLAGEN! Der Signierschlüssel für %(userId)s und Sitzung %(deviceId)s ist \"%(fprint)s\", was nicht mit dem bereitgestellten Schlüssel \"%(fingerprint)s\" übereinstimmt. Das könnte bedeuten, dass Ihre Kommunikation abgehört wird!",
+ "WARNING: KEY VERIFICATION FAILED! The signing key for %(userId)s and session %(deviceId)s is \"%(fprint)s\" which does not match the provided key \"%(fingerprint)s\". This could mean your communications are being intercepted!": "ACHTUNG: SCHLÜSSEL-VERIFIZIERUNG FEHLGESCHLAGEN! Der Signierschlüssel für %(userId)s und Sitzung %(deviceId)s ist \"%(fprint)s\", was nicht mit dem bereitgestellten Schlüssel \"%(fingerprint)s\" übereinstimmt. Das könnte bedeuten, dass deine Kommunikation abgehört wird!",
"Never send encrypted messages to unverified sessions from this session": "Sende niemals verschlüsselte Nachrichten von dieser Sitzung zu unverifizierten Sitzungen",
"Never send encrypted messages to unverified sessions in this room from this session": "Sende niemals verschlüsselte Nachrichten von dieser Sitzung zu unverifizierten Sitzungen in diesem Raum",
"Changing password will currently reset any end-to-end encryption keys on all sessions, making encrypted chat history unreadable, unless you first export your room keys and re-import them afterwards. In future this will be improved.": "Durch die Änderung des Passworts werden derzeit alle End-zu-End-Verschlüsselungsschlüssel in allen Sitzungen zurückgesetzt, sodass der verschlüsselte Chat-Verlauf nicht mehr lesbar ist, es sei denn, Sie exportieren zuerst Ihre Raumschlüssel und importieren sie anschließend wieder. In Zukunft wird dies verbessert werden.",
@@ -1562,7 +1562,7 @@
"You're previewing %(roomName)s. Want to join it?": "Du betrachtest %(roomName)s. Willst du beitreten?",
"%(senderName)s added the alternative addresses %(addresses)s for this room.|one": "%(senderName)s hat die alternative Adresse 2%(addresses)s für diesen Raum hinzugefügt.",
"%(senderName)s changed the addresses for this room.": "%(senderName)s hat die Adresse für diesen Raum geändert.",
- "Displays information about a user": "Zeigt Informationen über einen Benutzer",
+ "Displays information about a user": "Zeigt Informationen über ein/e Benutzer!n",
"%(senderDisplayName)s changed the room name from %(oldRoomName)s to %(newRoomName)s.": "%(senderDisplayName)s hat den Raumnamen von %(oldRoomName)s zu %(newRoomName)s geändert.",
"%(senderName)s added the alternative addresses %(addresses)s for this room.|other": "%(senderName)s hat die alternative Adresse %(addresses)s für diesen Raum hinzugefügt.",
"%(senderName)s removed the alternative addresses %(addresses)s for this room.|other": "%(senderName)s hat die alternativen Adressen %(addresses)s für diesen Raum entfernt.",
@@ -1578,7 +1578,7 @@
"%(senderName)s updated the rule banning servers matching %(glob)s for %(reason)s": "%(senderName)s aktualisierte die Ausschluss-Regel für Server, die aufgrund von %(reason)s %(glob)s entsprechen",
"%(senderName)s updated a ban rule matching %(glob)s for %(reason)s": "%(senderName)s aktualisierte eine Ausschluss-Regel, die wegen %(reason)s %(glob)s entspricht",
"%(senderName)s created a rule banning users matching %(glob)s for %(reason)s": "%(senderName)s erstellte eine Ausschluss-Regel für Nutzer, die wegen %(reason)s %(glob)s entspricht",
- "%(senderName)s created a rule banning rooms matching %(glob)s for %(reason)s": "%(senderName)s erstellte eine Ausschluss-Regel für Räume, die wegen %(reason)s %(glob)s entspricht",
+ "%(senderName)s created a rule banning rooms matching %(glob)s for %(reason)s": "%(senderName)s erstellt eine Ausschluss-Regel für Räume, die %(glob)s aufgrund von %(reason)s entspricht",
"%(senderName)s created a rule banning servers matching %(glob)s for %(reason)s": "%(senderName)s erstellte eine Ausschluss-Regel für Server, die aufgrund von %(reason)s %(glob)s entsprechen",
"%(senderName)s created a ban rule matching %(glob)s for %(reason)s": "%(senderName)s erstellt eine Ausschluss-Regel, die aufgrund von %(reason)s %(glob)s entsprechen",
"Do you want to chat with %(user)s?": "Möchtest du mit %(user)s chatten?",
@@ -1587,8 +1587,8 @@
"Reject & Ignore user": "Ablehnen & Nutzer ignorieren",
"%(senderName)s changed a rule that was banning users matching %(oldGlob)s to matching %(newGlob)s for %(reason)s": "%(senderName)s ändert eine Ausschluss-Regel von %(oldGlob)s nach %(newGlob)s, wegen %(reason)s",
"%(senderName)s changed a rule that was banning rooms matching %(oldGlob)s to matching %(newGlob)s for %(reason)s": "%(senderName)s ändert eine Ausschluss-Regel für Räume von %(oldGlob)s nach %(newGlob)s, wegen %(reason)s",
- "Allow fallback call assist server turn.matrix.org when your homeserver does not offer one (your IP address would be shared during a call)": "Erlaube den Standard-Server zur Anrufunterstützung (turn.matrix.org) zu verwenden wenn dein Heimserver keinen eigenen anbietet (deine IP Adresse wird bei dem Anruf übermittelt)",
- "Show more": "mehr",
+ "Allow fallback call assist server turn.matrix.org when your homeserver does not offer one (your IP address would be shared during a call)": "Auf den Server turn.matrix.org zurückgreifen, falls deine Heimserver keine Anruf-Assistenz anbietet (deine IP-Adresse wird während eines Anrufs geteilt)",
+ "Show more": "Mehr zeigen",
"This session is not backing up your keys, but you do have an existing backup you can restore from and add to going forward.": "Diese Sitzung speichert deine Schlüssel nicht, du kannst sie aber an die Schlüsselsicherung anschließen.",
"Connect this session to key backup before signing out to avoid losing any keys that may only be on this session.": "Verbinde diese Sitzung mit deiner Schlüsselsicherung bevor du dich abmeldest, um den Verlust von Schlüsseln zu vermeiden.",
"This backup is trusted because it has been restored on this session": "Dieser Sicherung wird vertraut, da sie während dieser Sitzung wiederhergestellt wurde",
@@ -1632,12 +1632,12 @@
"Make a copy of your recovery key": "Speichere deinen Wiederherstellungsschlüssel",
"Sends a message as html, without interpreting it as markdown": "Verschickt eine Nachricht im html-Format, ohne sie in Markdown zu formatieren",
"Show rooms with unread notifications first": "Räume mit nicht gelesenen Benachrichtungen zuerst zeigen",
- "Show shortcuts to recently viewed rooms above the room list": "Kurzbefehlezu den kürzlich gesichteteten Räumen über der Raumliste anzeigen",
- "Use Single Sign On to continue": "Benutze „Single Sign-On“ (Einmalanmeldung) um fortzufahren",
- "Confirm adding this email address by using Single Sign On to prove your identity.": "Bestätige das Hinzufügen dieser E-Mail-Adresse mit „Single Sign-On“, um deine Identität nachzuweisen.",
+ "Show shortcuts to recently viewed rooms above the room list": "Kurzbefehle zu den kürzlich gesichteteten Räumen über der Raumliste anzeigen",
+ "Use Single Sign On to continue": "Verwende Single Sign on um fortzufahren",
+ "Confirm adding this email address by using Single Sign On to prove your identity.": "Bestätige die hinzugefügte E-Mail-Adresse mit Single Sign-On, um deine Identität nachzuweisen.",
"Single Sign On": "Single Sign-On",
- "Confirm adding email": "Hinzufügen der E-Mail-Adresse bestätigen",
- "Confirm adding this phone number by using Single Sign On to prove your identity.": "Bestätige das Hinzufügen dieser Telefonnummer, indem du deine Identität mittels „Single Sign-On“ nachweist.",
+ "Confirm adding email": "Bestätige hinzugefügte E-Mail-Addresse",
+ "Confirm adding this phone number by using Single Sign On to prove your identity.": "Bestätige die hinzugefügte Telefonnummer, indem du deine Identität mittels Single Sign-On nachweist.",
"Click the button below to confirm adding this phone number.": "Klicke unten die Schaltfläche, um die hinzugefügte Telefonnummer zu bestätigen.",
"If you cancel now, you won't complete your operation.": "Wenn du jetzt abbrichst, wirst du deinen Vorgang nicht fertigstellen.",
"%(name)s is requesting verification": "%(name)s fordert eine Verifizierung an",
@@ -1645,14 +1645,14 @@
"Command failed": "Befehl fehlgeschlagen",
"Could not find user in room": "Der Benutzer konnte im Raum nicht gefunden werden",
"Click the button below to confirm adding this email address.": "Klicke unten auf die Schaltfläche, um die hinzugefügte E-Mail-Adresse zu bestätigen.",
- "Confirm adding phone number": "Hinzufügen der Telefonnummer bestätigen",
+ "Confirm adding phone number": "Bestätige hinzugefügte Telefonnummer",
"%(senderName)s changed a rule that was banning servers matching %(oldGlob)s to matching %(newGlob)s for %(reason)s": "%(senderName)s ändert eine Ausschluss-Regel für Server von %(oldGlob)s nach %(newGlob)s wegen %(reason)s",
"%(senderName)s updated a ban rule that was matching %(oldGlob)s to matching %(newGlob)s for %(reason)s": "%(senderName)s erneuert eine Ausschluss-Regel von %(oldGlob)s nach %(newGlob)s wegen %(reason)s",
- "Not Trusted": "Nicht vertrauenswürdig",
+ "Not Trusted": "Nicht vertraut",
"Manually Verify by Text": "Verifiziere manuell mit einem Text",
"Interactively verify by Emoji": "Verifiziere interaktiv mit Emojis",
"Support adding custom themes": "Unterstütze das Hinzufügen von benutzerdefinierten Designs",
- "Ask this user to verify their session, or manually verify it below.": "Bitte diese/n Nutzer!n, seine/ihre Sitzung zu verifizieren, oder verifiziere diese unten manuell.",
+ "Ask this user to verify their session, or manually verify it below.": "Bitte diesen Nutzer, seine Sitzung zu verifizieren, oder verifiziere diesen unten manuell.",
"a few seconds from now": "in ein paar Sekunden",
"Manually verify all remote sessions": "Verifiziere alle Remotesitzungen",
"Confirm the emoji below are displayed on both sessions, in the same order:": "Bestätige, dass die unten angezeigten Emojis auf beiden Sitzungen in der selben Reihenfolge angezeigt werden:",
@@ -1724,7 +1724,7 @@
"Upgrade this room to the recommended room version": "Aktualisiere diesen Raum auf die empfohlene Raumversion",
"this room": "Dieser Raum",
"View older messages in %(roomName)s.": "Zeige alte Nachrichten in %(roomName)s.",
- "Send a bug report with logs": "Sende Fehlermeldung mit Protokoll",
+ "Send a bug report with logs": "Sende einen Fehlerbericht mit Logs",
"Verify all your sessions to ensure your account & messages are safe": "Verifiziere alle deine Sitzungen, um dein Konto und deine Nachrichten zu schützen",
"Verify your other session using one of the options below.": "Verifiziere deine andere Sitzung mit einer der folgenden Optionen.",
"You signed in to a new session without verifying it:": "Du hast dich in einer neuen Sitzung angemeldet ohne sie zu verifizieren:",
@@ -1732,16 +1732,16 @@
"Upgrade": "Hochstufen",
"Verify the new login accessing your account: %(name)s": "Verifiziere die neue Anmeldung an deinem Konto: %(name)s",
"From %(deviceName)s (%(deviceId)s)": "Von %(deviceName)s (%(deviceId)s)",
- "Your homeserver does not support cross-signing.": "Dein Heimserver unterstützt cross-signing nicht.",
+ "Your homeserver does not support cross-signing.": "Dein Heimserver unterstützt Cross-Signing nicht.",
"Cross-signing and secret storage are enabled.": "Cross-signing und der sichere Speicher wurden eingerichtet.",
- "Your account has a cross-signing identity in secret storage, but it is not yet trusted by this session.": "Dein Konto hat eine cross-signing Identität im sicheren Speicher aber diese Sitzung wird noch nicht vertraut.",
- "Cross-signing and secret storage are not yet set up.": "Cross-signing und der sichere Speicher wurden noch nicht eingerichtet.",
- "Reset cross-signing and secret storage": "Setze cross-signing und den sicheren Speicher zurück",
+ "Your account has a cross-signing identity in secret storage, but it is not yet trusted by this session.": "Dein Konto hat eine Cross-Signing Identität im sicheren Speicher, aber dieser wird von dieser Sitzung noch nicht vertraut.",
+ "Cross-signing and secret storage are not yet set up.": "Cross-Signing und der sichere Speicher sind noch nicht eingerichtet.",
+ "Reset cross-signing and secret storage": "Setze Cross-Signing und den sicheren Speicher zurück",
"Bootstrap cross-signing and secret storage": "Richte cross-signing und den sicheren Speicher ein",
"unexpected type": "unbekannter Typ",
- "Cross-signing public keys:": "Öffentliche Cross-signing Schlüssel:",
+ "Cross-signing public keys:": "Öffentliche Cross-Signing-Schlüssel:",
"in memory": "im Speicher",
- "Cross-signing private keys:": "Private Cross-signing Schlüssel:",
+ "Cross-signing private keys:": "Private Cross-Signing-Schlüssel:",
"in secret storage": "im sicheren Speicher",
"Self signing private key:": "Selbst signierter privater Schlüssel:",
"cached locally": "lokal zwischengespeichert",
@@ -1754,7 +1754,7 @@
"exists": "existiert",
"Delete sessions|other": "Lösche Sitzungen",
"Delete sessions|one": "Lösche Sitzung",
- "Individually verify each session used by a user to mark it as trusted, not trusting cross-signed devices.": "Sitzungen eines Benutzers einzeln verifizieren. Geräten, die ein Benutzer als vertrauenswürdig markiert hat, wird nicht automatisch vertraut (cross-signing).",
+ "Individually verify each session used by a user to mark it as trusted, not trusting cross-signed devices.": "Alle Sitzungen einzeln verifizieren, anstatt auch Sitzungen zu vertrauen, die durch Cross-Signing verifiziert sind.",
"Securely cache encrypted messages locally for them to appear in search results, using ": "Der Zwischenspeicher für die lokale Suche in verschlüsselten Nachrichten benötigt ",
" to store messages from ": " um Nachrichten aus ",
"%(brand)s is missing some components required for securely caching encrypted messages locally. If you'd like to experiment with this feature, build a custom %(brand)s Desktop with search components added.": "%(brand)s benötigt weitere Komponenten um verschlüsselte Nachrichten lokal zu durchsuchen. Wenn du diese Funktion testen möchtest kannst du dir deine eigene Version von %(brand)s Desktop mit der integrierten Suchfunktion bauen.",
@@ -2055,7 +2055,7 @@
"Your new session is now verified. It has access to your encrypted messages, and other users will see it as trusted.": "Deine neue Sitzung ist nun verifiziert. Sie hat Zugriff auf deine verschlüsselten Nachrichten, und andere Benutzer sehen sie als vertrauenswürdig an.",
"Your new session is now verified. Other users will see it as trusted.": "Deine neue Sitzung ist nun verifiziert. Andere Benutzer sehen sie als vertrauenswürdig an.",
"well formed": "wohlgeformt",
- "If you don't want to use to discover and be discoverable by existing contacts you know, enter another identity server below.": "Wenn du nicht verwenden willst um andere Benutzer zu finden und gefunden zu werden, trage unten einen anderen Identitätsserver ein.",
+ "If you don't want to use to discover and be discoverable by existing contacts you know, enter another identity server below.": "Wenn du nicht verwenden willst, um Kontakte zu finden und von anderen gefunden zu werden, trage unten einen anderen Identitätsserver ein.",
"To report a Matrix-related security issue, please read the Matrix.org Security Disclosure Policy.": "Wenn du einen sicherheitsrelevaten Fehler melden möchtest, lies bitte die Matrix.org Security Disclosure Policy.",
"An error occurred changing the room's power level requirements. Ensure you have sufficient permissions and try again.": "Beim Ändern der Anforderungen für Benutzerrechte ist ein Fehler aufgetreten. Stelle sicher dass du die nötigen Berechtigungen besitzt und versuche es erneut.",
"An error occurred changing the user's power level. Ensure you have sufficient permissions and try again.": "Beim Ändern der Benutzerrechte ist ein Fehler aufgetreten. Stelle sicher dass du die nötigen Berechtigungen besitzt und versuche es erneut.",
@@ -2153,7 +2153,7 @@
"Self-verification request": "Selbstverifikationsanfrage",
"or another cross-signing capable Matrix client": "oder einen anderen Matrix Client der Cross-signing fähig ist",
"%(brand)s is securely caching encrypted messages locally for them to appear in search results:": "%(brand)s verwendet einen sicheren Zwischenspeicher für verschlüsselte Nachrichten, damit sie in den Suchergebnissen angezeigt werden:",
- "Liberate your communication": "Liberate your communication",
+ "Liberate your communication": "Befreie deine Kommunikation",
"Message downloading sleep time(ms)": "Wartezeit zwischen dem Herunterladen von Nachrichten (ms)",
"Navigate recent messages to edit": "Letzte Nachrichten zur Bearbeitung ansehen",
"Jump to start/end of the composer": "Springe zum Anfang/Ende der Nachrichteneingabe",
@@ -2333,9 +2333,9 @@
"Incoming voice call": "Eingehender Sprachanruf",
"Incoming video call": "Eingehender Videoanruf",
"Incoming call": "Eingehender Anruf",
- "There are advanced notifications which are not shown here.": "Es sind erweiterte Benachrichtigungen vorhanden, die hier nicht angezeigt werden.",
- "Are you sure you want to cancel entering passphrase?": "Bist du sicher dass du die Eingabe der Passphrase abbrechen möchtest?",
- "Use your account to sign in to the latest version": "Verwende dein Konto um dich bei der neusten Version anzumelden",
+ "There are advanced notifications which are not shown here.": "Erweiterte Benachrichtigungen, werden hier nicht angezeigt.",
+ "Are you sure you want to cancel entering passphrase?": "Bist du sicher, dass du die Eingabe der Passphrase abbrechen möchtest?",
+ "Use your account to sign in to the latest version": "Melde dich mit deinem Account in der neuesten Version an",
"* %(senderName)s %(emote)s": "* %(senderName)s %(emote)s",
"Enable advanced debugging for the room list": "Erweiterte Fehlersuche für die Raumliste aktivieren",
"Enable experimental, compact IRC style layout": "Kompaktes, experimentelles Layout im IRC-Stil aktivieren",
@@ -2344,7 +2344,7 @@
"%(brand)s Desktop": "%(brand)s Desktop",
"%(brand)s iOS": "%(brand)s iOS",
"%(brand)s X for Android": "%(brand)s X für Android",
- "We’re excited to announce Riot is now Element": "Wir freuen uns bekanntzugeben: Riot ist jetzt Element",
+ "We’re excited to announce Riot is now Element": "Wir freuen uns zu verkünden, dass Riot jetzt Element ist",
"%(brand)s can't securely cache encrypted messages locally while running in a web browser. Use %(brand)s Desktop for encrypted messages to appear in search results.": "%(brand)s kann verschlüsselte Nachrichten nicht sicher zwischenspeichern während es in einem Browser läuft. Verwende %(brand)s Desktop damit verschlüsselte Nachrichten durchsuchbar werden.",
"Show rooms with unread messages first": "Zeige Räume mit ungelesenen Nachrichten zuerst",
"Show previews of messages": "Zeige Vorschau von Nachrichten",
@@ -2361,5 +2361,67 @@
"%(brand)s encountered an error during upload of:": "%(brand)s hat einen Fehler festgestellt beim hochladen von:",
"Use your account to sign in to the latest version of the app at ": "Verwende dein Konto um dich an der neusten Version der App anzumelden",
"We’re excited to announce Riot is now Element!": "Wir freuen uns bekanntzugeben: Riot ist jetzt Element!",
- "Learn more at element.io/previously-riot": "Erfahre mehr unter element.io/previously-riot"
+ "Learn more at element.io/previously-riot": "Erfahre mehr unter element.io/previously-riot",
+ "The person who invited you already left the room.": "Die Person, die dich eingeladen hat, hat den Raum bereits verlassen.",
+ "The person who invited you already left the room, or their server is offline.": "Die Person, die dich eingeladen hat, hat den Raum bereits verlassen oder ihr Server ist offline.",
+ "Change notification settings": "Benachrichtigungseinstellungen ändern",
+ "Your server isn't responding to some requests.": "Dein Server antwortet nicht auf einige Anfragen.",
+ "Go to Element": "Zu Element gehen",
+ "Server isn't responding": "Server antwortet nicht",
+ "Your server isn't responding to some of your requests. Below are some of the most likely reasons.": "Server reagiert nicht auf einige deiner Anfragen. Im Folgenden sind einige der wahrscheinlichsten Gründe aufgeführt.",
+ "The server (%(serverName)s) took too long to respond.": "Der Server (%(serverName)s) brauchte zu lange zum antworten.",
+ "Your firewall or anti-virus is blocking the request.": "Deine Firewall oder Anti-Virus-Programm blockiert die Anfrage.",
+ "A browser extension is preventing the request.": "Eine Browser-Erweiterung verhindert die Anfrage.",
+ "The server is offline.": "Der Server ist offline.",
+ "The server has denied your request.": "Der Server hat deine Anfrage abgewiesen.",
+ "Your area is experiencing difficulties connecting to the internet.": "Deine Region hat Schwierigkeiten, eine Verbindung zum Internet herzustellen.",
+ "A connection error occurred while trying to contact the server.": "Beim Versuch, den Server zu kontaktieren, ist ein Verbindungsfehler aufgetreten.",
+ "You might have configured them in a client other than %(brand)s. You cannot tune them in %(brand)s but they still apply.": "Du hast sie ggf. in einem anderen Client als %(brand)s konfiguriert. Du kannst sie nicht in %(brand)s verändern, aber sie werden trotzdem angewandt.",
+ "Master private key:": "Privater Hauptschlüssel:",
+ "Set the name of a font installed on your system & %(brand)s will attempt to use it.": "Setze den Schriftnamen auf eine in deinem System installierte Schriftart & %(brand)s werden versuchen sie zu verwenden.",
+ "Custom Tag": "Benutzerdefinierter Tag",
+ "You’re already signed in and good to go here, but you can also grab the latest versions of the app on all platforms at element.io/get-started.": "Du bist bereits eingeloggt und kannst loslegen. Allerdings kannst du auch die neuesten Versionen der App für alle Plattformen unter element.io/get-started herunterladen.",
+ "You're all caught up.": "Alles gesichtet.",
+ "The server is not configured to indicate what the problem is (CORS).": "Der Server ist nicht so konfiguriert, dass das Problem angezeigt wird (CORS).",
+ "Recent changes that have not yet been received": "Letzte Änderungen, die noch nicht eingegangen sind",
+ "Set a Security Phrase": "Sicherheitsphrase setzen",
+ "Confirm Security Phrase": "Sicherheitsphrase bestätigen",
+ "Save your Security Key": "Sicherungsschlüssel sichern",
+ "Security Phrase": "Sicherheitsphrase",
+ "Enter your Security Phrase or Use your Security Key to continue.": "Gib deine Sicherheitsphrase ein oder benutze deinen Sicherheitsschlüssel um fortzufahren.",
+ "Security Key": "Sicherheitsschlüssel",
+ "Use your Security Key to continue.": "Benutze deinen Sicherheitsschlüssel um fortzufahren.",
+ "You can use the custom server options to sign into other Matrix servers by specifying a different homeserver URL. This allows you to use %(brand)s with an existing Matrix account on a different homeserver.": "Du kannst in den benutzerdefinierten Server-Optionen eine andere Heimserver URL angeben, um dich bei anderen Matrix Servern anzumelden. Dadurch kannst du %(brand)s mit einem existierenden Matrix-Account auf einem anderen Home-Server nutzen.",
+ "Enter the location of your Element Matrix Services homeserver. It may use your own domain name or be a subdomain of element.io.": "Gib die Adresse deines Element Matrix Services-Heimservers ein. Es kann deine eigene Domain oder eine Subdomain von element.io sein.",
+ "No files visible in this room": "Keine Dateien in diesem Raum",
+ "Attach files from chat or just drag and drop them anywhere in a room.": "Hänge Dateien aus dem Chat an oder ziehe sie einfach per Drag & Drop an eine beliebige Stelle im Raum.",
+ "You’re all caught up": "Alles gesichtet",
+ "You have no visible notifications in this room.": "Du hast keine sichtbaren Benachrichtigungen in diesem Raum.",
+ "Search rooms": "Räume suchen",
+ "%(brand)s Android": "%(brand)s Android",
+ "Safeguard against losing access to encrypted messages & data by backing up encryption keys on your server.": "Schütze dich vor dem Verlust des Zugriffs auf verschlüsselte Nachrichten und Daten, indem du Verschlüsselungsschlüssel auf deinem Server sicherst.",
+ "Generate a Security Key": "Sicherheitsschlüssel generieren",
+ "We’ll generate a Security Key for you to store somewhere safe, like a password manager or a safe.": "Wir generieren einen Sicherheitsschlüssel, den du an einem sicheren Ort wie z. B. in einem Passwort-Manager oder einem Safe aufbewahren kannst.",
+ "Enter a Security Phrase": "Sicherheitsphrase eingeben",
+ "Use a secret phrase only you know, and optionally save a Security Key to use for backup.": "Verwende für deine Sicherung eine geheime Phrase, die nur du kennst, und speichere optional einen Sicherheitsschlüssel.",
+ "Enter a security phrase only you know, as it’s used to safeguard your data. To be secure, you shouldn’t re-use your account password.": "Gibt für deine Datensicherung eine geheime Phrase ein, die nur du kennst. Um sicher zu gehen, benutze nicht dein Account-Passwort.",
+ "Store your Security Key somewhere safe, like a password manager or a safe, as it’s used to safeguard your encrypted data.": "Bewahre deinen Sicherheitsschlüssel an einem sicheren Ort wie z. B. in einem Passwort-Manager oder einem Safe auf. Er wird zum Schutz deiner verschlüsselten Daten verwendet.",
+ "If you cancel now, you may lose encrypted messages & data if you lose access to your logins.": "Wenn du jetzt abbrichst, kannst du verschlüsselte Nachrichten und Daten verlieren, wenn du den Zugriff auf deine Logins verlierst.",
+ "You can also set up Secure Backup & manage your keys in Settings.": "Du kannst auch in den Einstellungen eine Sicherung erstellen & deine Schlüssel verwalten.",
+ "Set up Secure backup": "Sicheres Backup einrichten",
+ "Show message previews for reactions in DMs": "Anzeigen einer Nachrichtenvorschau für Reaktionen in DMs",
+ "Show message previews for reactions in all rooms": "Zeigen Sie eine Nachrichtenvorschau für Reaktionen in allen Räumen an",
+ "Uploading logs": "Protokolle werden hochgeladen",
+ "Downloading logs": "Protokolle werden heruntergeladen",
+ "Explore public rooms": "Erkunde öffentliche Räume",
+ "Can't see what you’re looking for?": "Kannst du nicht finden wonach du suchst?",
+ "Explore all public rooms": "Erkunde alle öffentlichen Räume",
+ "%(count)s results|other": "%(count)s Ergebnisse",
+ "Preparing to download logs": "Bereite das Herunterladen der Protokolle vor",
+ "Download logs": "Protokolle herunterladen",
+ "Unexpected server error trying to leave the room": "Unerwarteter Server-Fehler beim Versuch den Raum zu verlassen",
+ "Error leaving room": "Fehler beim Verlassen des Raums",
+ "Communities v2 prototypes. Requires compatible homeserver. Highly experimental - use with caution.": "Communities v2 Prototyp. Benötigt einen kompatiblen Heimserver. Höchst experimentell - mit Vorsicht verwenden.",
+ "Explore rooms in %(communityName)s": "Erkunde Räume in %(communityName)s",
+ "Set up Secure Backup": "Sicherung einrichten"
}
diff --git a/src/i18n/strings/en_EN.json b/src/i18n/strings/en_EN.json
index 8314402849..bc0845386d 100644
--- a/src/i18n/strings/en_EN.json
+++ b/src/i18n/strings/en_EN.json
@@ -117,10 +117,6 @@
"Unable to enable Notifications": "Unable to enable Notifications",
"This email address was not found": "This email address was not found",
"Your email address does not appear to be associated with a Matrix ID on this Homeserver.": "Your email address does not appear to be associated with a Matrix ID on this Homeserver.",
- "Use your account to sign in to the latest version": "Use your account to sign in to the latest version",
- "We’re excited to announce Riot is now Element": "We’re excited to announce Riot is now Element",
- "Riot is now Element!": "Riot is now Element!",
- "Learn More": "Learn More",
"Sign In or Create Account": "Sign In or Create Account",
"Use your account or create a new one to continue.": "Use your account or create a new one to continue.",
"Create Account": "Create Account",
@@ -351,6 +347,10 @@
"Your browser does not support the required cryptography extensions": "Your browser does not support the required cryptography extensions",
"Not a valid %(brand)s keyfile": "Not a valid %(brand)s keyfile",
"Authentication check failed: incorrect password?": "Authentication check failed: incorrect password?",
+ "Unexpected server error trying to leave the room": "Unexpected server error trying to leave the room",
+ "Can't leave Server Notices room": "Can't leave Server Notices room",
+ "This room is used for important messages from the Homeserver, so you cannot leave it.": "This room is used for important messages from the Homeserver, so you cannot leave it.",
+ "Error leaving room": "Error leaving room",
"Unrecognised address": "Unrecognised address",
"You do not have permission to invite people to this room.": "You do not have permission to invite people to this room.",
"User %(userId)s is already in the room": "User %(userId)s is already in the room",
@@ -444,6 +444,7 @@
"%(senderName)s: %(reaction)s": "%(senderName)s: %(reaction)s",
"%(senderName)s: %(stickerName)s": "%(senderName)s: %(stickerName)s",
"Change notification settings": "Change notification settings",
+ "Communities v2 prototypes. Requires compatible homeserver. Highly experimental - use with caution.": "Communities v2 prototypes. Requires compatible homeserver. Highly experimental - use with caution.",
"New spinner design": "New spinner design",
"Message Pinning": "Message Pinning",
"Custom user status messages": "Custom user status messages",
@@ -452,6 +453,8 @@
"Multiple integration managers": "Multiple integration managers",
"Try out new ways to ignore people (experimental)": "Try out new ways to ignore people (experimental)",
"Support adding custom themes": "Support adding custom themes",
+ "Show message previews for reactions in DMs": "Show message previews for reactions in DMs",
+ "Show message previews for reactions in all rooms": "Show message previews for reactions in all rooms",
"Enable advanced debugging for the room list": "Enable advanced debugging for the room list",
"Show info about bridges in room settings": "Show info about bridges in room settings",
"Font size": "Font size",
@@ -505,7 +508,8 @@
"Enable experimental, compact IRC style layout": "Enable experimental, compact IRC style layout",
"Collecting app version information": "Collecting app version information",
"Collecting logs": "Collecting logs",
- "Uploading report": "Uploading report",
+ "Uploading logs": "Uploading logs",
+ "Downloading logs": "Downloading logs",
"Waiting for response from server": "Waiting for response from server",
"Messages containing my display name": "Messages containing my display name",
"Messages containing my username": "Messages containing my username",
@@ -641,7 +645,8 @@
"Confirm password": "Confirm password",
"Change Password": "Change Password",
"Your homeserver does not support cross-signing.": "Your homeserver does not support cross-signing.",
- "Cross-signing and secret storage are enabled.": "Cross-signing and secret storage are enabled.",
+ "Cross-signing and secret storage are ready for use.": "Cross-signing and secret storage are ready for use.",
+ "Cross-signing is ready for use, but secret storage is currently not being used to backup your keys.": "Cross-signing is ready for use, but secret storage is currently not being used to backup your keys.",
"Your account has a cross-signing identity in secret storage, but it is not yet trusted by this session.": "Your account has a cross-signing identity in secret storage, but it is not yet trusted by this session.",
"Cross-signing and secret storage are not yet set up.": "Cross-signing and secret storage are not yet set up.",
"Reset cross-signing and secret storage": "Reset cross-signing and secret storage",
@@ -653,9 +658,10 @@
"not found": "not found",
"Cross-signing private keys:": "Cross-signing private keys:",
"in secret storage": "in secret storage",
- "Self signing private key:": "Self signing private key:",
+ "Master private key:": "Master private key:",
"cached locally": "cached locally",
"not found locally": "not found locally",
+ "Self signing private key:": "Self signing private key:",
"User signing private key:": "User signing private key:",
"Session backup key:": "Session backup key:",
"Secret storage public key:": "Secret storage public key:",
@@ -1056,6 +1062,7 @@
"and %(count)s others...|other": "and %(count)s others...",
"and %(count)s others...|one": "and one other...",
"Invite to this room": "Invite to this room",
+ "Invite to this community": "Invite to this community",
"Invited": "Invited",
"Filter room members": "Filter room members",
"%(userName)s (power %(powerLevelNumber)s)": "%(userName)s (power %(powerLevelNumber)s)",
@@ -1114,11 +1121,17 @@
"People": "People",
"Start chat": "Start chat",
"Rooms": "Rooms",
- "Create room": "Create room",
+ "Add room": "Add room",
+ "Create new room": "Create new room",
+ "Explore community rooms": "Explore community rooms",
+ "Explore public rooms": "Explore public rooms",
"Low priority": "Low priority",
"System Alerts": "System Alerts",
"Historical": "Historical",
"Custom Tag": "Custom Tag",
+ "Can't see what you’re looking for?": "Can't see what you’re looking for?",
+ "Explore all public rooms": "Explore all public rooms",
+ "%(count)s results|other": "%(count)s results",
"This room": "This room",
"Joining room …": "Joining room …",
"Loading …": "Loading …",
@@ -1171,27 +1184,23 @@
"List options": "List options",
"Jump to first unread room.": "Jump to first unread room.",
"Jump to first invite.": "Jump to first invite.",
- "Add room": "Add room",
"Show %(count)s more|other": "Show %(count)s more",
"Show %(count)s more|one": "Show %(count)s more",
"Use default": "Use default",
"All messages": "All messages",
"Mentions & Keywords": "Mentions & Keywords",
"Notification options": "Notification options",
- "Leave Room": "Leave Room",
"Forget Room": "Forget Room",
"Favourited": "Favourited",
"Favourite": "Favourite",
"Low Priority": "Low Priority",
+ "Leave Room": "Leave Room",
"Room options": "Room options",
"%(count)s unread messages including mentions.|other": "%(count)s unread messages including mentions.",
"%(count)s unread messages including mentions.|one": "1 unread mention.",
"%(count)s unread messages.|other": "%(count)s unread messages.",
"%(count)s unread messages.|one": "1 unread message.",
"Unread messages.": "Unread messages.",
- "This room is public": "This room is public",
- "Away": "Away",
- "Add a topic": "Add a topic",
"Upgrading this room will shut down the current instance of the room and create an upgraded room with the same name.": "Upgrading this room will shut down the current instance of the room and create an upgraded room with the same name.",
"This room has already been upgraded.": "This room has already been upgraded.",
"This room is running room version , which this homeserver has marked as unstable.": "This room is running room version , which this homeserver has marked as unstable.",
@@ -1415,7 +1424,6 @@
"Submit logs": "Submit logs",
"Failed to load group members": "Failed to load group members",
"Filter community members": "Filter community members",
- "Invite to this community": "Invite to this community",
"Are you sure you want to remove '%(roomName)s' from %(groupId)s?": "Are you sure you want to remove '%(roomName)s' from %(groupId)s?",
"Removing a room from the community will also remove it from the community page.": "Removing a room from the community will also remove it from the community page.",
"Failed to remove room from community": "Failed to remove room from community",
@@ -1477,6 +1485,7 @@
"Rotate Right": "Rotate Right",
"Rotate clockwise": "Rotate clockwise",
"Download this file": "Download this file",
+ "Information": "Information",
"Language Dropdown": "Language Dropdown",
"Manage Integrations": "Manage Integrations",
"%(nameList)s %(transitionList)s": "%(nameList)s %(transitionList)s",
@@ -1546,8 +1555,7 @@
"Room directory": "Room directory",
"Sign in with single sign-on": "Sign in with single sign-on",
"And %(count)s more...|other": "And %(count)s more...",
- "ex. @bob:example.com": "ex. @bob:example.com",
- "Add User": "Add User",
+ "Home": "Home",
"Enter a server name": "Enter a server name",
"Looks good": "Looks good",
"Can't find this server or its room list": "Can't find this server or its room list",
@@ -1578,9 +1586,11 @@
"Please tell us what went wrong or, better, create a GitHub issue that describes the problem.": "Please tell us what went wrong or, better, create a GitHub issue that describes the problem.",
"Preparing to send logs": "Preparing to send logs",
"Failed to send logs: ": "Failed to send logs: ",
+ "Preparing to download logs": "Preparing to download logs",
"Reminder: Your browser is unsupported, so your experience may be unpredictable.": "Reminder: Your browser is unsupported, so your experience may be unpredictable.",
"Debug logs contain application usage data including your username, the IDs or aliases of the rooms or groups you have visited and the usernames of other users. They do not contain messages.": "Debug logs contain application usage data including your username, the IDs or aliases of the rooms or groups you have visited and the usernames of other users. They do not contain messages.",
"Before submitting logs, you must create a GitHub issue to describe your problem.": "Before submitting logs, you must create a GitHub issue to describe your problem.",
+ "Download logs": "Download logs",
"GitHub issue": "GitHub issue",
"Notes": "Notes",
"If there is additional context that would help in analysing the issue, such as what you were doing at the time, room IDs, user IDs, etc., please include those things here.": "If there is additional context that would help in analysing the issue, such as what you were doing at the time, room IDs, user IDs, etc., please include those things here.",
@@ -1588,6 +1598,15 @@
"Unable to load commit detail: %(msg)s": "Unable to load commit detail: %(msg)s",
"Unavailable": "Unavailable",
"Changelog": "Changelog",
+ "Email address": "Email address",
+ "Add another email": "Add another email",
+ "People you know on %(brand)s": "People you know on %(brand)s",
+ "Hide": "Hide",
+ "Show": "Show",
+ "Skip": "Skip",
+ "Send %(count)s invites|other": "Send %(count)s invites",
+ "Send %(count)s invites|one": "Send %(count)s invite",
+ "Invite people to join %(communityName)s": "Invite people to join %(communityName)s",
"You cannot delete this message. (%(code)s)": "You cannot delete this message. (%(code)s)",
"Removing…": "Removing…",
"Destroy cross-signing keys?": "Destroy cross-signing keys?",
@@ -1598,6 +1617,15 @@
"Clear all data in this session?": "Clear all data in this session?",
"Clearing all data from this session is permanent. Encrypted messages will be lost unless their keys have been backed up.": "Clearing all data from this session is permanent. Encrypted messages will be lost unless their keys have been backed up.",
"Clear all data": "Clear all data",
+ "There was an error creating your community. The name may be taken or the server is unable to process your request.": "There was an error creating your community. The name may be taken or the server is unable to process your request.",
+ "Community ID: +:%(domain)s": "Community ID: +:%(domain)s",
+ "Use this when referencing your community to others. The community ID cannot be changed.": "Use this when referencing your community to others. The community ID cannot be changed.",
+ "You can change this later if needed.": "You can change this later if needed.",
+ "What's the name of your community or team?": "What's the name of your community or team?",
+ "Enter name": "Enter name",
+ "Create": "Create",
+ "Add image (optional)": "Add image (optional)",
+ "An image will help people identify your community.": "An image will help people identify your community.",
"Community IDs cannot be empty.": "Community IDs cannot be empty.",
"Community IDs may only contain characters a-z, 0-9, or '=_-./'": "Community IDs may only contain characters a-z, 0-9, or '=_-./'",
"Something went wrong whilst creating your community": "Something went wrong whilst creating your community",
@@ -1606,20 +1634,22 @@
"Example": "Example",
"Community ID": "Community ID",
"example": "example",
- "Create": "Create",
"Please enter a name for the room": "Please enter a name for the room",
- "Set a room address to easily share your room with other people.": "Set a room address to easily share your room with other people.",
- "This room is private, and can only be joined by invitation.": "This room is private, and can only be joined by invitation.",
+ "Private rooms can be found and joined by invitation only. Public rooms can be found and joined by anyone.": "Private rooms can be found and joined by invitation only. Public rooms can be found and joined by anyone.",
+ "Private rooms can be found and joined by invitation only. Public rooms can be found and joined by anyone in this community.": "Private rooms can be found and joined by invitation only. Public rooms can be found and joined by anyone in this community.",
"You can’t disable this later. Bridges & most bots won’t work yet.": "You can’t disable this later. Bridges & most bots won’t work yet.",
"Enable end-to-end encryption": "Enable end-to-end encryption",
+ "You might enable this if the room will only be used for collaborating with internal teams on your homeserver. This cannot be changed later.": "You might enable this if the room will only be used for collaborating with internal teams on your homeserver. This cannot be changed later.",
+ "You might disable this if the room will be used for collaborating with external teams who have their own homeserver. This cannot be changed later.": "You might disable this if the room will be used for collaborating with external teams who have their own homeserver. This cannot be changed later.",
"Create a public room": "Create a public room",
"Create a private room": "Create a private room",
+ "Create a room in %(communityName)s": "Create a room in %(communityName)s",
"Name": "Name",
"Topic (optional)": "Topic (optional)",
"Make this room public": "Make this room public",
"Hide advanced": "Hide advanced",
"Show advanced": "Show advanced",
- "Block users on other matrix homeservers from joining this room (This setting cannot be changed later!)": "Block users on other matrix homeservers from joining this room (This setting cannot be changed later!)",
+ "Block anyone not part of %(serverName)s from ever joining this room.": "Block anyone not part of %(serverName)s from ever joining this room.",
"Create Room": "Create Room",
"Sign out": "Sign out",
"To avoid losing your chat history, you must export your room keys before logging out. You will need to go back to the newer version of %(brand)s to do this": "To avoid losing your chat history, you must export your room keys before logging out. You will need to go back to the newer version of %(brand)s to do this",
@@ -1654,6 +1684,8 @@
"Verification Requests": "Verification Requests",
"Toolbox": "Toolbox",
"Developer Tools": "Developer Tools",
+ "There was an error updating your community. The server is unable to process your request.": "There was an error updating your community. The server is unable to process your request.",
+ "Update community": "Update community",
"An error has occurred.": "An error has occurred.",
"Verify this user to mark them as trusted. Trusting users gives you extra peace of mind when using end-to-end encrypted messages.": "Verify this user to mark them as trusted. Trusting users gives you extra peace of mind when using end-to-end encrypted messages.",
"Verifying this user will mark their session as trusted, and also mark your session as trusted to them.": "Verifying this user will mark their session as trusted, and also mark your session as trusted to them.",
@@ -1676,9 +1708,11 @@
"The following users might not exist or are invalid, and cannot be invited: %(csvNames)s": "The following users might not exist or are invalid, and cannot be invited: %(csvNames)s",
"Recent Conversations": "Recent Conversations",
"Suggestions": "Suggestions",
+ "May include members not in %(communityName)s": "May include members not in %(communityName)s",
"Recently Direct Messaged": "Recently Direct Messaged",
"Direct Messages": "Direct Messages",
"Start a conversation with someone using their name, username (like ) or email address.": "Start a conversation with someone using their name, username (like ) or email address.",
+ "Start a conversation with someone using their name, username (like ) or email address. This won't invite them to %(communityName)s. To invite someone to %(communityName)s, click here.": "Start a conversation with someone using their name, username (like ) or email address. This won't invite them to %(communityName)s. To invite someone to %(communityName)s, click here.",
"Go": "Go",
"Invite someone using their name, username (like ), email address or share this room.": "Invite someone using their name, username (like ), email address or share this room.",
"a new master key signature": "a new master key signature",
@@ -1719,11 +1753,6 @@
"Use this session to verify your new one, granting it access to encrypted messages:": "Use this session to verify your new one, granting it access to encrypted messages:",
"If you didn’t sign in to this session, your account may be compromised.": "If you didn’t sign in to this session, your account may be compromised.",
"This wasn't me": "This wasn't me",
- "Use your account to sign in to the latest version of the app at ": "Use your account to sign in to the latest version of the app at ",
- "You’re already signed in and good to go here, but you can also grab the latest versions of the app on all platforms at element.io/get-started.": "You’re already signed in and good to go here, but you can also grab the latest versions of the app on all platforms at element.io/get-started.",
- "Go to Element": "Go to Element",
- "We’re excited to announce Riot is now Element!": "We’re excited to announce Riot is now Element!",
- "Learn more at element.io/previously-riot": "Learn more at element.io/previously-riot",
"If you run into any bugs or have feedback you'd like to share, please let us know on GitHub.": "If you run into any bugs or have feedback you'd like to share, please let us know on GitHub.",
"To help avoid duplicate issues, please view existing issues first (and add a +1) or create a new issue if you can't find it.": "To help avoid duplicate issues, please view existing issues first (and add a +1) or create a new issue if you can't find it.",
"Report bugs & give feedback": "Report bugs & give feedback",
@@ -1770,9 +1799,7 @@
"Clearing your browser's storage may fix the problem, but will sign you out and cause any encrypted chat history to become unreadable.": "Clearing your browser's storage may fix the problem, but will sign you out and cause any encrypted chat history to become unreadable.",
"Verification Pending": "Verification Pending",
"Please check your email and click on the link it contains. Once this is done, click continue.": "Please check your email and click on the link it contains. Once this is done, click continue.",
- "Email address": "Email address",
"This will allow you to reset your password and receive notifications.": "This will allow you to reset your password and receive notifications.",
- "Skip": "Skip",
"A username can only contain lower case letters, numbers and '=_-./'": "A username can only contain lower case letters, numbers and '=_-./'",
"Username not available": "Username not available",
"Username invalid: %(errMessage)s": "Username invalid: %(errMessage)s",
@@ -1795,7 +1822,7 @@
"Share Community": "Share Community",
"Share Room Message": "Share Room Message",
"Link to selected message": "Link to selected message",
- "COPY": "COPY",
+ "Copy": "Copy",
"Command Help": "Command Help",
"To help us prevent this in future, please send us logs.": "To help us prevent this in future, please send us logs.",
"Missing session data": "Missing session data",
@@ -1860,10 +1887,6 @@
"Warning: You should only set up key backup from a trusted computer.": "Warning: You should only set up key backup from a trusted computer.",
"Access your secure message history and set up secure messaging by entering your recovery key.": "Access your secure message history and set up secure messaging by entering your recovery key.",
"If you've forgotten your recovery key you can set up new recovery options": "If you've forgotten your recovery key you can set up new recovery options",
- "Private Chat": "Private Chat",
- "Public Chat": "Public Chat",
- "Custom": "Custom",
- "Address (optional)": "Address (optional)",
"Reject invitation": "Reject invitation",
"Are you sure you want to reject the invitation?": "Are you sure you want to reject the invitation?",
"Unable to reject invite": "Unable to reject invite",
@@ -1880,27 +1903,17 @@
"Source URL": "Source URL",
"Collapse Reply Thread": "Collapse Reply Thread",
"Report Content": "Report Content",
- "Failed to set Direct Message status of room": "Failed to set Direct Message status of room",
- "Failed to forget room %(errCode)s": "Failed to forget room %(errCode)s",
- "Notification settings": "Notification settings",
- "All messages (noisy)": "All messages (noisy)",
- "Mentions only": "Mentions only",
- "Leave": "Leave",
- "Forget": "Forget",
- "Direct Chat": "Direct Chat",
"Clear status": "Clear status",
"Update status": "Update status",
"Set status": "Set status",
"Set a new status...": "Set a new status...",
"View Community": "View Community",
- "Hide": "Hide",
- "Home": "Home",
- "Sign in": "Sign in",
- "Help": "Help",
"Reload": "Reload",
"Take picture": "Take picture",
"Remove for everyone": "Remove for everyone",
"Remove for me": "Remove for me",
+ "This room is public": "This room is public",
+ "Away": "Away",
"User Status": "User Status",
"powered by Matrix": "powered by Matrix",
"This homeserver would like to make sure you are not a robot.": "This homeserver would like to make sure you are not a robot.",
@@ -1935,6 +1948,7 @@
"Phone": "Phone",
"Not sure of your password? Set a new one": "Not sure of your password? Set a new one",
"Sign in with": "Sign in with",
+ "Sign in": "Sign in",
"No identity server is configured so you cannot add an email address in order to reset your password in the future.": "No identity server is configured so you cannot add an email address in order to reset your password in the future.",
"If you don't specify an email address, you won't be able to reset your password. Are you sure?": "If you don't specify an email address, you won't be able to reset your password. Are you sure?",
"Use an email address to recover your account": "Use an email address to recover your account",
@@ -1966,11 +1980,6 @@
"Sign in to your Matrix account on %(serverName)s": "Sign in to your Matrix account on %(serverName)s",
"Sign in to your Matrix account on ": "Sign in to your Matrix account on ",
"Sign in with SSO": "Sign in with SSO",
- "Sorry, your browser is not able to run %(brand)s.": "Sorry, your browser is not able to run %(brand)s.",
- "%(brand)s uses many advanced browser features, some of which are not available or experimental in your current browser.": "%(brand)s uses many advanced browser features, some of which are not available or experimental in your current browser.",
- "Please install Chrome, Firefox, or Safari for the best experience.": "Please install Chrome, Firefox, or Safari for the best experience.",
- "With your current browser, the look and feel of the application may be completely incorrect, and some or all features may not function. If you want to try it anyway you can continue, but you are on your own in terms of any issues you may encounter!": "With your current browser, the look and feel of the application may be completely incorrect, and some or all features may not function. If you want to try it anyway you can continue, but you are on your own in terms of any issues you may encounter!",
- "I understand the risks and wish to continue": "I understand the risks and wish to continue",
"Couldn't load page": "Couldn't load page",
"You must register to use this functionality": "You must register to use this functionality",
"You must join the room to see its files": "You must join the room to see its files",
@@ -1997,6 +2006,7 @@
"You are an administrator of this community. You will not be able to rejoin without an invite from another administrator.": "You are an administrator of this community. You will not be able to rejoin without an invite from another administrator.",
"Leave Community": "Leave Community",
"Leave %(groupName)s?": "Leave %(groupName)s?",
+ "Leave": "Leave",
"Unable to leave community": "Unable to leave community",
"Community Settings": "Community Settings",
"Want more than a community? Get your own server": "Want more than a community? Get your own server",
@@ -2027,10 +2037,7 @@
"Failed to reject invitation": "Failed to reject invitation",
"This room is not public. You will not be able to rejoin without an invite.": "This room is not public. You will not be able to rejoin without an invite.",
"Are you sure you want to leave the room '%(roomName)s'?": "Are you sure you want to leave the room '%(roomName)s'?",
- "Failed to leave room": "Failed to leave room",
- "Can't leave Server Notices room": "Can't leave Server Notices room",
- "This room is used for important messages from the Homeserver, so you cannot leave it.": "This room is used for important messages from the Homeserver, so you cannot leave it.",
- "Unknown error": "Unknown error",
+ "Failed to forget room %(errCode)s": "Failed to forget room %(errCode)s",
"Signed Out": "Signed Out",
"For security, this session has been signed out. Please sign in again.": "For security, this session has been signed out. Please sign in again.",
"Terms and Conditions": "Terms and Conditions",
@@ -2070,6 +2077,7 @@
"Find a room…": "Find a room…",
"Find a room… (e.g. %(exampleRoom)s)": "Find a room… (e.g. %(exampleRoom)s)",
"If you can't find the room you're looking for, ask for an invite or Create a new room.": "If you can't find the room you're looking for, ask for an invite or Create a new room.",
+ "Explore rooms in %(communityName)s": "Explore rooms in %(communityName)s",
"Clear filter": "Clear filter",
"Search rooms": "Search rooms",
"You can't send any messages until you review and agree to our terms and conditions.": "You can't send any messages until you review and agree to our terms and conditions.",
@@ -2096,19 +2104,25 @@
"Click to mute video": "Click to mute video",
"Click to unmute audio": "Click to unmute audio",
"Click to mute audio": "Click to mute audio",
+ "Create community": "Create community",
"Tried to load a specific point in this room's timeline, but you do not have permission to view the message in question.": "Tried to load a specific point in this room's timeline, but you do not have permission to view the message in question.",
"Tried to load a specific point in this room's timeline, but was unable to find it.": "Tried to load a specific point in this room's timeline, but was unable to find it.",
"Failed to load timeline position": "Failed to load timeline position",
"Uploading %(filename)s and %(count)s others|other": "Uploading %(filename)s and %(count)s others",
"Uploading %(filename)s and %(count)s others|zero": "Uploading %(filename)s",
"Uploading %(filename)s and %(count)s others|one": "Uploading %(filename)s and %(count)s other",
- "Switch to light mode": "Switch to light mode",
- "Switch to dark mode": "Switch to dark mode",
- "Switch theme": "Switch theme",
+ "Failed to find the general chat for this community": "Failed to find the general chat for this community",
+ "Notification settings": "Notification settings",
"Security & privacy": "Security & privacy",
"All settings": "All settings",
"Feedback": "Feedback",
+ "Community settings": "Community settings",
+ "User settings": "User settings",
+ "Switch to light mode": "Switch to light mode",
+ "Switch to dark mode": "Switch to dark mode",
+ "Switch theme": "Switch theme",
"User menu": "User menu",
+ "Community and user menu": "Community and user menu",
"Could not load user profile": "Could not load user profile",
"Verify this login": "Verify this login",
"Session verified": "Session verified",
@@ -2171,7 +2185,7 @@
"%(brand)s Web": "%(brand)s Web",
"%(brand)s Desktop": "%(brand)s Desktop",
"%(brand)s iOS": "%(brand)s iOS",
- "%(brand)s X for Android": "%(brand)s X for Android",
+ "%(brand)s Android": "%(brand)s Android",
"or another cross-signing capable Matrix client": "or another cross-signing capable Matrix client",
"Your new session is now verified. It has access to your encrypted messages, and other users will see it as trusted.": "Your new session is now verified. It has access to your encrypted messages, and other users will see it as trusted.",
"Your new session is now verified. Other users will see it as trusted.": "Your new session is now verified. Other users will see it as trusted.",
@@ -2202,6 +2216,7 @@
"User Autocomplete": "User Autocomplete",
"Passphrases must match": "Passphrases must match",
"Passphrase must not be empty": "Passphrase must not be empty",
+ "Unknown error": "Unknown error",
"Export room keys": "Export room keys",
"This process allows you to export the keys for messages you have received in encrypted rooms to a local file. You will then be able to import the file into another Matrix client in the future, so that client will also be able to decrypt these messages.": "This process allows you to export the keys for messages you have received in encrypted rooms to a local file. You will then be able to import the file into another Matrix client in the future, so that client will also be able to decrypt these messages.",
"The exported file will allow anyone who can read it to decrypt any encrypted messages that you can see, so you should be careful to keep it secure. To help with this, you should enter a passphrase below, which will be used to encrypt the exported data. It will only be possible to import the data by using the same passphrase.": "The exported file will allow anyone who can read it to decrypt any encrypted messages that you can see, so you should be careful to keep it secure. To help with this, you should enter a passphrase below, which will be used to encrypt the exported data. It will only be possible to import the data by using the same passphrase.",
@@ -2236,12 +2251,11 @@
"Confirm your recovery passphrase": "Confirm your recovery passphrase",
"Store your Security Key somewhere safe, like a password manager or a safe, as it’s used to safeguard your encrypted data.": "Store your Security Key somewhere safe, like a password manager or a safe, as it’s used to safeguard your encrypted data.",
"Download": "Download",
- "Copy": "Copy",
"Unable to query secret storage status": "Unable to query secret storage status",
"Retry": "Retry",
"If you cancel now, you may lose encrypted messages & data if you lose access to your logins.": "If you cancel now, you may lose encrypted messages & data if you lose access to your logins.",
"You can also set up Secure Backup & manage your keys in Settings.": "You can also set up Secure Backup & manage your keys in Settings.",
- "Set up Secure backup": "Set up Secure backup",
+ "Set up Secure Backup": "Set up Secure Backup",
"Upgrade your encryption": "Upgrade your encryption",
"Set a Security Phrase": "Set a Security Phrase",
"Confirm Security Phrase": "Confirm Security Phrase",
diff --git a/src/i18n/strings/eo.json b/src/i18n/strings/eo.json
index 8d07db7eaf..aec575b8b4 100644
--- a/src/i18n/strings/eo.json
+++ b/src/i18n/strings/eo.json
@@ -858,7 +858,7 @@
"Gift": "Donaco",
"Light bulb": "Lampo",
"Book": "Libro",
- "Pencil": "Grifelo",
+ "Pencil": "Krajono",
"Scissors": "Tondilo",
"Key": "Ŝlosilo",
"Hammer": "Martelo",
@@ -2387,5 +2387,25 @@
"Enable advanced debugging for the room list": "Ŝalti altnivelan erarserĉadon por la ĉambrobreto",
"* %(senderName)s %(emote)s": "* %(senderName)s %(emote)s",
"Custom Tag": "Propra etikedo",
- "Feedback": "Prikomenti"
+ "Feedback": "Prikomenti",
+ "The person who invited you already left the room.": "La persono, kiu vin invitis, jam foriris de la ĉambro.",
+ "The person who invited you already left the room, or their server is offline.": "Aŭ la persono, kiu vin invitis, jam foriris de la ĉambro, aŭ ĝia servilo estas eksterreta.",
+ "Change notification settings": "Ŝanĝi agordojn pri sciigoj",
+ "Show message previews for reactions in DMs": "Montri antaŭrigardojn al mesaĝoj ĉe reagoj en rektaj ĉambroj",
+ "Show message previews for reactions in all rooms": "Montri antaŭrigardojn al mesaĝoj ĉe reagoj en ĉiuj ĉambroj",
+ "Your server isn't responding to some requests.": "Via servilo ne respondas al iuj petoj.",
+ "Server isn't responding": "Servilo ne respondas",
+ "Your server isn't responding to some of your requests. Below are some of the most likely reasons.": "Via servilo ne respondas al iuj el viaj petoj. Vidu sube kelkon de la plej probablaj kialoj.",
+ "The server (%(serverName)s) took too long to respond.": "La servilo (%(serverName)s) tro longe ne respondis.",
+ "Your firewall or anti-virus is blocking the request.": "Via fajroŝirmilo aŭ kontraŭvirusilo blokas la peton.",
+ "A browser extension is preventing the request.": "Kromprogramo de la foliumilo malhelpas la peton.",
+ "The server is offline.": "La servilo estas eksterreta.",
+ "The server has denied your request.": "La servilo rifuzis vian peton.",
+ "Your area is experiencing difficulties connecting to the internet.": "Via loko nun havas problemojn pri interreta konekto.",
+ "A connection error occurred while trying to contact the server.": "Eraris konekto dum provo kontakti la servilon.",
+ "The server is not configured to indicate what the problem is (CORS).": "La servilo ne estas agordita por indiki la problemon (CORS).",
+ "Recent changes that have not yet been received": "Freŝaj ŝanĝoj ankoraŭ ne ricevitaj",
+ "No files visible in this room": "Neniuj dosieroj videblas en ĉi tiu ĉambro",
+ "You have no visible notifications in this room.": "Vi havas neniujn videblajn sciigojn en ĉi tiu ĉambro.",
+ "%(brand)s Android": "%(brand)s por Android"
}
diff --git a/src/i18n/strings/et.json b/src/i18n/strings/et.json
index 271893b862..8a0ba7f54b 100644
--- a/src/i18n/strings/et.json
+++ b/src/i18n/strings/et.json
@@ -170,7 +170,7 @@
"Are you sure you want to remove %(serverName)s": "Kas sa oled kindel et soovid eemadlada %(serverName)s",
"Remove server": "Eemalda server",
"%(networkName)s rooms": "%(networkName)s jututoad",
- "Are you sure you wish to remove (delete) this event? Note that if you delete a room name or topic change, it could undo the change.": "Kas sa oled kindel et soovid eemaldada (kustutada) seda sündmust? Pane tähele, et see muutus võib tagasi pöörduda, kui muudad hiljem jututoa nime või teemanime.",
+ "Are you sure you wish to remove (delete) this event? Note that if you delete a room name or topic change, it could undo the change.": "Kas sa oled kindel et soovid eemaldada (kustutada) seda sündmust? Pane tähele, et see muutus võib tagasi pöörduda, kui muudad hiljem jututoa nime või teema nime.",
"Sign out and remove encryption keys?": "Logi välja ja eemalda krüptimisvõtmed?",
"Upload files (%(current)s of %(total)s)": "Lae failid üles (%(current)s / %(total)s)",
"Upload files": "Lae failid üles",
@@ -198,7 +198,7 @@
"Leave": "Lahku",
"Forget": "Unusta",
"Favourite": "Lemmik",
- "Low Priority": "Madal prioriteet",
+ "Low Priority": "Vähetähtis",
"Direct Chat": "Otsevestlus",
"Clear status": "Eemalda olek",
"Update status": "Uuenda olek",
@@ -419,7 +419,7 @@
"Loading …": "Laen …",
"e.g. %(exampleValue)s": "näiteks %(exampleValue)s",
"Could not find user in room": "Jututoast ei leidnud kasutajat",
- "Show timestamps in 12 hour format (e.g. 2:30pm)": "Näita ajatempleid 12-tunnises vomingus (näiteks 2:30pl)",
+ "Show timestamps in 12 hour format (e.g. 2:30pm)": "Näita ajatempleid 12-tunnises vormingus (näiteks 2:30pl)",
"New published address (e.g. #alias:server)": "Uus avaldatud aadess (näiteks #alias:server)",
"New community ID (e.g. +foo:%(localDomain)s)": "Uus kogukonna tunnus (näiteks +midagi:%(localDomain)s)",
"e.g. my-room": "näiteks minu-jututuba",
@@ -512,7 +512,7 @@
"%(senderName)s placed a voice call. (not supported by this browser)": "%(senderName)s alustas häälkõnet. (sellel brauseril puudub niisuguste kõnede tugi)",
"%(senderName)s placed a video call.": "%(senderName)s alustas videokõnet.",
"%(senderName)s placed a video call. (not supported by this browser)": "%(senderName)s alustas videokõnet. (sellel brauseril puudub niisuguste kõnede tugi)",
- "%(senderDisplayName)s made the room invite only.": "%(senderDisplayName)s määras et jututuppa pääseb vaid kutsega.",
+ "%(senderDisplayName)s made the room invite only.": "%(senderDisplayName)s määras, et jututuppa pääseb vaid kutsega.",
"%(senderDisplayName)s changed the join rule to %(rule)s": "%(senderDisplayName)s muutis liitumisreeglid järgnevaks - %(rule)s",
"%(senderDisplayName)s has allowed guests to join the room.": "%(senderDisplayName)s on lubanud külalistel jututoaga liituda.",
"%(senderDisplayName)s has prevented guests from joining the room.": "%(senderDisplayName)s on määranud et külalised ei saa jututoaga liituda.",
@@ -607,7 +607,7 @@
"We've sent you an email to verify your address. Please follow the instructions there and then click the button below.": "Sinu aadressi kontrollimiseks saatsime sulle e-kirja. Palun järgi kirjas näidatud juhendit ja siis klõpsi alljärgnevat nuppu.",
"Email Address": "E-posti aadress",
"A text message has been sent to +%(msisdn)s. Please enter the verification code it contains.": "Saatsime tekstisõnumi numbrile +%(msisdn)s. Palun sisesta seal kuvatud kontrollkood.",
- "Phone Number": "Telefoni number",
+ "Phone Number": "Telefoninumber",
"Cannot add any more widgets": "Rohkem vidinaid ei õnnestu lisada",
"The maximum permitted number of widgets have already been added to this room.": "Suurim lubatud vidinate arv on siia jututuppa juba lisatud.",
"Join as voice or video.": "Liitu kas häälkõnega või videokõnega.",
@@ -650,7 +650,7 @@
"Where you’re logged in": "Kus sa oled võrku loginud",
"Manage the names of and sign out of your sessions below or verify them in your User Profile.": "Halda alljärgnevas oma sessioonide nimesid, logi neist välja või verifitseeri neid oma kasutajaprofiilis.",
"A session's public name is visible to people you communicate with": "Sessiooni avalik nimi on nähtav neile, kellega sa suhtled",
- "%(brand)s collects anonymous analytics to allow us to improve the application.": "Võimaldamaks meil rakendust parandada kogub %(brand)s anonüümset analüütikat.",
+ "%(brand)s collects anonymous analytics to allow us to improve the application.": "Võimaldamaks meil rakendust parandada kogub %(brand)s anonüümset teavet rakenduse kasutuse kohta.",
"Privacy is important to us, so we don't collect any personal or identifiable data for our analytics.": "Privaatsus on meile oluline ning seega me ei kogu ei isiklikke ega isikustatavaid andmeid.",
"Learn more about how we use analytics.": "Loe lisaks kuidas me kasutama analüütikat.",
"No media permissions": "Meediaõigused puuduvad",
@@ -792,7 +792,7 @@
"Verified!": "Verifitseeritud!",
"You've successfully verified this user.": "Sa oled edukalt verifitseerinud selle kasutaja.",
"Secure messages with this user are end-to-end encrypted and not able to be read by third parties.": "Turvalised sõnumid selle kasutajaga on läbivalt krüptitud ning kolmandad osapooled ei saa neid lugeda.",
- "Got It": "Saan aru",
+ "Got It": "Selge lugu",
"Scan this unique code": "Skaneeri seda unikaalset koodi",
"or": "või",
"Compare unique emoji": "Võrdle unikaalseid emoji'sid",
@@ -839,7 +839,7 @@
"Heart": "Süda",
"Smiley": "Smaili",
"Robot": "Robot",
- "Hat": "Müts",
+ "Hat": "Kübar",
"Glasses": "Prillid",
"Spanner": "Mutrivõti",
"Santa": "Jõuluvana",
@@ -870,7 +870,7 @@
"Anchor": "Ankur",
"Headphones": "Kõrvaklapid",
"Folder": "Kaust",
- "Pin": "Knopka",
+ "Pin": "Nööpnõel",
"Verify all your sessions to ensure your account & messages are safe": "Selleks et sinu konto ja sõnumid oleks turvatud, verifitseeri kõik oma sessioonid",
"Later": "Hiljem",
"Review": "Vaata üle",
@@ -1009,7 +1009,7 @@
"You are a member of this community": "Sa oled kogukonna liige",
"Who can join this community?": "Kes võib liituda selle kogukonnaga?",
"Everyone": "Kes iganes soovib",
- "Your community hasn't got a Long Description, a HTML page to show to community members. Click here to open settings and give it one!": "Sinu kogukonnal on puudu pikk kirjeldus, mis pole muud kui lihtne HTML-leht, mida kuvatakse liikmetele. Klõpsi siia ja loo selline leht!",
+ "Your community hasn't got a Long Description, a HTML page to show to community members. Click here to open settings and give it one!": "Sinu kogukonnal on puudu pikk kirjeldus, mis pole muud, kui lihtne HTML-leht, mida kuvatakse liikmetele. Klõpsi siia ja loo selline leht!",
"Long Description (HTML)": "Pikk kirjeldus (HTML)",
"Upload avatar": "Lae üles profiilipilt ehk avatar",
"Description": "Kirjeldus",
@@ -1025,7 +1025,7 @@
"Permissions": "Õigused",
"Select the roles required to change various parts of the room": "Vali rollid, mis on vajalikud jututoa eri osade muutmiseks",
"Enable encryption?": "Kas võtame krüptimise kasutusele?",
- "Once enabled, encryption for a room cannot be disabled. Messages sent in an encrypted room cannot be seen by the server, only by the participants of the room. Enabling encryption may prevent many bots and bridges from working correctly. Learn more about encryption.": "Kui kord juba kasutusele võetud, siis krüptimist enam hiljem ära lõpetada ei saa. Krüptitud sõnumeid ei saa lugeda ei vaheapealses veebiliikluses ega serveris ja vaid jututoa liikmed saavad neid lugeda. Krüptimise kasutusele võtmine takistada nii robotite kui sõnumisildade tööd. Lisateave krüptimise kohta.",
+ "Once enabled, encryption for a room cannot be disabled. Messages sent in an encrypted room cannot be seen by the server, only by the participants of the room. Enabling encryption may prevent many bots and bridges from working correctly. Learn more about encryption.": "Kui kord juba kasutusele võetud, siis krüptimist enam hiljem ära lõpetada ei saa. Krüptitud sõnumeid ei saa lugeda ei vaheapealses veebiliikluses ega serveris ja vaid jututoa liikmed saavad neid lugeda. Krüptimise kasutusele võtmine võib takistada nii robotite kui sõnumisildade tööd. Lisateave krüptimise kohta.",
"Guests cannot join this room even if explicitly invited.": "Külalised ei saa selle jututoaga liituda ka siis, kui neid on otseselt kutsutud.",
"Click here to fix": "Parandamiseks klõpsi siia",
"Server error": "Serveri viga",
@@ -1334,7 +1334,7 @@
"If you cancel now, you won't complete your operation.": "Kui sa katkestad nüüd, siis sul jääb pooleliolev tegevus lõpetamata.",
"Cancel entering passphrase?": "Kas katkestame paroolifraasi sisestamise?",
"Enter passphrase": "Sisesta paroolifraas",
- "Setting up keys": "Võtamevõtmed kasutusele",
+ "Setting up keys": "Võtame krüptovõtmed kasutusele",
"Room name or address": "Jututoa nimi või aadress",
"Unable to enable Notifications": "Teavituste kasutusele võtmine ei õnnestunud",
"This email address was not found": "Seda e-posti aadressi ei leidunud",
@@ -1918,7 +1918,7 @@
"You don't have permission to delete the address.": "Sinul pole õigusi selle aadressi kustutamiseks.",
"There was an error removing that address. It may no longer exist or a temporary error occurred.": "Selle aadressi kustutamisel tekkis viga. See kas juba on kustutatud või tekkis ajutine tõrge.",
"Error removing address": "Viga aadresi kustutamisel",
- "This room has no local addresses": "Sellel jututoal puudub kohalik aadress",
+ "This room has no local addresses": "Sellel jututoal puuduvad kohalikud aadressid",
"Local address": "Kohalik aadress",
"Published Addresses": "Avaldatud aadressid",
"Published addresses can be used by anyone on any server to join your room. To publish an address, it needs to be set as a local address first.": "Avaldatud aadresse saab mis iganes serveri kasutaja pruukida sinu jututoaga liitumiseks. Aadressi avaldamiseks peab ta alustuseks olema määratud kohaliku aadressina.",
@@ -2126,7 +2126,7 @@
"Restore": "Taasta",
"You'll need to authenticate with the server to confirm the upgrade.": "Uuenduse kinnitamiseks pead end autentima serveris.",
"Upgrade this session to allow it to verify other sessions, granting them access to encrypted messages and marking them as trusted for other users.": "Teiste sessioonide verifitseerimiseks pead uuendama seda sessiooni. Muud verifitseeritud sessioonid saavad sellega ligipääsu krüptitud sõnumitele ning nad märgitakse usaldusväärseteks ka teiste kasutajate jaoks.",
- "Enter a security phrase only you know, as it’s used to safeguard your data. To be secure, you shouldn’t re-use your account password.": "Andmete kaitsmiseks sisesta turvafraas, mida vaid sina tead. On mõistlik ja palun ära kasuta selleks oma tavalist konto salasõna.",
+ "Enter a security phrase only you know, as it’s used to safeguard your data. To be secure, you shouldn’t re-use your account password.": "Andmete kaitsmiseks sisesta turvafraas, mida vaid sina tead. Ole mõistlik ja palun ära kasuta selleks oma tavalist konto salasõna.",
"Enter a recovery passphrase": "Sisesta taastamiseks mõeldud paroolifraas",
"Great! This recovery passphrase looks strong enough.": "Suurepärane! Taastamiseks mõeldud paroolifraas on piisavalt kange.",
"That matches!": "Klapib!",
@@ -2140,7 +2140,7 @@
"If you cancel now, you may lose encrypted messages & data if you lose access to your logins.": "Kui sa tühistad nüüd, siis sa võid peale viimasest seadmest välja logimist kaotada ligipääsu oma krüptitud sõnumitele ja andmetele.",
"You can also set up Secure Backup & manage your keys in Settings.": "Samuti võid sa seadetes võtta kasutusse turvalise varunduse ning hallata oma krüptovõtmeid.",
"Set up Secure backup": "Võta kasutusele turvaline varundus",
- "Set a Security Phrase": "Sisesta turvafraas",
+ "Set a Security Phrase": "Määra turvafraas",
"Confirm Security Phrase": "Kinnita turvafraas",
"Save your Security Key": "Salvesta turvavõti",
"Unable to set up secret storage": "Turvahoidla kasutuselevõtmine ei õnnestu",
@@ -2289,8 +2289,8 @@
"All keys backed up": "Kõik krüptovõtmed on varundatud",
"Backup has a valid signature from this user": "Varukoopial on selle kasutaja kehtiv allkiri",
"Backup has a invalid signature from this user": "Varukoopial on selle kasutaja vigane allkiri",
- "Backup has a signature from unknown user with ID %(deviceId)s": "Varukoopial tundmatu kasutaja allkiri seadme tunnusega %(deviceId)s",
- "Backup has a signature from unknown session with ID %(deviceId)s": "Varukoopial tundmatu sessiooni allkiri seadme tunnusega %(deviceId)s",
+ "Backup has a signature from unknown user with ID %(deviceId)s": "Varukoopial on tundmatu kasutaja allkiri seadme tunnusega %(deviceId)s",
+ "Backup has a signature from unknown session with ID %(deviceId)s": "Varukoopial on tundmatu sessiooni allkiri seadme tunnusega %(deviceId)s",
"Backup has a valid signature from this session": "Varukoopial on selle sessiooni kehtiv allkiri",
"Backup has an invalid signature from this session": "Varukoopial on selle sessiooni vigane allkiri",
"Backup is not signed by any of your sessions": "Varunduse andmetel pole mitte ühegi sinu sessiooni allkirja",
@@ -2385,5 +2385,45 @@
"Set up Secure Message Recovery": "Võta kasutusele turvaline sõnumivõtmete varundus",
"Secure your backup with a recovery passphrase": "Krüpti oma varukoopia taastamiseks mõeldud paroolifraasiga",
"The person who invited you already left the room.": "See, kes sind jututoa liikmeks kutsus, on juba jututoast lahkunud.",
- "The person who invited you already left the room, or their server is offline.": "See, kes sind jututoa liikmeks kutsus, kas juba on jututoast lahkunud või tema koduserver on võrgust väljas."
+ "The person who invited you already left the room, or their server is offline.": "See, kes sind jututoa liikmeks kutsus, kas juba on jututoast lahkunud või tema koduserver on võrgust väljas.",
+ "Change notification settings": "Muuda teavituste seadistusi",
+ "Your server isn't responding to some requests.": "Sinu koduserver ei vasta mõnedele päringutele.",
+ "Server isn't responding": "Server ei vasta päringutele",
+ "Your server isn't responding to some of your requests. Below are some of the most likely reasons.": "Sinu koduserver ei vasta mõnedele sinu päringutele. Alljärgnevalt on mõned võimalikud põhjused.",
+ "The server (%(serverName)s) took too long to respond.": "Vastuseks serverist %(serverName)s kulus liiga palju aega.",
+ "Your firewall or anti-virus is blocking the request.": "Sinu tulemüür või viirusetõrjetarkvara blokeerib päringuid.",
+ "A browser extension is preventing the request.": "Brauserilaiendus takistab päringuid.",
+ "The server is offline.": "Serveril puudub võrguühendus või ta on lülitatud välja.",
+ "The server has denied your request.": "Server blokeerib sinu päringuid.",
+ "Your area is experiencing difficulties connecting to the internet.": "Sinu piirkonnas on tõrkeid internetiühenduses.",
+ "A connection error occurred while trying to contact the server.": "Serveriga ühenduse algatamisel tekkis viga.",
+ "The server is not configured to indicate what the problem is (CORS).": "Server on seadistatud varjama tegelikke veapõhjuseid (CORS).",
+ "No files visible in this room": "Selles jututoas pole nähtavaid faile",
+ "Attach files from chat or just drag and drop them anywhere in a room.": "Faile saad manueks lisada kas vastava nupu alt vestlusest või sikutades neid jututoa aknasse.",
+ "You have no visible notifications in this room.": "Jututoas pole nähtavaid teavitusi.",
+ "You're all caught up.": "Ei tea... kõik vist on nüüd tehtud.",
+ "You’re all caught up": "Ei tea... kõik vist on nüüd tehtud",
+ "%(brand)s Android": "%(brand)s Android",
+ "Show message previews for reactions in DMs": "Näita eelvaates otsesõnumitele regeerimisi",
+ "Show message previews for reactions in all rooms": "Näita kõikides jututubades eelvaadetes sõnumitele regeerimisi",
+ "Master private key:": "Üldine privaatvõti:",
+ "Recent changes that have not yet been received": "Hiljutised muudatused, mis pole veel alla laetud või saabunud",
+ "Explore public rooms": "Sirvi avalikke jututubasid",
+ "Forces the current outbound group session in an encrypted room to be discarded": "Sunnib loobuma praeguse krüptitud jututoa rühmavestluse seansist",
+ "You've previously used %(brand)s on %(host)s with lazy loading of members enabled. In this version lazy loading is disabled. As the local cache is not compatible between these two settings, %(brand)s needs to resync your account.": "Oled varem kasutanud %(brand)s serveriga %(host)s ja lubanud andmete laisa laadimise. Selles versioonis on laisk laadimine keelatud. Kuna kohalik vahemälu nende kahe seadistuse vahel ei ühildu, peab %(brand)s sinu konto uuesti sünkroonima.",
+ "If the other version of %(brand)s is still open in another tab, please close it as using %(brand)s on the same host with both lazy loading enabled and disabled simultaneously will cause issues.": "Kui %(brand)s teine versioon on mõnel teisel vahekaardil endiselt avatud, palun sulge see. %(brand)s kasutamine samal serveril põhjustab vigu olukorras, kus laisk laadimine on samal ajal lubatud ja keelatud.",
+ "Data from an older version of %(brand)s has been detected. This will have caused end-to-end cryptography to malfunction in the older version. End-to-end encrypted messages exchanged recently whilst using the older version may not be decryptable in this version. This may also cause messages exchanged with this version to fail. If you experience problems, log out and back in again. To retain message history, export and re-import your keys.": "%(brand)s vanema versiooni andmed on tuvastatud. See kindlasti põhjustab läbiva krüptimise tõrke vanemas versioonis. Läbivalt krüptitud sõnumid, mida on vanema versiooni kasutamise ajal hiljuti vahetatud, ei pruugi selles versioonis olla dekrüptitavad. See võib põhjustada vigu ka selle versiooniga saadetud sõnumite lugemisel. Kui teil tekib probleeme, logige välja ja uuesti sisse. Sõnumite ajaloo säilitamiseks eksportige ja uuesti importige oma krüptovõtmed.",
+ "Navigation": "Navigeerimine",
+ "Uploading logs": "Laen üles logisid",
+ "Downloading logs": "Laen alla logisid",
+ "Can't see what you’re looking for?": "Kas sa ei leia seda, mida otsisid?",
+ "Explore all public rooms": "Sirvi kõiki avalikke jututubasid",
+ "%(count)s results|other": "%(count)s tulemust",
+ "Preparing to download logs": "Valmistun logikirjete allalaadimiseks",
+ "Download logs": "Lae logikirjed alla",
+ "Unexpected server error trying to leave the room": "Jututoast lahkumisel tekkis serveris ootamatu viga",
+ "Error leaving room": "Viga jututoast lahkumisel",
+ "Communities v2 prototypes. Requires compatible homeserver. Highly experimental - use with caution.": "Kogukondade v2 prototüüp. Eeldab, et koduserver toetab sellist funktsionaalsust. Lahendus on esialgne ja katseline - kui kasutad, siis väga ettevaatlikult.",
+ "Explore rooms in %(communityName)s": "Uuri jututubasid %(communityName)s kogukonnas",
+ "Set up Secure Backup": "Võta kasutusele turvaline varundus"
}
diff --git a/src/i18n/strings/eu.json b/src/i18n/strings/eu.json
index 01afa51836..2740ea2079 100644
--- a/src/i18n/strings/eu.json
+++ b/src/i18n/strings/eu.json
@@ -2266,5 +2266,32 @@
"%(brand)s Web": "%(brand)s web",
"%(brand)s Desktop": "%(brand)s Desktop",
"%(brand)s iOS": "%(brand)s iOS",
- "%(brand)s X for Android": "%(brand)s X for Android"
+ "%(brand)s X for Android": "%(brand)s X for Android",
+ "Change notification settings": "Aldatu jakinarazpenen ezarpenak",
+ "Use custom size": "Erabili tamaina pertsonalizatua",
+ "Use a more compact ‘Modern’ layout": "Erabili mezuen antolaketa 'Modernoa', konpaktuagoa da",
+ "Use a system font": "Erabili sistemako letra-tipoa",
+ "System font name": "Sistemaren letra-tipoaren izena",
+ "Unknown caller": "Dei-egile ezezaguna",
+ "Incoming voice call": "Sarrerako ahots-deia",
+ "Incoming video call": "Sarrerako bideo-deia",
+ "Incoming call": "Sarrerako deia",
+ "Hey you. You're the best!": "Aupa txo. Onena zara!",
+ "Message layout": "Mezuen antolaketa",
+ "Compact": "Konpaktua",
+ "Modern": "Modernoa",
+ "Use default": "Erabili lehenetsia",
+ "Notification options": "Jakinarazpen ezarpenak",
+ "Forget Room": "Ahaztu gela",
+ "This room is public": "Gela hau publikoa da",
+ "Away": "Kanpoan",
+ "Click to view edits": "Klik egin edizioak ikusteko",
+ "Go to Element": "Joan Elementera",
+ "Learn more at element.io/previously-riot": "Ikasi gehiago element.io/previously-riot orrian",
+ "The server is offline.": "Zerbitzaria lineaz kanpo dago.",
+ "The server has denied your request.": "Zerbitzariak zure eskariari uko egin dio.",
+ "Wrong file type": "Okerreko fitxategi-mota",
+ "Looks good!": "Itxura ona du!",
+ "Search rooms": "Bilatu gelak",
+ "User menu": "Erabiltzailea-menua"
}
diff --git a/src/i18n/strings/fi.json b/src/i18n/strings/fi.json
index 8d620828e6..c6abfc0de7 100644
--- a/src/i18n/strings/fi.json
+++ b/src/i18n/strings/fi.json
@@ -134,7 +134,7 @@
"Last seen": "Viimeksi nähty",
"Leave room": "Poistu huoneesta",
"Logout": "Kirjaudu ulos",
- "Low priority": "Alhainen prioriteetti",
+ "Low priority": "Matala prioriteetti",
"Manage Integrations": "Hallinnoi integraatioita",
"Moderator": "Moderaattori",
"Name": "Nimi",
diff --git a/src/i18n/strings/gl.json b/src/i18n/strings/gl.json
index f06b1e22d9..0f2c83fd55 100644
--- a/src/i18n/strings/gl.json
+++ b/src/i18n/strings/gl.json
@@ -2233,7 +2233,7 @@
"Alt": "Alt",
"Alt Gr": "Alt Gr",
"Shift": "Maiús",
- "Super": "Super",
+ "Super": "Súper",
"Ctrl": "Ctrl",
"Toggle Bold": "Activa Resaltar",
"Toggle Italics": "Activa Cursiva",
@@ -2390,5 +2390,40 @@
"Custom Tag": "Etiqueta personal",
"* %(senderName)s %(emote)s": "* %(senderName)s %(emote)s",
"The person who invited you already left the room.": "A persoa que te convidou xa deixou a sala.",
- "The person who invited you already left the room, or their server is offline.": "A persoa que te convidou xa deixou a sala, ou o seu servidor non está a funcionar."
+ "The person who invited you already left the room, or their server is offline.": "A persoa que te convidou xa deixou a sala, ou o seu servidor non está a funcionar.",
+ "Change notification settings": "Cambiar os axustes das notificacións",
+ "Your server isn't responding to some requests.": "O teu servidor non responde a algunhas solicitudes.",
+ "You're all caught up.": "Xa estás ó día.",
+ "Server isn't responding": "O servidor non responde",
+ "Your server isn't responding to some of your requests. Below are some of the most likely reasons.": "O servidor non responde a algunhas peticións. Aquí tes algunha das razóns máis probables.",
+ "The server (%(serverName)s) took too long to respond.": "O servidor (%(serverName)s) tardou moito en responder.",
+ "Your firewall or anti-virus is blocking the request.": "O cortalumes ou antivirus está bloqueando a solicitude.",
+ "A browser extension is preventing the request.": "Unha extensión do navegador está evitando a solicitude.",
+ "The server is offline.": "O servidor está apagado.",
+ "The server has denied your request.": "O servidor rexeitou a solicitude.",
+ "Your area is experiencing difficulties connecting to the internet.": "Hai problemas de conexión a internet na túa localidade.",
+ "A connection error occurred while trying to contact the server.": "Aconteceu un fallo de conexión ó intentar contactar co servidor.",
+ "The server is not configured to indicate what the problem is (CORS).": "O servidor non está configurado para sinalar cal é o problema (CORS).",
+ "Recent changes that have not yet been received": "Cambios recentes que aínda non foron recibidos",
+ "No files visible in this room": "Non hai ficheiros visibles na sala",
+ "Attach files from chat or just drag and drop them anywhere in a room.": "Anexa filecheiros desde a conversa ou arrastra e sóltaos onde queiras nunha sala.",
+ "You’re all caught up": "Xa estás ó día",
+ "You have no visible notifications in this room.": "Non tes notificacións visibles nesta sala.",
+ "%(brand)s Android": "%(brand)s Android",
+ "Master private key:": "Chave mestra principal:",
+ "Show message previews for reactions in DMs": "Mostrar vista previa das mensaxes para reaccións en MDs",
+ "Show message previews for reactions in all rooms": "Mostrar vista previa das mensaxes para reaccións en todas as salas",
+ "Explore public rooms": "Explorar salas públicas",
+ "Uploading logs": "Subindo o rexistro",
+ "Downloading logs": "Descargando o rexistro",
+ "Can't see what you’re looking for?": "¿Non atopas o que buscas?",
+ "Explore all public rooms": "Explora todas as salas públicas",
+ "%(count)s results|other": "%(count)s resultados",
+ "Preparing to download logs": "Preparándose para descargar rexistro",
+ "Download logs": "Descargar rexistro",
+ "Unexpected server error trying to leave the room": "Fallo non agardado no servidor ó intentar saír da sala",
+ "Error leaving room": "Erro ó saír da sala",
+ "Communities v2 prototypes. Requires compatible homeserver. Highly experimental - use with caution.": "Prototipos de Comunidades v2. Require un servidor compatible. Característica experimental - usa con tino.",
+ "Explore rooms in %(communityName)s": "Explorar salas en %(communityName)s",
+ "Set up Secure Backup": "Configurar Copia de apoio Segura"
}
diff --git a/src/i18n/strings/hu.json b/src/i18n/strings/hu.json
index 209c237c0c..71dab37a55 100644
--- a/src/i18n/strings/hu.json
+++ b/src/i18n/strings/hu.json
@@ -811,7 +811,7 @@
"This room is used for important messages from the Homeserver, so you cannot leave it.": "Ez a szoba fontos szerverüzenetek közlésére jött létre, nem tudsz kilépni belőle.",
"No Audio Outputs detected": "Nem található hang kimenet",
"Audio Output": "Hang kimenet",
- "Share Link to User": "Hivatkozás megosztása felhasználóval",
+ "Share Link to User": "A felhasználóra mutató hivatkozás",
"Share room": "Szoba megosztása",
"Share Room": "Szoba megosztása",
"Link to most recent message": "A legfrissebb üzenetre hivatkozás",
@@ -987,7 +987,7 @@
"Send typing notifications": "Gépelés visszajelzés küldése",
"Enable Community Filter Panel": "Közösségi szűrő panel bekapcsolása",
"Messages containing my username": "Üzenetek amik a nevemet tartalmazzák",
- "The other party cancelled the verification.": "A másik fél törölte az ellenőrzést.",
+ "The other party cancelled the verification.": "A másik fél megszakította az ellenőrzést.",
"Verified!": "Ellenőrizve!",
"You've successfully verified this user.": "Sikeresen ellenőrizted ezt a felhasználót.",
"Secure messages with this user are end-to-end encrypted and not able to be read by third parties.": "Az üzenetek a felhasználóval végponttól végpontig titkosítva vannak és azt más nem tudja elolvasni.",
@@ -1630,7 +1630,7 @@
"%(role)s in %(roomName)s": "%(role)s a szobában: %(roomName)s",
"Messages in this room are end-to-end encrypted.": "Az üzenetek a szobában végponttól végpontig titkosítottak.",
"Security": "Biztonság",
- "Verify": "Ellenőriz",
+ "Verify": "Ellenőrzés",
"Any of the following data may be shared:": "Az alábbi adatok közül bármelyik megosztásra kerülhet:",
"Your display name": "Megjelenítési neved",
"Your avatar URL": "Profilképed URL-je",
@@ -1888,7 +1888,7 @@
"You've successfully verified %(displayName)s!": "Sikeresen ellenőrizted a felhasználót: %(displayName)s!",
"Got it": "Értem",
"Encryption enabled": "Titkosítás bekapcsolva",
- "Messages in this room are end-to-end encrypted. Learn more & verify this user in their user profile.": "Ebben a szobában az üzenetek végpontok között titkosítottak. További információkért és ellenőrzéshez nyisd meg a felhasználó profilját.",
+ "Messages in this room are end-to-end encrypted. Learn more & verify this user in their user profile.": "Ebben a szobában az üzenetek végpontok között titkosítottak. További információkért és az ellenőrzéshez nyisd meg a felhasználók profiljait!",
"Encryption not enabled": "Titkosítás nincs engedélyezve",
"The encryption used by this room isn't supported.": "A szobában használt titkosítás nem támogatott.",
"Clear all data in this session?": "Minden adat törlése ebben a munkamenetben?",
@@ -2109,7 +2109,7 @@
"Server did not return valid authentication information.": "A szerver semmilyen érvényes azonosítási információt sem küldött vissza.",
"There was a problem communicating with the server. Please try again.": "A szerverrel való kommunikációval probléma történt. Kérlek próbáld újra.",
"Sign in with SSO": "Belépés SSO-val",
- "Welcome to %(appName)s": "Üdv itt: %(appName)s",
+ "Welcome to %(appName)s": "Üdvözöl az %(appName)s",
"Liberate your communication": "Szabadítsd fel a kommunikációdat",
"Send a Direct Message": "Közvetlen üzenet küldése",
"Explore Public Rooms": "Nyilvános szobák felderítése",
@@ -2177,7 +2177,7 @@
"Waiting for your other session to verify…": "A másik munkameneted ellenőrzésére várunk…",
"You've successfully verified your device!": "Sikeresen ellenőrizted az eszközödet!",
"Message deleted": "Üzenet törölve",
- "Message deleted by %(name)s": "%(name)s törölte az üzenetet",
+ "Message deleted by %(name)s": "%(name)s törölte ezt az üzenetet",
"QR Code": "QR kód",
"To continue, use Single Sign On to prove your identity.": "A folytatáshoz a személyazonosságod megerősítéséhez használd az egyszeri bejelentkezést.",
"Confirm to continue": "Erősítsd meg a továbblépéshez",
@@ -2234,12 +2234,12 @@
"Emoji picker": "Emodzsi választó",
"No recently visited rooms": "Nincsenek nemrégiben meglátogatott szobák",
"People": "Emberek",
- "Sort by": "Rendezve:",
+ "Sort by": "Rendezés",
"Unread rooms": "Olvasatlan szobák",
"Always show first": "Mindig az elsőt mutatja",
"Show": "Mutat",
"Message preview": "Üzenet előnézet",
- "List options": "Lista beállítások",
+ "List options": "Lista beállításai",
"Show %(count)s more|other": "Még %(count)s megjelenítése",
"Show %(count)s more|one": "Még %(count)s megjelenítése",
"Leave Room": "Szoba elhagyása",
@@ -2404,5 +2404,14 @@
"Your area is experiencing difficulties connecting to the internet.": "Probléma az Internet elérésben.",
"A connection error occurred while trying to contact the server.": "Kapcsolati hiba lépett fel miközben a szervert próbáltad elérni.",
"The server is not configured to indicate what the problem is (CORS).": "A szerver nincs beállítva, hogy megmutassa mi okozhatta a hibát (CORS).",
- "Recent changes that have not yet been received": "Legutóbbi változások amik még nem érkeztek meg"
+ "Recent changes that have not yet been received": "Legutóbbi változások amik még nem érkeztek meg",
+ "Show message previews for reactions in DMs": "Üzenet előnézet mutatása a reakcióhoz a közvetlen beszélgetéseknél",
+ "Show message previews for reactions in all rooms": "Üzenet előnézet mutatása a reakciókhoz minden szobában",
+ "Master private key:": "Privát elsődleges kulcs:",
+ "No files visible in this room": "Ebben a szobában nincsenek fájlok",
+ "Attach files from chat or just drag and drop them anywhere in a room.": "Csatolj fájlt a csevegésből vagy húzd és ejtsd bárhova a szobában.",
+ "You’re all caught up": "Mindent elolvastál",
+ "You have no visible notifications in this room.": "Nincsenek látható értesítéseid ebben a szobában.",
+ "%(brand)s Android": "%(brand)s Android",
+ "Explore public rooms": "Nyilvános szobák felderítése"
}
diff --git a/src/i18n/strings/it.json b/src/i18n/strings/it.json
index 3ed851fd95..8cea189ff6 100644
--- a/src/i18n/strings/it.json
+++ b/src/i18n/strings/it.json
@@ -2391,5 +2391,37 @@
"Click to view edits": "Clicca per vedere le modifiche",
"Are you sure you want to cancel entering passphrase?": "Sei sicuro di volere annullare l'inserimento della frase?",
"* %(senderName)s %(emote)s": "* %(senderName)s %(emote)s",
- "Custom Tag": "Etichetta personalizzata"
+ "Custom Tag": "Etichetta personalizzata",
+ "The person who invited you already left the room.": "La persona che ti ha invitato è già uscita dalla stanza.",
+ "The person who invited you already left the room, or their server is offline.": "La persona che ti ha invitato è già uscita dalla stanza, o il suo server è offline.",
+ "Change notification settings": "Cambia impostazioni di notifica",
+ "Your server isn't responding to some requests.": "Il tuo server non sta rispondendo ad alcune richieste.",
+ "Master private key:": "Chiave privata principale:",
+ "You're all caught up.": "Non hai nulla di nuovo da vedere.",
+ "Server isn't responding": "Il server non risponde",
+ "Your server isn't responding to some of your requests. Below are some of the most likely reasons.": "Il tuo server non sta rispondendo ad alcune tue richieste. Sotto trovi alcuni probabili motivi.",
+ "The server (%(serverName)s) took too long to respond.": "Il server (%(serverName)s) ha impiegato troppo tempo per rispondere.",
+ "Your firewall or anti-virus is blocking the request.": "Il tuo firewall o antivirus sta bloccando la richiesta.",
+ "A browser extension is preventing the request.": "Un'estensione del browser sta impedendo la richiesta.",
+ "The server is offline.": "Il server è offline.",
+ "The server has denied your request.": "Il server ha negato la tua richiesta.",
+ "Your area is experiencing difficulties connecting to the internet.": "La tua area sta riscontrando difficoltà di connessione a internet.",
+ "A connection error occurred while trying to contact the server.": "Si è verificato un errore di connessione tentando di contattare il server.",
+ "The server is not configured to indicate what the problem is (CORS).": "Il server non è configurato per indicare qual è il problema (CORS).",
+ "Recent changes that have not yet been received": "Modifiche recenti che non sono ancora state ricevute",
+ "No files visible in this room": "Nessun file visibile in questa stanza",
+ "Attach files from chat or just drag and drop them anywhere in a room.": "Allega file dalla chat o trascinali in qualsiasi punto in una stanza.",
+ "You’re all caught up": "Non hai nulla di nuovo da vedere",
+ "You have no visible notifications in this room.": "Non hai alcuna notifica visibile in questa stanza.",
+ "%(brand)s Android": "%(brand)s Android",
+ "Show message previews for reactions in DMs": "Mostra anteprime messaggi per le reazioni nei messaggi diretti",
+ "Show message previews for reactions in all rooms": "Mostra anteprime messaggi per le reazioni in tutte le stanze",
+ "Explore public rooms": "Esplora stanze pubbliche",
+ "Uploading logs": "Invio dei log",
+ "Downloading logs": "Scaricamento dei log",
+ "Can't see what you’re looking for?": "Non vedi quello che cerchi?",
+ "Explore all public rooms": "Esplora tutte le stanze pubbliche",
+ "%(count)s results|other": "%(count)s risultati",
+ "Preparing to download logs": "Preparazione al download dei log",
+ "Download logs": "Scarica i log"
}
diff --git a/src/i18n/strings/ja.json b/src/i18n/strings/ja.json
index ee3871fc0f..4edf415efb 100644
--- a/src/i18n/strings/ja.json
+++ b/src/i18n/strings/ja.json
@@ -579,7 +579,7 @@
"%(severalUsers)sleft %(count)s times|one": "%(severalUsers)s は退出しました",
"%(oneUser)sleft %(count)s times|other": "%(oneUser)s は %(count)s 回退出しました",
"%(oneUser)sleft %(count)s times|one": "%(oneUser)s は退出しました",
- "%(severalUsers)sjoined and left %(count)s times|other": "%(severalUsers)s が%(count)s 回参加し、退出した",
+ "%(severalUsers)sjoined and left %(count)s times|other": "%(severalUsers)s が %(count)s 回参加し、退出しました",
"%(severalUsers)sjoined and left %(count)s times|one": "%(severalUsers)s は参加して退出しました",
"%(oneUser)sjoined and left %(count)s times|other": "%(oneUser)s が %(count)s 回参加し退出しました",
"%(oneUser)sjoined and left %(count)s times|one": "%(oneUser)s が参加し退出しました",
@@ -668,7 +668,7 @@
"Update any local room aliases to point to the new room": "新しいルームを指すようにローカルルームのエイリアスを更新する",
"Stop users from speaking in the old version of the room, and post a message advising users to move to the new room": "古いバージョンの部屋でのユーザーの発言を停止し、新しい部屋に移動するようユーザーに通知するメッセージを投稿する",
"Mention": "記載",
- "%(severalUsers)shad their invitations withdrawn %(count)s times|other": "%(severalUsers)s が %(count)s 回招待を撤回した",
+ "%(severalUsers)shad their invitations withdrawn %(count)s times|other": "%(severalUsers)s が %(count)s 回招待を取り消しました",
"was unbanned %(count)s times|one": "ブロック解除されました",
"Put a link back to the old room at the start of the new room so people can see old messages": "新しい部屋の始めに古い部屋にリンクを張って、人々が古いメッセージを見ることができるようにする",
"Sign out": "サインアウト",
@@ -1370,5 +1370,22 @@
"Always show the window menu bar": "常にウィンドウメニューバーを表示する",
"Create room": "部屋を作成",
"Show %(count)s more|other": "さらに %(count)s 件を表示",
- "Show %(count)s more|one": "さらに %(count)s 件を表示"
+ "Show %(count)s more|one": "さらに %(count)s 件を表示",
+ "%(num)s minutes ago": "%(num)s 分前",
+ "%(num)s hours ago": "%(num)s 時間前",
+ "%(num)s days ago": "%(num)s 日前",
+ "Favourited": "お気に入り登録中",
+ "Room options": "部屋の設定",
+ "Ignored users": "無視しているユーザー",
+ "Show tray icon and minimize window to it on close": "トレイアイコンを表示しウィンドウを閉じても最小化して待機する",
+ "This message cannot be decrypted": "メッセージが復号できません",
+ "Unencrypted": "暗号化されていません",
+ "Encrypted by a deleted session": "削除済みのセッションによる暗号化",
+ "Scroll to most recent messages": "最新のメッセージを表示",
+ "Emoji picker": "絵文字を選択",
+ "All rooms": "全ての部屋",
+ "Your server": "あなたのサーバー",
+ "Matrix": "Matrix",
+ "Add a new server": "新しいサーバーを追加",
+ "Server name": "サーバー名"
}
diff --git a/src/i18n/strings/jbo.json b/src/i18n/strings/jbo.json
index 9ac42af1de..f2c9dc6e43 100644
--- a/src/i18n/strings/jbo.json
+++ b/src/i18n/strings/jbo.json
@@ -363,8 +363,8 @@
"Success!": ".i snada",
"Room List": "liste le'i ve zilbe'i",
"Upload a file": "nu kibdu'a pa vreji",
- "Verify your other session using one of the options below.": ".i ko cuxna da le di'e gai'o le ka tadji lo nu do co'a lacri",
- "Ask this user to verify their session, or manually verify it below.": ".i ko cpedu le ka co'a lacri le se samtcise'u kei le pilno vau ja pilno le di'e gai'o le ka co'a lacri",
+ "Verify your other session using one of the options below.": ".i ko cuxna da le di'e cei'i le ka tadji lo nu do co'a lacri",
+ "Ask this user to verify their session, or manually verify it below.": ".i ko cpedu le ka co'a lacri le se samtcise'u kei le pilno vau ja pilno le di'e cei'i le ka co'a lacri",
"Not Trusted": "na se lacri",
"Manually Verify by Text": "nu pilno pa lerpoi lo nu co'a lacri",
"Interactively verify by Emoji": "nu pilno vu'i pa cinmo sinxa lo nu co'a lacri",
@@ -375,7 +375,7 @@
"%(names)s and %(lastPerson)s are typing …": ".i la'o zoi. %(names)s .zoi je la'o zoi. %(lastPerson)s .zoi ca'o ciska",
"Cannot reach homeserver": ".i ca ku na da ka'e zilbe'i le samtcise'u",
"Match system theme": "nu mapti le jvinu be le vanbi",
- "Never send encrypted messages to unverified sessions in this room from this session": "nu na pa mifra be pa notci cu zilbe'i pa se samtcise'u poi na se lanli ku'o le se samtcise'u le gai'o",
+ "Never send encrypted messages to unverified sessions in this room from this session": "nu na pa mifra be pa notci cu zilbe'i pa se samtcise'u poi na se lanli ku'o le se samtcise'u le cei'i",
"Order rooms by name": "nu porsi tu'a lo cmene",
"Messages containing my username": "nu pa se pagbu be le judri be mi cu zilbe'i",
"Messages containing @room": "nu pa se pagbu be zoi zoi. @room .zoi cu zilbe'i",
@@ -472,9 +472,9 @@
"Riot is now Element!": ".i zo .elyment. basti zo .raiyt. le ka cmene",
"Learn More": "nu facki",
"We’re excited to announce Riot is now Element!": ".i fizbu lo nu gubni xusra le du'u zo .elyment. basti zo .raiyt. le ka cmene",
- "Messages in this room are secured with end-to-end encryption. Only you and the recipient(s) have the keys to read these messages.": ".i ro zilbe'i be fo le gai'o cu mifra .i le ka ka'e tcidu lo notci cu steci fi lu'i do je ro pagbu be le se zilbe'i",
- "Messages in this room are end-to-end encrypted.": ".i ro zilbe'i be fo le gai'o cu mifra",
- "Messages in this room are not end-to-end encrypted.": ".i na pa zilbe'i be fo le gai'o cu mifra",
+ "Messages in this room are secured with end-to-end encryption. Only you and the recipient(s) have the keys to read these messages.": ".i ro zilbe'i be fo le cei'i cu mifra .i le ka ka'e tcidu lo notci cu steci fi lu'i do je ro pagbu be le se zilbe'i",
+ "Messages in this room are end-to-end encrypted.": ".i ro zilbe'i be fo le cei'i cu mifra",
+ "Messages in this room are not end-to-end encrypted.": ".i na pa zilbe'i be fo le cei'i cu mifra",
"Members": "pagbu le se zilbe'i",
"Files": "vreji",
"Trusted": "se lacri",
@@ -487,8 +487,8 @@
"Hide sessions": "nu ro se samtcise'u cu zilmipri",
"Invite": "nu friti le ka ziljmina",
"Logout": "nu co'u jaspu",
- "For help with using %(brand)s, click here or start a chat with our bot using the button below.": ".i gi je lo nu samcu'a le dei gai'o gi lo nu co'a tavla le sampre cu tadji lo nu facki le du'u tadji lo nu pilno la'o zoi. %(brand)s .zoi",
- "This room is end-to-end encrypted": ".i ro zilbe'i be fo le gai'o cu mifra",
+ "For help with using %(brand)s, click here or start a chat with our bot using the button below.": ".i gi je lo nu samcu'a le dei cei'i gi lo nu co'a tavla le sampre cu tadji lo nu facki le du'u tadji lo nu pilno la'o zoi. %(brand)s .zoi",
+ "This room is end-to-end encrypted": ".i ro zilbe'i be fo le cei'i cu mifra",
"Everyone in this room is verified": ".i do lacri ro pagbu be le se zilbe'i",
"Start chat": "nu co'a tavla",
"Create room": "nu cupra pa ve zilbe'i",
@@ -534,7 +534,7 @@
"Unable to leave community": ".i da nabmi fi lo nu do zilvi'u le girzu",
"Join this community": "nu do ziljmina le girzu",
"Leave this community": "nu do zilvi'u le girzu",
- "Your community hasn't got a Long Description, a HTML page to show to community members. Click here to open settings and give it one!": ".i na da tcila skicu be le girzu bei ro girzu pagbu be'o lerpoi bau la'au xy. bu ty. my. ly. li'u .i lo nu samcu'a le dei gai'o cu tadji lo nu da go'i",
+ "Your community hasn't got a Long Description, a HTML page to show to community members. Click here to open settings and give it one!": ".i na da tcila skicu be le girzu bei ro girzu pagbu be'o lerpoi bau la'au xy. bu ty. my. ly. li'u .i lo nu samcu'a le dei cei'i cu tadji lo nu da go'i",
"Long Description (HTML)": "tcila skicu lerpoi bau la'au xy. bu ty. my. ly. li'u",
"Community %(groupId)s not found": ".i na da poi girzu zo'u facki le du'u zoi zoi. %(groupId)s .zoi judri da",
"This homeserver does not support communities": ".i le samtcise'u na kakne tu'a lo girzu",
diff --git a/src/i18n/strings/kab.json b/src/i18n/strings/kab.json
index 343238e626..9af55c0793 100644
--- a/src/i18n/strings/kab.json
+++ b/src/i18n/strings/kab.json
@@ -354,7 +354,7 @@
"Please check your email and click on the link it contains. Once this is done, click continue.": "Ma ulac aɣilif, senqed imayl-ik/im syen sit ɣef useɣwen i yellan. Akken ara yemmed waya, sit ad tkemmleḍ.",
"This will allow you to reset your password and receive notifications.": "Ayagi ad ak(akem)-yeǧǧ ad twennzeḍ awal-ik/im uffir yerna ad d-tremseḍ ilɣa.",
"A username can only contain lower case letters, numbers and '=_-./'": "Isem n useqdac yezmer kan ad yegber isekkilen imeẓyanen, izwilen neɣ '=_-./'",
- "Username invalid: %(errMessage)s": "Isem n useqdac d armeɣtu",
+ "Username invalid: %(errMessage)s": "Isem n useqdac d arameɣtu: %(errMessage)s",
"An error occurred: %(error_string)s": "Tella-d tuccḍa: %(error_string)s",
"To get started, please pick a username!": "I wakken ad tebduḍ, ttxil-k/m fren isem n useqdac!",
"This will be your account name on the homeserver, or you can pick a different server.": "Wagi ad yili d isem-ik/im deg usebter agejdan, neɣ tzemreḍ ad tferneḍ aqeddac-nniḍen.",
@@ -568,9 +568,9 @@
"%(displayName)s is typing …": "%(displayName)s yettaru-d …",
"%(names)s and %(count)s others are typing …|other": "%(names)s d %(count)s wiyaḍ ttarun-d …",
"%(names)s and %(count)s others are typing …|one": "%(names)s d wayeḍ-nniḍen yettaru-d …",
- "%(names)s and %(lastPerson)s are typing …": "%(names)s d %(count)s ttarun-d …",
- "%(items)s and %(count)s others|other": "%(names)s d %(count)s wiyaḍ",
- "%(items)s and %(count)s others|one": "%(names)s d wayeḍ-nniḍen",
+ "%(names)s and %(lastPerson)s are typing …": "%(names)s d %(lastPerson)s ttarun-d …",
+ "%(items)s and %(count)s others|other": "%(items)s d %(count)s wiyaḍ",
+ "%(items)s and %(count)s others|one": "%(items)s d wayeḍ-nniḍen",
"%(items)s and %(lastItem)s": "%(items)s d %(lastItem)s",
"a few seconds ago": "kra n tesinin seg yimir-nni",
"about a minute ago": "tasdidt seg yimir-nni",
@@ -647,7 +647,7 @@
" to store messages from ": " i usekles n yiznan sɣur ",
"rooms.": "tixxamin.",
"Connecting to integration manager...": "Tuqqna ɣer umsefrak n useddu...",
- "Cannot connect to integration manager": "Ur nessaweḍ ara ad neqqen ɣer umsefrak n useddu...",
+ "Cannot connect to integration manager": "Ur nessaweḍ ara ad neqqen ɣer umsefrak n useddu",
"Delete Backup": "Kkes aḥraz",
"Encrypted messages are secured with end-to-end encryption. Only you and the recipient(s) have the keys to read these messages.": "Iznan yettwawgelhen ttuḥerzen s uwgelhen n yixef ɣer yixef. Ala kečč d unermas (inermasen) i yesεan tisura akken ad ɣren iznan-a.",
"This session is backing up your keys. ": "Tiɣimit tḥerrez tisura-inek·inem. ",
@@ -719,7 +719,7 @@
"%(num)s hours ago": "%(num)s usrag seg yimir-nni",
"about a day ago": "azal n wass seg yimir-nni",
"%(num)s days ago": "%(num)s wussan seg yimir-nni",
- "a few seconds from now": "Kra n tesinin seg yimir-a",
+ "a few seconds from now": "kra n tesinin seg yimir-a",
"%(name)s (%(userId)s)": "%(name)s (%(userId)s)",
"Not a valid %(brand)s keyfile": "Afaylu n tsarut %(brand)s d arameɣtu",
"User %(user_id)s does not exist": "Aseqdac %(user_id)s ulac-it",
@@ -731,9 +731,9 @@
"Avoid dates and years that are associated with you": "Zgel izmaz akked iseggasen i icudden ɣur-k",
"System font name": "Isem n tsefsit n unagraw",
"Send analytics data": "Azen isefka n tesleḍt",
- "Cancelling…": "Asefsex...",
- "They match": "Mṣadan",
- "They don't match": "Ur mṣadan ara",
+ "Cancelling…": "Asefsex…",
+ "They match": "Msaḍan",
+ "They don't match": "Ur msaḍan ara",
"Dog": "Aqjun",
"Horse": "Aεewdiw",
"Pig": "Ilef",
@@ -759,5 +759,1320 @@
"Glasses": "Tisekkadin",
"Umbrella": "Tasiwant",
"Gift": "Asefk",
- "Light bulb": "Taftilt"
+ "Light bulb": "Taftilt",
+ "Power level must be positive integer.": "Ilaq ad yili uswir n tezmert d ummid ufrir.",
+ "Sends a message as plain text, without interpreting it as markdown": "Yuzen izen d aḍris aččuran war ma isegza-t s tukksa n tecreḍt",
+ "You do not have the required permissions to use this command.": "Ur tesεiḍ ara tisirag akken ad tesqedceḍ taladna-a.",
+ "Double check that your server supports the room version chosen and try again.": "Senqed akken ilaq ma yella aqeddac-inek·inem issefrak lqem n texxamtyettwafernen syen εreḍ tikkelt-nniḍen.",
+ "Changes your display nickname": "Ibeddel isem-inek·inem yettwaskanen",
+ "Changes your display nickname in the current room only": "Ibeddel isem-inek·inem i d-yettwaskanen degtexxamt kan tamirant",
+ "Kicks user with given id": "Suffeɣ aseqdac s usulay i d-yettunefken",
+ "Unignored user": "Aseqdac ur yettuzeglen ara",
+ "You are no longer ignoring %(userId)s": "Dayen ur tettazgaleḍ ara akk %(userId)s",
+ "Opens the Developer Tools dialog": "Yeldi adiwenni n yifecka n uneflay",
+ "Adds a custom widget by URL to the room": "Yerna awiǧit udmawan s URL ɣer texxamt",
+ "Please supply a widget URL or embed code": "Ttxil-k·m mudd URL n uwiǧit neɣ tangalt tusliɣt",
+ "Verifies a user, session, and pubkey tuple": "Yessenqad tagrumma-a: aseqdac, tiɣimit d tsarut tazayezt",
+ "WARNING: Session already verified, but keys do NOT MATCH!": "ΓUR-K·M: Tettwasenqed tɣimit yakan maca tisura ur mṣadant ara!",
+ "%(senderName)s requested a VoIP conference.": "%(senderName)s isuter-d asarag VoIP.",
+ "%(oldDisplayName)s changed their display name to %(displayName)s.": "%(oldDisplayName)s ibeddel isem-ines yettwaskanen s %(displayName)s.",
+ "%(senderName)s set their display name to %(displayName)s.": "%(senderName)s yesbadu isem yettwaskanen s %(displayName)s.",
+ "%(senderName)s kicked %(targetName)s.": "%(senderName)s yessuffeɣ %(targetName)s.",
+ "%(senderDisplayName)s changed the room name from %(oldRoomName)s to %(newRoomName)s.": "%(senderDisplayName)s ibeddel isem n texxamt seg %(oldRoomName)s ɣer %(newRoomName)s.",
+ "%(senderDisplayName)s changed the room name to %(roomName)s.": "%(senderDisplayName)s ibeddel isem n texxamt s %(roomName)s.",
+ "%(senderDisplayName)s made the room public to whoever knows the link.": "%(senderDisplayName)s yerra taxxamt d tazayazt i kra n win yessnen aseɣwen.",
+ "%(senderDisplayName)s changed the join rule to %(rule)s": "%(senderDisplayName)s ibeddel alugen n uttekki s %(rule)s",
+ "%(senderDisplayName)s has prevented guests from joining the room.": "%(senderDisplayName)s ur yeǧǧi ara i yimerza ad kecmen ɣer texxamt.",
+ "%(senderDisplayName)s changed guest access to %(rule)s": "%(senderDisplayName)s ibeddel anekcum n yimerza s %(rule)s",
+ "%(senderName)s set the main address for this room to %(address)s.": "%(senderName)s yesbadu tansa tagejdant i texxamt-a s %(address)s.",
+ "%(senderName)s added the alternative addresses %(addresses)s for this room.|one": "%(senderName)s yerna tansa-nniḍen %(addresses)s i texxamt-a.",
+ "%(senderName)s removed the alternative addresses %(addresses)s for this room.|other": "%(senderName)s yekkes tansa-nni-nniḍen %(addresses)s i texxamt-a.",
+ "%(senderName)s removed the alternative addresses %(addresses)s for this room.|one": "%(senderName)s yekkes tansa-nni tayeḍ %(addresses)s i texxamt-a.",
+ "%(senderName)s changed the alternative addresses for this room.": "%(senderName)s ibeddel tansa-nni tayeḍ n texxamt-a.",
+ "%(senderName)s changed the main and alternative addresses for this room.": "%(senderName)s ibeddel tansa tagejdant d tansa-nni tayeḍ i texxamt-a.",
+ "Sends a message as html, without interpreting it as markdown": "Yuzen izen d html war ma isegza-t s tukksa n tecreḍt",
+ "Deops user with given id": "Aseqdac Deops s usulay i d-yettunefken",
+ "Sends the given message coloured as a rainbow": "Yuzen iznan i d-yettunefken yeɣman s yiniten am teslit n Unẓar",
+ "Sends the given emote coloured as a rainbow": "Yuzen tanfalit i d-yettunefken yeɣman s yiniten am teslit n Unẓar",
+ "%(targetName)s accepted the invitation for %(displayName)s.": "%(targetName)s yeqbel tinnubga i %(displayName)s.",
+ "%(senderName)s changed the addresses for this room.": "%(senderName)s ibeddel tansiwin n texxamt-a.",
+ "(not supported by this browser)": "(ur yettusefrak ara sɣur iminig-a)",
+ "%(senderName)s answered the call.": "%(senderName)s yerra ɣef usiwel.",
+ "(could not connect media)": "(tuqqna n umidya tegguma)",
+ "%(senderName)s placed a voice call.": "%(senderName)s isɛedda asiwel s taɣect.",
+ "%(senderName)s placed a voice call. (not supported by this browser)": "%(senderName)s isɛedda asiwel s taɣect. (ur yettusefrak ara s yiming-a)",
+ "%(senderName)s placed a video call.": "%(senderName)s isɛedda asiwel s tvidyut.",
+ "%(senderName)s placed a video call. (not supported by this browser)": "%(senderName)s isɛedda asiwel s tvidyut. (ur yettusefrak ara s yiming-a)",
+ "%(senderName)s made future room history visible to anyone.": "%(senderName)s yerra amazray n texxamt i d-iteddun yettban i yal amdan.",
+ "%(senderName)s changed the pinned messages for the room.": "%(senderName)s ibeddel iznan yerzin n texxamt.",
+ "%(widgetName)s widget modified by %(senderName)s": "%(widgetName)s awiǧit yettwabeddel sɣur %(senderName)s",
+ "Manually Verify by Text": "Senqed s ufus s ttawil n uḍris",
+ "Interactively verify by Emoji": "Senqed amyigew s yimujit",
+ "Cannot reach homeserver": "Anekcum ɣer uqeddac agejdan d awezɣi",
+ "Cannot reach identity server": "Anekcum ɣer uqeddac n tmagit d awezɣi",
+ "No homeserver URL provided": "Ulac URL n uqeddac agejdan i d-yettunefken",
+ "about a minute from now": "akka tsasdidt seg yimir-a",
+ "%(num)s minutes from now": "%(num)s tesdidin seg yimir-nni",
+ "about an hour from now": "akka asrag seg yimir-a",
+ "%(num)s hours from now": "%(num)s yisragen seg yimir-a",
+ "about a day from now": "akka ass seg yimir-a",
+ "%(num)s days from now": "%(num)s wussan seg yimir-a",
+ "Unrecognised address": "Tansa ur tettwassen ara",
+ "You do not have permission to invite people to this room.": "Ur tesεiḍ ara tasiregt ad d-necdeḍ imdanen ɣer texxamt-a.",
+ "User %(userId)s is already in the room": "Aseqdac %(userId)s yella yakan deg texxamt",
+ "User %(user_id)s may or may not exist": "Aseqdac %(user_id)s yezmer yella, yezmer ulac-it",
+ "The user's homeserver does not support the version of the room.": "Aqeddac agejdan n useqdac ur issefrek ara lqem n texxamt yettwafernen.",
+ "All-uppercase is almost as easy to guess as all-lowercase": "Meṛṛa isekkilen imeqranen fessus-it i usumer ɣef akk isekkilen imeẓẓyanen",
+ "Recent years are easy to guess": "Iseggasen n melmi kan sehlen i tifin",
+ "Dates are often easy to guess": "Izemzen sehlen i tiftin",
+ "This is a top-10 common password": "Wagi d awal uffir gar 10 yimezwura yettwassnen",
+ "This is a top-100 common password": "Wagi d awal uffir gar 100 yimezwura yettwassnen",
+ "This is a very common password": "Wagi d awal uffir yettwassnen",
+ "I want to help": "Bɣiɣ ad d-muddeɣ tallalt",
+ "Enable them now": "Sermed-iten tura",
+ "* %(senderName)s %(emote)s": "* %(senderName)s %(emote)s",
+ "Change notification settings": "Snifel iɣewwaren n yilɣa",
+ "Match system theme": "Asentel n unagraw yemṣadan",
+ "Never send encrypted messages to unverified sessions from this session": "Ur ttazen ara akk iznan yettwawgelhen ɣer tɣimiyin ur nettusenqad ara seg tɣimit-a",
+ "Messages in group chats": "Iznan n yidiwenniyen n ugraw",
+ "Call invitation": "Ancad n tinnubga",
+ "Messages sent by bot": "Iznan yettwaznen s Bot",
+ "When rooms are upgraded": "Mi ara ttwaleqqment texxamin",
+ "My Ban List": "Tabdart-inu n tigtin",
+ "Incoming voice call": "Asiwel s taɣect ikcem-d",
+ "Incoming video call": "Asiwel s tvidyut ikcem-d",
+ "Incoming call": "Asiwel i d-ikecmen",
+ "Got It": "Awi-t",
+ "From %(deviceName)s (%(deviceId)s)": "Seg %(deviceName)s (%(deviceId)s)",
+ "Accept to continue:": "Qbel i wakken ad tkemmleḍ:",
+ "This bridge was provisioned by .": "Tileggit-a tella-d sɣur .",
+ "This bridge is managed by .": "Tileggit-a tettusefrak sɣur .",
+ "Workspace: %(networkName)s": "Tallunt n uxeddim: %(networkName)s",
+ "Channel: %(channelName)s": "Abadu: %(channelName)s",
+ "Upload new:": "Asali amaynut:",
+ "New passwords don't match": "Awalen uffiren imaynuten ur mṣadan ara",
+ "Passwords can't be empty": "Awalen uffiren ur ilaq ara ad ilin d ilmawen",
+ "in account data": "deg yisefka n umiḍan",
+ "Confirm deleting these sessions by using Single Sign On to prove your identity.|other": "Sentem tukksa n tɣimiyin-a s useqdec n unekcum asuf i ubeggen n timagit-ik(im).",
+ "Confirm deleting these sessions by using Single Sign On to prove your identity.|one": "Sentem tukksa n tɣimit-a s useqdec n unekcum asuf i ubeggen n timagit-ik·im.",
+ "Confirm deleting these sessions": "Sentem tukksa n tɣimiyin-a",
+ "Restore from Backup": "Tiririt seg uḥraz",
+ "All keys backed up": "Akk tisura ttwaḥerzent",
+ "Backup version: ": "Lqem n uḥraz: ",
+ "Failed to change settings": "Asnifel n yiɣewwaren ur yeddi ara",
+ "Failed to update keywords": "Aleqqem n wawalen ufrinen ur yeddi ara",
+ "Enable notifications for this account": "Sens ilɣa i umiḍan-a",
+ "Enable email notifications": "Sens ilɣa n yimayla",
+ "Notification targets": "Isaḍasen n yilɣa",
+ "Advanced notification settings": "Iɣewwaren n yilɣa leqqayen",
+ "Enable desktop notifications for this session": "Sens ilɣa n tnirawt i tɣimit-a",
+ "Enable audible notifications for this session": "Sens ilɣa imsiwal i texxamt",
+ "Upgrade to your own domain": "Leqqem ɣer taɣult-inek kečč",
+ "Profile picture": "Tugna n umaɣnu",
+ "Checking server": "Asenqed n uqeddac",
+ "Change identity server": "Snifel aqeddac n timagit",
+ "You should:": "Aql-ak·am:",
+ "Disconnect anyway": "Ɣas akken ffeɣ seg tuqqna",
+ "Do not use an identity server": "Ur seqdac ara aqeddac n timagt",
+ "Manage integrations": "Sefrek imsidf",
+ "Checking for an update...": "Anadi n lqem...",
+ "Downloading update...": "Asali n lqem...",
+ "New version available. Update now.": "Lqem amaynut yella. Leqqem tura.",
+ "Check for update": "Nadi lqem",
+ "Invalid theme schema.": "Azenziɣ n usentel d arameɣtu.",
+ "Theme added!": "Asentel yettwarnan!",
+ "Custom theme URL": "Sagen URL n usentel",
+ "Add theme": "Rnu asentel",
+ "Customise your appearance": "Err arwes-ik·im d udmawan",
+ "Set a new account password...": "Sbadu awal uffir amaynut n umiḍan...",
+ "Account management": "Asefrek n umiḍan",
+ "Deactivate Account": "Sens amiḍan",
+ "Deactivate account": "Sens amiḍan",
+ "Bug reporting": "Aneqqis n wabug",
+ "Submit debug logs": "Azen iɣmisen n wabug",
+ "Clear cache and reload": "Sfeḍ takatut tuffirt syen sali-d",
+ "%(brand)s version:": "Lqem %(brand)s:",
+ "olm version:": "lqem n olm:",
+ "Ignored/Blocked": "Yettunfen/Yettusweḥlen",
+ "Error unsubscribing from list": "Tuccḍa deg usefsex n ujerred seg texxamt",
+ "Server rules": "Ilugan n uqeddac",
+ "User rules": "Ilugan n useqdac",
+ "You are currently ignoring:": "Aql-ak tura tuɣaleḍ deg rrif:",
+ "Ignored users": "Iseqdacen yettunfen",
+ "Personal ban list": "Tabdart n tigtin tudmawant",
+ "Server or user ID to ignore": "Asulay n uqeddac neɣ n useqdac ara yuɣalen deg rrif",
+ "eg: @bot:* or example.org": "eg: @bot:* neɣ amedya.org",
+ "Room list": "Tabdart n texxamt",
+ "Autocomplete delay (ms)": "Tanzagt n usmad awurman (ms)",
+ "": "",
+ "Session ID:": "Asulay n tɣimit:",
+ "Message search": "Anadi n yizen",
+ "Default Device": "Ibenk arussin",
+ "Voice & Video": "Ameslaw & Tavidyut",
+ "Upgrade this room to the recommended room version": "Leqqem taxxamt-a ɣer lqem n texxamt yelhan",
+ "this room": "taxxamt-a",
+ "Internal room ID:": "Asulay n texxamt tagensant:",
+ "Room version": "Lqem n texxamt",
+ "Room version:": "Lqem n texxamt:",
+ "Open Devtools": "Ldi Devtools",
+ "Notification sound": "Imesli i yilɣa",
+ "Change main address for the room": "Beddel tansa tagejdant n texxamt",
+ "Change permissions": "Beddel tisirag",
+ "Change topic": "Beddel asentel",
+ "Upgrade the room": "Leqqem taxxamt",
+ "Enable room encryption": "Rmed awgelhen n texxamt",
+ "Failed to unban": "Sefsex aḍraq yugi ad yeddu",
+ "Banned by %(displayName)s": "Yettwagi sɣur %(displayName)s",
+ "Send messages": "Azen iznan",
+ "Invite users": "Nced-d iseqdacen",
+ "Change settings": "Snifel iɣewwaren",
+ "Kick users": "Suffeɣ iseqdacen",
+ "Ban users": "Agi yiseqdacen",
+ "Remove messages": "Kkes iznan",
+ "Privileged Users": "Iseqdacen i yettwafernen",
+ "Muted Users": "Iseqdacen i isusmen",
+ "Banned users": "Iseqdacen i yettwagin",
+ "Enable encryption?": "Rmed awgelhen?",
+ "Remove %(email)s?": "Kkes %(email)s?",
+ "Unable to add email address": "D awezɣi ad ternuḍ tansa n yimayl",
+ "Remove %(phone)s?": "Kkes %(phone)s?",
+ "This room is end-to-end encrypted": "Taxxamt-a tettwawgelhen seg yixef ɣer yixef",
+ "Edit message": "Ẓreg izen",
+ "Key request sent.": "Asuter n tsarut yettwazen.",
+ "This message cannot be decrypted": "Izen-a ur yezmir ara ad yettuwgelhen",
+ "Encrypted by a deleted session": "Yettuwgelhen s texxamt yettwakksen",
+ "Scroll to most recent messages": "Drurem ɣer yiznan akk n melmi kan",
+ "Close preview": "Mdel taskant",
+ "and %(count)s others...|other": "d %(count)s wiyaḍ...",
+ "and %(count)s others...|one": "d wayeḍ-nniḍen...",
+ "Invite to this room": "Nced-d ɣer texxamt-a",
+ "Filter room members": "Sizdeg iɛeggalen n texxamt",
+ "%(userName)s (power %(powerLevelNumber)s)": "%(userName)s (i iǧehden %(powerLevelNumber)s",
+ "Voice call": "Asiwel s taɣect",
+ "Video call": "Asiwel s tvidyut",
+ "Send an encrypted reply…": "Azen tiririt yettuwgelhen…",
+ "Send a reply…": "Azen tiririt…",
+ "Send an encrypted message…": "Azen izen yettuwgelhen…",
+ "Send a message…": "Azen izen…",
+ "Italics": "Uknan",
+ "No pinned messages.": "Ulac iznan yerzin.",
+ "Pinned Messages": "Iznan yerzin",
+ "Online for %(duration)s": "Srid azal n %(duration)s",
+ "Idle for %(duration)s": "D arurmid azal n %(duration)s",
+ "Offline for %(duration)s": "Beṛṛa n tuqqna azal n %(duration)s",
+ "Seen by %(userName)s at %(dateTime)s": "Iwala-t %(userName)s at %(dateTime)s",
+ "Replying": "Tiririt",
+ "Guests can join": "Inebgawen zemren ad ttekkin",
+ "(~%(count)s results)|one": "(~%(count)s igmaḍ)",
+ "Join Room": "Rnu ɣer texxamt",
+ "Forget room": "Tettuḍ taxxamt",
+ "Rooms": "Timɣiwent",
+ "Custom Tag": "Sagen tabzimt",
+ "This room": "Taxxamt-a",
+ "Loading …": "La d-yettali…",
+ "Rejecting invite …": "Tigtin n tinnubga…",
+ "Join the conversation with an account": "Ttekki deg udiwenni s umiḍan",
+ "Loading room preview": "Taskant n texxamt i la d-tettali",
+ "Re-join": "Ales attekki",
+ "Try to join anyway": "Ɣas akken ɛreḍ ad tettekkiḍ",
+ "Join the discussion": "Ttekki deg udiwenni",
+ "Start chatting": "Bdu adiwenni",
+ "%(roomName)s is not accessible at this time.": "%(roomName)s ulac anekcum ɣer-s akka tura.",
+ "Show previews of messages": "Sken tiskanin n yiznan",
+ "Jump to first unread room.": "Ɛeddi ɣer texxamt tamezwarut ur nettwaɣra ara.",
+ "Jump to first invite.": "Ɛreddi ɣer tinnubga tamezwarut.",
+ "Add room": "Rnu taxxamt",
+ "All messages": "Iznan i meṛṛa",
+ "Mentions & Keywords": "Ibdaren & Awalen ufrinen",
+ "Forget Room": "Tettuḍ taxxamt",
+ "Leave Room": "Ffeɣ seg texxamt",
+ "Add a topic": "Rnu asentel",
+ "This Room": "Taxxamt-a",
+ "Search…": "Nadi…",
+ "Send as message": "Azen-it d izen",
+ "Add some now": "Rnu kra tura",
+ "Hide Stickers": "Ffer istikiyen",
+ "Failed to revoke invite": "Asefsex n tinnubga ur yeddi ara",
+ "Admin Tools": "Ifecka n unedbal",
+ "Revoke invite": "Sefesex tinnubga",
+ "Invited by %(sender)s": "Yettunced-d sɣur %(sender)s",
+ "not specified": "ur iban ara",
+ "Other published addresses:": "Tansiwin-nniḍen i d-yeffɣen:",
+ "Invalid community ID": "Asulay n temɣiwent d arussin",
+ "Start Verification": "Bdu asenqed",
+ "Verify User": "Senqed aseqdac",
+ "Your messages are not secure": "Iznan-inek·inem d ariɣelsanen",
+ "Hide verified sessions": "Ffer tiɣimiyin yettwasneqden",
+ "%(count)s sessions|other": "Tiɣimiyin n %(count)s",
+ "Hide sessions": "Ffer tiɣimiyin",
+ "Jump to read receipt": "Ɛeddi ɣer tɣuri n wawwaḍ",
+ "Share Link to User": "Bḍu aseɣwen d useqdac",
+ "Disinvite this user?": "Kkes-d tinnubga n useqdac?",
+ "Kick this user?": "Suffeɣ aseqdac-a?",
+ "Remove %(count)s messages|one": "Kkes 1 izen",
+ "Remove recent messages": "Kkes iznan n melmi kan",
+ "Unban this user?": "Sefsex aḍraq n useqdac-a?",
+ "Ban this user?": "Zgel aseqdac-a?",
+ "Failed to mute user": "Tasusmi n useqdac ur yeddi ara",
+ "Remove from community": "Kkes seg temɣiwent",
+ "Disinvite this user from community?": "Kkes tinnubga n useqdac-a seg temɣiwent?",
+ "Remove this user from community?": "Kkes aseqdac-a seg temɣiwent?",
+ "Failed to withdraw invitation": "Tukksa n tinnubga ur yeddi ara",
+ "Deactivate user?": "Kkes aseqdac-a?",
+ "Deactivate user": "Kkes aseqdac",
+ "Verify by scanning": "Senqed s usiggez",
+ "Verify by emoji": "Senqed s yimujit",
+ "Verification timed out.": "Yemmed wakud n usenqed.",
+ "%(displayName)s cancelled verification.": "%(displayName)s isefsex asenqed.",
+ "You cancelled verification.": "Tesfesxeḍ asenqed.",
+ "Verification cancelled": "Yefsex usenqed",
+ "Encryption enabled": "Awgelhen ur yeddi ara",
+ "Decrypt %(text)s": "Wgelhen %(text)s",
+ "Download %(text)s": "Sader %(text)s",
+ "You verified %(name)s": "Tezsneqdeḍ %(name)s",
+ "%(name)s cancelled verifying": "%(name)s isefsex asenqed",
+ "You accepted": "Tqebleḍ",
+ "%(name)s accepted": "%(name)s yettwaqbel",
+ "You declined": "Tugiḍ",
+ "You cancelled": "Tesfesxeḍ",
+ "%(name)s declined": "%(name)s yettwagi",
+ "%(name)s cancelled": "%(name)s yettwasefsex",
+ "%(name)s wants to verify": "%(name)s yebɣa ad isenqed",
+ "Message deleted by %(name)s": "Izen yettwakkes sɣur %(name)s",
+ "Message deleted on %(date)s": "Izen yettwakkes deg %(date)s",
+ "Add an Integration": "Rnu asidef",
+ "Can't load this message": "Yegguma ad d-yali yizen-a",
+ "Submit logs": "Azen iɣmisen",
+ "Filter community members": "Sizdeg imttekkiyen n texxamt",
+ "Invite to this community": "Ancad ɣer temɣiwent",
+ "Visibility in Room List": "Abani n tebdart n texxamin",
+ "Only visible to community members": "Yettban kan i yimttekkiyen n temɣiwent",
+ "Add rooms to this community": "Rnu tixxamin ɣer temɣiwent",
+ "Filter community rooms": "Sizdeg tixxamin ɣer temɣiwent",
+ "Smileys & People": "Acmumeḥ & Imdanen",
+ "Animals & Nature": "Iɣersiwen & ugama",
+ "Activities": "Irmad",
+ "Travel & Places": "Inig & Imukan",
+ "Cancel search": "Sefsex anadi",
+ "Your user ID": "Asulay-ik·m n useqdac",
+ "Your theme": "Asentel-inek·inem",
+ "Room ID": "Asulay n texxamt",
+ "Widget ID": "Asulay n yiwiǧit",
+ "Download this file": "Sali-d afaylu-a",
+ "Manage Integrations": "Sefrek imsidaf",
+ "%(nameList)s %(transitionList)s": "%(nameList)s %(transitionList)s",
+ "Power level": "Sagen aswir",
+ "Custom level": "Sagen aswir",
+ "In reply to": "Deg tririt i",
+ "e.g. my-room": "e.g. taxxamt-inu",
+ "Please provide a room address": "Ttxil-k·m mudd-d tansa n texxamt",
+ "Sign in with single sign-on": "Qqen s unekcum asuf",
+ "And %(count)s more...|other": "D %(count)s ugar...",
+ "Enter a server name": "Sekcem isem n uqeddac",
+ "Matrix": "Matrix",
+ "Matrix ID": "Asulay n Matrix",
+ "Matrix Room ID": "Asulay n n texxamt n Matrix",
+ "The following users may not exist": "Iseqdacen i d-iteddun yezmer ad ilin ulac-iten",
+ "Invite anyway": "Ɣas akken nced-d",
+ "Preparing to send logs": "Aheyyi n tuzna n yiɣmisen",
+ "Failed to send logs: ": "Tuzna n yiɣmisen ur teddi ara: ",
+ "Send logs": "Azen iɣmisen",
+ "Clear all data": "Sfeḍ meṛṛa isefka",
+ "Create Community": "Rnu tamɣiwent",
+ "Community Name": "Isem n temɣiwent",
+ "Please enter a name for the room": "Ttxil-k·m sekcem isem i texxamt",
+ "Enable end-to-end encryption": "Awgelhen seg yixef ɣer yixef ur yeddi ara",
+ "Topic (optional)": "Asentel (afrayan)",
+ "Make this room public": "Err taxxamt-a d tazayezt",
+ "Continue With Encryption Disabled": "Kemmel s uwgelhen yensan",
+ "Confirm your account deactivation by using Single Sign On to prove your identity.": "Sentem asensi n umiḍan s useqdec n unekcum asuf i ubeggen n timagit-ik·im.",
+ "Confirm account deactivation": "Sentem asensi n umiḍan",
+ "Send Custom Event": "Azen tadyant tudmawant",
+ "Event sent!": "Tadyant tettwazen!",
+ "Send Account Data": "Azen isefka n umiḍan",
+ "Filter results": "Igmaḍ n usizdeg",
+ "Verification Requests": "Tuttriwin n usenqed",
+ "Waiting for partner to confirm...": "Aṛaǧu n umendad ad isentem...",
+ "Incoming Verification Request": "Tuttra n usenqed i d-ikecmen",
+ "Confirm to continue": "Sentem i wakken ad tkemmleḍ",
+ "Failed to invite the following users to chat: %(csvUsers)s": "Ancad n yiseqdacen i d-iteddun ɣer udiwenni ur yeddi ara: %(csvUsers)s",
+ "Failed to find the following users": "Ur nessaweḍ ara ad naf iseqdacen",
+ "Recent Conversations": "Idiwenniyen n melmi kan",
+ "Direct Messages": "Iznan usligen",
+ "Upload completed": "Asali yemmed",
+ "Signature upload success": "Asali n uzmul yedda akken iwata",
+ "Clear cache and resync": "Sfeḍ takatut tuffirt syen ales amtawi",
+ "Failed to upgrade room": "Aleqqem n texxamt ur yeddi ara",
+ "Upgrade this room to version %(version)s": "Leqqem taxxamt-a ɣer lqem amaynut %(version)s",
+ "Upgrade Room Version": "Lqem n uleqqem n texxamt",
+ "Automatically invite users": "Nced-d iseqdacen s wudem awurman",
+ "Upgrade private room": "Leqqem taxxamt tusligt",
+ "Upgrade public room": "Leqqem taxxamt tazayezt",
+ "Server isn't responding": "Ulac tiririt sɣur aqeddac",
+ "The server is offline.": "Aqeddac ha-t-an beṛṛa n tuqqna.",
+ "Clear Storage and Sign Out": "Sfeḍ aklas syen ffeɣ seg tuqqna",
+ "Send Logs": "Azen iɣmisen",
+ "Unable to restore session": "D awezɣi ad d-tuɣal texxamt",
+ "Verification Pending": "Asenqed yettṛaǧu",
+ "Share User": "Bḍu aseqdac",
+ "Share Community": "Bḍu tamɣiwent",
+ "Link to selected message": "Aseɣwen n yizen i yettwafernen",
+ "Missing session data": "Isefka n tɣimit xuṣṣen",
+ "Upload all": "Sali-d kullec",
+ "Cancel All": "Sefsex kullec",
+ "Verify other session": "Senqed tiɣimit tayeḍ",
+ "Verification Request": "Asuter n usenqed",
+ "Use your Security Key to continue.": "Seqdec tasarut-ik·im n tɣellist akken ad tkemmleḍ.",
+ "Incorrect recovery passphrase": "Tafyirt tuffirt n uεeddi d tarameɣtut",
+ "Unable to restore backup": "Tiririt n uḥraz tugi ad teddu",
+ "Keys restored": "Tisura ttwaskelsent",
+ "Enter recovery passphrase": "Sekcem tafyirt tuffirt n tririt",
+ "Enter recovery key": "Sekcem tasarut tririt",
+ "Private Chat": "Adiwenni uslig",
+ "Public Chat": "Adiwenni azayez",
+ "Address (optional)": "Tansa (tafrayan)",
+ "Reject invitation": "Agi tinnubga",
+ "Unable to reject invite": "Tegtin n tinnubga tegguma ad teddu",
+ "Resend edit": "Ales tuzna n useẓreg",
+ "Resend removal": "Azen tikkelt-nniḍen tukksa",
+ "Cancel Sending": "Sefsex tuzna",
+ "Share Permalink": "Bḍu aseɣwen ameɣlal",
+ "Share Message": "Bḍu izen",
+ "Collapse Reply Thread": "Fneẓ asqerdec n tririt",
+ "Report Content": "Agbur n uneqqis",
+ "All messages (noisy)": "Iznan i meṛṛa (sɛan ṣṣut)",
+ "Direct Chat": "Adiwenni uslig",
+ "Clear status": "Sfeḍ addaden",
+ "Update status": "Leqqem addaden",
+ "Set a new status...": "Sbadu addad amaynut...",
+ "View Community": "Wali tamɣiwent",
+ "Remove for everyone": "Kkes i meṛṛa",
+ "Remove for me": "Kkes i nekk",
+ "User Status": "Addaden n useqdac",
+ "Start authentication": "Bdu alɣu",
+ "Sign in with SSO": "Anekcum s SSO",
+ "Couldn't load page": "Asali n usebter ur yeddi ara",
+ "Add rooms to the community summary": "Rnu tixxamin ɣer ugzul n temɣiwent",
+ "Which rooms would you like to add to this summary?": "Anti tixxamin i tebɣiḍ ad tent-ternuḍ ɣer uzwel-a?",
+ "Add to summary": "Rnu ɣer ugzul",
+ "Add a Room": "Rnu taxxamt",
+ "Add users to the community summary": "Rnu iseqdacen ɣer ugzul n temɣiwent",
+ "Who would you like to add to this summary?": "Anwa i tebɣiḍ ad t-ternuḍ ɣer ugzul-a?",
+ "Add a User": "Rnu aseqdac",
+ "Failed to update community": "Aleqqem n temɣiwent ur yeddi ara",
+ "Unable to accept invite": "Aqbal n tinnubga d awezɣi",
+ "Unable to join community": "Timerna ɣer temɣiwent d awezɣi",
+ "Leave Community": "Ffeɣ seg temɣiwent",
+ "Leave %(groupName)s?": "Ffeɣ seg %(groupName)s?",
+ "Unable to leave community": "D awezɣi ad teffɣeḍ seg temɣiwent",
+ "Community Settings": "Iɣewwaren n temɣiwent",
+ "Featured Users:": "Iseqdacen i ifazen:",
+ "Join this community": "Rnu ɣer temɣiwent-a",
+ "Leave this community": "Ffeɣ seg temɣiwent-a",
+ "You are an administrator of this community": "Aql-ak·akem d (t)anedbal(t) n temɣiwent-a",
+ "You are a member of this community": "Aql-ak·akem d (t)aɛeggal(t) n temɣiwent-a",
+ "Who can join this community?": "Anwa i izemren ad d-yernu ɣer temɣiwent-a?",
+ "Long Description (HTML)": "Aglam ɣezzifen (HTML)",
+ "Community %(groupId)s not found": "Ur tettwaf ara temɣiwent %(groupId)s",
+ "This homeserver does not support communities": "Aqeddac-a agejdan ur issefrek ara timɣiwanin",
+ "Failed to load %(groupId)s": "Asali n %(groupId)s ur yeddi ara",
+ "Welcome to %(appName)s": "Ansuf ɣer %(appName)s",
+ "Send a Direct Message": "Azen izen uslig",
+ "Failed to reject invitation": "Tigtin n tinnubga ur yeddi ara",
+ "Failed to leave room": "Tuffɣa seg texxamt ur yeddi ara",
+ "Signed Out": "Yeffeɣ seg tuqqna",
+ "Self-verification request": "Asuter n usenqed awurman",
+ "Create a new community": "Rnu tamɣiwent tamaynut",
+ "Remove from Directory": "Kkes seg ukaram",
+ "Unable to join network": "Timerna ɣer uzeṭṭa d tawezɣit",
+ "Clear filter": "Sfeḍ asizdeg",
+ "%(count)s of your messages have not been sent.|one": "Izen-inek·inem ur yettwazen ara.",
+ "Room": "Taxxamt",
+ "Failed to reject invite": "Tigtin n tinnubga ur yeddi ara",
+ "Click to unmute video": "Sit i wakken ad tesremdeḍ tavidyut",
+ "Click to mute video": "Sit i wakken ad tsenseḍ tavidyut",
+ "Click to unmute audio": "Sit i wakken ad tesremdeḍ ameslaw",
+ "Click to mute audio": "Sit i wakken ad tsenseḍ ameslaw",
+ "Switch to light mode": "Uɣal ɣer uskar aceɛlal",
+ "Switch to dark mode": "Uɣal ɣer uskar aberkan",
+ "Switch theme": "Abeddel n usentel",
+ "All settings": "Akk iɣewwaren",
+ "Verify this login": "Senqed anekcam-a",
+ "A new password must be entered.": "Awal uffir amaynut ilaq ad yettusekcem.",
+ "Your Matrix account on ": "Amiḍan-ik·im Matrix deg ",
+ "Send Reset Email": "Azen imayl n uwennez",
+ "Set a new password": "Sbadu awal uffir amaynut",
+ "General failure": "Tuccḍa tamatut",
+ "This account has been deactivated.": "Amiḍan-a yettuḥbes.",
+ "Continue with previous account": "Kemmel s umiḍan yezrin",
+ "Log in to your new account.": "Kcem ɣer umiḍan-ik·im amaynut.",
+ "%(brand)s Web": "%(brand)s Web",
+ "%(brand)s Desktop": "%(brand)s n tnarit",
+ "%(brand)s iOS": "%(brand)s iOS",
+ "%(brand)s Android": "%(brand)s Andriod",
+ "Incorrect password": "Awal uffir d arameɣtu",
+ "Failed to re-authenticate": "Aɛiwed n usesteb ur yeddi ara",
+ "Command Autocomplete": "Asmad awurman n tiludna",
+ "Emoji Autocomplete": "Asmad awurman n yimujit",
+ "Enter a recovery passphrase": "Sekcem tafyirt tuffirt n tririt",
+ "Use an identity server to invite by email. Click continue to use the default identity server (%(defaultIdentityServerName)s) or manage in Settings.": "Seqdec aqeddac n timagit i uncad s yimayl. Sit, tkemmleḍ aseqdec n uqeddac n timagit amezwer (%(defaultIdentityServerName)s) neɣ sefrek deg yiɣewwaren.",
+ "WARNING: KEY VERIFICATION FAILED! The signing key for %(userId)s and session %(deviceId)s is \"%(fprint)s\" which does not match the provided key \"%(fingerprint)s\". This could mean your communications are being intercepted!": "ƔUR-K·M: tASARUT N USENQED UR TEDDI ARA! Tasarut n uzmul n %(userId)s akked tɣimit %(deviceId)s d \"%(fprint)s\" ur imṣada ara d tsarut i d-yettunefken \"%(fingerprint)s\". Ayagi yezmer ad d-yini tiywalin-ik·im ttusweḥlent!",
+ "The signing key you provided matches the signing key you received from %(userId)s's session %(deviceId)s. Session marked as verified.": "Tasarut n uzmul i d-tefkiḍ temṣada d tsarut n uzmul i d-tremseḍ seg tɣimit %(userId)s's %(deviceId)s. Tiɣimit tettucreḍ tettwasenqed.",
+ "Displays list of commands with usages and descriptions": "Yeskan tabdart n tiludna s usegdec d uglam",
+ "%(senderDisplayName)s enabled flair for %(groups)s in this room.": "%(senderDisplayName)s yermed aɣawas i %(groups)s deg texxamt-a.",
+ "%(senderDisplayName)s disabled flair for %(groups)s in this room.": "%(senderDisplayName)s isens aɣawas i %(groups)s deg texxamt-a.",
+ "%(senderDisplayName)s enabled flair for %(newGroups)s and disabled flair for %(oldGroups)s in this room.": "%(senderDisplayName)s yermed aɣawas i %(newGroups)s syen isens aɣawas i %(oldGroups)s deg texxamt-a.",
+ "%(senderName)s revoked the invitation for %(targetDisplayName)s to join the room.": "%(senderName)s yeḥwi tinubga i %(targetDisplayName)s i uttekkki deg texxamt.",
+ "Unicorn": "Azara",
+ "Penguin": "Awarfus",
+ "Octopus": "Azayz",
+ "Globe": "Amaḍal",
+ "Pizza": "Tapizzat",
+ "Spanner": "Tasarut",
+ "Santa": "Santa",
+ "Hourglass": "Amasrag",
+ "Scissors": "Timqestin",
+ "Hammer": "Tafḍist",
+ "Train": "Tamacint",
+ "Aeroplane": "Asafag",
+ "Rocket": "Timeẓdit",
+ "Guitar": "Tagitaṛt",
+ "Trumpet": "Lɣiḍa",
+ "Bell": "Anayna",
+ "Pin": "Amessak",
+ "Your server isn't responding to some requests.": "Aqeddac-inek·inem ur d-yettarra ara ɣef kra n yisuturen.",
+ "Decline (%(counter)s)": "Agi (%(counter)s)",
+ "Failed to upload profile picture!": "Asali n tewlaft n umaɣnu ur yeddui ara!",
+ "No display name": "Ulac meffer isem",
+ "Export E2E room keys": "Sifeḍ tisura n texxamt E2E",
+ "Do you want to set an email address?": "Tebɣiḍ ad tazneḍ tansa n yimayl?",
+ "Your homeserver does not support cross-signing.": "Aqeddac-ik·im agejdan ur yessefrak ara azmul anmidag.",
+ "Cross-signing and secret storage are enabled.": "Azmul anmidag d uklas uffir ur ttwaremden ara.",
+ "Your account has a cross-signing identity in secret storage, but it is not yet trusted by this session.": "Amiḍan-inek·inem ɣer-s timagit n uzmul anmidag deg uklas uffir, maca mazal ur yettwaman ara sɣur taxxamt-a.",
+ "Cross-signing and secret storage are not yet set up.": "Azmul anmidag d uklas uffir mazal ar tura ur ttusbadeun ara.",
+ "Reset cross-signing and secret storage": "Wennez azmul anmidag d uklas uffir",
+ "Bootstrap cross-signing and secret storage": "Azmul anmidag s tazwara d uklas uffir",
+ "well formed": "imsel akken iwata",
+ "unexpected type": "anaw ur nettwaṛǧa ara",
+ "Cross-signing public keys:": "Tisura n uzmul anmidag tizuyaz:",
+ "in memory": "deg tkatut",
+ "Cross-signing private keys:": "Tisura tusligin n uzmul anmidag:",
+ "Create room": "Rnu taxxamt",
+ "System Alerts": "Ilɣa n unagraw",
+ "Forget this room": "Ttu taxxamt-a",
+ "Reject & Ignore user": "Agi & Zgel aseqdac",
+ "%(roomName)s does not exist.": "%(roomName)s ulac-it.",
+ "Don't ask me again": "Ur d-sutur ara tikelt-nniḍen",
+ "Show rooms with unread messages first": "Sken tixxamin yesεan iznan ur nettwaɣra ara d timezwura",
+ "List options": "Tixtiṛiyin n tebdart",
+ "Show %(count)s more|other": "Sken %(count)s ugar",
+ "Show %(count)s more|one": "Sken %(count)s ugar",
+ "Use default": "Seqdec udem amezwer",
+ "Notification options": "Tixtiṛiyin n wulɣu",
+ "Room options": "Tixtiṛiyin n texxamt",
+ "%(count)s unread messages including mentions.|one": "1 ubdar ur nettwaɣra ara.",
+ "%(count)s unread messages.|other": "Iznan ur nettwaɣra ara %(count)s.",
+ "%(count)s unread messages.|one": "1 yizen ur nettwaɣra ara.",
+ "Unread messages.": "Iznan ur nettwaɣra ara.",
+ "All Rooms": "Akk tixxamin",
+ "Unknown Command": "Taladna tarussint",
+ "Show Stickers": "Sken istikiyen",
+ "Mark all as read": "Creḍ kullec yettwaɣra",
+ "Error creating address": "Tuccḍa deg tmerna n tensa",
+ "Error removing address": "Tuccḍa deg tukksa n tensa",
+ "Main address": "Tansa tagejdant",
+ "Local address": "Tansa tadigant",
+ "Published Addresses": "Tansiwin tizuyaz",
+ "Local Addresses": "Tansiwin tidiganin",
+ "Room Name": "Isem n texxamt",
+ "Room Topic": "Asentel n texxamt",
+ "Room avatar": "Avaṭar n texxamt",
+ "Accepting…": "Aqbal…",
+ "Your homeserver": "Aqeddac-ik·im agejdan",
+ "Accepting …": "Aqbal…",
+ "Your display name": "Isem-ik·im yettwaskanen",
+ "Your avatar URL": "URL n avatar-inek·inem",
+ "%(brand)s URL": "%(brand)s URL",
+ "Using this widget may share data with %(widgetDomain)s & your Integration Manager.": "Aseqdec n uwiǧit-a yezmer ad yebḍu isefka d %(widgetDomain)s & amsefrak-inek·inem n umsidef.",
+ "Using this widget may share data with %(widgetDomain)s.": "Aseqdec n uwiǧit-a yezmer ad bḍun yisefka d %(widgetDomain)s.",
+ "Widgets do not use message encryption.": "Iwiǧiten ur seqdacen ara awgelhen n yiznan.",
+ "Widget added by": "Awiǧit yettwarna sɣur",
+ "This widget may use cookies.": "Awiǧit-a yezmer ad iseqdec inagan n tuqqna.",
+ "Delete Widget": "Kkes awiǧit",
+ "Deleting a widget removes it for all users in this room. Are you sure you want to delete this widget?": "Tukksan n uwiǧit, ad t-tekkes akk i yiseqdacen n texxamt-nni. D tidet tebɣiḍ ad tekkseḍ awiǧit-a?",
+ "Delete widget": "Kkes awiǧit",
+ "Failed to remove widget": "Tukksa n uwiǧit ur teddi ara",
+ "An error ocurred whilst trying to remove the widget from the room": "Tella-d tuccḍa lawan n tukksa n uwiǧit seg texxamt",
+ "Minimize apps": "Semi isnasen",
+ "Maximize apps": "Semer isnasen",
+ "Popout widget": "Awiǧit attalan",
+ "Please create a new issue on GitHub so that we can investigate this bug.": "Ttxil-k·m rnu ugur amaynut deg GitHub akken ad nessiweḍ ad nezrew abug-a.",
+ "expand": "snefli",
+ "You cannot delete this image. (%(code)s)": "Ur tezmireḍ ara ad tekkseḍ tugna-a. (%(code)s)",
+ "Uploaded on %(date)s by %(user)s": "Yuli-d deg %(date)s sɣur %(user)s",
+ "Rotate Left": "Zzi ɣer uzelmaḍ",
+ "Rotate Right": "Zzi ɣer uyeffus",
+ "Language Dropdown": "Tabdart n udrurem n tutlayin",
+ "%(severalUsers)sjoined %(count)s times|other": "%(severalUsers)srnan-d %(count)s tikkal",
+ "%(severalUsers)sjoined %(count)s times|one": "%(severalUsers)srnan-d",
+ "%(oneUser)sjoined %(count)s times|other": "%(oneUser)syerna-d %(count)s tikkal",
+ "%(oneUser)sjoined %(count)s times|one": "%(oneUser)syerna-d",
+ "%(severalUsers)sleft %(count)s times|other": "%(severalUsers)sffɣen %(count)s tikkal",
+ "%(severalUsers)sleft %(count)s times|one": "%(severalUsers)s ffɣen",
+ "%(oneUser)sleft %(count)s times|other": "%(oneUser)s yeffeɣ %(count)s tikkal",
+ "%(oneUser)sleft %(count)s times|one": "%(oneUser)s yeffeɣ",
+ "%(severalUsers)sjoined and left %(count)s times|other": "%(severalUsers)srnan-d syen ffɣen %(count)s tikkal",
+ "%(severalUsers)sjoined and left %(count)s times|one": "%(severalUsers)srnan-d syen ffɣen",
+ "%(oneUser)sjoined and left %(count)s times|other": "%(oneUser)syerna-d syen yeffeɣ %(count)s tikkal",
+ "%(oneUser)sjoined and left %(count)s times|one": "%(oneUser)syerna-d syen yeffeɣ",
+ "%(severalUsers)sleft and rejoined %(count)s times|other": "%(severalUsers)sffɣen syen uɣalen-d %(count)s tikkal",
+ "%(severalUsers)sleft and rejoined %(count)s times|one": "%(severalUsers)sffɣen syen uɣalen-d",
+ "%(oneUser)sleft and rejoined %(count)s times|other": "%(oneUser)syeffeɣ-d syen yuɣal-d %(count)s tikkal",
+ "%(oneUser)sleft and rejoined %(count)s times|one": "%(oneUser)syeffeɣ-d syen yuɣal-d",
+ "%(severalUsers)srejected their invitations %(count)s times|other": "%(severalUsers)sugin tinubgiwin-nsen %(count)s tikkal",
+ "%(severalUsers)srejected their invitations %(count)s times|one": "%(severalUsers)sugin tinubgiwin-nsen",
+ "%(oneUser)srejected their invitation %(count)s times|other": "%(oneUser)syugi tinubga-ines %(count)s tikkal",
+ "%(oneUser)srejected their invitation %(count)s times|one": "%(oneUser)syugi tinubga-ines",
+ "%(severalUsers)shad their invitations withdrawn %(count)s times|other": "%(severalUsers)sunfen i tinubgiwin-nsen yettwagin %(count)s tikkal",
+ "%(severalUsers)shad their invitations withdrawn %(count)s times|one": "%(severalUsers)sunfen i tinubgiwin-nsen yettwagin",
+ "%(oneUser)shad their invitation withdrawn %(count)s times|other": "%(oneUser)syunef i tinubga-ines yettwagin %(count)s tikkal",
+ "%(oneUser)shad their invitation withdrawn %(count)s times|one": "%(oneUser)syunef i tinubga-ines yettwagin",
+ "were invited %(count)s times|other": "ttwanecden-d %(count)s tikkal",
+ "were invited %(count)s times|one": "ttwanecden-d",
+ "was invited %(count)s times|other": "yettwanced-d %(count)s tikkal",
+ "was invited %(count)s times|one": "yettwanced-d",
+ "were banned %(count)s times|other": "ttwazeglen %(count)s tikkal",
+ "were banned %(count)s times|one": "ttwazeglen",
+ "was banned %(count)s times|other": "yettwazgel %(count)s tikkal",
+ "was banned %(count)s times|one": "yettwazgel",
+ "were unbanned %(count)s times|other": "ur ttwazeglen ara %(count)s tikkal",
+ "were unbanned %(count)s times|one": "ur ttwazeglen ara",
+ "was unbanned %(count)s times|other": "ur yettwazgel ara %(count)s tikkal",
+ "was unbanned %(count)s times|one": "ur yettwazgel ara",
+ "were kicked %(count)s times|other": "ttwasuffɣen %(count)s tikkal",
+ "were kicked %(count)s times|one": "ttwasuffɣen",
+ "was kicked %(count)s times|other": "yettwasuffeɣ %(count)s tikkal",
+ "was kicked %(count)s times|one": "yettwasuffeɣ",
+ "%(severalUsers)schanged their name %(count)s times|other": "%(severalUsers)sbeddlen ismawen-nsen %(count)s tikkal",
+ "%(severalUsers)schanged their name %(count)s times|one": "%(severalUsers)sbeddlen ismawen-nsen",
+ "%(oneUser)schanged their name %(count)s times|other": "%(oneUser)sibeddel isem-is %(count)s tikkal",
+ "%(oneUser)schanged their name %(count)s times|one": "%(oneUser)sibeddel isem-is",
+ "%(severalUsers)schanged their avatar %(count)s times|other": "%(severalUsers)sbeddlen ivaṭaren-nsen %(count)s tikkal",
+ "%(severalUsers)schanged their avatar %(count)s times|one": "%(severalUsers)sbeddlen ivaṭaren-nsen",
+ "%(oneUser)schanged their avatar %(count)s times|other": "%(oneUser)sibeddel avaṭar-ines %(count)s tikkal",
+ "%(oneUser)schanged their avatar %(count)s times|one": "%(oneUser)sibeddel avaṭar-ines",
+ "%(severalUsers)smade no changes %(count)s times|other": "%(severalUsers)sur gin ara isnifal %(count)s tikkal",
+ "%(severalUsers)smade no changes %(count)s times|one": "%(severalUsers)sur gin ara isnifal",
+ "%(oneUser)smade no changes %(count)s times|other": "%(oneUser)sur ye gi ara isnifal %(count)s tikkal",
+ "%(oneUser)smade no changes %(count)s times|one": "%(oneUser)sur ye gi ara isnifal",
+ "QR Code": "Tangalt QR",
+ "Unable to load event that was replied to, it either does not exist or you do not have permission to view it.": "YEgguma ad d-tali tedyant iɣef d-ttunefk tririt, ahat d tilin ur telli ara neɣ ur tesɛiḍ ara tisirag ad tt-twaliḍ.",
+ "Room address": "Tansa n texxamt",
+ "Some characters not allowed": "Kra n yisekkilen ur ttusirgen ara",
+ "This address is available to use": "Tansa-a tella i useqdec",
+ "This address is already in use": "Tansa-a ha-tt-an yakan deg useqdec",
+ "Room directory": "Akaram n texxamt",
+ "ex. @bob:example.com": "am. @bob:amedya.com",
+ "Looks good": "Ayagi yettban yelha",
+ "Can't find this server or its room list": "D awezɣi ad d-naf aqeddac-a neɣ tabdart-is n texxamt",
+ "All rooms": "Akk tixxamin",
+ "Your server": "Aqeddac-ik·im",
+ "Are you sure you want to remove %(serverName)s": "D tidet tebɣiḍ ad tekkseḍ %(serverName)s",
+ "Remove server": "Kkes aqeddac",
+ "Add a new server": "Rnu aqeddac amaynut",
+ "Enter the name of a new server you want to explore.": "Sekcem isem n uqeddac amaynut i tebɣiḍ ad tesnirmeḍ.",
+ "Add a new server...": "Rnu aqeddac amaynut...",
+ "%(networkName)s rooms": "Tixxamin %(networkName)s",
+ "Matrix rooms": "Tixxamin n Matrix",
+ "That doesn't look like a valid email address": "Ur tettban ara d tansa n yimayl tameɣtut",
+ "You have entered an invalid address.": "Teskecmeḍ tansa n yimayl tarameɣtut.",
+ "Try using one of the following valid address types: %(validTypesList)s.": "Ɛreḍ ad tesqedceḍ yiwen seg wanawen n tansa tameɣtut i d-iteddun: %(validTypesList)s.",
+ "Use an identity server to invite by email. Use the default (%(defaultIdentityServerName)s) or manage in Settings.": "Seqdec aqeddac n timagit i uncad s yimayl. Seqdec (%(defaultIdentityServerName)s) amezwer neɣ sefrek deg yiɣewwaren.",
+ "Use an identity server to invite by email. Manage in Settings.": "Seqdec aqeddac n timagit i uncad s yimayl. Sefrek deg yiɣewwaren.",
+ "This room is public": "Taxxamt-a d tazayezt",
+ "Terms and Conditions": "Tiwtilin d tfadiwin",
+ "Review terms and conditions": "Senqed tiwtilin d tfadiwin",
+ "Your Communities": "Timɣiwnin-inek·inem",
+ "Communities": "Timɣiwnin",
+ "Remove %(name)s from the directory?": "Kkes %(name)s seg ukaram?",
+ "delete the address.": "kkes tansa.",
+ "Room not found": "Ur tettwaf ara texxamt",
+ "Find a room…": "Af-d taxxamt…",
+ "Search rooms": "Nadi tixxamin",
+ "%(senderName)s sent an invitation to %(targetDisplayName)s to join the room.": "%(senderName)s yuzen tinubga i %(targetDisplayName)s i wakken ad d-yernu ɣer texxamt.",
+ "%(senderName)s made future room history visible to all room members, from the point they are invited.": "%(senderName)s yerra amazray n texxamt tamaynut yettban i meṛṛa iɛeggalen n texxamt, segmi ara d-ttwanecden.",
+ "%(senderName)s made future room history visible to all room members, from the point they joined.": "%(senderName)s yerra amazray n texxamt tamaynut yettban i meṛṛa iɛeggalen n texxamt, segmi ara d-rnun.",
+ "%(senderName)s made future room history visible to all room members.": "%(senderName)s yerra amazray n texxamt tamaynut yettban i meṛṛa iɛeggalen n texxamt.",
+ "%(senderName)s made future room history visible to unknown (%(visibility)s).": "%(senderName)s yerra amazray n texxamt tamaynut yettban i wid ur nettwassen ara (%(visibility)s).",
+ "%(userId)s from %(fromPowerLevel)s to %(toPowerLevel)s": "%(userId)s seg %(fromPowerLevel)s ɣer %(toPowerLevel)s",
+ "%(senderName)s changed the power level of %(powerLevelDiffText)s.": "%(senderName)s yettwabeddel uswir afellay n %(powerLevelDiffText)s.",
+ "%(senderName)s removed the rule banning users matching %(glob)s": "%(senderName)s yekkes alugen i yugin iseqdacen yemṣadan d %(glob)s",
+ "%(senderName)s removed the rule banning rooms matching %(glob)s": "%(senderName)s yekkes alugen i yugin tixxamin yemṣadan d %(glob)s",
+ "%(senderName)s removed the rule banning servers matching %(glob)s": "%(senderName)s yekkes alugen i yugin iqeddacen yemṣadan d %(glob)s",
+ "%(senderName)s removed a ban rule matching %(glob)s": "%(senderName)s yekkes alugen n tigtin yemṣadan d %(glob)s",
+ "%(senderName)s updated an invalid ban rule": "%(senderName)s ileqqem alugen n tigtin arameɣtu",
+ "%(senderName)s updated the rule banning users matching %(glob)s for %(reason)s": "%(senderName)s ileqqem alugen i yugin iseqdacen yemṣadan d %(glob)s i %(reason)s",
+ "%(senderName)s updated the rule banning rooms matching %(glob)s for %(reason)s": "%(senderName)s ileqqem alugen i yugin tixxamin yemṣadan d %(glob)s i %(reason)s",
+ "%(senderName)s updated the rule banning servers matching %(glob)s for %(reason)s": "%(senderName)s ileqqem alugen i yugin iqeddacen yemṣadan d %(glob)s i %(reason)s",
+ "%(senderName)s updated a ban rule matching %(glob)s for %(reason)s": "%(senderName)s ileqqem alugen n tigtin yemṣadan d %(glob)s i %(reason)s",
+ "%(senderName)s created a rule banning users matching %(glob)s for %(reason)s": "%(senderName)s yerna alugen i yugin iseqdacen yemṣadan d %(glob)s i %(reason)s",
+ "%(senderName)s created a rule banning rooms matching %(glob)s for %(reason)s": "%(senderName)s yerna alugen i yugin tixxamin yemṣadan d %(glob)s i %(reason)s",
+ "%(senderName)s created a rule banning servers matching %(glob)s for %(reason)s": "%(senderName)s yerna alugen i yugin iqeddacen yemṣadan d %(glob)s i %(reason)s",
+ "%(senderName)s created a ban rule matching %(glob)s for %(reason)s": "%(senderName)s yerna alugen yemṣadan d %(glob)s i %(reason)s",
+ "%(senderName)s changed a rule that was banning users matching %(oldGlob)s to matching %(newGlob)s for %(reason)s": "%(senderName)s ibeddel alugen i yugin iseqdacen yemṣadan d %(oldGlob)s deg %(newGlob)s yemṣadan i %(reason)s",
+ "%(senderName)s changed a rule that was banning rooms matching %(oldGlob)s to matching %(newGlob)s for %(reason)s": "%(senderName)s ibeddel alugen i yugin tixxamin yemṣadan d %(oldGlob)s deg %(newGlob)s yemṣadan i %(reason)s",
+ "%(senderName)s changed a rule that was banning servers matching %(oldGlob)s to matching %(newGlob)s for %(reason)s": "%(senderName)s ibeddel alugen i yugin tixxamin iqeddacen d %(oldGlob)s deg %(newGlob)s yemṣadan i %(reason)s",
+ "%(senderName)s updated a ban rule that was matching %(oldGlob)s to matching %(newGlob)s for %(reason)s": "%(senderName)s ibeddel alugen i yemṣadan d %(oldGlob)s deg %(newGlob)s yemṣadan i %(reason)s",
+ "You signed in to a new session without verifying it:": "Teqqneḍ ɣer tɣimit war ma tesneqdeḍ-tt:",
+ "Verify your other session using one of the options below.": "Senqed tiɣimiyin-ik·im tiyaḍ s useqdec yiwet seg textiṛiyin ddaw.",
+ "%(name)s (%(userId)s) signed in to a new session without verifying it:": "%(name)s (%(userId)s) yeqqen ɣer tɣimit tamaynut war ma isenqed-itt:",
+ "Ask this user to verify their session, or manually verify it below.": "Suter deg useqdac-a ad isenqed tiɣimit-is, neɣ senqed-itt ddaw s ufus.",
+ "Ensure you have a stable internet connection, or get in touch with the server admin": "Ḍmen qbel tesɛiḍ tuqqna i igerrzen, neɣ nermes anedbal n uqeddac",
+ "Ask your %(brand)s admin to check your config for incorrect or duplicate entries.": "Suter deg %(brand)s unedbal ad isenqed tawila-ik·im n unekcam arameɣtu neɣ i d-yuɣalen.",
+ "The message you are trying to send is too large.": "Izen i tettaɛraḍeḍ ad t-tazneḍ ɣezzif aṭas.",
+ "This homeserver has hit its Monthly Active User limit.": "Aqeddac-a agejdan yewweḍ ɣer talast n useqdac urmid n wayyur.",
+ "Please contact your service administrator to continue using the service.": "Ttxil-k·m nermes anedbal-ik·im n uqeddac i wakken ad tkemmleḍ aseqdec n uqeddac.",
+ "Unable to connect to Homeserver. Retrying...": "Yegguma ad yeqqen ɣer uqeddac agejdan. Ales aneɛruḍ...",
+ "Use a few words, avoid common phrases": "Seqdec kra n wawalen, sinef i tefyar i d-yettuɣalen",
+ "No need for symbols, digits, or uppercase letters": "Ulayɣer izamulen, izwilen d yisekkilen imeqqranen",
+ "Make a copy of your recovery key": "Eg anɣal i tsarut-ik·im n uɛeddi",
+ "Create key backup": "Rnu aḥraz n tsarut",
+ "Unable to create key backup": "Yegguma ad yernu uḥraz n tsarut",
+ "If you don't want to set this up now, you can later in Settings.": "Ma yella ur tebɣiḍ ara ad t-tesbaduḍ tura, tzemreḍ ad t-tgeḍ mbeɛd deg yiɣewwaren.",
+ "A new recovery passphrase and key for Secure Messages have been detected.": "Tasarut tuffirt n uɛeddi tamaynut d tsarut i tɣellist n yiznan ttwafent.",
+ "This session is encrypting history using the new recovery method.": "Tiɣimit-a, amazray-ines awgelhen yesseqdac tarrayt n uɛeddi tamaynut.",
+ "If disabled, messages from encrypted rooms won't appear in search results.": "Ma yella tensa, iznan n texxamin tiwgelhanin ur d-ttbanen ara deg yigmaḍ n unadi.",
+ "%(brand)s is securely caching encrypted messages locally for them to appear in search results:": "%(brand)s iteffer iznan iwgelhanen idiganen s wudem aɣelsan i wakken ad d-banen deg yigmaḍ n unadi:",
+ "Message downloading sleep time(ms)": "Akud n usgunfu n usali n yiznan (ms)",
+ "Dismiss read marker and jump to bottom": "Zgel ticreḍt n tɣuri, tɛeddiḍ d akessar",
+ "Show display name changes": "Sken isnifal n yisem yettwaskanen",
+ "Show read receipts sent by other users": "Sken awwaḍen n tɣuri yettwaznen sɣur yiseqdacen-nniḍen",
+ "Show timestamps in 12 hour format (e.g. 2:30pm)": "Sken azemzakud s umasal 12 yisragen (am. 14:30)",
+ "Always show message timestamps": "Sken yal tikkelt azemzakud n yiznan",
+ "Autoplay GIFs and videos": "Taɣuri tawurmant n GIFs d tvidyutin",
+ "When I'm invited to a room": "Mi ara d-ttunecdeɣ ɣer texxamt",
+ "This is your list of users/servers you have blocked - don't leave the room!": "Tagi d tabdart-ik·im n yiseqdacen/yiqeddacen i tesweḥleḍ - ur teffeɣ ara seg texxamt!",
+ "Active call": "Asiwel urmid",
+ "Verified!": "Yettwasenqed!",
+ "Scan this unique code": "Ḍumm tangalt-a tasuft",
+ "Compare unique emoji": "Serwes gar yimujiten asufen",
+ "in secret storage": "deg uklas uffir",
+ "Master private key:": "Tasarut tusligt tagejdant:",
+ "cached locally": "yettwaffer s wudem adigan",
+ "not found locally": "ulac s wudem adigan",
+ "Self signing private key:": "Tasarut tusligt n uzmul awurman:",
+ "User signing private key:": "Tasarut tusligt n uzmul n useqdac:",
+ "Session backup key:": "Tasarut n uḥraz n tɣimit:",
+ "Secret storage public key:": "Tasarut tazayezt n uḥraz uffir:",
+ "Homeserver feature support:": "Asefrek n tmahilt n Homeserver:",
+ "exists": "yella",
+ "Your homeserver does not support session management.": "Aqeddac-ik·im agejdan ur yessefrak ara asefrek n tɣimit.",
+ "Unable to load session list": "Asali n tebdart n tɣimit ur yeddi ara",
+ "Click the button below to confirm deleting these sessions.|other": "Sit ɣef tqeffalt ddaw akken ad tesnetmeḍ tukksa n tɣimiyin-a.",
+ "Click the button below to confirm deleting these sessions.|one": "Sit ɣef tqeffalt ddaw akken ad tesnetmeḍ tukksa n tɣimit-a.",
+ "Unable to load key backup status": "Asali n waddad n uḥraz n tsarut ur yeddi ara",
+ "not stored": "ur yettusekles ara",
+ "Backing up %(sessionsRemaining)s keys...": "Aḥraz n tsura %(sessionsRemaining)s...",
+ "Backup has a valid signature from this user": "Aḥraz ɣer-s azmul ameɣtu sɣur aseqdac-a",
+ "Backup has a invalid signature from this user": "Aḥraz ɣer-s azmul arameɣtu sɣur aseqdac-a",
+ "Backup has a signature from unknown user with ID %(deviceId)s": "Aḥraz ɣer-s azmul sɣur useqdac arussin s usulay %(deviceId)s",
+ "Backup has a signature from unknown session with ID %(deviceId)s": "Aḥraz ɣer-s azmul seg tiɣimit arussin s usulay %(deviceId)s",
+ "Backup has a valid signature from this session": "Aḥraz ɣer-s azmul ameɣtu seg tɣimit-a",
+ "Backup has an invalid signature from this session": "Aḥraz ɣer-s azmul arameɣtu seg tɣimit-a",
+ "Backup has a valid signature from verified session ": "Aḥraz ɣer-s azmul ameɣtu seg tɣimit yettwasneqden ",
+ "Backup has a valid signature from unverified session ": "Aḥraz ɣer-s azmul ameɣtu seg tɣimit ur yettwasneqden ara ",
+ "Backup has an invalid signature from verified session ": "Aḥraz ɣer-s azmul arameɣtu seg tɣimit yettwasneqden ",
+ "Backup has an invalid signature from unverified session ": "Aḥraz ɣer-s azmul arameɣtu seg tɣimit ur yettwasneqden ara ",
+ "Backup is not signed by any of your sessions": "Aḥraz ur yettuzmel ara ula seg yiwet n tɣimit-ik·im",
+ "Algorithm: ": "Alguritm: ",
+ "Backup key stored: ": "Tasarut n uḥraz tettwasekles: ",
+ "Your keys are not being backed up from this session.": "Tisura-inek·inem ur ttwaḥrazent ara seg tɣimit-a.",
+ "Start using Key Backup": "Bdu aseqdec n uḥraz n tsarut",
+ "Flair": "Lbenna",
+ "Failed to change password. Is your password correct?": "Asnifel n wawal uffir ur yeddi ara. Awal-ik·im d ameɣtu?",
+ "Email addresses": "Tansiwin n yimayl",
+ "Phone numbers": "Uṭṭunen n tiliɣri",
+ "Language and region": "Tutlayt d temnaḍt",
+ "Yours, or the other users’ session": "Tiɣimit-ik·im neɣ tin n yiseqdacen wiyaḍ",
+ "Not trusted": "Ur yettwattkal ara",
+ "%(count)s verified sessions|other": "%(count)s isenqed tiɣimiyin",
+ "%(count)s verified sessions|one": "1 n tɣimit i yettwasneqden",
+ "%(count)s sessions|one": "Tiɣimit n %(count)s",
+ "Direct message": "Izen uslig",
+ "Demote yourself?": "Ṣubb deg usellun-ik·im?",
+ "Demote": "Ṣubb deg usellun",
+ "Disinvite": "Kkes-d tinnubga",
+ "Kick": "Suffeɣ",
+ "Failed to kick": "Asuffeɣ ur yeddi ara",
+ "No recent messages by %(user)s found": "Ulac iznan i yettwafen sɣur %(user)s",
+ "Try scrolling up in the timeline to see if there are any earlier ones.": "Ɛreḍ adrurem deg wazemzakud i wakken ad twaliḍ ma yella llan wid yellan uqbel.",
+ "Remove recent messages by %(user)s": "Kkes iznan n melmi kan sɣur %(user)s",
+ "You are about to remove %(count)s messages by %(user)s. This cannot be undone. Do you wish to continue?|other": "Aql-ak·akem akken ara tekkseḍ iznan n %(count)s sɣur %(user)s. Ulac tuɣalin ɣer deffir deg waya. Tebɣiḍ ad tkemmleḍ?",
+ "You are about to remove %(count)s messages by %(user)s. This cannot be undone. Do you wish to continue?|one": "Aql-ak·akem akken ara tekkseḍ 1 yizen sɣur %(user)s. Ulac tuɣalin ɣer deffir deg waya. Tebɣiḍ ad tkemmleḍ?",
+ "For a large amount of messages, this might take some time. Please don't refresh your client in the meantime.": "I tugget meqqren n yiznan, ayagi yezmer ad yeṭṭef kra n wakud. Ṛǧu ur sirin ara amsaɣ-ik·im deg leɛḍil.",
+ "Remove %(count)s messages|other": "Kkes iznan n %(count)s",
+ "Ban": "Agi",
+ "Failed to ban user": "Tigtin n useqdac ur yeddi ara",
+ "Failed to remove user from community": "Tukksa n useqdac seg temɣiwent ur yeddi ara",
+ "%(role)s in %(roomName)s": "%(role)s deg %(roomName)s",
+ "Failed to change power level": "Asnifel n uswir afellay ur yeddi ara",
+ "Failed to deactivate user": "Asensi n useqdac ur yeddi ara",
+ "This client does not support end-to-end encryption.": "Amsaɣ-a ur yessefrak ara awgelhen seg yixef ɣer yixef.",
+ "Ask %(displayName)s to scan your code:": "Suter deg %(displayName)s aḍummu n tengalt-ik·im:",
+ "If you can't scan the code above, verify by comparing unique emoji.": "Ma yella ur tezmireḍ ara ad tḍummeḍ tangalt nnig, senqed s userwes s yimujiten asufen.",
+ "Verify by comparing unique emoji.": "Senqed s userwes s yimujiten asufen.",
+ "Almost there! Is your other session showing the same shield?": "Qrib ad tawḍeḍ! Wissen ma yella tiɣimit-ik·im-nniḍen kifkif aɣar i d-teskanay?",
+ "Almost there! Is %(displayName)s showing the same shield?": "Qrib ad tawḍeḍ! Wissen ma yella%(displayName)s kifkif aɣar i d-yeskanay?",
+ "Verify all users in a room to ensure it's secure.": "Senqed akk iseqdacen yellan deg texxamt i wakken ad tḍemneḍ d taɣelsant.",
+ "In encrypted rooms, verify all users to ensure it’s secure.": "Deg texxamin tiwgelhanin, senqed akk iseqdacen i wakken ad tḍemneḍ d tiɣelsanin.",
+ "You've successfully verified your device!": "Tesneqdeḍ akken iwata ibenk-inek·inem!",
+ "You've successfully verified %(deviceName)s (%(deviceId)s)!": "Tesneqdeḍ akken iwata %(deviceName)s (%(deviceId)s)!",
+ "You've successfully verified %(displayName)s!": "Tesneqdeḍ akken iwata %(displayName)s!",
+ "Start verification again from the notification.": "Bdu asenqed daɣen seg ulɣu.",
+ "Start verification again from their profile.": "Bdu asenqed daɣen seg umaɣnu-nsen.",
+ "You cancelled verification on your other session.": "Tesfesxeḍ asenqed deg tɣimiyin tiyaḍ.",
+ "Compare emoji": "Serwes imujiten",
+ "Encryption not enabled": "Awgelhen ur yermid ara",
+ "The encryption used by this room isn't supported.": "Awgelhen yettusqedcen ur yettusefrak ara s texxamt-a.",
+ "Error decrypting audio": "Tuccḍa deg uwgelhen n umeslaw",
+ "React": "Sedmer",
+ "Message Actions": "Tigawin n yizen",
+ "Invalid file%(extra)s": "D afaylu %(extra)s arameɣtu",
+ "Error decrypting image": "Tuccḍa deg uwgelhen n tugna",
+ "Show image": "Sken tugna",
+ "Invalid base_url for m.identity_server": "D arameɣtu base_url i m.identity_server",
+ "Signing In...": "Anekcum ɣer...",
+ "If you've joined lots of rooms, this might take a while": "Ma yella tettekkaḍ deg waṭas n texxamin, ayagi yezmer ad yeṭṭef kra n wakud",
+ "Set a display name:": "Sbadu isem n uskan:",
+ "Upload an avatar:": "Sali-d avaṭar:",
+ "Use Recovery Key": "Seqdec tasarut n uɛeddi",
+ "Emoji": "Imujit",
+ "For maximum security, this should be different from your account password.": "I wugar n tɣellist, wagi ilaq ad yemgarad ɣef wawal uffir n umiḍan-ik·im.",
+ "Set up with a recovery key": "Sbadu s tsarut n uɛeddi",
+ "Please enter your recovery passphrase a second time to confirm.": "Ttxil-ik·im sekcem tafyirt-ik·im tuffirt n uɛeddi tikkelt tis sant i usentem.",
+ "Repeat your recovery passphrase...": "Ales-as i tefyirt-ik·im tuffirt n uɛeddi...",
+ "Keep a copy of it somewhere secure, like a password manager or even a safe.": "Ḥrez anɣal-ines deg wadeg aɣelsan, am umsefrak n wawalen uffiren neɣ am usenduq iǧehden.",
+ "Your recovery key": "Tasarut-ik·im n uɛeddi",
+ "Your recovery key has been copied to your clipboard, paste it to:": "Tasarut-ik·im n uɛeddi tettwanɣel ɣer ɣef wafus, senteḍ-itt deg:",
+ "Your recovery key is in your Downloads folder.": "Tasarut-ik·im n tririt ha-tt-an deg ufaylu n yisidar.",
+ "Print it and store it somewhere safe": "Siggez-itt syen kles-itt deg wadeg aɣelsan",
+ "Save it on a USB key or backup drive": "Sekles-itt ɣef tsarut USB neɣ deg yibenk n uḥraz",
+ "Copy it to your personal cloud storage": "Nɣel-itt ɣer uklas-ik·im n usigna udmawan",
+ "Your keys are being backed up (the first backup could take a few minutes).": "Tisura-ik·im la ttwaḥrazent (aḥraz amezwaru yezmer ad yeṭṭef kra n tesdidin).",
+ "Set up Secure Message Recovery": "Sbadu iznan iɣelsanen n tririt",
+ "Secure your backup with a recovery passphrase": "Ḍmen aḥrazen-inek·inem s tefyirt tuffirt n uɛeddi",
+ "Unexpected error resolving homeserver configuration": "Tuccḍa ur nettwaṛǧa ara lawan n uṣeggem n twila n uqeddac agejdan",
+ "Unexpected error resolving identity server configuration": "Tuccḍa ur nettwaṛǧa ara lawan n uṣeggem n uqeddac n timagit",
+ "This homeserver has exceeded one of its resource limits.": "Aqeddac-a agejdan iɛedda yiwet seg tlisa-ines tiɣbula.",
+ "Your browser does not support the required cryptography extensions": "Iminig-ik·im ur issefrak ara iseɣzaf n uwgelhen yettusran",
+ "Authentication check failed: incorrect password?": "Asenqed n usesteb ur yeddi ara: awal uffir d arameɣtu?",
+ "Can't leave Server Notices room": "Ur nezmir ara ad neǧǧ taxxamt n yiwenniten n uqeddac",
+ "This room is used for important messages from the Homeserver, so you cannot leave it.": "Taxxamt-a tettuseqdac i yiznan yesɛan azal sɣur aqeddac agejdan, ɣef waya ur tezmireḍ ara ad tt-teǧǧeḍ.",
+ "Error leaving room": "Tuccaḍa deg tuffɣa seg texxamt",
+ "The user must be unbanned before they can be invited.": "Aseqdac ilaq ad yettwakkes uqbel ad izmiren ad t-id-snubegten.",
+ "Use a longer keyboard pattern with more turns": "Seqdec talɣa n unasiw ɣezzifen s wugar n tuzzyiwin",
+ "Capitalization doesn't help very much": "Tira timeqqranin ur tettɛawan ara aṭas",
+ "Reversed words aren't much harder to guess": "Awalen imettiyen ur weɛrit ara i tifin",
+ "Predictable substitutions like '@' instead of 'a' don't help very much": "Isnifal yettbeddilen am '@' deg wadeg n 'a' ur ttɛawanen ara aṭas",
+ "Repeats like \"aaa\" are easy to guess": "Allus am \"aaa\" fessus i usumer",
+ "Repeats like \"abcabcabc\" are only slightly harder to guess than \"abc\"": "Allus am \"abcabcabc\" yewɛer cwiṭ i tifin ɣef \"abc\"",
+ "Sequences like abc or 6543 are easy to guess": "Asemyizwer am abc neɣ 6543 fessus i usumer",
+ "This is similar to a commonly used password": "Wagi kifkif am wawal uffir yettwaseqdacen acḥal n tikkal",
+ "A word by itself is easy to guess": "Awal s timmad-is fessus i usumer",
+ "Names and surnames by themselves are easy to guess": "Ismawen d yismawen n useqdac s timmad-nsen fessusit i usumer",
+ "Common names and surnames are easy to guess": "Ismawen d yismawen n useqdac yettwassnen fessusit i usumer",
+ "Straight rows of keys are easy to guess": "Idurren ubdisen n tsura fessusit i ussumer",
+ "Short keyboard patterns are easy to guess": "Tinerufin n unasiw amecṭuḥ fessusit i ussumer",
+ "Help us improve %(brand)s": "Mudd-aɣ-d tallalt ad nesnerni %(brand)s",
+ "Send anonymous usage data which helps us improve %(brand)s. This will use a cookie.": "Azen inesfka n useqdec udrig ayen ara aɣ-iɛawnen ad nesnerni %(brand)s. Ayagi ad isseqdec inagan n tuqqna.",
+ "Review where you’re logged in": "Senqed ansi i d-tkecmeḍ",
+ "Verify all your sessions to ensure your account & messages are safe": "Senqed akk tiqimiyin-ik·im i wakken ad tḍemneḍ amiḍan-ik·m & yiznan d iɣelsanen",
+ "You are not receiving desktop notifications": "Ur d-termiseḍ ara ilɣa n tnarit",
+ "Your homeserver has exceeded its user limit.": "Aqeddac-inek·inem agejdan yewweḍ ɣer talast n useqdac.",
+ "Your homeserver has exceeded one of its resource limits.": "Aqeddac-inek·inem agejdan iɛedda yiwet seg tlisa-ines tiɣbula.",
+ "Contact your server admin.": "Nermes anedbal-inek·inem n uqeddac.",
+ "To return to your account in future you need to set a password": "Akken ad tuɣaleḍ ɣer umiḍan-ik·im ɣer sdat tesriḍ ad tesbaduḍ awal uffir",
+ "New spinner design": "Afeṣṣel amaynut n usezzay ",
+ "Render simple counters in room header": "Err amsiḍen afessa ɣef uqerru n texxamt",
+ "Multiple integration managers": "Imsefrak n waṭas n yimsidaf",
+ "Try out new ways to ignore people (experimental)": "Ɛreḍ iberdan-nniḍen i tigtin n yimdanen (armitan)",
+ "Show message previews for reactions in DMs": "Sken timeẓriwin n yiznan i tsedmirin deg DMs",
+ "Show message previews for reactions in all rooms": "Sken timeẓriwin n yiznan i tsedmirin deg meṛṛa tixxamin",
+ "Enable advanced debugging for the room list": "Rmed tamseɣtayt leqqayen i tebdart n texxamt",
+ "Enable big emoji in chat": "Rmed imujit ameqqran deg udiwenni",
+ "Automatically replace plain text Emoji": "Semselsi iujit n uḍris aččuran s wudem awurman",
+ "Enable Community Filter Panel": "Rmed agalis n umsizdeg n temɣiwent",
+ "Use a system font": "Seqdec tasefsit n unagraw",
+ "Size must be a number": "Teɣzi ilaq ad tili d uṭṭun",
+ "Message layout": "Talɣa n yizen",
+ "Discovery": "Tagrut",
+ "Help & About": "Tallalt & Ɣef",
+ "Homeserver is": "Aqeddac agejdan d",
+ "Identity Server is": "Aqeddac n timagit d",
+ "Access Token:": "Ajuṭu n unekcum:",
+ "click to reveal": "sit i ubeggen",
+ "Labs": "Tinarimin",
+ "Customise your experience with experimental labs features. Learn more.": "Sagen tarmit-ik·im s tmahilin n tinarimin tirmitanin. Issin ugar.",
+ "Error adding ignored user/server": "Tuccḍa deg tmerna n useqdac/uqeddac yettwanfen",
+ "Something went wrong. Please try again or view your console for hints.": "Yella wayen ur nteddu ara akken iwata, ma ulac aɣilif ales tikkelt-nniḍen neɣ senqed tadiwent-ik·im i yiwellihen.",
+ "Error subscribing to list": "Tuccḍa deg ujerred ɣef tebdart",
+ "Please verify the room ID or address and try again.": "Ma ulac aɣilif senqed asulay n texxamt neɣ tansa syen ɛreḍ tikkelt-nniḍen.",
+ "Error removing ignored user/server": "Tuccḍa deg tukksa n useqdac/uqeddac yettwanfen",
+ "Please try again or view your console for hints.": "Ma ulac aɣilif ales tikkelt-nniḍen neɣ senqed tadiwent-ik·im i yiwellihen.",
+ "Ban list rules - %(roomName)s": "Ilugan n tebdart n tigtin - %(roomName)s",
+ "You have not ignored anyone.": "Ur tunifeḍ ula i yiwen.",
+ "You are not subscribed to any lists": "Ur tettwajerrdeḍ ula deg yiwet n tebdart",
+ "View rules": "Senqed ilugan",
+ "You are currently subscribed to:": "Aql-ak·akem akka tura tjerrdeḍ ɣer:",
+ "⚠ These settings are meant for advanced users.": "⚠ Iɣewwaren-a n yiseqdac ifazen.",
+ "Subscribed lists": "Tibdarin n ujerred",
+ "Import E2E room keys": "Kter tisura n texxamt E2E",
+ "Cryptography": "Awgelhan",
+ "Session key:": "Tasarut n tɣimit:",
+ "Bulk options": "Tixtiṛiyin s ubleɣ",
+ "Accept all %(invitedRooms)s invites": "Qbel akk tinubgiwin %(invitedRooms)s",
+ "Reject all %(invitedRooms)s invites": "Agi akk tinubgiwin %(invitedRooms)s",
+ "Key backup": "Araz n tsarut",
+ "Cross-signing": "Azmul anmidag",
+ "Security & Privacy": "Taɣellist & tbaḍnit",
+ "Where you’re logged in": "Ansi i d-tkecmeḍ",
+ "Learn more about how we use analytics.": "Issin ugar ɣef wamek i nesseqdac tasleḍt.",
+ "No media permissions": "Ulac tisirag n umidyat",
+ "Missing media permissions, click the button below to request.": "Ulac tisirag n umidyat, sit ɣef tqeffalt ddaw i usentem.",
+ "Request media permissions": "Suter tisirag n umidyat",
+ "No Audio Outputs detected": "Ulac tuffɣiwin n umeslaw i d-yettwafen",
+ "No Microphones detected": "Ulac isawaḍen i d-yettwafen",
+ "No Webcams detected": "Ulac tikamiṛatin i d-yettwafen",
+ "Audio Output": "Tuffɣa n umeslaw",
+ "View older messages in %(roomName)s.": "Senqed iznan iqburen deg %(roomName)s.",
+ "Room information": "Talɣut n texxamt",
+ "Developer options": "Tixtiṛiyin s uneflay",
+ "This room is bridging messages to the following platforms. Learn more.": "Taxxamt-a tettcuddu iznan ɣer tɣerɣar i d-iteddun. Issin ugar.",
+ "This room isn’t bridging messages to any platforms. Learn more.": "Taxxamt-a ur tettcuddu ara iznan ɣer tɣerɣar i d-iteddun. Issin ugar.",
+ "Bridges": "Tileggiyin",
+ "Room Addresses": "Tansiwin n texxamt",
+ "URL Previews": "Tiskanin n URL",
+ "Uploaded sound": "Ameslaw i d-yulin",
+ "Set a new custom sound": "Sbadu ameslaw udmawan amaynut",
+ "Change room avatar": "Beddel avaṭar n texxamt",
+ "Change room name": "Beddel isem n texxamt",
+ "Change history visibility": "Beddel amazray n texxamt",
+ "Modify widgets": "Snifel iwiǧiten",
+ "Unban": "Asefsex n tigtin",
+ "Error changing power level requirement": "Tuccḍa deg usnifel n tuttra n uswir afellay",
+ "Error changing power level": "Tuccḍa deg usnifel n uswir afellay",
+ "Notify everyone": "Selɣu yal yiwen",
+ "Send %(eventType)s events": "Azen tidyanin n %(eventType)s",
+ "Roles & Permissions": "Timlellay & Tisirag",
+ "Click here to fix": "Sit dagi i uṣeggem",
+ "To link to this room, please add an address.": "I ucuddu ɣer texxamt-a, ttxil-k·m rnu tansa.",
+ "Only people who have been invited": "Ala imdanen i d-yettusnubegten",
+ "Anyone who knows the room's link, apart from guests": "Yal win·tin yessnen aseɣwen n texxamt slid inebgawen",
+ "Anyone who knows the room's link, including guests": "Yal win·tin yessnen aseɣwen n texxamt rnu-d ɣer-sen inebgawen",
+ "Members only (since the point in time of selecting this option)": "Iɛeggalen kan (segmi yebda ufran n textiṛit-a)",
+ "Members only (since they were invited)": "Iɛeggalen kan (segmi ara d-ttwanecden)",
+ "Members only (since they joined)": "Iɛeggalen kan (segmi ara d-ttwarnun)",
+ "Encrypted": "Yettwawgelhen",
+ "Who can access this room?": "Anwa i izemren ad d-yernu ɣer texxamt-a?",
+ "Who can read history?": "Anwa i izemren ad d-iɣer amazray?",
+ "Unable to revoke sharing for email address": "Asefsex n beṭṭu n tansa n yimayl ur yeddi ara",
+ "Unable to share email address": "Beṭṭu n tansa n yimayl ur yeddi ara",
+ "Your email address hasn't been verified yet": "Tansa n yimayl-ik·im ur tettwasenqed ara akka ar tura",
+ "Unable to verify email address.": "Asenqed n tansa n yimayl ur yeddi ara.",
+ "Verify the link in your inbox": "Senqed aseɣwen deg tbewwaḍt-ik·im n yimayl",
+ "Revoke": "Ḥwi",
+ "Unable to revoke sharing for phone number": "Aḥwi n beṭṭu n tansa n yimayl ur yeddi ara",
+ "Unable to share phone number": "Beṭṭu n wuṭṭun n tilifun ur yeddi ara",
+ "Unable to verify phone number.": "Asenqed n wuṭṭun n tilifun ur yeddi ara.",
+ "Incorrect verification code": "Tangalt n usenqed d tarussint",
+ "Please enter verification code sent via text.": "Ttxil-k·m sekcem tangalt n usenqed i ak·am-d-yettwaznen s SMS.",
+ "Unable to remove contact information": "Tukksa n talɣut n unermas ur teddi ara",
+ "Invalid Email Address": "Tansa n yimayl d tarameɣtut",
+ "This doesn't appear to be a valid email address": "Tagi ur tettban ara d tansa n yimayl tameɣtut",
+ "A text message has been sent to +%(msisdn)s. Please enter the verification code it contains.": "Izen n uḍris yettwazen ɣer +%(msisdn)s. Ttxil-k·m sekcem tangalt n usenqed yellan deg-s.",
+ "Cannot add any more widgets": "Ur yezmir ara ad yernu ugar n yiwiǧiten",
+ "Add a widget": "Rnu awiǧit",
+ "Drop File Here": "Sers afaylu dagi",
+ "Drop file here to upload": "Eǧǧ afaylu dagi i usali",
+ " (unsupported)": " ·(ur yettwasefrak ara)",
+ "Join as voice or video.": "Ttekki d taɣuct neɣ tavidyut.",
+ "Ongoing conference call%(supportedText)s.": "Asarag s usiwel iteddu%(supportedText)s.",
+ "This user has not verified all of their sessions.": "Aseqdac-a ur issenqed ara akk tiɣimiyin-ines.",
+ "You have not verified this user.": "Ur tesneqdeḍ aea aseqdac-a.",
+ "You have verified this user. This user has verified all of their sessions.": "Tesneqdeḍ aseqdac-a. Aseqdac-a issenqed akk tiɣimiyin-ines.",
+ "Someone is using an unknown session": "Yella win yesseqdacen tiɣimit tarussint",
+ "Everyone in this room is verified": "Yal yiwen deg taxxamt-a yettwasenqed",
+ "Mod": "Atrar",
+ "This event could not be displayed": "Tadyant-a ur tezmir ad d-tettwaskan",
+ "%(senderName)s sent an image": "%(senderName)s yuzen-d tugna",
+ "%(senderName)s sent a video": "%(senderName)s yuzen-d tavidyut",
+ "%(senderName)s uploaded a file": "%(senderName)s yessuli-d afaylu",
+ "Your key share request has been sent - please check your other sessions for key share requests.": "Asuter-ik·im n beṭṭ n tsarut yettwazen - ttxil-k·m senqed tiɣimiyin-ik·im-nniḍen i yisutar n beṭṭu n tsarut.",
+ "Re-request encryption keys from your other sessions.": "Suter i tikkelt-nniḍen tisura n uwgelhen seg tɣimiyin-ik·im tiyaḍ.",
+ "Encrypted by an unverified session": "Yettuwgelhen s tɣimit ur nettwasenqed ara",
+ "Unencrypted": "Ur yettwawgelhen ara",
+ "The authenticity of this encrypted message can't be guaranteed on this device.": "Asesteb n yizen-a awgelhen ur yettwaḍman ara deg yibenk-a.",
+ "Please select the destination room for this message": "Ttxil-k·m fren taxxamt n userken n yizen-a",
+ "Invited": "Yettwancad",
+ "Hangup": "Ɛelleq",
+ "Emoji picker": "Amefran n yimujit",
+ "The conversation continues here.": "Adiwenni yettkemmil dagi.",
+ "This room has been replaced and is no longer active.": "Taxxamt-a ad tettusmelsi, dayen d tarurmidt.",
+ "You do not have permission to post to this room": "Ur tesεiḍ ara tasiregt ad d-tsuffɣeḍ deg texxamt-a",
+ "Code block": "Iḥder n tengalt",
+ "Unpin Message": "Senser-d izen",
+ "Jump to message": "Ɛeddi ɣer yizen",
+ "%(duration)ss": "%(duration)ss",
+ "%(duration)sm": "%(duration)sm",
+ "%(duration)sh": "%(duration)sh",
+ "%(duration)sd": "%(duration)sd",
+ "Unknown for %(duration)s": "D arussin azal n %(duration)s",
+ "Offline": "Beṛṛa n tuqqna",
+ "Seen by %(displayName)s (%(userName)s) at %(dateTime)s": "Iwala-t %(displayName)s (%(userName)s) ɣef %(dateTime)s",
+ "Room %(name)s": "Taxxamt %(name)s",
+ "No recently visited rooms": "Ulac taxxamt yemmeẓren melmi kan",
+ "No rooms to show": "Ulac tixxamin i uskan",
+ "Unnamed room": "Taxxamt war isem",
+ "World readable": "Amaḍal yettwaɣran",
+ "(~%(count)s results)|other": "(~%(count)s igmaḍ)",
+ "Share room": "Bḍu taxxamt",
+ "Invites": "Inced-d",
+ "Start chat": "Bdu adiwenni",
+ "Create new room": "Rnu taxxamt tamaynut",
+ "Explore public rooms": "Snirem tixxamin tizuyaz",
+ "Low priority": "Tazwart taddayt",
+ "Historical": "Amazray",
+ "Can't see what you’re looking for?": "Ur yezmir ara ad iwali acu i tettnadiḍ?",
+ "Explore all public rooms": "Snirem akk tixxamin tizuyaz",
+ "%(count)s results|other": "%(count)s yigmaḍ",
+ "Joining room …": "Rnu ɣer texxamt…",
+ "You were kicked from %(roomName)s by %(memberName)s": "Tettwasuffɣeḍ-d seg %(roomName)s sɣur %(memberName)s",
+ "Reason: %(reason)s": "Taɣzint: %(reason)s",
+ "You were banned from %(roomName)s by %(memberName)s": "Tettwaɛezleḍ-d seg %(roomName)s sɣur %(memberName)s",
+ "Something went wrong with your invite to %(roomName)s": "Yella wayen ur nteddu ara akken ilaq d tinubga-ik·im ɣer %(roomName)s",
+ "unknown error code": "tangalt n tuccḍa tarussint",
+ "You can only join it with a working invite.": "Tzemreḍ kan ad ternuḍ ɣer-s ala s tinubga n uxeddim.",
+ "You can still join it because this is a public room.": "Mazal tzemreḍ ad ternuḍ ɣer-s acku taxxamt-a d tazayezt.",
+ "This invite to %(roomName)s was sent to %(email)s which is not associated with your account": "Tinubga-a ɣer %(roomName)s tettwazen i %(email)s ur nettwacudd ara d umiḍan-ik·im",
+ "Link this email with your account in Settings to receive invites directly in %(brand)s.": "Qqen imayl-a ɣer umiḍan-ik·im deg yiɣewwaren i wakken ad d-tremseḍ tinubgiwin srid deg %(brand)s.",
+ "This invite to %(roomName)s was sent to %(email)s": "Tinubga-a ɣer %(roomName)s tettwazen i %(email)s",
+ "Use an identity server in Settings to receive invites directly in %(brand)s.": "Seqdec aqeddac n timagit deg yiɣewwaren i wakken ad d-tremseḍ tinubgiwin srid deg %(brand)s.",
+ "Share this email in Settings to receive invites directly in %(brand)s.": "Bḍu imayl-a deg yiɣewwaren i wakken ad d-tremseḍ tinubgiwin srid deg %(brand)s.",
+ "Do you want to chat with %(user)s?": "Tebɣiḍ ad temmeslayeḍ d %(user)s?",
+ " wants to chat": " yebɣa ad immeslay",
+ "Do you want to join %(roomName)s?": "Tebɣiḍ ad tettekkiḍ deg %(roomName)s?",
+ " invited you": " inced-ik·im",
+ "You're previewing %(roomName)s. Want to join it?": "Tessenqadeḍ %(roomName)s. Tebɣiḍ ad ternuḍ ɣur-s?",
+ "%(roomName)s can't be previewed. Do you want to join it?": "%(roomName)s ur tezmir ara ad tettwasenqed. Tebɣiḍ ad ternuḍ ɣer-s?",
+ "Favourited": "Yettusmenyaf",
+ "Favourite": "Asmenyif",
+ "Low Priority": "Tazwart taddayt",
+ "%(count)s unread messages including mentions.|other": "%(count)s yiznan ur nettwaɣra ara rnu ɣer-sen ibdaren.",
+ "This room has already been upgraded.": "Taxxamt-a tettuleqqam yakan.",
+ "This room is running room version , which this homeserver has marked as unstable.": "Taxxamt-a tesedday lqem n texxamt , i yecreḍ uqeddac-a agejdan ur yerkid ara.",
+ "Only room administrators will see this warning": "Ala inedbalen kan n texxamt ara iwalin tuccḍa-a",
+ "Server unavailable, overloaded, or something else went wrong.": "Aqeddac ulac-it, neɣ iɛebba aṭas neɣ yella wayen ur nteddu ara akken ilaq.",
+ "You're all caught up.": "Tessawḍeḍ ad tqeḍɛeḍ kullec.",
+ "The server has denied your request.": "Aqeddac yugi asuter-ik·im.",
+ "Your area is experiencing difficulties connecting to the internet.": "Tamnaḍt-ik·im temlal-d uguren n tuqqna ɣer internet.",
+ "A connection error occurred while trying to contact the server.": "Tuccḍa deg tuqqna lawan n uneɛruḍ ad nnermes aqeddac.",
+ "The server is not configured to indicate what the problem is (CORS).": "Aqeddac ur yettusesteb ara i wakken ad d-imel anida-t wugur (CORPS).",
+ "Recent changes that have not yet been received": "Isnifal imaynuten ur d-newwiḍ ara akka ar tura",
+ "Sign out and remove encryption keys?": "Ffeɣ syen kkes tisura tiwgelhanin?",
+ "You have successfully set a password!": "Tesbaduḍ akken iwata awal uffir!",
+ "You have successfully set a password and an email address!": "Tesbaduḍ akken iwata awal uffird tansa n yimayl!",
+ "You can now return to your account after signing out, and sign in on other devices.": "Tzemreḍ tura ad tuɣaleḍ ɣer umiḍan-ik·im mbeɛd mi d-teffɣeḍ, syen kcem ɣer yibenkan-nniḍen.",
+ "Remember, you can always set an email address in user settings if you change your mind.": "Cfu, tzemreḍ melmi i ak-yehwa ad tesbaduḍ tansa n yimayl deg yiɣewwaren n useqdac ma yella tbeddleḍ ṛṛay-ik·im.",
+ "(HTTP status %(httpStatus)s)": "(HTTP addad %(httpStatus)s)",
+ "Please set a password!": "Ttxil-ik·im sbadu awal uffir!",
+ "This will allow you to return to your account after signing out, and sign in on other sessions.": "Ayagi ad ak·akem-yeǧǧ ad tuɣaleḍ ɣer umiḍan-ik·im mbeɛd mi d-teffɣeḍ, syen kcem ɣer yibenkan-nniḍen.",
+ "Share Room": "Bḍu taxxamt",
+ "Link to most recent message": "Aseɣwen n yizen akk aneggaru",
+ "Share Room Message": "Bḍu izen n texxamt",
+ "Command Help": "Tallalt n tiludna",
+ "Integration Manager": "Amsefrak n umsidef",
+ "Find others by phone or email": "Af-d wiyaḍ s tiliɣri neɣ s yimayl",
+ "Be found by phone or email": "Ad d-yettwaf s tiliɣri neɣ s yimayl",
+ "Upload files (%(current)s of %(total)s)": "Sali-d ifuyla (%(current)s ɣef %(total)s)",
+ "Liberate your communication": "Serreḥ i teywalt-ik·im",
+ "Explore Public Rooms": "Snirem tixxamin tizuyaz",
+ "Create a Group Chat": "Rnu adiwenni n ugraw",
+ "This room is not public. You will not be able to rejoin without an invite.": "Taxxamt-a mačči d tazayezt. Ur tezmireḍ ara ad ternuḍ ɣer-s war tinubga.",
+ "Are you sure you want to leave the room '%(roomName)s'?": "S tidet tebɣiḍ ad teǧǧeḍ taxxamt '%(roomName)s'?",
+ "For security, this session has been signed out. Please sign in again.": "Ɣef ssebba n tɣellist, taxxamt-a ad temdel. Ttxil-k·m ɛreḍ tikkelt-nniḍen.",
+ "Old cryptography data detected": "Ala isefka iweglehnen i d-iteffɣen",
+ "%(creator)s created and configured the room.": "%(creator)s yerna-d taxxamt syen yeswel taxxamt.",
+ "You can register, but some features will be unavailable until the identity server is back online. If you keep seeing this warning, check your configuration or contact a server admin.": "Tzemreḍ ad tjerrdeḍ, maca kra n tmahilin ur ttilint ara almi yuɣal-d uqeddac n tmagit. Ma mazal tettwaliḍ alɣu-a, senqed tawila-inek•inem neɣ nermes anedbal n uqeddac.",
+ "You can reset your password, but some features will be unavailable until the identity server is back online. If you keep seeing this warning, check your configuration or contact a server admin.": "Tzemreḍ ad talseḍ awennez i wawal-ik•im uffir, maca kra n tmahilin ur ttilint ara almi yuɣal-d uqeddac n tmagit. Ma mazal tettwaliḍ alɣu-a, senqed tawila-inek•inem neɣ nermes anedbal n uqeddac.",
+ "You can log in, but some features will be unavailable until the identity server is back online. If you keep seeing this warning, check your configuration or contact a server admin.": "Tzemreḍ ad teqqneḍ, maca kra n tmahilin ur ttilint ara almi yuɣal-d uqeddac n tmagit. Ma mazal tettwaliḍ alɣu-a senqed tawila-inek•inem neɣ nermes anedbal n uqeddac.",
+ "Verify yourself & others to keep your chats safe": "Senqed iman-ik•im d wiyaḍ akken ad qqimen yidiwenniyen-ik•im d iɣellsanen",
+ "The person who invited you already left the room.": "Amdan i k•kem-iɛerḍen dayen yeǧǧa taxxamt.",
+ "The person who invited you already left the room, or their server is offline.": "Amdan i k•kem-iɛerḍen dayen yeǧǧa taxxamt, neɣ d aqeddac-is i d aruqqin.",
+ "Show info about bridges in room settings": "Sken-d tilɣa ɣef teqneṭrin deg yiɣewwaṛen n texxamt",
+ "Enable Emoji suggestions while typing": "Rmed asumer n yimujiten deg wakud n tira",
+ "Use a more compact ‘Modern’ layout": "Seqdec taneɣruft 'tatrart' yessden ugar",
+ "Show a placeholder for removed messages": "Sken-d iznan yettwakksen",
+ "Show join/leave messages (invites/kicks/bans unaffected)": "Sken iznan n tmerna d tuffɣa (tinubgiwin/asufeɣ/anfay ur ttwaḥsaben ara)",
+ "Enable automatic language detection for syntax highlighting": "Rmed tifin tawurmant n tutlayt i useɣti n tira",
+ "Show avatars in user and room mentions": "Sken ivaṭaren deg yibdaren n useqdac neɣ n texxamt",
+ "Never send encrypted messages to unverified sessions in this room from this session": "Ur ttazen ara akk iznan yettwawgelhen ɣer tɣimiyin ur nettusenqad ara seg tɣimit-a",
+ "Enable URL previews by default for participants in this room": "Rmed tiskanin n URL s wudem amezwer i yimttekkiyen deg texxamt-a",
+ "Allow Peer-to-Peer for 1:1 calls": "Sireg isawalen udem e wudem i 1:1",
+ "Enable inline URL previews by default": "Rmed tiskanin n URL srid s wudem amezwer",
+ "Enable URL previews for this room (only affects you)": "Rmed tiskanin n URL i texxamt-a (i ak·akem-yeɛnan kan)",
+ "Enable widget screenshots on supported widgets": "Rmed tuṭṭfiwin n ugdil n uwiǧit deg yiwiǧiten yettwasferken",
+ "Identity Server (%(server)s)": "Aqeddac n timagit (%(server)s)",
+ "Identity Server": "Aqeddac n timagit",
+ "Enter a new identity server": "Sekcem aqeddac n timagit amaynut",
+ "No update available.": "Ulac lqem i yellan.",
+ "Hey you. You're the best!": "Kečč·kemm. Ulac win i ak·akem-yifen!",
+ "Use between %(min)s pt and %(max)s pt": "Seqdec gar %(min)s pt d %(max)s pt",
+ "Explore Room State": "Snirem addad n texxamt",
+ "Explore Account Data": "Snirem isefka n umiḍan",
+ "View Servers in Room": "Senqed iqeddacen deg texxamt",
+ "Toolbox": "Tabewwaḍt n yifecka",
+ "Developer Tools": "Ifecka n uneflay",
+ "An error has occurred.": "Tella-d tuccḍa.",
+ "Integrations are disabled": "Imsidaf ttwasensen",
+ "Integrations not allowed": "Imsidaf ur ttusirgen ara",
+ "a new master key signature": "tasarut tusligt tagejdant tamaynut",
+ "a new cross-signing key signature": "azmul amaynut n tsarut n uzmul amdigan",
+ "a device cross-signing signature": "azmul n uzmul amdigan n yibenk",
+ "a key signature": "azmul n tsarut",
+ "%(brand)s encountered an error during upload of:": "%(brand)s yemlal-d d tuccḍa mi ara d-yessalay:",
+ "Cancelled signature upload": "Asali n uzmul yettwasefsex",
+ "Unable to upload": "Yegguma ad d-yali",
+ "Signature upload failed": "Asali n uzmul ur yeddi ara",
+ "Incompatible local cache": "Tuffra tadigant ur temṣada ara",
+ "Room Settings - %(roomName)s": "Iɣewwaren n texxamt - %(roomName)s",
+ "The room upgrade could not be completed": "Aleqqem n texxamt yegguma ad yemmed",
+ "Show a reminder to enable Secure Message Recovery in encrypted rooms": "Sken asmekti i urmed n tririt n yiznan iɣellsanen deg texxamin yettwawgelhen",
+ "Show hidden events in timeline": "Sken-d ineḍruyen yeffren deg uzray",
+ "Enable message search in encrypted rooms": "Rmed anadi n yiznan deg texxamin yettwawgelhen",
+ "Manually verify all remote sessions": "Senqed s ufus akk tiɣimiyin tinmeggagin",
+ "IRC display name width": "Tehri n yisem i d-yettwaseknen IRC",
+ "Collecting app version information": "Alqaḍ n telɣa n lqem n usnas",
+ "Uploading logs": "Asali n yiɣmisen",
+ "Downloading logs": "Asader n yiɣmisen",
+ "Messages in one-to-one chats": "Iznan deg yidiwenniyen usriden",
+ "Encrypted messages in one-to-one chats": "Iznan yettwawgelhen deg yidiwenniyen usriden",
+ "Encrypted messages in group chats": "Iznan yettwawgelhen deg yidiwenniyen n ugraw",
+ "Unknown caller": "Asiwel arussin",
+ "The other party cancelled the verification.": "Wayeḍ issefsex asenqed.",
+ "You've successfully verified this user.": "Tesneqdeḍ aseqdac-a akken iwata.",
+ "Secure messages with this user are end-to-end encrypted and not able to be read by third parties.": "Iznan iɣellsanen akked useqdac-a ttwawgelhen seg yixef ɣer yixef yerna yiwen ur yezmir ad ten-iɣeṛ.",
+ "Verify this session by completing one of the following:": "Senqed tiɣimit-a s usmad n tigawin-a:",
+ "Confirm the emoji below are displayed on both sessions, in the same order:": "Sentem dakken imujiten seddaw ttbanen-d deg tɣimiyin i snat, s yiwen n umyizwer:",
+ "Verify this user by confirming the following emoji appear on their screen.": "Senqed aseqdac-a s usentem dakken imujiten-a ttbanen-d ɣef ugdil-is.",
+ "Verify this session by confirming the following number appears on its screen.": "Senqed tiɣimit-a s usentem dakken amḍan-a ittban-d ɣef ugdil-is.",
+ "Verify this user by confirming the following number appears on their screen.": "Senqed aseqdac-a s usentem dakken amḍan-a ittban-d ɣef ugdil-is.",
+ "Waiting for your other session to verify…": "Deg uraǧu n usenqed n tɣimit-ik•im-nniḍen…",
+ "Thumbs up": "Adebbuz d asawen",
+ "Changing password will currently reset any end-to-end encryption keys on all sessions, making encrypted chat history unreadable, unless you first export your room keys and re-import them afterwards. In future this will be improved.": "Abeddel n wawal uffir ad yales awennez i tsura akk n uwgelhen seg yixef ɣer yixef deg tɣimiyin akk, d ayen ara yerren amazray n udiwenni ur yettwaɣer ara, anagar ma tsifḍeḍ tisura-inek•inem n uwgelhen seg tazwara ad tɛawdeḍ ad tent-tketreḍ. Ɣer sdat, aya ad yennerni.",
+ "Forces the current outbound group session in an encrypted room to be discarded": "Ḥettem tiɣimit n ugraw ara d-yeffɣen akka tura deg texxamt tawgelhant ad tettwakkes",
+ "Unexpected server error trying to leave the room": "Tuccḍa n uqeddac ur nettwaṛǧa ara lawan n tuffɣa seg texxamt",
+ "Prompt before sending invites to potentially invalid matrix IDs": "Suter send tuzna n tnubgiwin i yisulayen i izmren ad ilin d arimeɣta",
+ "Show shortcuts to recently viewed rooms above the room list": "Sken inegzumen i texxamin i d-ibanen melmi kan nnig tebdart n texxamt",
+ "Send read receipts for messages (requires compatible homeserver to disable)": "Azen inagan n tɣuri i yiznan (yesra aqeddac agejdan yemṣadan i wakken ad yens)",
+ "Show previews/thumbnails for images": "Sken tiskanin/tinfulin i tugniwin",
+ "How fast should messages be downloaded.": "Acḥal i ilaq ad yili urured i wakken ad d-adren yiznan.",
+ "Enable experimental, compact IRC style layout": "Rmed aseflu n wanaw n IRC armitan, ussid ",
+ "Waiting for %(displayName)s to verify…": "Aṛaǧu n %(displayName)s i usenqed...",
+ "Securely cache encrypted messages locally for them to appear in search results, using ": "Ḥrez iznan iwgelhanen idiganen s wudem awurman i wakken ad d-banen deg yigmaḍ n unadi, s useqdec ",
+ "Securely cache encrypted messages locally for them to appear in search results.": "Ḥrez iznan iwgelhanen idiganen s wudem awurman i wakken ad d-banen deg yigmaḍ n unadi.",
+ "The integration manager is offline or it cannot reach your homeserver.": "Amsefrak n umsidef ha-t-an beṛṛa n tuqqna neɣ ur yezmir ara ad yaweḍ ɣer uqeddac-ik·im agejdan.",
+ "This backup is trusted because it has been restored on this session": "Aḥraz yettwaḍman acku yuɣal-d seg tɣimit-a ",
+ "Back up your keys before signing out to avoid losing them.": "Ḥrez tisura-ik·im send tuffɣa i wakken ur ttruḥunt ara.",
+ "Error saving email notification preferences": "Tuccḍa deg usekles n yismenyaf n ulɣu n yimayl",
+ "An error occurred whilst saving your email notification preferences.": "Tella-d tuccḍa lawan n usekles n yismenyaf n ulɣu n yimayl.",
+ "Can't update user notification settings": "D awezɣi ad ttwaleqqmen iɣewwaren n yilɣa n useqdac",
+ "Messages containing keywords": "Iznan ideg llan awalen ufrinen",
+ "Notify for all other messages/rooms": "Ṭṭef-d ilɣa i meṛṛa iznan/tixxamin",
+ "Notify me for anything else": "Azen-iyi-d ilɣa i wayen akk ara yellan",
+ "All notifications are currently disabled for all targets.": "Meṛṛa ilɣa nsan akka tura i meṛṛa isaḍasen.",
+ "On": "Yermed",
+ "Noisy": "Sɛan ṣṣut",
+ "wait and try again later": "ṛǧu syen ɛreḍ tikkelt-nniḍen",
+ "You must specify an event type!": "Ilaq ad d-tferneḍ anaw n tedyant!",
+ "Failed to send custom event.": "Ur teddi ara tuzna n tedyant tudmawant.",
+ "Event Type": "Anaw n tedyant",
+ "State Key": "Tasarut n waddad",
+ "Event Content": "Agbur n tedyant",
+ "This session, or the other session": "Tiɣimita, neɣ tiɣimit tayeḍ",
+ "If you didn’t sign in to this session, your account may be compromised.": "Ma yella ur teqqineḍ ara ɣer tɣimit-a, amiḍan-ik·im yezmer ad yettwaker.",
+ "Please fill why you're reporting.": "Ttxil-k·m ini-aɣ-d ayɣer i d-tettazneḍ alɣu.",
+ "Report Content to Your Homeserver Administrator": "Ttxil-k·m azen aneqqis i unedbal-ik·im n usebter agejdan.",
+ "Wrong Recovery Key": "Mačči d tasarut-ik·im n uɛeddi tagi",
+ "Invalid Recovery Key": "Tasarut-ik·im n uɛeddi d tarameɣtut",
+ "Security Phrase": "Tafyirt n tɣellist",
+ "Restoring keys from backup": "Tiririt n tsura seg uḥraz",
+ "Fetching keys from server...": "Tiririt n tsura seg uḥraz...",
+ "%(completed)s of %(total)s keys restored": "%(completed)s n %(total)s tsura i yettwarran",
+ "Unable to load backup status": "Yegguma ad d-yali waddad n uḥraz",
+ "Recovery key mismatch": "Tasarut n tririt ur temṣada ara",
+ "No backup found!": "Ulac aḥraz yettwafen!",
+ "Failed to decrypt %(failedCount)s sessions!": "Awgelhen n tɣimiyin %(failedCount)s ur yeddi ara",
+ "Successfully restored %(sessionCount)s keys": "Tiririt n tsura n %(sessionCount)s yedda akken iwata",
+ "This looks like a valid recovery key!": "Ayagi yettban am wakken tasarut n tririt d tameɣtut!",
+ "Not a valid recovery key": "Tasarut n tririt mačči d tameɣtut",
+ "Are you sure you want to reject the invitation?": "S tidet tebɣiḍ ad tesfesxeḍ tinubga?",
+ "Resend %(unsentCount)s reaction(s)": "Ales tuzna n tsedmirt (tsedmirin) %(unsentCount)s",
+ "Forward Message": "Welleh izen",
+ "Pin Message": "Rzi izen",
+ "View Decrypted Source": "Senqed taɣbalut tawgelhent",
+ "Unhide Preview": "Sban-d taskant",
+ "Take picture": "Ṭṭef-d tawleft",
+ "Away": "Akin",
+ "This homeserver would like to make sure you are not a robot.": "Aqeddac-a aqejdan yesra ad iẓer ma mačči d aṛubut i telliḍ.",
+ "Country Dropdown": "Tabdart n udrurem n tmura",
+ "You can use the custom server options to sign into other Matrix servers by specifying a different homeserver URL. This allows you to use %(brand)s with an existing Matrix account on a different homeserver.": "Tzemreḍ ad tesqedceḍ tixtiṛiyin n uqeddac udmawan i wakken ad teqqneḍ ɣer iqeddacen-nniḍen n Matrix s ufran n URL n uqeddac agejdan yemgaraden. Ayagi ad ak-yeǧǧ ad tesqedceḍ %(brand)s s umiḍan n Matrix yellan ɣef uqeddac agejdan yemgaraden.",
+ "Confirm your identity by entering your account password below.": "Sentem timagit-ik·im s usekcem n wawal uffir n umiḍan-ik·im ddaw.",
+ "Please review and accept all of the homeserver's policies": "Ttxil-k·m senqed syen qbel tisertiyin akk n uqeddac agejdan",
+ "Please review and accept the policies of this homeserver:": "Ttxil-k·m senqed syen qbel tisertiyin n uqeddac-a agejdan",
+ "An email has been sent to %(emailAddress)s": "Yettwazen yimayl ɣer %(emailAddress)s",
+ "Token incorrect": "Ajuṭu d arameɣtu",
+ "Identity Server URL": "URL n uqeddac n timagit",
+ "Other servers": "Iqeddacen wiya",
+ "Sign in to your Matrix account on %(serverName)s": "Qqen ɣer umiḍan-ik·im n Matrix deg %(serverName)s",
+ "Sorry, your browser is not able to run %(brand)s.": "Suref-aɣ, iminig-ik·im ur yezmir ara ad iseddu %(brand)s.",
+ "You must register to use this functionality": "Ilaq-ak·am ad teskelseḍ i wakken ad tesxedmeḍ tamahilt-a",
+ "No files visible in this room": "Ulac ifuyla i d-ibanen deg texxamt-a",
+ "Featured Rooms:": "Tixxamin i ifazen:",
+ "Upload avatar": "Sali-d avaṭar",
+ "Failed to forget room %(errCode)s": "Tatut n texxamt %(errCode)s ur teddi ara",
+ "Find a room… (e.g. %(exampleRoom)s)": "Af-d taxxamt… (am. %(exampleRoom)s)",
+ "Search failed": "Ur iddi ara unadi",
+ "No more results": "Ulac ugar n yigmaḍ",
+ "Fill screen": "Agdil aččuran",
+ "Uploading %(filename)s and %(count)s others|other": "Asali n %(filename)s d %(count)s wiyaḍ-nniḍen",
+ "Uploading %(filename)s and %(count)s others|zero": "Asali n %(filename)s",
+ "Uploading %(filename)s and %(count)s others|one": "Asali n %(filename)s d %(count)s wayeḍ-nniḍen",
+ "Security & privacy": "Taɣellist & tbaḍnit",
+ "User menu": "Umuɣ n useqdac",
+ "Could not load user profile": "Yegguma ad d-yali umaɣnu n useqdac",
+ "Session verified": "Tiɣimit tettwasenqed",
+ "Failed to send email": "Tuzna n yimayl ur teddi ara",
+ "New passwords must match each other.": "Awalen uffiren imaynuten ilaq ad mṣadan.",
+ "Your Matrix account on %(serverName)s": "Amiḍan-ik·im Matrix deg %(serverName)s",
+ "I have verified my email address": "Sneqdeɣ tansa-inu n yimayl",
+ "Return to login screen": "Uɣal ɣer ugdil n tuqqna",
+ "Incorrect username and/or password.": "Isem n uqeddac d/neɣ awal uffir d arameɣtu.",
+ "Registration Successful": "Asekles yemmed akken iwata",
+ "Save your Security Key": "Sekles tasarut-ik·im n tɣellist",
+ "Unable to set up secret storage": "Asbadu n uklas uffir d awezɣi",
+ "Paperclip": "Tamessakt n lkaɣeḍ",
+ "Are you sure? You will lose your encrypted messages if your keys are not backed up properly.": "Tettḥeqqeḍ? Ad tesruḥeḍ iznan-ik•im yettwawgelhen ma tisura-k•m ur klisent ara akken ilaq.",
+ "Cactus": "Akermus",
+ "Enter keywords separated by a comma:": "Sekcem awalen uffiren gar-asen tafrayt:",
+ "Add an email address to configure email notifications": "Rnu tansa n yimayl i uswel n yilɣa s yimayl",
+ "Notifications on the following keywords follow rules which can’t be displayed here:": "Ilɣa deg wawalen-a ufranen i d-iteddun ṭṭafaren ilugan ur yezmiren ara ad d-ttwaskanen ara da:",
+ "Unable to fetch notification target list": "D awazɣi ad d-nerr tabdart n yisaḍasen n yilɣa",
+ "There are advanced notifications which are not shown here.": "Llan yilɣa leqqayen ur d-nettwaskan ara da.",
+ "You might have configured them in a client other than %(brand)s. You cannot tune them in %(brand)s but they still apply.": "Ahat tsewleḍ-ten deg yimsaɣ-nniḍen mačči deg %(brand)s. Ur tezmireḍ ara ad ten-tṣeggmeḍ deg %(brand)s maca mazal-iten teddun.",
+ "Show message in desktop notification": "Sken-d iznan deg yilɣa n tnarit",
+ "Identity Server URL must be HTTPS": "URL n uqeddac n timagit ilaq ad yili d HTTPS",
+ "Not a valid Identity Server (status code %(code)s)": "Aqeddac n timagit mačči d ameɣtu (status code %(code)s)",
+ "Could not connect to Identity Server": "Ur izmir ara ad yeqqen ɣer uqeddac n timagit",
+ "Disconnect from the identity server and connect to instead?": "Ffeɣ seg tuqqna n uqeddac n timagit syen qqen ɣer deg wadeg-is?",
+ "Terms of service not accepted or the identity server is invalid.": "Tiwtilin n uqeddac ur ttwaqbalent ara neɣ aqeddac n timagit d arameɣtu.",
+ "The identity server you have chosen does not have any terms of service.": "Aqeddac n timagit i tferneḍ ulac akk ɣer-s tiwtilin n uqeddac.",
+ "Disconnect identity server": "Ffeɣ seg tuqqna n uqeddac n timagit",
+ "Disconnect from the identity server ?": "Ffeɣ seg tuqqna n uqeddac n timagi t?",
+ "You should remove your personal data from identity server before disconnecting. Unfortunately, identity server is currently offline or cannot be reached.": "Ilaq-ak·am ad tekkseḍ isefka-inek·inem udmawanen seg uqeddac n timagit send ad teffɣeḍ seg tuqqna. Nesḥassef, aqeddac n timagit akka tura ha-t beṛṛa n tuqqna neɣ awwaḍ ɣer-s ulamek.",
+ "check your browser plugins for anything that might block the identity server (such as Privacy Badger)": "senqed izegrar n yiming-ik·im i kra n wayen i izemren ad isewḥel aqeddac n timagit (am Privacy Badger)",
+ "contact the administrators of identity server ": "nermes inedbalen n uqeddac n timagit ",
+ "You are still sharing your personal data on the identity server .": "Mazal-ik·ikem tbeṭṭuḍ isefka-inek·inem udmawanen ɣef uqeddac n timagit .",
+ "Error encountered (%(errorDetail)s).": "Tuccaḍ i d-yettwamuggren (%(errorDetail)s).",
+ "Custom font size can only be between %(min)s pt and %(max)s pt": "Teɣzi n tsefsit tudmawant tezmer kan ad tili gar %(min)s pt d %(max)s pt",
+ "Error downloading theme information.": "Tuccḍa deg usali n telɣut n usentel.",
+ "Set the name of a font installed on your system & %(brand)s will attempt to use it.": "Sbadu isem n tsefsit yettwasbedden ɣef unagraw-ik·im & %(brand)s ad yeɛreḍ ad t-isseqdec.",
+ "Appearance Settings only affect this %(brand)s session.": "Ala iɣewwaren n urwes i izemren ad beddlen kra deg tɣimit-a %(brand)s.",
+ "Deactivating your account is a permanent action - be careful!": "Asensi n umiḍan-inek·inem d ayen ara yilin i lebda - Ɣur-k·m!",
+ "For help with using %(brand)s, click here.": "I tallalt n useqdec n %(brand)s, sit dagi.",
+ "For help with using %(brand)s, click here or start a chat with our bot using the button below.": "I tallalt ɣef useqdec n %(brand)s, sit dagi neɣ bdu adiwenni d wabuṭ-nneɣ s useqdec n tqeffalt ddaw.",
+ "If you've submitted a bug via GitHub, debug logs can help us track down the problem. Debug logs contain application usage data including your username, the IDs or aliases of the rooms or groups you have visited and the usernames of other users. They do not contain messages.": "Ma yella tuzneḍ ugur deg Github, iɣmisen n temseɣtit zemren ad aɣ-ɛiwnen ad negzu ugur. Iɣmisen n temseɣtit deg-sen isefka n useqdec n usnas am yisem n useqdec, am yisulayen neɣ am yismawen i yettunefken i texxamin neɣ i yigrawen ɣer wuɣur terziḍ d yismawen n useqdac n yiseqdacen-nniḍen. Ulac deg-sen iznan.",
+ "To report a Matrix-related security issue, please read the Matrix.org Security Disclosure Policy.": "I wakken ad d-tazneḍ ugur n tɣellist i icudden ɣer Matrix, ttxil-k·m ɣer tasertit n ukcaf n tɣellist deg Matrix.org.",
+ "Add users and servers you want to ignore here. Use asterisks to have %(brand)s match any characters. For example, @bot:* would ignore all users that have the name 'bot' on any server.": "Rnu dagi iseqdacen d yiqeddacen i tebɣiḍ ad tzegleḍ. Seqdec izamelen n yitran i wakken %(brand)s ad yemṣada d yal asekkil. D amedya, @bot:* izeggel akk iseqdacen i yesɛan isem \"abuṭ\" ɣef yal aqeddac.",
+ "Subscribing to a ban list will cause you to join it!": "Amulteɣ ɣer tebdart n tegtin ad ak·akem-yawi ad tettekkiḍ deg-s!",
+ "If this isn't what you want, please use a different tool to ignore users.": "Ma yella ayagi mačči d ayen i tebɣiḍ, ttxil-k·m seqdec afecku-nniḍen i wakken ad tzegleḍ iseqdacen.",
+ "Room ID or address of ban list": "Asulay n texxamt neɣ tansa n tebdart n tegtin",
+ "Start automatically after system login": "Bdu s wudem awurman seld tuqqna ɣer unagraw",
+ "Always show the window menu bar": "Afeggag n wumuɣ n usfaylu eǧǧ-it yettban",
+ "Show tray icon and minimize window to it on close": "Sken tagnit n ufeggag n waddad, tsemziḍ asfaylu n umdal",
+ "Read Marker lifetime (ms)": "Ɣer tanzagt n tudert n tecreḍt (ms)",
+ "Read Marker off-screen lifetime (ms)": "Ɣer tanzagt n tudert n tecreḍt beṛṛa n ugdil (ms)",
+ "Unignore": "Ur yettwazgel ara",
+ "Your server admin has disabled end-to-end encryption by default in private rooms & Direct Messages.": "Anedbal-ik·im n uqeddac issens awgelhen seg yixef ɣer yixef s wudem amezwer deg texxamin tusligin & yiznan usriden.",
+ "Manage the names of and sign out of your sessions below or verify them in your User Profile.": "Sefrek ismawen syen ffeɣ seg tɣimiyin-ik·im ddaw neɣ senqed-itent deg umaɣnu-ik·im n useqdac.",
+ "A session's public name is visible to people you communicate with": "Isem n tiɣimit tazayezt yettban i yimdanen wukud tettmeslayeḍ",
+ "%(brand)s collects anonymous analytics to allow us to improve the application.": "%(brand)s ileqqeḍ tasleḍt tudrigt i wakken ad aɣ-iɛawen ad nesnerni asnas.",
+ "You have ignored this user, so their message is hidden. Show anyways.": "Tzegleḍ useqdac-a, ihi iznan-ines ffren. Ɣas akken sken-iten-id.",
+ "You cancelled verifying %(name)s": "Tesfesxeḍ asenqed n %(name)s",
+ "Declining …": "Tigtin...",
+ "You sent a verification request": "Tuzneḍ asuter n usenqed",
+ "Error decrypting video": "Tuccḍa deg uwgelhen n tvidyut",
+ "Reactions": "Tisedmirin",
+ " reacted with %(content)s": " isedmer s %(content)s",
+ "reacted with %(shortName)s": "issedmer s %(shortName)s",
+ "%(senderDisplayName)s changed the avatar for %(roomName)s": "%(senderDisplayName)s ibeddel avaṭar i %(roomName)s",
+ "%(senderDisplayName)s removed the room avatar.": "%(senderDisplayName)s yekkes avaṭar n texxamt.",
+ "%(senderDisplayName)s changed the room avatar to ": "%(senderDisplayName)s ibeddel avaṭar n texxamt i ",
+ "This room is a continuation of another conversation.": "Taxxamt-a d akemmel n udiwenni-nniḍen.",
+ "Click here to see older messages.": "Sit da i wakken ad twaliḍ iznan iqdimen.",
+ "Failed to copy": "Anɣal ur yeddi ara",
+ "Edited at %(date)s": "Yettwaẓreg deg %(date)s",
+ "Click to view edits": "Sit i wakken ad twaliḍ aseẓreg",
+ "Edited at %(date)s. Click to view edits.": "Yettwaẓreg deg %(date)s. Sit i wakken ad twaliḍ iseẓrag.",
+ "Failed to load group members": "Ur yeddi ara usali n yiɛeggalen n ugraw",
+ "Are you sure you want to remove '%(roomName)s' from %(groupId)s?": "Tebɣiḍ s tidet ad tekkseḍ '%(roomName)s' seg %(groupId)s?",
+ "Removing a room from the community will also remove it from the community page.": "Tukksa n texxamt seg temɣiwent ad tt-yekkes ula seg usebter n temɣiwent.",
+ "Failed to remove room from community": "Tukksa n texxamt seg temɣiwent ur yeddi ara",
+ "Failed to remove '%(roomName)s' from %(groupId)s": "Ur teddi ara tukksa n '%(roomName)s' seg %(groupId)s",
+ "Something went wrong!": "Yella wayen ur nteddu ara akken iwata!",
+ "The visibility of '%(roomName)s' in %(groupId)s could not be updated.": "Abani n '%(roomName)s' deg %(groupId)s yegguma ad ttuleqqem.",
+ "Visible to everyone": "Iban i medden akk",
+ "Something went wrong when trying to get your communities.": "Yella wayen ur nteddu ara akken deg uneɛruḍ n wawwaḍ ɣer temɣiwnin-ik·im.",
+ "Display your community flair in rooms configured to show it.": "Sken lbenna n temɣiwent-ik·im deg texxamin yettusewlen ad ttwaskanent.",
+ "You're not currently a member of any communities.": "Akka tura ur telliḍ d aɛeggal ula deg yiwet temɣiwent.",
+ "Frequently Used": "Yettuseqdac s waṭas",
+ "Quick Reactions": "Tisedmirin tiruradin",
+ "Unknown Address": "D tansa tarussint",
+ "Any of the following data may be shared:": "Yal yiwen seg yisefka i d-iteddun zemren ad ttwabḍun:",
+ "Invite anyway and never warn me again": "Ɣas akken nced-d yerna ur iyi-id-ttɛeggin ara akk",
+ "Please tell us what went wrong or, better, create a GitHub issue that describes the problem.": "Ttxil-k·m ini-aɣ-d acu ur nteddu ara akken ilaq neɣ, akken i igerrez, rnu ugur deg Github ara ad d-igelmen ugur.",
+ "Preparing to download logs": "Aheyyi i usali n yiɣmisen",
+ "There's no one else here! Would you like to invite others or stop warning about the empty room?": "Ulac ula d yiwen da! Tebɣiḍ ad d-necdeḍ wiyaḍ neɣ aḥbas n uɛeggen ɣef texxamt tilemt?",
+ "You seem to be in a call, are you sure you want to quit?": "Tettbaneḍ aql-ak·akem deg useiwel, tebɣiḍ s tidet ad teffɣeḍ?",
+ "Failed to load timeline position": "Asali n yideg n tesnakudt ur yeddi ara",
+ "Sign in instead": "Kcem axiṛ",
+ "Invalid homeserver discovery response": "Tiririt n usnirem n uqeddac agejdan d tarameɣtut",
+ "Failed to get autodiscovery configuration from server": "Awway n uswel n usnirem awurman seg uqeddac ur yeddi ara",
+ "Invalid base_url for m.homeserver": "D arameɣtu base_url i m.homeserver",
+ "Homeserver URL does not appear to be a valid Matrix homeserver": "URL n uqeddac agejdan ur yettban ara d aqeddac agejdan n Matrix ameɣtu",
+ "Invalid identity server discovery response": "Tiririt n usnirem n uqeddac n timagitn d tarameɣtut",
+ "Identity server URL does not appear to be a valid identity server": "URL n uqeddac n timagit ur yettban ara d aqeddac n timagit ameɣtu",
+ "This homeserver does not support login using email address.": "Aqeddac-a agejdan ur yessefrak ara inekcum s useqdec n tansa n yimayl.",
+ "Please contact your service administrator to continue using this service.": "Ttxil-k·m nermes anedbal-ik·im n uqeddac i wakken ad tkemmleḍ aseqdec n yibenk-a.",
+ "Failed to fetch avatar URL": "Tiririt n URL ur teddi ara",
+ "Unable to query for supported registration methods.": "Anadi n tarrayin n usekles yettusefraken d awezi.",
+ "Registration has been disabled on this homeserver.": "Aklas yensa deg uqeddac-a agejdan.",
+ "This server does not support authentication with a phone number.": "Aqeddac-a ur yessefrak ara asesteb s wuṭṭun n tilifun.",
+ "You can now close this window or log in to your new account.": "Tzemreḍ tura ad tmedleḍ asfaylu-a neɣ kcem ɣer umiḍan-ik·im amaynut.",
+ "Use Recovery Key or Passphrase": "Seqdec tasarut tuffirt neɣ tafyirt tuffirt n uεeddi",
+ "This requires the latest %(brand)s on your other devices:": "Ayagi yesra %(brand)s tineggura ɣef yibenkan-ik·im wiyaḍ:",
+ "or another cross-signing capable Matrix client": "neɣ amsaɣ-nniḍen n Matrix yemṣadan d uzmul amdigan",
+ "Your new session is now verified. Other users will see it as trusted.": "Tiɣimit-ik·im tamaynut tettwasenqed tura. Ad tt-walin wiyaḍ tettwaḍman.",
+ "Failed to re-authenticate due to a homeserver problem": "Allus n usesteb ur yeddi ara ssebbba n wugur deg uqeddac agejdan",
+ "Enter your password to sign in and regain access to your account.": "Sekcem awal-ik·im uffir i wakken ad teqqneḍ syen ad tkecmeḍ i tikkelt tayeḍ ɣer umiḍan-ik·im.",
+ "Use a secret phrase only you know, and optionally save a Security Key to use for backup.": "Seqdec tafyirt tuffirt i tessneḍ kan kečč·kemm, syen sekles ma tebɣiḍ tasarut n tɣellist i useqdec-ines i uḥraz.",
+ "Restore your key backup to upgrade your encryption": "Err-d aḥraz n tsarut-ik·im akken ad tleqqmeḍ awgelhen-ik·im",
+ "You'll need to authenticate with the server to confirm the upgrade.": "Ad teḥqiǧeḍ asesteb s uqeddac i wakken ad tesnetmeḍ lqem.",
+ "Unable to query secret storage status": "Tuttra n waddad n uklas uffir ur teddi ara",
+ "You can also set up Secure Backup & manage your keys in Settings.": "Tzemreḍ daɣen aḥraz uffir & tesferkeḍ tisura-ik·im deg yiɣewwaren.",
+ "We'll store an encrypted copy of your keys on our server. Secure your backup with a recovery passphrase.": "Ad d-terreḍ anɣal awgelhan n tsura-ik·im ɣef uqeddac-nneɣ. Ḥrez aḥrazen s tefyirt tuffirt n uɛeddi.",
+ "Without setting up Secure Message Recovery, you won't be able to restore your encrypted message history if you log out or use another session.": "War aswel n Secure Message Recovery, ur tettizmireḍ ara ad d-terreḍ amazray-ik·im n yiznan iwgelhanen ma yella teffɣeḍ neɣ tesqedceḍ tiɣimit-nniḍen.",
+ "Without setting up Secure Message Recovery, you'll lose your secure message history when you log out.": "War aswel n Secure Message Recovery, ad tmedleḍ amazray-ik·im n yiznan uffiren ma yella teffɣeḍ.",
+ "If you didn't set the new recovery method, an attacker may be trying to access your account. Change your account password and set a new recovery method immediately in Settings.": "Ma yella ur tesbaduḍ ara tarrayt n tririt tamaynut, yezmer ad yili umaker ara iɛerḍen ad yekcem ɣer umiḍan-ik·im. Beddel awal uffir n umiḍan-ik·im syen sbadu tarrayt n tririt tamaynut din din deg yiɣewwaren.",
+ "This session has detected that your recovery passphrase and key for Secure Messages have been removed.": "Tiɣimit-a tufa-d tafyirt-ik·im tuffirt n tririt d tsarut-ik·im n yiznan uffiren ttwakksent.",
+ "If you didn't remove the recovery method, an attacker may be trying to access your account. Change your account password and set a new recovery method immediately in Settings.": "Ma yella ur tekkiseḍ ara tarrayt n tririt tamaynut, yezmer ad yili umaker ara iɛerḍen ad yekcem ɣer umiḍan-ik·im. Beddel awal uffir n umiḍan-ik·im syen sbadu tarrayt n tririt tamaynut din din deg yiɣewwaren."
}
diff --git a/src/i18n/strings/nb_NO.json b/src/i18n/strings/nb_NO.json
index f0c9827c06..1f6720f613 100644
--- a/src/i18n/strings/nb_NO.json
+++ b/src/i18n/strings/nb_NO.json
@@ -1407,5 +1407,14 @@
"Sign in to your Matrix account on %(serverName)s": "Logg inn på Matrix-kontoen din på %(serverName)s",
"Sign in to your Matrix account on ": "Logg inn på Matrix-kontoen din på ",
"If you've joined lots of rooms, this might take a while": "Hvis du har blitt med i mange rom, kan dette ta en stund",
- "Your new session is now verified. It has access to your encrypted messages, and other users will see it as trusted.": "Den nye økten din er nå verifisert. Den har tilgang til dine krypterte meldinger, og andre brukere vil se at den blir stolt på."
+ "Your new session is now verified. It has access to your encrypted messages, and other users will see it as trusted.": "Den nye økten din er nå verifisert. Den har tilgang til dine krypterte meldinger, og andre brukere vil se at den blir stolt på.",
+ "%(senderName)s made future room history visible to all room members, from the point they are invited.": "%(senderName)s gjorde fremtidig romhistorikk synlig for alle rommedlemmer, fra det tidspunktet de ble/blir invitert.",
+ "%(senderName)s made future room history visible to all room members, from the point they joined.": "%(senderName)s gjorde fremtidig romhistorikk synlig for alle rommedlemmer, fra det tidspunktet de ble med.",
+ "%(senderName)s made future room history visible to all room members.": "%(senderName)s gjorde fremtidig romhistorikk synlig for alle rommedlemmer.",
+ "%(senderName)s made future room history visible to anyone.": "%(senderName)s gjorde fremtidig romhistorikk synlig for alle.",
+ "%(senderName)s made future room history visible to unknown (%(visibility)s).": "%(senderName)s gjorde fremtidig romhistorikk synlig for alle rommedlemmer (%(visibility)s).",
+ "To return to your account in future you need to set a password": "For å komme tilbake til kontoen din senere, må du velge et passord",
+ "Please forget all messages I have sent when my account is deactivated (Warning: this will cause future users to see an incomplete view of conversations)": "Vennligst glem alle meldingene jeg har sendt når kontoen min er deaktivert (Advarsel: Dette vil føre til at fremtidige brukere ser en ufullstendig visning av samtaler)",
+ "To help us prevent this in future, please send us logs.": "For å hjelpe oss med å forhindre dette i fremtiden, vennligst send oss loggfiler.",
+ "No identity server is configured so you cannot add an email address in order to reset your password in the future.": "Ingen identitetstjener er satt opp, så du kan ikke bruke en E-postadresse til å tilbakestille passordet ditt senere."
}
diff --git a/src/i18n/strings/oc.json b/src/i18n/strings/oc.json
index 124439a802..cd62ff69db 100644
--- a/src/i18n/strings/oc.json
+++ b/src/i18n/strings/oc.json
@@ -59,5 +59,284 @@
"This Room": "Aquesta sala",
"All Rooms": "Totas les salas",
"Search…": "Cercar…",
- "Server error": "Error servidor"
+ "Server error": "Error servidor",
+ "Single Sign On": "Autentificacion unica",
+ "Confirm": "Confirmar",
+ "Dismiss": "Far desaparéisser",
+ "OK": "D’acòrdi",
+ "Continue": "Contunhar",
+ "Go Back": "En arrièr",
+ "Cancel": "Anullar",
+ "Sun": "Dg",
+ "Mon": "Dl",
+ "Tue": "Dm",
+ "Wed": "Dc",
+ "Thu": "Dj",
+ "Fri": "Dv",
+ "Sat": "Ds",
+ "Jan": "Gen",
+ "Feb": "Febr",
+ "Mar": "Març",
+ "Apr": "Abr",
+ "May": "mai",
+ "Jun": "Junh",
+ "Jul": "Julh",
+ "Aug": "Ago",
+ "Sep": "Set",
+ "Oct": "Oct",
+ "Nov": "Nov",
+ "Dec": "Dec",
+ "PM": "PM",
+ "AM": "AM",
+ "Trust": "Aprovacion",
+ "Sign In": "Se connectar",
+ "Default": "Predefinit",
+ "Moderator": "Moderator",
+ "Admin": "Admin",
+ "Operation failed": "L'operacion a fracassat",
+ "Messages": "Messatges",
+ "Actions": "Accions",
+ "Advanced": "Avançat",
+ "Other": "Autre",
+ "Usage": "Usatge",
+ "Command failed": "La comanda a fracassat",
+ "Thank you!": "Mercés !",
+ "Reason": "Rason",
+ "Light": "Clar",
+ "Dark": "Escur",
+ "Review": "Reveire",
+ "Notifications": "Notificacions",
+ "Close": "Tampar",
+ "Ok": "Validar",
+ "Set up": "Parametrar",
+ "Upgrade": "Metre a jorn",
+ "Verify": "Verificar",
+ "Update": "Mesa a jorn",
+ "Restart": "Reaviar",
+ "Font size": "Talha de poliça",
+ "Incoming video call": "Sonada vidèo entranta",
+ "Incoming call": "Sonada entranta",
+ "Accept": "Acceptar",
+ "Start": "Començament",
+ "Cancelling…": "Anullacion...",
+ "Fish": "Pes",
+ "Butterfly": "Parpalhòl",
+ "Tree": "Arborescéncia",
+ "Cloud": "Nívol",
+ "Apple": "Apple",
+ "Heart": "Còr",
+ "Clock": "Relòtge",
+ "Pencil": "Gredon",
+ "Scissors": "Cisèus intelligents",
+ "Lock": "Verrolhar",
+ "Key": "Clau",
+ "Telephone": "Telefòn",
+ "Trophy": "Trophy",
+ "Ball": "Balas",
+ "Anchor": "Ancorar",
+ "Headphones": "Escotadors",
+ "Folder": "Dorsièr",
+ "Pin": "Penjar",
+ "Upload": "Enviar",
+ "Show less": "Ne veire mens",
+ "Show more": "Ne veire mai",
+ "Current password": "Senhal actual",
+ "New Password": "Senhal novèl",
+ "Confirm password": "Confirmar lo senhal",
+ "Change Password": "Modificar senhal",
+ "not found": "pas trobat",
+ "exists": "existís",
+ "Authentication": "Autentificacion",
+ "ID": "ID",
+ "Manage": "Manage",
+ "Enable": "Activar",
+ "Restore from Backup": "Restablir a partir de l'archiu",
+ "Keywords": "Mots clau",
+ "Clear notifications": "Escafar",
+ "Off": "Atudat",
+ "Display Name": "Nom d'afichatge",
+ "Save": "Salvagardar",
+ "Disconnect": "Se desconnectar",
+ "Go back": "Precedent",
+ "Change": "Cambiar",
+ "Theme": "Tèma",
+ "Compact": "Ordenador",
+ "Success": "Succès",
+ "Profile": "Perfil",
+ "Account": "Compte",
+ "General": "General",
+ "Legal": "Legal",
+ "Credits": "Crèdits",
+ "FAQ": "FAQ",
+ "Keyboard Shortcuts": "Acorchis de clavièr",
+ "Versions": "Versions",
+ "Unsubscribe": "Se desabonar",
+ "Ignore": "Ignorar",
+ "Subscribe": "S'inscriure",
+ "Preferences": "Preferéncias",
+ "Composer": "Compositor",
+ "Timeline": "Axe temporal",
+ "Unignore": "Ignorar pas",
+ "Security & Privacy": "Seguretat e vida privada",
+ "Audio Output": "Sortida àudio",
+ "Microphone": "Microfòn",
+ "Camera": "Aparelh de fotografiar",
+ "Bridges": "Bridges",
+ "Sounds": "Sons",
+ "Reset": "Recomençar",
+ "Browse": "Percórrer",
+ "Unban": "Reabilitar",
+ "Permissions": "Permissions",
+ "Encryption": "Chiframent",
+ "Encrypted": "Chifrat",
+ "Complete": "Acabat",
+ "Revoke": "Revocar",
+ "Share": "Partiment",
+ "Add": "Ajustar",
+ "Phone Number": "Numèro de telefòn",
+ "Mod": "Moderador",
+ "Unencrypted": "Pas chifrat",
+ "Hangup": "Penjar",
+ "Italics": "Italicas",
+ "Strikethrough": "Raiat",
+ "Invites": "Convits",
+ "People": "Gent",
+ "Historical": "Istoric",
+ "Sign Up": "S’inscriure",
+ "Appearance": "Aparéncia",
+ "Sort by": "Triar per",
+ "Activity": "Activitat",
+ "A-Z": "A-Z",
+ "List options": "Opcions de lista",
+ "Favourite": "Favorit",
+ "Low Priority": "Prioritat bassa",
+ "Mark all as read": "Tot marcar coma legit",
+ "Members": "Participants",
+ "Trusted": "Fisable",
+ "Not trusted": "Pas securizat",
+ "Invite": "Convidar",
+ "Demote": "Retrogradar",
+ "Kick": "Forabandir",
+ "Ban": "Bandir",
+ "Are you sure?": "O volètz vertadièrament ?",
+ "Security": "Seguretat",
+ "Yes": "Òc",
+ "Got it": "Ai comprés",
+ "Sunday": "Dimenge",
+ "Monday": "Diluns",
+ "Tuesday": "Dimars",
+ "Wednesday": "Dimècres",
+ "Thursday": "Dijòus",
+ "Friday": "Divendres",
+ "Saturday": "Dissabte",
+ "Today": "Uèi",
+ "Yesterday": "Ièr",
+ "View Source": "Veire la font",
+ "Reply": "Respondre",
+ "Edit": "Editar",
+ "Attachment": "Pèça junta",
+ "Show image": "Afichar l'imatge",
+ "Show all": "O mostrar tot",
+ "Failed to copy": "Impossible de copiar",
+ "Smileys & People": "Emoticònas e personatges",
+ "Animals & Nature": "Animals e natura",
+ "Food & Drink": "Noiridura e bevenda",
+ "Activities": "Activitats",
+ "Travel & Places": "Viatges e luòcs",
+ "Objects": "Objèctes",
+ "Symbols": "Simbòls",
+ "Flags": "Marcadors",
+ "Categories": "Categorias",
+ "Cancel search": "Anullar la recèrca",
+ "More options": "Autras opcions",
+ "Join": "Jónher",
+ "No results": "Pas cap de resultat",
+ "Rotate Left": "Pivotar cap a èrra",
+ "Rotate Right": "Pivotar cap a drecha",
+ "Rotate clockwise": "Pivotar dins lo sens de las agulhas d'un relòtge",
+ "Add User": "Apondre un utilizaire",
+ "Matrix": "Matritz",
+ "Server name": "Títol del servidor",
+ "email address": "adreça de messatjariá",
+ "Notes": "Nòtas",
+ "Unavailable": "Pas disponible",
+ "Changelog": "Istoric dels cambiaments (Changelog)",
+ "Removing…": "Supression en cors…",
+ "Example": "Exemple",
+ "example": "exemple",
+ "Create": "Crear",
+ "Name": "Escais",
+ "Sign out": "Se desconnectar",
+ "Back": "Precedenta",
+ "Send": "Mandar",
+ "Toolbox": "Bóstia d'aisinas",
+ "Developer Tools": "Aisinas de desvolopament",
+ "An error has occurred.": "Una error s'es producha.",
+ "Suggestions": "Prepausicions",
+ "Go": "Validar",
+ "Session name": "Nom de session",
+ "Your password": "Vòstre senhal",
+ "Refresh": "Actualizada",
+ "Email address": "Adreça de corrièl",
+ "Skip": "Ignorar",
+ "Checking...": "Verificacion en cors...",
+ "Copy": "Copiar",
+ "Terms of Service": "Terms of Service",
+ "Service": "Servici",
+ "Summary": "Resumit",
+ "Document": "Document",
+ "Next": "Seguent",
+ "Upload files": "Mandar de fichièrs",
+ "Allow": "Autorizar",
+ "Deny": "Refusar",
+ "Custom": "Personalizada",
+ "Address (optional)": "Adreça (opcionala)",
+ "Leave": "Quitar",
+ "Forget": "Doblidar",
+ "Hide": "Amagar",
+ "Home": "Dorsièr personal",
+ "Sign in": "Connexion",
+ "Reload": "Tornar cargar",
+ "Away": "Absent",
+ "Submit": "Mandar",
+ "Enter password": "Sasissètz lo senhal",
+ "Email": "Corrièl",
+ "Username": "Nom d'_utilizaire",
+ "Phone": "Telefòn",
+ "Passwords don't match": "Los senhals correspondon pas",
+ "Register": "S'enregistrar",
+ "Free": "Liure",
+ "Premium": "De la melhora qualitat",
+ "Everyone": "Tot lo monde",
+ "Description": "descripcion",
+ "Unknown error": "Error desconeguda",
+ "Logout": "Desconnexion",
+ "Preview": "Apercebut",
+ "View": "Visualizacion",
+ "Search failed": "La recèrca a fracassat",
+ "Room": "Sala",
+ "Feedback": "Comentaris",
+ "Incorrect password": "Senhal incorrècte",
+ "Commands": "Comandas",
+ "Emoji": "Emoji",
+ "Users": "Utilizaires",
+ "Export": "Exportar",
+ "Import": "Importar",
+ "Restore": "Restablir",
+ "Download": "Telecargament",
+ "Retry": "Tornar ensajar",
+ "Success!": "Capitada !",
+ "Navigation": "Navigacion",
+ "Alt": "Alt",
+ "Alt Gr": "Alt Gr",
+ "Shift": "Descalatge",
+ "Super": "Super",
+ "Ctrl": "Ctrl",
+ "Upload a file": "Actualizar un fichièr",
+ "Page Up": "Pagina precedenta",
+ "Page Down": "Pagina seguenta",
+ "Esc": "Escap",
+ "Enter": "Entrada",
+ "Space": "Espaci",
+ "End": "Fin"
}
diff --git a/src/i18n/strings/pt_BR.json b/src/i18n/strings/pt_BR.json
index 60beb2b726..c16e7a980d 100644
--- a/src/i18n/strings/pt_BR.json
+++ b/src/i18n/strings/pt_BR.json
@@ -3,14 +3,14 @@
"Admin": "Administrador/a",
"Advanced": "Avançado",
"New passwords don't match": "As novas senhas não conferem",
- "A new password must be entered.": "Uma nova senha precisa ser informada.",
+ "A new password must be entered.": "Uma nova senha precisa ser inserida.",
"Anyone who knows the room's link, apart from guests": "Qualquer pessoa que tenha o link da sala, exceto visitantes",
"Anyone who knows the room's link, including guests": "Qualquer pessoa que tenha o link da sala, incluindo visitantes",
- "Are you sure you want to reject the invitation?": "Você tem certeza que deseja rejeitar este convite?",
- "Banned users": "Usuárias/os banidas/os",
- "Bans user with given id": "Banir usuários com o identificador informado",
- "%(senderDisplayName)s changed the topic to \"%(topic)s\".": "%(senderDisplayName)s mudou a descrição para \"%(topic)s\".",
- "Changes your display nickname": "Troca o seu apelido",
+ "Are you sure you want to reject the invitation?": "Tem certeza de que deseja recusar o convite?",
+ "Banned users": "Usuários banidos",
+ "Bans user with given id": "Bane o usuário com o ID indicado",
+ "%(senderDisplayName)s changed the topic to \"%(topic)s\".": "%(senderDisplayName)s alterou a descrição para \"%(topic)s\".",
+ "Changes your display nickname": "Alterar seu nome e sobrenome",
"Click here to fix": "Clique aqui para resolver isso",
"Commands": "Comandos",
"Confirm password": "Confirme a nova senha",
@@ -18,17 +18,17 @@
"Create Room": "Criar Sala",
"Cryptography": "Criptografia",
"Current password": "Senha atual",
- "Deactivate Account": "Desativar conta",
+ "Deactivate Account": "Desativar minha conta",
"Default": "Padrão",
- "Deops user with given id": "Retirar função de moderador do usuário com o identificador informado",
+ "Deops user with given id": "Retirar nível de moderador do usuário com o identificador informado",
"Displays action": "Visualizar atividades",
"Emoji": "Emoji",
"Error": "Erro",
"Export E2E room keys": "Exportar chaves ponta-a-ponta da sala",
- "Failed to change password. Is your password correct?": "Não foi possível mudar a senha. A sua senha está correta?",
+ "Failed to change password. Is your password correct?": "Não foi possível alterar a senha. A sua senha está correta?",
"Failed to leave room": "Falha ao tentar deixar a sala",
- "Failed to reject invitation": "Falha ao tentar rejeitar convite",
- "Failed to unban": "Não foi possível desfazer o banimento",
+ "Failed to reject invitation": "Falha ao tentar recusar o convite",
+ "Failed to unban": "Não foi possível remover o banimento",
"Favourite": "Favoritar",
"Favourites": "Favoritos",
"Filter room members": "Filtrar integrantes da sala",
@@ -39,13 +39,13 @@
"Historical": "Histórico",
"Homeserver is": "Servidor padrão é",
"Identity Server is": "O servidor de identificação é",
- "I have verified my email address": "Eu verifiquei o meu endereço de email",
+ "I have verified my email address": "Eu confirmei o meu endereço de e-mail",
"Import E2E room keys": "Importar chave de criptografia ponta-a-ponta (E2E) da sala",
- "Invalid Email Address": "Endereço de email inválido",
+ "Invalid Email Address": "Endereço de e-mail inválido",
"Invites": "Convidar",
- "Invites user with given id to current room": "Convidar usuários com um dado identificador para esta sala",
- "Sign in with": "Quero entrar",
- "Kicks user with given id": "Remove usuário com o identificador informado",
+ "Invites user with given id to current room": "Convida o usuário com o ID especificado para esta sala",
+ "Sign in with": "Entrar com",
+ "Kicks user with given id": "Remover o usuário com o ID informado",
"Labs": "Laboratório",
"Leave room": "Sair da sala",
"Logout": "Sair",
@@ -56,22 +56,22 @@
"New passwords must match each other.": "As novas senhas informadas precisam ser idênticas.",
"Notifications": "Notificações",
"": "",
- "No users have specific privileges in this room": "Nenhum/a usuário/a possui privilégios específicos nesta sala",
+ "No users have specific privileges in this room": "Nenhum usuário possui privilégios específicos nesta sala",
"Only people who have been invited": "Apenas pessoas que tenham sido convidadas",
"Password": "Senha",
"Passwords can't be empty": "As senhas não podem estar em branco",
"Permissions": "Permissões",
"Phone": "Telefone",
- "Please check your email and click on the link it contains. Once this is done, click continue.": "Por favor verifique seu email e clique no link enviado. Quando finalizar este processo, clique para continuar.",
+ "Please check your email and click on the link it contains. Once this is done, click continue.": "Por favor, confirme o seu e-mail e clique no link enviado. Feito isso, clique em continuar.",
"Privileged Users": "Usuárias/os privilegiadas/os",
"Profile": "Perfil",
- "Reject invitation": "Rejeitar convite",
+ "Reject invitation": "Recusar o convite",
"Remove": "Apagar",
"Return to login screen": "Retornar à tela de login",
"Room Colour": "Cores da sala",
"Rooms": "Salas",
"Searches DuckDuckGo for results": "Buscar por resultados no buscador DuckDuckGo",
- "Send Reset Email": "Enviar email para redefinição de senha",
+ "Send Reset Email": "Enviar e-mail para redefinição de senha",
"Server may be unavailable, overloaded, or you hit a bug.": "O servidor pode estar indisponível ou sobrecarregado, ou então você encontrou uma falha no sistema.",
"Session ID": "Identificador de sessão",
"Settings": "Configurações",
@@ -80,25 +80,25 @@
"Sign out": "Sair",
"Someone": "Alguém",
"Success": "Sucesso",
- "The email address linked to your account must be entered.": "O endereço de email relacionado a sua conta precisa ser informado.",
- "This doesn't appear to be a valid email address": "Este não aparenta ser um endereço de email válido",
+ "The email address linked to your account must be entered.": "O e-mail vinculado à sua conta precisa ser informado.",
+ "This doesn't appear to be a valid email address": "Este não aparenta ser um endereço de e-mail válido",
"This room is not accessible by remote Matrix servers": "Esta sala não é acessível para servidores Matrix remotos",
- "Unable to add email address": "Não foi possível adicionar endereço de email",
+ "Unable to add email address": "Não foi possível adicionar um endereço de e-mail",
"Unable to remove contact information": "Não foi possível remover informação de contato",
- "Unable to verify email address.": "Não foi possível verificar o endereço de email.",
- "Unban": "Desfazer banimento",
+ "Unable to verify email address.": "Não foi possível confirmar o endereço de e-mail.",
+ "Unban": "Remover banimento",
"unknown error code": "código de erro desconhecido",
- "Upload avatar": "Enviar uma imagem de perfil",
+ "Upload avatar": "Enviar uma foto de perfil",
"Upload file": "Enviar arquivo",
"Users": "Usuários",
- "Verification Pending": "Verificação pendente",
+ "Verification Pending": "Confirmação pendente",
"Video call": "Chamada de vídeo",
"Voice call": "Chamada de voz",
- "VoIP conference finished.": "Conferência VoIP encerrada.",
- "VoIP conference started.": "Conferência VoIP iniciada.",
+ "VoIP conference finished.": "Chamada em grupo encerrada.",
+ "VoIP conference started.": "Chamada em grupo iniciada.",
"Who can access this room?": "Quem pode acessar esta sala?",
"Who can read history?": "Quem pode ler o histórico da sala?",
- "You do not have permission to post to this room": "Você não tem permissão de postar nesta sala",
+ "You do not have permission to post to this room": "Você não tem permissão para digitar nesta sala",
"You have no visible notifications": "Voce não possui notificações visíveis",
"Sun": "Dom",
"Mon": "Seg",
@@ -123,19 +123,19 @@
"%(weekDayName)s %(time)s": "%(weekDayName)s às %(time)s",
"%(targetName)s accepted an invitation.": "%(targetName)s aceitou um convite.",
"%(targetName)s accepted the invitation for %(displayName)s.": "%(targetName)s aceitou o convite para %(displayName)s.",
- "%(senderName)s answered the call.": "%(senderName)s atendeu à chamada.",
- "%(senderName)s banned %(targetName)s.": "%(senderName)s removeu %(targetName)s da sala.",
+ "%(senderName)s answered the call.": "%(senderName)s aceitou a chamada.",
+ "%(senderName)s banned %(targetName)s.": "%(senderName)s baniu %(targetName)s.",
"Call Timeout": "Tempo esgotado. Chamada encerrada",
- "%(senderName)s changed their profile picture.": "%(senderName)s alterou sua imagem de perfil.",
- "%(senderName)s changed the power level of %(powerLevelDiffText)s.": "%(senderName)s alterou o nível de permissões de %(powerLevelDiffText)s.",
+ "%(senderName)s changed their profile picture.": "%(senderName)s alterou a foto de perfil.",
+ "%(senderName)s changed the power level of %(powerLevelDiffText)s.": "%(senderName)s alterou o nível de permissão de %(powerLevelDiffText)s.",
"%(senderDisplayName)s changed the room name to %(roomName)s.": "%(senderDisplayName)s alterou o nome da sala para %(roomName)s.",
"click to reveal": "clique para ver",
"/ddg is not a command": "/ddg não é um comando",
- "%(senderName)s ended the call.": "%(senderName)s finalizou a chamada.",
+ "%(senderName)s ended the call.": "%(senderName)s encerrou a chamada.",
"Existing Call": "Chamada em andamento",
- "Failed to send email": "Não foi possível enviar email",
+ "Failed to send email": "Não foi possível enviar e-mail",
"Failed to send request.": "Não foi possível mandar requisição.",
- "Failed to verify email address: make sure you clicked the link in the email": "Não foi possível verificar o endereço de email: verifique se você realmente clicou no link que está no seu email",
+ "Failed to verify email address: make sure you clicked the link in the email": "Falha ao confirmar o endereço de e-mail: certifique-se de clicar no link do e-mail",
"Failure to create room": "Não foi possível criar a sala",
"%(userId)s from %(fromPowerLevel)s to %(toPowerLevel)s": "%(userId)s de %(fromPowerLevel)s para %(toPowerLevel)s",
"%(senderName)s invited %(targetName)s.": "%(senderName)s convidou %(targetName)s.",
@@ -150,80 +150,80 @@
"Missing room_id in request": "Faltou o id da sala na requisição",
"Missing user_id in request": "Faltou o id de usuário na requisição",
"(not supported by this browser)": "(não é compatível com este navegador)",
- "Power level must be positive integer.": "O nível de permissões tem que ser um número inteiro e positivo.",
+ "Power level must be positive integer.": "O nível de permissão precisa ser um número inteiro e positivo.",
"Reason": "Razão",
"%(targetName)s rejected the invitation.": "%(targetName)s recusou o convite.",
- "%(senderName)s removed their display name (%(oldDisplayName)s).": "%(senderName)s removeu o seu nome público (%(oldDisplayName)s).",
- "%(senderName)s removed their profile picture.": "%(senderName)s removeu sua imagem de perfil.",
- "%(senderName)s requested a VoIP conference.": "%(senderName)s está solicitando uma conferência de voz.",
- "%(brand)s does not have permission to send you notifications - please check your browser settings": "%(brand)s não tem permissões para enviar notificações a você - por favor, verifique as configurações do seu navegador",
- "%(brand)s was not given permission to send notifications - please try again": "%(brand)s não tem permissões para enviar notificações a você - por favor, tente novamente",
+ "%(senderName)s removed their display name (%(oldDisplayName)s).": "%(senderName)s removeu o nome e sobrenome (%(oldDisplayName)s).",
+ "%(senderName)s removed their profile picture.": "%(senderName)s removeu a foto de perfil.",
+ "%(senderName)s requested a VoIP conference.": "%(senderName)s deseja iniciar uma chamada em grupo.",
+ "%(brand)s does not have permission to send you notifications - please check your browser settings": "%(brand)s não tem permissão para lhe enviar notificações - confirme as configurações do seu navegador",
+ "%(brand)s was not given permission to send notifications - please try again": "%(brand)s não tem permissão para lhe enviar notificações - tente novamente",
"Room %(roomId)s not visible": "A sala %(roomId)s não está visível",
"%(senderDisplayName)s sent an image.": "%(senderDisplayName)s enviou uma imagem.",
"%(senderName)s sent an invitation to %(targetDisplayName)s to join the room.": "%(senderName)s enviou um convite para %(targetDisplayName)s entrar na sala.",
- "%(senderName)s set a profile picture.": "%(senderName)s definiu uma imagem de perfil.",
- "%(senderName)s set their display name to %(displayName)s.": "%(senderName)s definiu seu nome público para %(displayName)s.",
- "This email address is already in use": "Este endereço de email já está sendo usado",
- "This email address was not found": "Este endereço de email não foi encontrado",
- "The remote side failed to pick up": "Houve alguma falha que não permitiu a outra pessoa atender à chamada",
+ "%(senderName)s set a profile picture.": "%(senderName)s definiu uma foto de perfil.",
+ "%(senderName)s set their display name to %(displayName)s.": "%(senderName)s definiu o nome e sobrenome para %(displayName)s.",
+ "This email address is already in use": "Este endereço de e-mail já está em uso",
+ "This email address was not found": "Este endereço de e-mail não foi encontrado",
+ "The remote side failed to pick up": "A pessoa não atendeu a chamada",
"This room is not recognised.": "Esta sala não é reconhecida.",
"This phone number is already in use": "Este número de telefone já está sendo usado",
- "To use it, just wait for autocomplete results to load and tab through them.": "Para usar esta funcionalidade, espere o carregamento dos resultados de autocompletar e então escolha entre as opções.",
- "%(senderName)s unbanned %(targetName)s.": "%(senderName)s desfez o banimento de %(targetName)s.",
+ "To use it, just wait for autocomplete results to load and tab through them.": "Para usar este recurso, aguarde o carregamento dos resultados de autocompletar e então escolha entre as opções.",
+ "%(senderName)s unbanned %(targetName)s.": "%(senderName)s removeu o banimento de %(targetName)s.",
"Unable to capture screen": "Não foi possível capturar a imagem da tela",
"Unable to enable Notifications": "Não foi possível ativar as notificações",
"Upload Failed": "O envio falhou",
"Usage": "Uso",
- "VoIP is unsupported": "Chamada de voz não permitida",
+ "VoIP is unsupported": "Chamadas de voz não são suportadas",
"%(senderName)s withdrew %(targetName)s's invitation.": "%(senderName)s desfez o convite a %(targetName)s.",
"You are already in a call.": "Você já está em uma chamada.",
- "You cannot place a call with yourself.": "Você não pode iniciar uma chamada.",
- "You cannot place VoIP calls in this browser.": "Você não pode fazer chamadas de voz neste navegador.",
- "You need to be able to invite users to do that.": "Para fazer isso, você tem que ter permissão para convidar outras pessoas.",
- "You need to be logged in.": "Você tem que estar logado.",
- "Your email address does not appear to be associated with a Matrix ID on this Homeserver.": "O seu endereço de email não parece estar associado a uma conta de usuária/o Matrix neste servidor.",
- "Set a display name:": "Defina um nome público para você:",
- "Upload an avatar:": "Envie uma imagem de perfil para identificar você:",
+ "You cannot place a call with yourself.": "Você não pode iniciar uma chamada consigo mesmo.",
+ "You cannot place VoIP calls in this browser.": "Chamadas de voz não são suportadas neste navegador.",
+ "You need to be able to invite users to do that.": "Para fazer isso, precisa ter permissão para convidar outras pessoas.",
+ "You need to be logged in.": "Você precisa estar logado.",
+ "Your email address does not appear to be associated with a Matrix ID on this Homeserver.": "O seu endereço de e-mail não parece estar associado a uma conta de usuária/o Matrix neste servidor.",
+ "Set a display name:": "Defina um nome e sobrenome:",
+ "Upload an avatar:": "Enviar uma foto de perfil:",
"This server does not support authentication with a phone number.": "Este servidor não permite a autenticação através de números de telefone.",
"An error occurred: %(error_string)s": "Um erro ocorreu: %(error_string)s",
"There are no visible files in this room": "Não há arquivos públicos nesta sala",
"Connectivity to the server has been lost.": "A conexão com o servidor foi perdida. Verifique sua conexão de internet.",
"Sent messages will be stored until your connection has returned.": "Imagens enviadas ficarão armazenadas até que sua conexão seja reestabelecida.",
- "Active call": "Chamada ativa",
+ "Active call": "Chamada em andamento",
"Failed to forget room %(errCode)s": "Falhou ao esquecer a sala %(errCode)s",
"%(items)s and %(lastItem)s": "%(items)s e %(lastItem)s",
"and %(count)s others...|one": "e um outro...",
"and %(count)s others...|other": "e %(count)s outros...",
"Are you sure?": "Você tem certeza?",
"Attachment": "Anexo",
- "Autoplay GIFs and videos": "Reproduzir automaticamente GIFs e videos",
+ "Autoplay GIFs and videos": "Reproduzir GIFs e vídeos automaticamente",
"%(weekDayName)s, %(monthName)s %(day)s %(fullYear)s %(time)s": "%(weekDayName)s, %(day)s de %(monthName)s de %(fullYear)s às %(time)s",
- "Can't connect to homeserver via HTTP when an HTTPS URL is in your browser bar. Either use HTTPS or enable unsafe scripts.": "Não consigo conectar ao servidor padrão através de HTTP quando uma URL HTTPS está na barra de endereços do seu navegador. Use HTTPS ou então habilite scripts não seguros no seu navegador.",
+ "Can't connect to homeserver via HTTP when an HTTPS URL is in your browser bar. Either use HTTPS or enable unsafe scripts.": "Uma conexão com o servidor local via HTTP não pode ser estabelecida se a barra de endereços do navegador contiver um endereço HTTPS. Use HTTPS ou, em vez disso, permita ao navegador executar scripts não seguros.",
"Change Password": "Alterar senha",
"Click to mute audio": "Clique para colocar o áudio no mudo",
- "Click to mute video": "Clique para desabilitar imagens de vídeo",
- "Click to unmute video": "Clique para voltar a mostrar imagens de vídeo",
+ "Click to mute video": "Clique para desativar o som do vídeo",
+ "Click to unmute video": "Clique para ativar o som do vídeo",
"Click to unmute audio": "Clique para retirar áudio do mudo",
"Command error": "Erro de comando",
"Decrypt %(text)s": "Descriptografar %(text)s",
"Disinvite": "Desconvidar",
"Download %(text)s": "Baixar %(text)s",
- "Failed to ban user": "Não foi possível banir o/a usuário/a",
- "Failed to change power level": "Não foi possível mudar o nível de permissões",
+ "Failed to ban user": "Não foi possível banir o usuário",
+ "Failed to change power level": "Não foi possível alterar o nível de permissão",
"Failed to join room": "Não foi possível ingressar na sala",
- "Failed to kick": "Não foi possível remover usuária/o",
+ "Failed to kick": "Não foi possível remover o usuário",
"Failed to load timeline position": "Não foi possível carregar a posição na linha do tempo",
"Failed to mute user": "Não foi possível remover notificações da/do usuária/o",
- "Failed to reject invite": "Não foi possível rejeitar o convite",
- "Failed to set display name": "Houve falha ao definir o nome público",
+ "Failed to reject invite": "Não foi possível recusar o convite",
+ "Failed to set display name": "Falha ao definir o nome e sobrenome",
"Fill screen": "Tela cheia",
- "Incorrect verification code": "Código de verificação incorreto",
+ "Incorrect verification code": "Código de confirmação incorreto",
"Join Room": "Ingressar na sala",
"Jump to first unread message.": "Ir diretamente para a primeira das mensagens não lidas.",
- "Kick": "Remover",
+ "Kick": "Remover da sala",
"not specified": "não especificado",
"No more results": "Não há mais resultados",
- "No results": "Sem resultados",
+ "No results": "Nenhum resultado",
"OK": "Ok",
"Search": "Buscar",
"Search failed": "Busca falhou",
@@ -237,16 +237,16 @@
"Tried to load a specific point in this room's timeline, but was unable to find it.": "Tentei carregar um ponto específico na linha do tempo desta sala, mas não o encontrei.",
"You seem to be in a call, are you sure you want to quit?": "Parece que você está em uma chamada. Tem certeza que quer sair?",
"You seem to be uploading files, are you sure you want to quit?": "Parece que você está enviando arquivos. Tem certeza que quer sair?",
- "You will not be able to undo this change as you are promoting the user to have the same power level as yourself.": "Você não poderá desfazer esta mudança, pois estará dando a este(a) usuário(a) o mesmo nível de permissões que você.",
+ "You will not be able to undo this change as you are promoting the user to have the same power level as yourself.": "Você não poderá desfazer essa alteração, pois está promovendo o usuário ao mesmo nível de permissão que você.",
"Room": "Sala",
"Cancel": "Cancelar",
- "Ban": "Banir",
+ "Ban": "Banir da sala",
"Access Token:": "Token de acesso:",
"Always show message timestamps": "Sempre mostrar as datas das mensagens",
"Authentication": "Autenticação",
"An error has occurred.": "Ocorreu um erro.",
- "Email": "Email",
- "Email address": "Endereço de email",
+ "Email": "E-mail",
+ "Email address": "Endereço de e-mail",
"Error decrypting attachment": "Erro ao descriptografar o anexo",
"Invalid file%(extra)s": "Arquivo inválido %(extra)s",
"Mute": "Mudo",
@@ -271,11 +271,11 @@
"This process allows you to export the keys for messages you have received in encrypted rooms to a local file. You will then be able to import the file into another Matrix client in the future, so that client will also be able to decrypt these messages.": "Este processo permite que você exporte as chaves para mensagens que você recebeu em salas criptografadas para um arquivo local. Você poderá então importar o arquivo para outro cliente Matrix no futuro, de modo que este cliente também poderá descriptografar suas mensagens.",
"The export file will be protected with a passphrase. You should enter the passphrase here, to decrypt the file.": "O arquivo exportado será protegido com uma senha. Você deverá inserir a senha aqui para poder descriptografar o arquivo futuramente.",
"You must join the room to see its files": "Você precisa ingressar na sala para ver seus arquivos",
- "Reject all %(invitedRooms)s invites": "Rejeitar todos os %(invitedRooms)s convites",
+ "Reject all %(invitedRooms)s invites": "Recusar todos os %(invitedRooms)s convites",
"Failed to invite": "Falha ao enviar o convite",
"Failed to invite the following users to the %(roomName)s room:": "Falha ao convidar as(os) seguintes usuárias(os) para a sala %(roomName)s:",
"Confirm Removal": "Confirmar a remoção",
- "Are you sure you wish to remove (delete) this event? Note that if you delete a room name or topic change, it could undo the change.": "Tem certeza de que deseja apagar este evento? Observe que, se você apagar o nome ou alterar a descrição de uma sala, pode desfazer a alteração.",
+ "Are you sure you wish to remove (delete) this event? Note that if you delete a room name or topic change, it could undo the change.": "Tem certeza de que deseja apagar este evento? Observe que, se você apagar a alteração do nome ou descrição de uma sala, isso reverterá a alteração.",
"Unknown error": "Erro desconhecido",
"Incorrect password": "Senha incorreta",
"Unable to restore session": "Não foi possível restaurar a sessão",
@@ -285,7 +285,7 @@
"Add User": "Adicionar usuária(o)",
"Custom Server Options": "Opções para Servidor Personalizado",
"Dismiss": "Descartar",
- "Please check your email to continue registration.": "Por favor, verifique o seu e-mail para continuar o processo de registro.",
+ "Please check your email to continue registration.": "Por favor, confirme o seu e-mail para continuar a inscrição.",
"Token incorrect": "Token incorreto",
"Please enter the code it contains:": "Por favor, entre com o código que está na mensagem:",
"powered by Matrix": "oferecido por Matrix",
@@ -297,56 +297,56 @@
"URL Previews": "Pré-visualização de links",
"Drop file here to upload": "Arraste um arquivo aqui para enviar",
" (unsupported)": " (não suportado)",
- "Ongoing conference call%(supportedText)s.": "Conferência%(supportedText)s em andamento.",
+ "Ongoing conference call%(supportedText)s.": "Chamada em grupo em andamento%(supportedText)s.",
"Online": "Conectada/o",
"Idle": "Ocioso",
- "Offline": "Offline",
+ "Offline": "Desconectado",
"The exported file will allow anyone who can read it to decrypt any encrypted messages that you can see, so you should be careful to keep it secure. To help with this, you should enter a passphrase below, which will be used to encrypt the exported data. It will only be possible to import the data by using the same passphrase.": "O arquivo exportado irá permitir a qualquer pessoa que o acesse a descriptografar qualquer uma das mensagens criptografadas que você veja, portanto seja bastante cuidadosa(o) em manter este arquivo seguro. Para deixar este arquivo mais protegido, recomendamos que você insira uma senha abaixo, que será usada para criptografar o arquivo. Só será possível importar os dados usando exatamente a mesma senha.",
"This process allows you to import encryption keys that you had previously exported from another Matrix client. You will then be able to decrypt any messages that the other client could decrypt.": "Este processo faz com que você possa importar as chaves de criptografia que tinha previamente exportado de outro cliente Matrix. Você poderá então descriptografar todas as mensagens que o outro cliente pôde criptografar.",
"Start automatically after system login": "Iniciar automaticamente ao iniciar o sistema",
- "You are about to be taken to a third-party site so you can authenticate your account for use with %(integrationsUrl)s. Do you wish to continue?": "Você será levado agora a um site de terceiros para poder autenticar a sua conta para uso com o serviço %(integrationsUrl)s. Você quer continuar?",
+ "You are about to be taken to a third-party site so you can authenticate your account for use with %(integrationsUrl)s. Do you wish to continue?": "Você será redirecionado para um site de terceiros para poder autenticar a sua conta, tendo em vista usar o serviço %(integrationsUrl)s. Deseja prosseguir?",
"Export": "Exportar",
"Import": "Importar",
- "Incorrect username and/or password.": "Nome de usuária(o) e/ou senha incorreto.",
+ "Incorrect username and/or password.": "Nome de usuário e/ou senha incorreto.",
"Invited": "Convidada(o)",
"Results from DuckDuckGo": "Resultados de DuckDuckGo",
- "Verified key": "Chave verificada",
+ "Verified key": "Chave confirmada",
"%(senderDisplayName)s removed the room avatar.": "%(senderDisplayName)s removeu a foto da sala.",
- "%(senderDisplayName)s changed the avatar for %(roomName)s": "%(senderDisplayName)s alterou a imagem da sala %(roomName)s",
+ "%(senderDisplayName)s changed the avatar for %(roomName)s": "%(senderDisplayName)s alterou a foto da sala %(roomName)s",
"%(senderDisplayName)s changed the room avatar to ": "%(senderDisplayName)s alterou a foto da sala para ",
"No Microphones detected": "Não foi detectado nenhum microfone",
- "No Webcams detected": "Não foi detectada nenhuma Webcam",
- "No media permissions": "Não há permissões de uso de vídeo/áudio no seu navegador",
- "You may need to manually permit %(brand)s to access your microphone/webcam": "Você talvez precise autorizar manualmente que o %(brand)s acesse seu microfone e webcam",
+ "No Webcams detected": "Nenhuma câmera detectada",
+ "No media permissions": "Não tem permissões para acessar a mídia",
+ "You may need to manually permit %(brand)s to access your microphone/webcam": "Pode ser necessário permitir manualmente ao %(brand)s acessar seu microfone ou sua câmera",
"Default Device": "Aparelho padrão",
"Microphone": "Microfone",
- "Camera": "Câmera de vídeo",
+ "Camera": "Câmera",
"Add a topic": "Adicionar uma descrição",
"Anyone": "Qualquer pessoa",
- "Are you sure you want to leave the room '%(roomName)s'?": "Você tem certeza que deseja sair da sala '%(roomName)s'?",
+ "Are you sure you want to leave the room '%(roomName)s'?": "Tem certeza de que deseja sair da sala '%(roomName)s'?",
"Custom level": "Nível personalizado",
"Register": "Registre-se",
"Save": "Salvar",
- "You have disabled URL previews by default.": "Você desabilitou pré-visualizações de links por padrão.",
- "You have enabled URL previews by default.": "Você habilitou pré-visualizações de links por padrão.",
+ "You have disabled URL previews by default.": "Você desativou pré-visualizações de links por padrão.",
+ "You have enabled URL previews by default.": "Você ativou pré-visualizações de links por padrão.",
"Add": "Adicionar",
"Error: Problem communicating with the given homeserver.": "Erro: problema de comunicação com o Servidor de Base fornecido.",
- "Failed to fetch avatar URL": "Falha ao obter a URL da imagem de perfil",
+ "Failed to fetch avatar URL": "Falha ao obter o link da foto de perfil",
"Home": "Início",
"The phone number entered looks invalid": "O número de telefone inserido parece ser inválido",
"Uploading %(filename)s and %(count)s others|zero": "Enviando o arquivo %(filename)s",
"Uploading %(filename)s and %(count)s others|one": "Enviando o arquivo %(filename)s e %(count)s outros arquivos",
"Uploading %(filename)s and %(count)s others|other": "Enviando o arquivo %(filename)s e %(count)s outros arquivos",
- "Username invalid: %(errMessage)s": "Nome de usuária(o) inválido: %(errMessage)s",
- "You must register to use this functionality": "Você deve se registrar para poder usar esta funcionalidade",
+ "Username invalid: %(errMessage)s": "Nome de usuário inválido: %(errMessage)s",
+ "You must register to use this functionality": "Você deve se registrar para usar este recurso",
"Create new room": "Criar nova sala",
"Room directory": "Lista pública de salas",
"Start chat": "Iniciar conversa",
"New Password": "Nova senha",
- "Username available": "Nome de usuária(o) disponível",
- "Username not available": "Nome de usuária(o) indisponível",
- "Something went wrong!": "Algo deu errado!",
- "This will be your account name on the homeserver, or you can pick a different server.": "Este será seu nome de conta no Servidor de Base , ou então você pode escolher um servidor diferente.",
+ "Username available": "Nome de usuário disponível",
+ "Username not available": "Nome de usuário indisponível",
+ "Something went wrong!": "Não foi possível carregar!",
+ "This will be your account name on the homeserver, or you can pick a different server.": "Esse será o nome da sua conta no servidor principal, ou então você pode escolher um servidor diferente.",
"If you already have a Matrix account you can log in instead.": "Se você já tem uma conta Matrix, pode também fazer login.",
"Accept": "Aceitar",
"Active call (%(roomName)s)": "Chamada ativa (%(roomName)s)",
@@ -356,18 +356,18 @@
"Custom": "Personalizado",
"Decline": "Recusar",
"Drop File Here": "Arraste o arquivo aqui",
- "Failed to upload profile picture!": "Falha ao enviar a imagem de perfil!",
+ "Failed to upload profile picture!": "Falha ao enviar a foto de perfil!",
"Incoming call from %(name)s": "Recebendo chamada de %(name)s",
"Incoming video call from %(name)s": "Recebendo chamada de vídeo de %(name)s",
"Incoming voice call from %(name)s": "Recebendo chamada de voz de %(name)s",
"Join as voice or video.": "Participar por voz ou por vídeo.",
- "Last seen": "Último uso",
- "No display name": "Sem nome público de usuária(o)",
+ "Last seen": "Visto por último às",
+ "No display name": "Nenhum nome e sobrenome",
"Private Chat": "Conversa privada",
"Public Chat": "Conversa pública",
"%(roomName)s does not exist.": "%(roomName)s não existe.",
"%(roomName)s is not accessible at this time.": "%(roomName)s não está acessível neste momento.",
- "Seen by %(userName)s at %(dateTime)s": "Visto por %(userName)s em %(dateTime)s",
+ "Seen by %(userName)s at %(dateTime)s": "Lida por %(userName)s em %(dateTime)s",
"Start authentication": "Iniciar autenticação",
"This room": "Esta sala",
"unknown caller": "a pessoa que está chamando é desconhecida",
@@ -380,7 +380,7 @@
"(no answer)": "(sem resposta)",
"(unknown failure: %(reason)s)": "(falha desconhecida: %(reason)s)",
"Your browser does not support the required cryptography extensions": "O seu navegador não suporta as extensões de criptografia necessárias",
- "Not a valid %(brand)s keyfile": "Não é um arquivo de chaves %(brand)s válido",
+ "Not a valid %(brand)s keyfile": "Não é um arquivo de chave válido do %(brand)s",
"Authentication check failed: incorrect password?": "Falha ao checar a autenticação: senha incorreta?",
"Do you want to set an email address?": "Você deseja definir um endereço de e-mail?",
"This will allow you to reset your password and receive notifications.": "Isso permitirá que você redefina sua senha e receba notificações.",
@@ -390,13 +390,13 @@
"Add to community": "Adicionar à comunidade",
"Add rooms to the community": "Adicionar salas à comunidade",
"Failed to invite users to community": "Falha ao convidar os usuários à comunidade",
- "Failed to invite users to %(groupId)s": "Falha ao convidar os usuários para %(groupId)s",
+ "Failed to invite users to %(groupId)s": "Falha ao convidar usuários para %(groupId)s",
"Failed to invite the following users to %(groupId)s:": "Falha ao convidar os seguintes usuários para %(groupId)s:",
- "Failed to add the following rooms to %(groupId)s:": "Falha ao adicionar as seguintes salas para %(groupId)s:",
+ "Failed to add the following rooms to %(groupId)s:": "Falha ao adicionar as seguintes salas em %(groupId)s:",
"You are not in this room.": "Você não está nesta sala.",
- "You do not have permission to do that in this room.": "Você não tem permissão para fazer isto nesta sala.",
- "Ignored user": "Usuário ignorado",
- "You are no longer ignoring %(userId)s": "Você parou de ignorar %(userId)s",
+ "You do not have permission to do that in this room.": "Você não tem permissão para fazer isso nesta sala.",
+ "Ignored user": "Usuário bloqueado",
+ "You are no longer ignoring %(userId)s": "Você não está mais bloqueando %(userId)s",
"Edit": "Editar",
"Unpin Message": "Desafixar Mensagem",
"Add rooms to this community": "Adicionar salas na comunidade",
@@ -405,23 +405,23 @@
"Your language of choice": "O idioma que você selecionou",
"Which officially provided instance you are using, if any": "Qual instância oficial você está usando, se for o caso",
"Whether or not you're using the Richtext mode of the Rich Text Editor": "Se você está usando o editor de texto visual",
- "Your homeserver's URL": "A URL do seu Servidor de Base (homeserver)",
+ "Your homeserver's URL": "O endereço do seu servidor local",
"The information being sent to us to help make %(brand)s better includes:": "As informações que estão sendo enviadas para ajudar a melhorar o %(brand)s incluem:",
- "Where this page includes identifiable information, such as a room, user or group ID, that data is removed before being sent to the server.": "Quando esta página tem informação de identificação, como uma sala, ID de usuária/o ou de grupo, estes dados são removidos antes de serem enviados ao servidor.",
+ "Where this page includes identifiable information, such as a room, user or group ID, that data is removed before being sent to the server.": "Quando esta página inclui informações identificáveis, como uma sala, ID de usuário ou de comunidade, estes dados são removidos antes de serem enviados ao servidor.",
"Call Failed": "A chamada falhou",
"PM": "PM",
"AM": "AM",
- "%(weekDayName)s, %(monthName)s %(day)s %(fullYear)s": "%(weekDayName)s, %(day)s de %(monthName)s de%(fullYear)s",
+ "%(weekDayName)s, %(monthName)s %(day)s %(fullYear)s": "%(weekDayName)s, %(day)s de %(monthName)s de %(fullYear)s",
"Who would you like to add to this community?": "Quem você gostaria de adicionar a esta comunidade?",
"Warning: any person you add to a community will be publicly visible to anyone who knows the community ID": "Atenção: qualquer pessoa que você adicionar a esta comunidade estará publicamente visível para todas as pessoas que conheçam o ID da comunidade",
"Invite new community members": "Convidar novos integrantes para a comunidade",
"Which rooms would you like to add to this community?": "Quais salas você quer adicionar a esta comunidade?",
"Show these rooms to non-members on the community page and room list?": "Exibir estas salas para não integrantes na página da comunidade e na lista de salas?",
"Unable to create widget.": "Não foi possível criar o widget.",
- "You are now ignoring %(userId)s": "Você está agora ignorando %(userId)s",
- "Unignored user": "Usuária/o não está sendo mais ignorada/o",
- "%(oldDisplayName)s changed their display name to %(displayName)s.": "%(oldDisplayName)s alterou o seu nome público para %(displayName)s.",
- "%(senderName)s changed the pinned messages for the room.": "%(senderName)s alterou as mensagens fixas da sala.",
+ "You are now ignoring %(userId)s": "Agora você está bloqueando %(userId)s",
+ "Unignored user": "Usuário desbloqueado",
+ "%(oldDisplayName)s changed their display name to %(displayName)s.": "%(oldDisplayName)s alterou o nome e sobrenome para %(displayName)s.",
+ "%(senderName)s changed the pinned messages for the room.": "%(senderName)s alterou as mensagens fixadas da sala.",
"%(widgetName)s widget modified by %(senderName)s": "O widget %(widgetName)s foi modificado por %(senderName)s",
"%(widgetName)s widget added by %(senderName)s": "O widget %(widgetName)s foi criado por %(senderName)s",
"%(widgetName)s widget removed by %(senderName)s": "O widget %(widgetName)s foi removido por %(senderName)s",
@@ -432,7 +432,7 @@
"Mirror local video feed": "Espelhar o feed de vídeo local",
"Enable inline URL previews by default": "Ativar, por padrão, a visualização de resumo de links",
"Enable URL previews for this room (only affects you)": "Ativar, para esta sala, a visualização de links (só afeta você)",
- "Enable URL previews by default for participants in this room": "Ativar, para todas/os as/os integrantes desta sala, a visualização de links",
+ "Enable URL previews by default for participants in this room": "Ativar, para todos os integrantes desta sala, a visualização de links",
"Cannot add any more widgets": "Não é possível adicionar novos widgets",
"The maximum permitted number of widgets have already been added to this room.": "O número máximo de widgets permitidos já foi atingido nesta sala.",
"Add a widget": "Adicionar um widget",
@@ -440,17 +440,17 @@
"%(senderName)s sent a video": "%(senderName)s enviou um vídeo",
"%(senderName)s uploaded a file": "%(senderName)s enviou um arquivo",
"Disinvite this user?": "Desconvidar esta/e usuária/o?",
- "Kick this user?": "Excluir esta/e usuária/o?",
- "Unban this user?": "Desfazer o banimento desta/e usuária/o?",
- "Ban this user?": "Banir esta/e usuária/o?",
- "You will not be able to undo this change as you are demoting yourself, if you are the last privileged user in the room it will be impossible to regain privileges.": "Você não poderá desfazer esta alteração, já que está baixando suas próprias permissões. Se você for a última pessoa nesta sala, será impossível recuperar as permissões atuais.",
- "Unignore": "Não ignorar mais",
- "Ignore": "Ignorar",
+ "Kick this user?": "Remover este usuário?",
+ "Unban this user?": "Remover o banimento deste usuário?",
+ "Ban this user?": "Banir este usuário?",
+ "You will not be able to undo this change as you are demoting yourself, if you are the last privileged user in the room it will be impossible to regain privileges.": "Você não poderá desfazer essa alteração, já que está rebaixando sua própria permissão. Se você for a última pessoa nesta sala, será impossível recuperar a permissão atual.",
+ "Unignore": "Desbloquear",
+ "Ignore": "Bloquear",
"Jump to read receipt": "Ir para a confirmação de leitura",
"Mention": "Mencionar",
"Invite": "Convidar",
- "Send an encrypted reply…": "Enviar uma resposta criptografada…",
- "Send an encrypted message…": "Enviar mensagem criptografada…",
+ "Send an encrypted reply…": "Digite sua resposta criptografada…",
+ "Send an encrypted message…": "Digite uma mensagem criptografada…",
"Jump to message": "Pular para mensagem",
"No pinned messages.": "Não há mensagens fixas.",
"Loading...": "Carregando...",
@@ -461,31 +461,31 @@
"%(duration)sd": "%(duration)sd",
"Online for %(duration)s": "Online há %(duration)s",
"Idle for %(duration)s": "Inativo há %(duration)s",
- "Offline for %(duration)s": "Offline há %(duration)s",
+ "Offline for %(duration)s": "Desconectado há %(duration)s",
"Unknown for %(duration)s": "Status desconhecido há %(duration)s",
"Unknown": "Desconhecido",
- "Replying": "Respondendo",
+ "Replying": "Em resposta a",
"No rooms to show": "Nenhuma sala para mostrar",
"Unnamed room": "Sala sem nome",
"World readable": "Aberto publicamente à leitura",
"Guests can join": "Convidadas/os podem entrar",
"Community Invites": "Convites a comunidades",
- "Banned by %(displayName)s": "Banida/o por %(displayName)s",
- "Publish this room to the public in %(domain)s's room directory?": "Quer publicar esta sala na lista pública de salas em %(domain)s's?",
+ "Banned by %(displayName)s": "Banido por %(displayName)s",
+ "Publish this room to the public in %(domain)s's room directory?": "Quer publicar esta sala na lista pública de salas da %(domain)s?",
"Members only (since the point in time of selecting this option)": "Apenas integrantes (a partir do momento em que esta opção for selecionada)",
"Members only (since they were invited)": "Apenas integrantes (desde que foram convidadas/os)",
"Members only (since they joined)": "Apenas integrantes (desde que entraram na sala)",
"Invalid community ID": "ID de comunidade inválido",
"'%(groupId)s' is not a valid community ID": "'%(groupId)s' não é um ID de comunidade válido",
- "Flair": "Insígnia",
- "Showing flair for these communities:": "Esta sala mostrará insígnias para as seguintes comunidades:",
- "This room is not showing flair for any communities": "Esta sala não está mostrando fairs para nenhuma comunidade",
+ "Flair": "Ícone",
+ "Showing flair for these communities:": "Esta sala mostra ícones das seguintes comunidades:",
+ "This room is not showing flair for any communities": "Esta sala não mostra ícones de alguma comunidade",
"New community ID (e.g. +foo:%(localDomain)s)": "Novo ID de comunidade (p.ex: +foo:%(localDomain)s)",
"URL previews are enabled by default for participants in this room.": "Pré-visualizações de links estão ativadas por padrão para participantes desta sala.",
"URL previews are disabled by default for participants in this room.": "Pré-visualizações de links estão desativadas por padrão para participantes desta sala.",
"Copied!": "Copiado!",
"Failed to copy": "Não foi possível copiar",
- "An email has been sent to %(emailAddress)s": "Um email foi enviado para %(emailAddress)s",
+ "An email has been sent to %(emailAddress)s": "Um e-mail foi enviado para %(emailAddress)s",
"A text message has been sent to %(msisdn)s": "Uma mensagem de texto foi enviada para %(msisdn)s",
"Remove from community": "Remover da comunidade",
"Disinvite this user from community?": "Desconvidar esta pessoa da comunidade?",
@@ -493,23 +493,23 @@
"Failed to withdraw invitation": "Não foi possível retirar o convite",
"Failed to remove user from community": "Não foi possível remover esta pessoa da comunidade",
"Filter community members": "Filtrar participantes da comunidade",
- "Are you sure you want to remove '%(roomName)s' from %(groupId)s?": "Tem certeza que quer remover a sala '%(roomName)s' do grupo %(groupId)s?",
+ "Are you sure you want to remove '%(roomName)s' from %(groupId)s?": "Tem certeza que quer remover a sala '%(roomName)s' da comunidade %(groupId)s?",
"Removing a room from the community will also remove it from the community page.": "Remover uma sala da comunidade também a removerá da página da comunidade.",
"Failed to remove room from community": "Não foi possível remover a sala da comunidade",
- "Failed to remove '%(roomName)s' from %(groupId)s": "Não foi possível remover a sala '%(roomName)s' do grupo %(groupId)s",
- "The visibility of '%(roomName)s' in %(groupId)s could not be updated.": "A visibilidade da sala '%(roomName)s' do grupo %(groupId)s não pôde ser atualizada.",
+ "Failed to remove '%(roomName)s' from %(groupId)s": "Não foi possível remover a sala '%(roomName)s' da comunidade %(groupId)s",
+ "The visibility of '%(roomName)s' in %(groupId)s could not be updated.": "A visibilidade da sala '%(roomName)s' na comunidade %(groupId)s não pôde ser atualizada.",
"Visibility in Room List": "Visibilidade na lista de salas",
- "Visible to everyone": "Visível para todo mundo",
+ "Visible to everyone": "Visível para todos",
"Only visible to community members": "Apenas visível para integrantes da comunidade",
"Filter community rooms": "Filtrar salas da comunidade",
- "Something went wrong when trying to get your communities.": "Algo deu errado quando estava carregando suas comunidades.",
- "Display your community flair in rooms configured to show it.": "Mostrar a insígnia de sua comunidade em salas configuradas para isso.",
+ "Something went wrong when trying to get your communities.": "Não foi possível carregar suas comunidades.",
+ "Display your community flair in rooms configured to show it.": "Mostrar o ícone da sua comunidade nas salas que o permitem.",
"You're not currently a member of any communities.": "Atualmente você não é integrante de nenhuma comunidade.",
"Allow": "Permitir",
"Delete Widget": "Apagar widget",
"Deleting a widget removes it for all users in this room. Are you sure you want to delete this widget?": "Remover um widget o remove para todas as pessoas desta sala. Tem certeza que quer remover este widget?",
"Delete widget": "Remover widget",
- "Minimize apps": "Minimizar apps",
+ "Minimize apps": "Minimizar app",
"Communities": "Comunidades",
"%(nameList)s %(transitionList)s": "%(nameList)s %(transitionList)s",
"%(severalUsers)sjoined %(count)s times|other": "%(severalUsers)s entraram %(count)s vezes",
@@ -528,38 +528,38 @@
"%(severalUsers)sleft and rejoined %(count)s times|one": "%(severalUsers)s saíram e entraram",
"%(oneUser)sleft and rejoined %(count)s times|other": "%(oneUser)s saiu e entrou %(count)s vezes",
"%(oneUser)sleft and rejoined %(count)s times|one": "%(oneUser)s saiu e entrou",
- "%(severalUsers)srejected their invitations %(count)s times|other": "%(severalUsers)s rejeitaram seus convites %(count)s vezes",
- "%(severalUsers)srejected their invitations %(count)s times|one": "%(severalUsers)s rejeitaram seus convites",
- "%(oneUser)srejected their invitation %(count)s times|other": "%(oneUser)s rejeitou seu convite %(count)s vezes",
- "%(oneUser)srejected their invitation %(count)s times|one": "%(oneUser)s rejeitou seu convite",
- "%(severalUsers)shad their invitations withdrawn %(count)s times|other": "%(severalUsers)s tiveram seus convites retirados %(count)s vezes",
- "%(severalUsers)shad their invitations withdrawn %(count)s times|one": "%(severalUsers)s tiveram seus convites retirados",
- "%(oneUser)shad their invitation withdrawn %(count)s times|other": "%(oneUser)s teve seus convites removidos %(count)s vezes",
- "%(oneUser)shad their invitation withdrawn %(count)s times|one": "%(oneUser)s teve seu convite removido",
+ "%(severalUsers)srejected their invitations %(count)s times|other": "%(severalUsers)s recusaram os convites %(count)s vezes",
+ "%(severalUsers)srejected their invitations %(count)s times|one": "%(severalUsers)s recusaram os convites",
+ "%(oneUser)srejected their invitation %(count)s times|other": "%(oneUser)s recusou o convite %(count)s vezes",
+ "%(oneUser)srejected their invitation %(count)s times|one": "%(oneUser)s recusou o convite",
+ "%(severalUsers)shad their invitations withdrawn %(count)s times|other": "%(severalUsers)s tiveram os convites retirados %(count)s vezes",
+ "%(severalUsers)shad their invitations withdrawn %(count)s times|one": "%(severalUsers)s tiveram os convites retirados",
+ "%(oneUser)shad their invitation withdrawn %(count)s times|other": "%(oneUser)s teve os convites removidos %(count)s vezes",
+ "%(oneUser)shad their invitation withdrawn %(count)s times|one": "%(oneUser)s teve o convite removido",
"were invited %(count)s times|other": "foram convidadas/os %(count)s vezes",
"were invited %(count)s times|one": "foram convidadas/os",
"was invited %(count)s times|other": "foi convidada/o %(count)s vezes",
"was invited %(count)s times|one": "foi convidada/o",
- "were banned %(count)s times|other": "foram banidas/os %(count)s vezes",
- "were banned %(count)s times|one": "foram banidas/os",
- "was banned %(count)s times|other": "foi banida/o %(count)s vezes",
- "was banned %(count)s times|one": "foi banida/o",
- "were unbanned %(count)s times|other": "tiveram seu banimento desfeito %(count)s vezes",
- "were unbanned %(count)s times|one": "tiveram seu banimento desfeito",
- "was unbanned %(count)s times|other": "teve seu banimento desfeito %(count)s vezes",
- "was unbanned %(count)s times|one": "teve seu banimento desfeito",
- "were kicked %(count)s times|other": "foram chutados %(count)s vezes",
- "were kicked %(count)s times|one": "foram excluídas/os",
- "was kicked %(count)s times|other": "foi excluída/o %(count)s vezes",
- "was kicked %(count)s times|one": "foi excluída/o",
- "%(severalUsers)schanged their name %(count)s times|other": "%(severalUsers)s alteraram o seu nome %(count)s vezes",
- "%(severalUsers)schanged their name %(count)s times|one": "%(severalUsers)s alteraram o seu nome",
- "%(oneUser)schanged their name %(count)s times|other": "%(oneUser)s alterou o seu nome %(count)s vezes",
- "%(oneUser)schanged their name %(count)s times|one": "%(oneUser)s alterou o seu nome",
- "%(severalUsers)schanged their avatar %(count)s times|other": "%(severalUsers)s alteraram a sua imagem de perfil %(count)s vezes",
- "%(severalUsers)schanged their avatar %(count)s times|one": "%(severalUsers)s alteraram a sua imagem de perfil",
- "%(oneUser)schanged their avatar %(count)s times|other": "%(oneUser)s alterou a sua imagem de perfil %(count)s vezes",
- "%(oneUser)schanged their avatar %(count)s times|one": "%(oneUser)s alterou a sua imagem de perfil",
+ "were banned %(count)s times|other": "foram banidos %(count)s vezes",
+ "were banned %(count)s times|one": "foram banidos",
+ "was banned %(count)s times|other": "foi banido %(count)s vezes",
+ "was banned %(count)s times|one": "foi banido",
+ "were unbanned %(count)s times|other": "tiveram o banimento removido %(count)s vezes",
+ "were unbanned %(count)s times|one": "tiveram o banimento removido",
+ "was unbanned %(count)s times|other": "teve o banimento removido %(count)s vezes",
+ "was unbanned %(count)s times|one": "teve o banimento removido",
+ "were kicked %(count)s times|other": "foram removidos %(count)s vezes",
+ "were kicked %(count)s times|one": "foram removidos",
+ "was kicked %(count)s times|other": "foi removido %(count)s vezes",
+ "was kicked %(count)s times|one": "foi removido",
+ "%(severalUsers)schanged their name %(count)s times|other": "%(severalUsers)s alteraram o nome e sobrenome %(count)s vezes",
+ "%(severalUsers)schanged their name %(count)s times|one": "%(severalUsers)s alteraram o nome e sobrenome",
+ "%(oneUser)schanged their name %(count)s times|other": "%(oneUser)s alterou o nome e sobrenome %(count)s vezes",
+ "%(oneUser)schanged their name %(count)s times|one": "%(oneUser)s alterou o nome e sobrenome",
+ "%(severalUsers)schanged their avatar %(count)s times|other": "%(severalUsers)s alteraram as fotos de perfil %(count)s vezes",
+ "%(severalUsers)schanged their avatar %(count)s times|one": "%(severalUsers)s alteraram as fotos de perfil",
+ "%(oneUser)schanged their avatar %(count)s times|other": "%(oneUser)s alterou a foto de perfil %(count)s vezes",
+ "%(oneUser)schanged their avatar %(count)s times|one": "%(oneUser)s alterou a foto de perfil",
"%(items)s and %(count)s others|other": "%(items)s e %(count)s outras",
"%(items)s and %(count)s others|one": "%(items)s e uma outra",
"collapse": "recolher",
@@ -573,14 +573,14 @@
"You have entered an invalid address.": "Você entrou com um endereço inválido.",
"Community IDs cannot be empty.": "IDs de comunidades não podem estar em branco.",
"Community IDs may only contain characters a-z, 0-9, or '=_-./'": "IDs de comunidade podem apenas ter os seguintes caracteres: a-z, 0-9, ou '=_-./'",
- "Something went wrong whilst creating your community": "Algo deu errado ao criar sua comunidade",
+ "Something went wrong whilst creating your community": "Não foi possível criar sua comunidade. Por favor, tente novamente",
"Create Community": "Criar comunidade",
"Community Name": "Nome da comunidade",
"Example": "Exemplo",
"Community ID": "ID da comunidade",
"example": "exemplo",
"Create": "Criar",
- "To get started, please pick a username!": "Para começar, escolha um nome de usuária/o!",
+ "To get started, please pick a username!": "Para começar, escolha um nome de usuário!",
"
HTML for your community's page
\n
\n Use the long description to introduce new members to the community, or distribute\n some important links\n
\n
\n You can even use 'img' tags\n
\n": "
HTML para a página da sua comunidade
\n
\n Use a descrição longa para apresentar a comunidade para novas/os integrantes ou partilhe links importantes.\n
\n
\n Você pode até mesmo usar tags 'img' do HTML\n
\n",
"Add rooms to the community summary": "Adicionar salas para o índice da comunidade",
"Which rooms would you like to add to this summary?": "Quais salas você gostaria de adicionar a este índice?",
@@ -598,12 +598,12 @@
"Failed to upload image": "O envio da imagem falhou",
"Failed to update community": "A atualização da comunidade falhou",
"Unable to accept invite": "Não foi possível aceitar o convite",
- "Unable to reject invite": "Não foi possível rejeitar o convite",
+ "Unable to reject invite": "Não foi possível recusar o convite",
"Leave Community": "Deixar a comunidade",
"Leave %(groupName)s?": "Quer sair da comunidade %(groupName)s?",
"Leave": "Sair",
"Community Settings": "Configurações da comunidade",
- "These rooms are displayed to community members on the community page. Community members can join the rooms by clicking on them.": "Estas salas são exibidas para as/os integrantes da comunidade na página da comunidade. Integrantes da comunidade podem entrar nas salas ao clicar nas mesmas.",
+ "These rooms are displayed to community members on the community page. Community members can join the rooms by clicking on them.": "Essas salas são exibidas para os membros da comunidade na página da comunidade. Os membros da comunidade entram nas salas clicando nelas.",
"Featured Rooms:": "Salas em destaque:",
"Featured Users:": "Pessoas em destaque:",
"%(inviter)s has invited you to join this community": "%(inviter)s convidou você para entrar nesta comunidade",
@@ -629,93 +629,93 @@
"Privacy is important to us, so we don't collect any personal or identifiable data for our analytics.": "A privacidade é importante para nós, portanto nós não coletamos nenhum dado pessoa ou identificável para nossas estatísticas.",
"Learn more about how we use analytics.": "Saiba mais sobre como nós usamos os dados estatísticos.",
"Check for update": "Verificar atualizações",
- "An email has been sent to %(emailAddress)s. Once you've followed the link it contains, click below.": "Um email foi enviado para %(emailAddress)s. Quando você tiver seguido o link que está nesta mensagem, clique abaixo.",
+ "An email has been sent to %(emailAddress)s. Once you've followed the link it contains, click below.": "Um e-mail foi enviado para %(emailAddress)s. Após clicar no link contido no e-mail, clique abaixo.",
"Please note you are logging into the %(hs)s server, not matrix.org.": "Note que você está se conectando ao servidor %(hs)s, e não ao servidor matrix.org.",
"This homeserver doesn't offer any login flows which are supported by this client.": "Este servidor de base (homeserver) não oferece fluxos de login que funcionem neste cliente.",
"Define the power level of a user": "Definir o nível de permissões de um(a) usuário(a)",
- "Ignores a user, hiding their messages from you": "Ignora um(a) usuário(a), ocultando suas mensagens de você",
- "Stops ignoring a user, showing their messages going forward": "Deixa de ignorar um(a) usuário(a), exibindo suas mensagens daqui para frente",
+ "Ignores a user, hiding their messages from you": "Bloquear um usuário, esconderá as mensagens dele de você",
+ "Stops ignoring a user, showing their messages going forward": "Desbloquear um usuário, exibe suas mensagens daqui para frente",
"Notify the whole room": "Notifica a sala inteira",
"Room Notification": "Notificação da sala",
"Failed to set direct chat tag": "Falha ao definir esta conversa como direta",
"Failed to remove tag %(tagName)s from room": "Falha ao remover a tag %(tagName)s da sala",
"Failed to add tag %(tagName)s to room": "Falha ao adicionar a tag %(tagName)s para a sala",
- "Did you know: you can use communities to filter your %(brand)s experience!": "Você sabia? Você pode usar as comunidades para filtrar a sua experiência no %(brand)s!",
- "To set up a filter, drag a community avatar over to the filter panel on the far left hand side of the screen. You can click on an avatar in the filter panel at any time to see only the rooms and people associated with that community.": "Para criar um filtro, arraste a imagem de uma comunidade sobre o painel de filtros na extrema esquerda da sua tela. Você pode clicar na imagem de uma comunidade no painel de filtros a qualquer momento para ver apenas as salas e pessoas associadas com esta comunidade.",
+ "Did you know: you can use communities to filter your %(brand)s experience!": "Você sabia? Você pode usar comunidades para filtrar a sua experiência no %(brand)s!",
+ "To set up a filter, drag a community avatar over to the filter panel on the far left hand side of the screen. You can click on an avatar in the filter panel at any time to see only the rooms and people associated with that community.": "Para criar um filtro, arraste a foto de uma comunidade sobre o painel de filtros na extrema esquerda da sua tela. Você pode clicar na foto de uma comunidade no painel de filtros a qualquer momento para ver apenas as salas e pessoas associadas com esta comunidade.",
"Key request sent.": "Requisição de chave enviada.",
- "Fetching third party location failed": "Falha ao acessar localização de terceiros",
+ "Fetching third party location failed": "Falha ao acessar a localização de terceiros",
"I understand the risks and wish to continue": "Entendo os riscos e desejo continuar",
"Send Account Data": "Enviar Dados da Conta",
"Advanced notification settings": "Configurações avançadas de notificação",
"Uploading report": "Enviando o relatório",
"Sunday": "Domingo",
- "Notification targets": "Alvos de notificação",
+ "Notification targets": "Aparelhos notificados",
"Today": "Hoje",
- "You are not receiving desktop notifications": "Você não está recebendo notificações desktop",
- "Friday": "Sexta",
+ "You are not receiving desktop notifications": "Você não está recebendo notificações na área de trabalho",
+ "Friday": "Sexta-feira",
"Update": "Atualizar",
"What's New": "Novidades",
"On": "Ativado",
- "Changelog": "Histórico de alterações",
- "Waiting for response from server": "Esperando por resposta do servidor",
+ "Changelog": "Registro de alterações",
+ "Waiting for response from server": "Aguardando a resposta do servidor",
"Uploaded on %(date)s by %(user)s": "Enviada em %(date)s por %(user)s",
"Send Custom Event": "Enviar Evento Customizado",
- "All notifications are currently disabled for all targets.": "Todas as notificações estão atualmente desabilitadas para todos os casos.",
+ "All notifications are currently disabled for all targets.": "Todas as notificações estão desativadas para todos os casos.",
"Forget": "Esquecer",
"You cannot delete this image. (%(code)s)": "Você não pode apagar esta imagem. (%(code)s)",
"Cancel Sending": "Cancelar o envio",
"This Room": "Esta sala",
"Resend": "Reenviar",
- "Error saving email notification preferences": "Erro ao salvar as preferências de notificação por email",
- "Messages containing my display name": "Mensagens contendo meu nome público",
+ "Error saving email notification preferences": "Erro ao salvar a configuração de notificações por e-mail",
+ "Messages containing my display name": "Mensagens contendo meu nome e sobrenome",
"Messages in one-to-one chats": "Mensagens em conversas pessoais",
"Unavailable": "Indisponível",
- "View Decrypted Source": "Ver a fonte descriptografada",
+ "View Decrypted Source": "Ver código-fonte descriptografado",
"Failed to update keywords": "Falha ao alterar as palavras-chave",
"remove %(name)s from the directory.": "remover %(name)s da lista pública de salas.",
"Notifications on the following keywords follow rules which can’t be displayed here:": "Notificações sobre as seguintes palavras-chave seguem regras que não podem ser exibidas aqui:",
"Please set a password!": "Por favor, defina uma senha!",
"You have successfully set a password!": "Você definiu sua senha com sucesso!",
- "An error occurred whilst saving your email notification preferences.": "Um erro ocorreu enquanto o sistema estava salvando suas preferências de notificação por email.",
- "Explore Room State": "Explorar Estado da Sala",
- "Source URL": "URL fonte",
+ "An error occurred whilst saving your email notification preferences.": "Ocorreu um erro ao salvar sua configuração de notificações por e-mail.",
+ "Explore Room State": "Explorar estado da sala",
+ "Source URL": "Link do código-fonte",
"Messages sent by bot": "Mensagens enviadas por bots",
"Filter results": "Filtrar resultados",
"Members": "Membros",
- "No update available.": "Não há atualizações disponíveis.",
- "Noisy": "Barulhento",
+ "No update available.": "Nenhuma atualização disponível.",
+ "Noisy": "Ativado com som",
"Files": "Arquivos",
"Collecting app version information": "Coletando informação sobre a versão do app",
"Keywords": "Palavras-chave",
- "Enable notifications for this account": "Ativar notificações para esta conta",
+ "Enable notifications for this account": "Receba notificações de novas mensagens",
"Invite to this community": "Convidar para essa comunidade",
"Messages containing keywords": "Mensagens contendo palavras-chave",
"Room not found": "Sala não encontrada",
- "Tuesday": "Terça",
+ "Tuesday": "Terça-feira",
"Enter keywords separated by a comma:": "Coloque cada palavras-chave separada por vírgula:",
"Search…": "Buscar…",
"You have successfully set a password and an email address!": "Você definiu uma senha e um endereço de e-mail com sucesso!",
"Remove %(name)s from the directory?": "Remover %(name)s da lista pública de salas?",
- "%(brand)s uses many advanced browser features, some of which are not available or experimental in your current browser.": "O %(brand)s usa muitas funcionalidades avançadas do navegador, algumas das quais não estão disponíveis ou ainda são experimentais no seu navegador atual.",
+ "%(brand)s uses many advanced browser features, some of which are not available or experimental in your current browser.": "%(brand)s usa muitos recursos avançados, e alguns deles não estão disponíveis ou ainda são experimentais no seu navegador de internet atual.",
"Developer Tools": "Ferramentas do desenvolvedor",
- "Explore Account Data": "Explorar Dados da Conta",
+ "Explore Account Data": "Explorar dados da conta",
"Remove from Directory": "Remover da lista pública de salas",
"Saturday": "Sábado",
"Remember, you can always set an email address in user settings if you change your mind.": "Lembre-se: você pode sempre definir um endereço de e-mail nas configurações de usuário, se mudar de ideia.",
"Direct Chat": "Conversa pessoal",
"The server may be unavailable or overloaded": "O servidor pode estar inacessível ou sobrecarregado",
- "Reject": "Rejeitar",
- "Failed to set Direct Message status of room": "Falha em definir a mensagem de status da sala",
- "Monday": "Segunda",
- "All messages (noisy)": "Todas as mensagens (alto)",
- "Enable them now": "Habilitar agora",
+ "Reject": "Recusar",
+ "Failed to set Direct Message status of room": "Falha em definir a descrição da conversa",
+ "Monday": "Segunda-feira",
+ "All messages (noisy)": "Todas as mensagens (com som)",
+ "Enable them now": "Ativá-los agora",
"Toolbox": "Ferramentas",
"Collecting logs": "Coletando logs",
"You must specify an event type!": "Você precisa especificar um tipo do evento!",
"(HTTP status %(httpStatus)s)": "(Status HTTP %(httpStatus)s)",
"Invite to this room": "Convidar para esta sala",
"Send logs": "Enviar registros",
- "All messages": "Todas as mensagens",
+ "All messages": "Todas as mensagens novas",
"Call invitation": "Convite para chamada",
"Downloading update...": "Baixando atualização...",
"State Key": "Chave do Estado",
@@ -723,61 +723,61 @@
"What's new?": "O que há de novidades?",
"Notify me for anything else": "Notificar-me sobre qualquer outro evento",
"When I'm invited to a room": "Quando sou convidada(o) a uma sala",
- "Can't update user notification settings": "Não é possível atualizar as preferências de notificação",
+ "Can't update user notification settings": "Não foi possível atualizar a configuração das notificações",
"Notify for all other messages/rooms": "Notificar para todas as outras mensagens e salas",
"Unable to look up room ID from server": "Não foi possível buscar identificação da sala no servidor",
"Couldn't find a matching Matrix room": "Não foi possível encontrar uma sala correspondente no servidor Matrix",
"All Rooms": "Todas as salas",
"You cannot delete this message. (%(code)s)": "Você não pode apagar esta mensagem. (%(code)s)",
- "Thursday": "Quinta",
+ "Thursday": "Quinta-feira",
"Forward Message": "Encaminhar",
"Back": "Voltar",
"Reply": "Responder",
- "Show message in desktop notification": "Mostrar mensagens na notificação",
+ "Show message in desktop notification": "Mostrar a mensagem na notificação da área de trabalho",
"Unhide Preview": "Mostrar a pré-visualização",
"Unable to join network": "Não foi possível conectar na rede",
- "Sorry, your browser is not able to run %(brand)s.": "Perdão. O seu navegador não é capaz de rodar o %(brand)s.",
+ "Sorry, your browser is not able to run %(brand)s.": "Infelizmente, o seu navegador não é capaz de rodar o %(brand)s.",
"Messages in group chats": "Mensagens em salas",
"Yesterday": "Ontem",
"Error encountered (%(errorDetail)s).": "Erro encontrado (%(errorDetail)s).",
"Low Priority": "Baixa prioridade",
- "Unable to fetch notification target list": "Não foi possível obter a lista de alvos de notificação",
+ "Unable to fetch notification target list": "Não foi possível obter a lista de aparelhos notificados",
"Set Password": "Definir senha",
"Off": "Desativado",
"Mentions only": "Apenas menções",
- "Wednesday": "Quarta",
+ "Wednesday": "Quarta-feira",
"You can now return to your account after signing out, and sign in on other devices.": "Agora você pode retornar à sua conta depois de sair, e fazer login em outros aparelhos.",
- "Enable email notifications": "Ativar notificações por email",
+ "Enable email notifications": "Ativar notificações por e-mail",
"Event Type": "Tipo do Evento",
"Download this file": "Baixar este arquivo",
"Pin Message": "Fixar Mensagem",
- "Failed to change settings": "Falhou ao mudar as preferências",
+ "Failed to change settings": "Falha ao alterar as configurações",
"View Community": "Ver a comunidade",
"Event sent!": "Evento enviado!",
- "View Source": "Ver a fonte",
+ "View Source": "Ver código-fonte",
"Event Content": "Conteúdo do Evento",
"Thank you!": "Obrigado!",
"Quote": "Citar",
- "With your current browser, the look and feel of the application may be completely incorrect, and some or all features may not function. If you want to try it anyway you can continue, but you are on your own in terms of any issues you may encounter!": "Com o seu navegador atual, a aparência e sensação de uso da aplicação podem estar completamente incorretas, e algumas das funcionalidades poderão não funcionar. Se você quiser tentar de qualquer maneira, pode continuar, mas aí vai ter que se virar sozinho(a) com os problemas que porventura encontrar!",
+ "With your current browser, the look and feel of the application may be completely incorrect, and some or all features may not function. If you want to try it anyway you can continue, but you are on your own in terms of any issues you may encounter!": "Com o seu navegador atual, a aparência e sensação de uso da aplicação podem estar completamente incorretas, e alguns dos recursos poderão não funcionar. Você ainda pode prosseguir, mas estará sozinho diante de problemas que possam surgir!",
"Checking for an update...": "Verificando se há atualizações...",
"Every page you use in the app": "Toda a página que você usa no aplicativo",
- "e.g. ": "ex. ",
+ "e.g. ": "por exemplo: ",
"Your device resolution": "A resolução do seu aparelho",
"Call in Progress": "Chamada em andamento",
- "A call is currently being placed!": "Uma chamada está sendo feita atualmente!",
+ "A call is currently being placed!": "Uma chamada já está em andamento!",
"A call is already in progress!": "Uma chamada já está em andamento!",
- "Permission Required": "Permissão Exigida",
- "You do not have permission to start a conference call in this room": "Você não tem permissão para iniciar uma chamada de conferência nesta sala",
- "Unable to load! Check your network connectivity and try again.": "Incapaz de carregar! Verifique sua conectividade de rede e tente novamente.",
+ "Permission Required": "Permissão necessária",
+ "You do not have permission to start a conference call in this room": "Você não tem permissão para iniciar uma chamada em grupo nesta sala",
+ "Unable to load! Check your network connectivity and try again.": "Não foi possível carregar! Verifique sua conexão de rede e tente novamente.",
"Failed to invite users to the room:": "Não foi possível convidar usuários para a sala:",
"Missing roomId.": "RoomId ausente.",
"Opens the Developer Tools dialog": "Abre a caixa de diálogo Ferramentas do desenvolvedor",
- "Forces the current outbound group session in an encrypted room to be discarded": "Força a atual sessão de grupo de saída em uma sala criptografada a ser descartada",
+ "Forces the current outbound group session in an encrypted room to be discarded": "Força a atual sessão da comunidade em uma sala criptografada a ser descartada",
"e.g. %(exampleValue)s": "ex. %(exampleValue)s",
- "%(senderName)s set the main address for this room to %(address)s.": "%(senderName)s definiu o endereço principal desta sala para %(address)s.",
- "%(senderName)s removed the main address for this room.": "%(senderName)s removeu o endereço principal para esta sala.",
+ "%(senderName)s set the main address for this room to %(address)s.": "%(senderName)s definiu o endereço principal desta sala como %(address)s.",
+ "%(senderName)s removed the main address for this room.": "%(senderName)s removeu o endereço principal desta sala.",
"This homeserver has hit its Monthly Active User limit.": "Este homeserver atingiu seu limite de usuário ativo mensal.",
- "This homeserver has exceeded one of its resource limits.": "Este homeserver ultrapassou um dos seus limites de recursos.",
+ "This homeserver has exceeded one of its resource limits.": "Este servidor local ultrapassou um dos seus limites de recursos.",
"Please contact your service administrator to continue using the service.": "Por favor, entre em contato com o seu administrador de serviços para continuar usando o serviço.",
"Unable to connect to Homeserver. Retrying...": "Não é possível conectar-se ao Homeserver. Tentando novamente ...",
"You do not have permission to invite people to this room.": "Você não tem permissão para convidar pessoas para esta sala.",
@@ -805,7 +805,7 @@
"This is a very common password": "Isto é uma senha muito comum",
"This is similar to a commonly used password": "Isto é similar a uma senha muito comum",
"A word by itself is easy to guess": "Uma palavra por si só é fácil de adivinhar",
- "Names and surnames by themselves are easy to guess": "Nomes e sobrenomes sozinhos são fáceis de adivinhar",
+ "Names and surnames by themselves are easy to guess": "Nomes e sobrenomes por si só são fáceis de adivinhar",
"Common names and surnames are easy to guess": "Nomes e sobrenomes comuns são fáceis de adivinhar",
"Straight rows of keys are easy to guess": "Linhas retas de teclas são fáceis de adivinhar",
"Short keyboard patterns are easy to guess": "Padrões de teclado curtos são fáceis de adivinhar",
@@ -814,89 +814,89 @@
"Please contact your homeserver administrator.": "Por favor, entre em contato com o administrador do seu homeserver.",
"Custom user status messages": "Mensagens de status de usuário personalizadas",
"Always show encryption icons": "Mostrar sempre ícones de criptografia",
- "Show a reminder to enable Secure Message Recovery in encrypted rooms": "Mostrar um lembrete para ativar o Secure Message Recovery em salas criptografadas",
+ "Show a reminder to enable Secure Message Recovery in encrypted rooms": "Mostrar um lembrete para ativar a recuperação de mensagens seguras em salas criptografadas",
"Send analytics data": "Enviar dados analíticos",
"Enable widget screenshots on supported widgets": "Ativar capturas de tela do widget em widgets suportados",
"Show developer tools": "Mostrar ferramentas de desenvolvedor",
"Messages containing @room": "Mensagens contendo @room",
"Encrypted messages in one-to-one chats": "Mensagens criptografadas em bate-papos individuais",
- "Encrypted messages in group chats": "Mensagens criptografadas em bate-papos de grupo",
+ "Encrypted messages in group chats": "Mensagens criptografadas em conversas em grupo",
"Delete Backup": "Deletar Backup",
"Unable to load key backup status": "Não é possível carregar o status da chave de backup",
"Backup version: ": "Versão do Backup: ",
"Algorithm: ": "Algoritmo: ",
"This event could not be displayed": "Este evento não pôde ser exibido",
"Use a longer keyboard pattern with more turns": "Use um padrão de teclas em diferentes direções e sentido",
- "Share Link to User": "Compartilhar Link com Usuário",
+ "Share Link to User": "Compartilhar este usuário",
"This room has been replaced and is no longer active.": "Esta sala foi substituída e não está mais ativa.",
"The conversation continues here.": "A conversa continua aqui.",
- "Seen by %(displayName)s (%(userName)s) at %(dateTime)s": "Visto por %(displayName)s (%(userName)s) em %(dateTime)s",
+ "Seen by %(displayName)s (%(userName)s) at %(dateTime)s": "Lida por %(displayName)s (%(userName)s) em %(dateTime)s",
"Share room": "Compartilhar sala",
- "System Alerts": "Alertas do Sistema",
- "Don't ask again": "Não pergunte novamente",
+ "System Alerts": "Alertas do sistema",
+ "Don't ask again": "Não perguntar novamente",
"Set up": "Configurar",
"Muted Users": "Usuários silenciados",
"Open Devtools": "Abrir as Ferramentas de Desenvolvimento",
- "Only room administrators will see this warning": "Somente administradores de sala verão esse aviso",
- "You don't currently have any stickerpacks enabled": "Atualmente, você não tem nenhum stickerpacks ativado",
+ "Only room administrators will see this warning": "Somente administradores de sala verão esse alerta",
+ "You don't currently have any stickerpacks enabled": "No momento, você não tem pacotes de figurinhas ativados",
"Demote": "Reduzir privilégio",
"Demote yourself?": "Reduzir seu próprio privilégio?",
"Add some now": "Adicione alguns agora",
- "Stickerpack": "Stickerpack",
- "Hide Stickers": "Esconder Stickers",
- "Show Stickers": "Mostrar Stickers",
- "In encrypted rooms, like this one, URL previews are disabled by default to ensure that your homeserver (where the previews are generated) cannot gather information about links you see in this room.": "Em salas criptografadas, como esta, as visualizações de URL são desabilitadas por padrão para garantir que o seu homeserver (onde as visualizações são geradas) não possa coletar informações sobre os links que você vê nesta sala.",
- "When someone puts a URL in their message, a URL preview can be shown to give more information about that link such as the title, description, and an image from the website.": "Quando alguém coloca um URL em sua mensagem, uma visualização de URL pode ser exibida para fornecer mais informações sobre esse link, como o título, a descrição e uma imagem do site.",
+ "Stickerpack": "Pacote de figurinhas",
+ "Hide Stickers": "Esconder figurinhas",
+ "Show Stickers": "Enviar figurinhas",
+ "In encrypted rooms, like this one, URL previews are disabled by default to ensure that your homeserver (where the previews are generated) cannot gather information about links you see in this room.": "Em salas criptografadas, como esta, as pré-visualizações de links estão desativadas por padrão para garantir que o seu servidor local (onde as visualizações são geradas) não possa coletar informações sobre os links que você vê nesta sala.",
+ "When someone puts a URL in their message, a URL preview can be shown to give more information about that link such as the title, description, and an image from the website.": "Quando alguém inclui um link em uma mensagem, a pré-visualização do link pode ser exibida para fornecer mais informações sobre esse link, como o título, a descrição e uma imagem do site.",
"This room is a continuation of another conversation.": "Esta sala é uma continuação de outra conversa.",
"Click here to see older messages.": "Clique aqui para ver as mensagens mais antigas.",
"Please review and accept all of the homeserver's policies": "Por favor, revise e aceite todas as políticas do homeserver",
- "Please review and accept the policies of this homeserver:": "Por favor, revise e aceite as políticas deste homeserver:",
+ "Please review and accept the policies of this homeserver:": "Por favor, revise e aceite as políticas deste servidor local:",
"Code": "Código",
- "The email field must not be blank.": "O campo de email não pode estar em branco.",
+ "The email field must not be blank.": "O campo de e-mail não pode estar em branco.",
"The phone number field must not be blank.": "O campo do número de telefone não pode estar em branco.",
"The password field must not be blank.": "O campo da senha não pode ficar em branco.",
- "Failed to load group members": "Falha ao carregar membros do grupo",
+ "Failed to load group members": "Falha ao carregar membros da comunidade",
"Failed to remove widget": "Falha ao remover o widget",
"An error ocurred whilst trying to remove the widget from the room": "Ocorreu um erro ao tentar remover o widget da sala",
"Unable to load event that was replied to, it either does not exist or you do not have permission to view it.": "Não é possível carregar o evento que foi respondido, ele não existe ou você não tem permissão para visualizá-lo.",
- "That doesn't look like a valid email address": "Isso não parece ser um endereço de e-mail válido",
+ "That doesn't look like a valid email address": "Este não parece ser um endereço de e-mail válido",
"Preparing to send logs": "Preparando para enviar registros",
"Logs sent": "Registros enviados",
- "Failed to send logs: ": "Falha ao enviar registros: ",
+ "Failed to send logs: ": "Falha ao enviar registros:· ",
"Submit debug logs": "Submeter registros de depuração",
- "Debug logs contain application usage data including your username, the IDs or aliases of the rooms or groups you have visited and the usernames of other users. They do not contain messages.": "Os registros de depuração contêm dados de uso do aplicativo, incluindo seu nome de usuário, os IDs ou aliases das salas ou grupos que você visitou e os nomes de usuários de outros usuários. Eles não contêm mensagens.",
+ "Debug logs contain application usage data including your username, the IDs or aliases of the rooms or groups you have visited and the usernames of other users. They do not contain messages.": "Os registros de depuração contêm dados de uso do aplicativo, incluindo seu nome de usuário, os IDs ou aliases das salas ou comunidades que você visitou e os nomes de usuários de outros usuários. Eles não contêm mensagens.",
"Before submitting logs, you must create a GitHub issue to describe your problem.": "Antes de enviar os registros, você deve criar um bilhete de erro no GitHub para descrever seu problema.",
"Unable to load commit detail: %(msg)s": "Não é possível carregar os detalhes do commit: %(msg)s",
- "To avoid losing your chat history, you must export your room keys before logging out. You will need to go back to the newer version of %(brand)s to do this": "Para evitar perder seu histórico de bate-papo, você deve exportar as chaves da sua sala antes de se desconectar. Para fazer isso, você precisará retornar na versão mais atual do %(brand)s",
+ "To avoid losing your chat history, you must export your room keys before logging out. You will need to go back to the newer version of %(brand)s to do this": "Para evitar perder seu histórico de bate-papo, você precisa exportar as chaves da sua sala antes de se desconectar. Quando entrar novamente, você precisará usar a versão mais atual do %(brand)s",
"Incompatible Database": "Banco de dados incompatível",
"Continue With Encryption Disabled": "Continuar com criptografia desativada",
"This will make your account permanently unusable. You will not be able to log in, and no one will be able to re-register the same user ID. This will cause your account to leave all rooms it is participating in, and it will remove your account details from your identity server. This action is irreversible.": "Isso tornará sua conta permanentemente inutilizável. Você não poderá efetuar login e ninguém poderá registrar novamente o mesmo ID de usuário. Isso fará com que sua conta deixe todas as salas nas quais está participando e removerá os detalhes da sua conta do seu servidor de identidade. Esta ação é irreversível. b>",
"Deactivating your account does not by default cause us to forget messages you have sent. If you would like us to forget your messages, please tick the box below.": "Desativar sua conta não faz com que, por padrão, esqueçamos as mensagens que você enviou. B> Se você quiser que esqueçamos suas mensagens, marque a caixa abaixo.",
- "Message visibility in Matrix is similar to email. Our forgetting your messages means that messages you have sent will not be shared with any new or unregistered users, but registered users who already have access to these messages will still have access to their copy.": "A visibilidade da mensagem no Matrix é semelhante ao e-mail. O fato de esquecermos suas mensagens significa que as mensagens que você enviou não serão compartilhadas com usuários novos ou não registrados, mas os usuários registrados que já têm acesso a essas mensagens ainda terão acesso a suas cópias.",
- "Please forget all messages I have sent when my account is deactivated (Warning: this will cause future users to see an incomplete view of conversations)": "Por favor, esqueça todas as mensagens que enviei quando minha conta for desativada (Aviso: b> isso fará com que futuros usuários vejam uma visão incompleta das conversas)",
+ "Message visibility in Matrix is similar to email. Our forgetting your messages means that messages you have sent will not be shared with any new or unregistered users, but registered users who already have access to these messages will still have access to their copy.": "A visibilidade das mensagens no Matrix é semelhante ao e-mail. O fato de esquecermos suas mensagens significa que as mensagens que você enviou não serão compartilhadas com usuários novos ou não registrados, mas os usuários registrados que já têm acesso a essas mensagens ainda terão acesso à cópia delas.",
+ "Please forget all messages I have sent when my account is deactivated (Warning: this will cause future users to see an incomplete view of conversations)": "Quando minha conta for desativada, exclua todas as mensagens que eu enviei (Atenção: isso fará com que futuros usuários tenham uma visão incompleta das conversas)",
"To continue, please enter your password:": "Para continuar, por favor digite sua senha:",
"Incompatible local cache": "Cache local incompatível",
"Clear cache and resync": "Limpar cache e ressincronizar",
- "%(brand)s now uses 3-5x less memory, by only loading information about other users when needed. Please wait whilst we resynchronise with the server!": "%(brand)s agora usa 3-5x menos memória, pois carrega informação sobre outros usuários apenas quando necessário. Por favor, aguarde enquanto ressincronizamos com o servidor!",
- "Updating %(brand)s": "Atualizando %(brand)s",
+ "%(brand)s now uses 3-5x less memory, by only loading information about other users when needed. Please wait whilst we resynchronise with the server!": "%(brand)s agora usa de 3 a 5 vezes menos memória, pois carrega as informações dos outros usuários apenas quando for necessário. Por favor, aguarde enquanto ressincronizamos com o servidor!",
+ "Updating %(brand)s": "Atualizando o %(brand)s",
"Failed to upgrade room": "Falha ao atualizar a sala",
"The room upgrade could not be completed": "A atualização da sala não pode ser completada",
"Upgrade this room to version %(version)s": "Atualize essa sala para versão %(version)s",
"Upgrade Room Version": "Atualize a Versão da Sala",
- "Create a new room with the same name, description and avatar": "Criar uma nova sala com o mesmo nome, descrição e avatar",
- "Stop users from speaking in the old version of the room, and post a message advising users to move to the new room": "Impedir usuários de conversar na versão antiga da sala e postar uma mensagem aconselhando os usuários a migrarem para a nova sala",
+ "Create a new room with the same name, description and avatar": "Criar uma nova sala com o mesmo nome, descrição e foto",
+ "Stop users from speaking in the old version of the room, and post a message advising users to move to the new room": "Impeça os usuários de conversarem na versão antiga da sala. Além disso, digite uma mensagem aconselhando os usuários a migrarem para a nova sala",
"Put a link back to the old room at the start of the new room so people can see old messages": "Colocar um link para a sala antiga no começo da sala nova de modo que as pessoas possam ver mensagens antigas",
- "You've previously used %(brand)s on %(host)s with lazy loading of members enabled. In this version lazy loading is disabled. As the local cache is not compatible between these two settings, %(brand)s needs to resync your account.": "Você já usou o %(brand)s em %(host)s com o carregamento Lazy de membros ativado. Nesta versão, o carregamento Lazy está desativado. Como o cache local não é compatível entre essas duas configurações, a %(brand)s precisa ressincronizar sua conta.",
+ "You've previously used %(brand)s on %(host)s with lazy loading of members enabled. In this version lazy loading is disabled. As the local cache is not compatible between these two settings, %(brand)s needs to resync your account.": "Você já usou o %(brand)s em %(host)s com o carregamento Lazy de membros ativado. Nesta versão, o carregamento Lazy está desativado. Como o cache local não é compatível entre essas duas configurações, o %(brand)s precisa ressincronizar sua conta.",
"If the other version of %(brand)s is still open in another tab, please close it as using %(brand)s on the same host with both lazy loading enabled and disabled simultaneously will cause issues.": "Se a outra versão do %(brand)s ainda estiver aberta em outra aba, por favor, feche-a pois usar o %(brand)s no mesmo host com o carregamento Lazy ativado e desativado simultaneamente causará problemas.",
"Update any local room aliases to point to the new room": "Atualize todos os aliases da sala local para apontar para a nova sala",
"Clear Storage and Sign Out": "Limpar armazenamento e sair",
- "Refresh": "Atualizar",
+ "Refresh": "Recarregar",
"We encountered an error trying to restore your previous session.": "Encontramos um erro ao tentar restaurar sua sessão anterior.",
"Clearing your browser's storage may fix the problem, but will sign you out and cause any encrypted chat history to become unreadable.": "Limpar o armazenamento do seu navegador pode resolver o problema, mas você será deslogado e isso fará que qualquer histórico de bate-papo criptografado fique ilegível.",
"Checking...": "Checando...",
"Share Room": "Compartilhar Sala",
"Link to most recent message": "Link para a mensagem mais recente",
- "Share User": "Compartilhar Usuário",
+ "Share User": "Compartilhar usuário",
"Share Community": "Compartilhar Comunidade",
"Share Room Message": "Compartilhar Mensagem da Sala",
"Link to selected message": "Link para a mensagem selecionada",
@@ -906,13 +906,13 @@
"No backup found!": "Nenhum backup encontrado!",
"Access your secure message history and set up secure messaging by entering your recovery passphrase.": "Acesse seu histórico de mensagens seguras e configure mensagens seguras digitando sua frase secreta de recuperação.",
"Next": "Próximo",
- "If you've forgotten your recovery passphrase you can use your recovery key or set up new recovery options": "Se você esqueceu sua frase secreata de recuperação, você pode usar sua chave de recuperação button1> ou configurar novas opções de recuperação button2>",
- "This looks like a valid recovery key!": "Isso parece uma chave de recuperação válida!",
+ "If you've forgotten your recovery passphrase you can use your recovery key or set up new recovery options": "Se você esqueceu sua frase secreta de recuperação, você pode usar sua chave de recuperação ou configurar novas opções de recuperação",
+ "This looks like a valid recovery key!": "A chave de recuperação está correta!",
"Not a valid recovery key": "Não é uma chave de recuperação válida",
"Access your secure message history and set up secure messaging by entering your recovery key.": "Acesse seu histórico seguro de mensagens e configure mensagens seguras inserindo sua chave de recuperação.",
"Share Message": "Compartilhar Mensagem",
"Popout widget": "Widget Popout",
- "Send Logs": "Enviar relatos de problemas",
+ "Send Logs": "Enviar registros",
"Failed to decrypt %(failedCount)s sessions!": "Falha ao descriptografar as sessões de %(failedCount)s!",
"Set a new status...": "Definir um novo status ...",
"Collapse Reply Thread": "Recolher grupo de respostas",
@@ -920,23 +920,23 @@
"Unable to join community": "Não é possível participar da comunidade",
"You are an administrator of this community. You will not be able to rejoin without an invite from another administrator.": "Você é um administrador dessa comunidade. Você não poderá se reingressar sem um convite de outro administrador.",
"Unable to leave community": "Não é possível sair da comunidade",
- "Changes made to your community name and avatar might not be seen by other users for up to 30 minutes.": "Alterações feitas à sua comunidade nome bold1> e avatar bold2> podem não ser vistas por outros usuários por até 30 minutos.",
+ "Changes made to your community name and avatar might not be seen by other users for up to 30 minutes.": "Alterações no nome e na foto da sua comunidade demoram até 30 minutos para serem vistas por todos os usuários.",
"Join this community": "Junte-se a esta comunidade",
"Leave this community": "Deixe esta comunidade",
"Who can join this community?": "Quem pode participar desta comunidade?",
"Everyone": "Todos",
- "Can't leave Server Notices room": "Não é possível sair da sala Notificações do servidor",
+ "Can't leave Server Notices room": "Não é possível sair da sala Avisos do Servidor",
"This room is used for important messages from the Homeserver, so you cannot leave it.": "Esta sala é usada para mensagens importantes do Homeserver, então você não pode sair dela.",
"Terms and Conditions": "Termos e Condições",
"To continue using the %(homeserverDomain)s homeserver you must review and agree to our terms and conditions.": "To continue using the %(homeserverDomain)s homeserver you must review and agree to our terms and conditions.\n\nPara continuar usando o homeserver %(homeserverDomain)s, você deve rever e concordar com nossos termos e condições.",
"Review terms and conditions": "Revise os termos e condições",
"You can't send any messages until you review and agree to our terms and conditions.": "Você não pode enviar nenhuma mensagem até revisar e concordar com nossos termos e condições.",
"Your message wasn't sent because this homeserver has hit its Monthly Active User Limit. Please contact your service administrator to continue using the service.": "Sua mensagem não foi enviada porque este homeserver atingiu seu Limite de usuário ativo mensal. Por favor, entre em contato com o seu administrador de serviços para continuar usando o serviço.",
- "Your message wasn't sent because this homeserver has exceeded a resource limit. Please contact your service administrator to continue using the service.": "Sua mensagem não foi enviada porque este homeserver excedeu o limite de recursos. Por favor, entre em contato com o seu administrador de serviços para continuar usando o serviço.",
- "If you've submitted a bug via GitHub, debug logs can help us track down the problem. Debug logs contain application usage data including your username, the IDs or aliases of the rooms or groups you have visited and the usernames of other users. They do not contain messages.": "Se você enviou um bug por meio do GitHub, os logs de depuração podem nos ajudar a rastrear o problema. Os logs de depuração contêm dados de uso do aplicativo, incluindo seu nome de usuário, os IDs ou apelidos das salas ou grupos que você visitou e os nomes de usuários de outros usuários. Eles não contêm mensagens.",
+ "Your message wasn't sent because this homeserver has exceeded a resource limit. Please contact your service administrator to continue using the service.": "Sua mensagem não foi enviada porque este servidor local excedeu o limite de recursos. Por favor, entre em contato com o seu administrador de serviços para continuar usando o serviço.",
+ "If you've submitted a bug via GitHub, debug logs can help us track down the problem. Debug logs contain application usage data including your username, the IDs or aliases of the rooms or groups you have visited and the usernames of other users. They do not contain messages.": "Se você enviou um bug por meio do GitHub, os logs de depuração podem nos ajudar a rastrear o problema. Os logs de depuração contêm dados de uso do aplicativo, incluindo seu nome de usuário, os IDs ou apelidos das salas ou comunidades que você visitou e os nomes de usuários de outros usuários. Eles não contêm mensagens.",
"Legal": "Legal",
- "No Audio Outputs detected": "Nenhuma saída de áudio detectada",
- "Audio Output": "Saída de áudio",
+ "No Audio Outputs detected": "Nenhuma caixa de som detectada",
+ "Audio Output": "Caixa de som",
"Invalid homeserver discovery response": "Resposta de descoberta de homeserver inválida",
"Invalid identity server discovery response": "Resposta de descoberta do servidor de identidade inválida",
"General failure": "Falha geral",
@@ -956,7 +956,7 @@
"Without setting up Secure Message Recovery, you'll lose your secure message history when you log out.": "Sem configurar a Recuperação Segura de Mensagens, você perderá seu histórico de mensagens seguras quando fizer logout.",
"If you don't want to set this up now, you can later in Settings.": "Se você não quiser configurá-lo agora, poderá fazê-lo posteriormente em Configurações.",
"New Recovery Method": "Novo método de recuperação",
- "If you didn't set the new recovery method, an attacker may be trying to access your account. Change your account password and set a new recovery method immediately in Settings.": "Se você não definiu o novo método de recuperação, um invasor pode estar tentando acessar sua conta. Altere a senha da sua conta e defina um novo método de recuperação imediatamente em Configurações.",
+ "If you didn't set the new recovery method, an attacker may be trying to access your account. Change your account password and set a new recovery method immediately in Settings.": "Se você não definiu o novo método de recuperação, um invasor pode estar tentando acessar sua conta. Altere a senha da sua conta e defina um novo método de recuperação imediatamente nas Configurações.",
"Set up Secure Messages": "Configurar mensagens seguras",
"Go to Settings": "Ir para as configurações",
"Unrecognised address": "Endereço não reconhecido",
@@ -971,41 +971,41 @@
"Gets or sets the room topic": "Consultar ou definir a descrição da sala",
"This room has no topic.": "Esta sala não tem descrição.",
"Sets the room name": "Define o nome da sala",
- "Group & filter rooms by custom tags (refresh to apply changes)": "Agrupar e filtrar salas por tags personalizadas (atualize para aplicar as alterações)",
+ "Group & filter rooms by custom tags (refresh to apply changes)": "Agrupar e filtrar salas por tags personalizadas (recarregue para aplicar as alterações)",
"Render simple counters in room header": "Renderizar contadores simples no cabeçalho da sala",
- "Enable Emoji suggestions while typing": "Ativar sugestões de emoticons ao digitar",
+ "Enable Emoji suggestions while typing": "Ativar sugestões de emojis ao digitar",
"Show a placeholder for removed messages": "Mostrar um marcador para as mensagens removidas",
- "Show join/leave messages (invites/kicks/bans unaffected)": "Mostrar mensagens de entrar/sair (convites/chutes/banimentos não afetados)",
- "Show avatar changes": "Mostrar alterações de avatar",
+ "Show join/leave messages (invites/kicks/bans unaffected)": "Mostrar mensagens de entrar/sair (não considera convites/remoções/banimentos)",
+ "Show avatar changes": "Mostrar alterações de foto de perfil",
"The file '%(fileName)s' exceeds this homeserver's size limit for uploads": "O arquivo '%(fileName)s' excede o limite de tamanho deste homeserver para uploads",
- "Changes your display nickname in the current room only": "Altera seu apelido de exibição apenas na sala atual",
+ "Changes your display nickname in the current room only": "Altera o seu nome e sobrenome apenas na sala atual",
"%(senderDisplayName)s upgraded this room.": "%(senderDisplayName)s atualizou esta sala.",
"%(senderDisplayName)s made the room public to whoever knows the link.": "%(senderDisplayName)s tornou a sala pública para quem conhece o link.",
"%(senderDisplayName)s made the room invite only.": "%(senderDisplayName)s tornou a sala disponível apenas por convite.",
"%(senderDisplayName)s changed the join rule to %(rule)s": "%(senderDisplayName)s alterou a regra de entrada para %(rule)s",
"%(senderDisplayName)s has allowed guests to join the room.": "%(senderDisplayName)s permitiu que os convidados entrem na sala.",
- "%(senderDisplayName)s has prevented guests from joining the room.": "%(senderDisplayName)s impediu que os convidados entrassem na sala.",
- "%(senderDisplayName)s changed guest access to %(rule)s": "%(senderDisplayName)s mudou o perfil de acesso do convidado para %(rule)s",
- "%(senderDisplayName)s enabled flair for %(groups)s in this room.": "%(senderDisplayName)s habilitou insígnias para %(groups)s nesta sala.",
- "%(senderDisplayName)s disabled flair for %(groups)s in this room.": "%(senderDisplayName)s desabilitou insígnias para %(groups)s nesta sala.",
- "%(senderDisplayName)s enabled flair for %(newGroups)s and disabled flair for %(oldGroups)s in this room.": "%(senderDisplayName)s habilitou insígnias para %(newGroups)s e desabilitou insígnias para %(oldGroups)s nesta sala.",
+ "%(senderDisplayName)s has prevented guests from joining the room.": "%(senderDisplayName)s impediu que convidados entrassem na sala.",
+ "%(senderDisplayName)s changed guest access to %(rule)s": "%(senderDisplayName)s alterou a permissão de acesso de convidados para %(rule)s",
+ "%(senderDisplayName)s enabled flair for %(groups)s in this room.": "%(senderDisplayName)s ativou o ícone de %(groups)s nesta sala.",
+ "%(senderDisplayName)s disabled flair for %(groups)s in this room.": "%(senderDisplayName)s desativou o ícone de %(groups)s nesta sala.",
+ "%(senderDisplayName)s enabled flair for %(newGroups)s and disabled flair for %(oldGroups)s in this room.": "%(senderDisplayName)s ativou o ícone de %(newGroups)s e desativou o ícone de %(oldGroups)s nesta sala.",
"%(displayName)s is typing …": "%(displayName)s está digitando…",
"%(names)s and %(count)s others are typing …|other": "%(names)s e %(count)s outras pessoas estão digitando…",
- "%(names)s and %(count)s others are typing …|one": "%(names)s e outro está digitando …",
- "%(names)s and %(lastPerson)s are typing …": "%(names)s e %(lastPerson)s estão digitando …",
+ "%(names)s and %(count)s others are typing …|one": "%(names)s e outra pessoa estão digitando…",
+ "%(names)s and %(lastPerson)s are typing …": "%(names)s e %(lastPerson)s estão digitando…",
"Show read receipts sent by other users": "Mostrar confirmações de leitura enviadas por outros usuários",
- "Show avatars in user and room mentions": "Mostrar avatares em menções de usuários e salas",
- "Enable big emoji in chat": "Ativar emoticons grandes no bate-papo",
- "Send typing notifications": "Enviar notificações de digitação",
- "Enable Community Filter Panel": "Ativar painel de filtro da comunidade",
+ "Show avatars in user and room mentions": "Mostrar fotos de perfil em menções de usuários e de salas",
+ "Enable big emoji in chat": "Ativar emojis grandes no bate-papo",
+ "Send typing notifications": "Permitir que saibam quando eu estiver digitando",
+ "Enable Community Filter Panel": "Ativar o painel de comunidades",
"Allow Peer-to-Peer for 1:1 calls": "Permitir Peer-to-Peer para chamadas 1:1",
"Messages containing my username": "Mensagens contendo meu nome de usuário",
- "The other party cancelled the verification.": "A outra parte cancelou a verificação.",
- "Verified!": "Verificado!",
+ "The other party cancelled the verification.": "Seu contato cancelou a confirmação.",
+ "Verified!": "Confirmado!",
"You've successfully verified this user.": "Você confirmou este usuário com sucesso.",
- "Secure messages with this user are end-to-end encrypted and not able to be read by third parties.": "Mensagens seguras com este usuário são criptografadas de ponta a ponta e não podem ser lidas por terceiros.",
- "Got It": "Entendi",
- "Unable to find a supported verification method.": "Não é possível encontrar um método de confirmação suportado.",
+ "Secure messages with this user are end-to-end encrypted and not able to be read by third parties.": "As mensagens com este usuário estão protegidas com a criptografia de ponta a ponta e não podem ser lidas por terceiros.",
+ "Got It": "Ok, entendi",
+ "Unable to find a supported verification method.": "Não há um método de confirmação suportado.",
"Dog": "Cachorro",
"Cat": "Gato",
"Lion": "Leão",
@@ -1036,18 +1036,18 @@
"Pizza": "Pizza",
"Cake": "Bolo",
"Heart": "Coração",
- "Smiley": "Smiley",
+ "Smiley": "Sorriso",
"Robot": "Robô",
"Hat": "Chapéu",
"Glasses": "Óculos",
- "Spanner": "Chave",
+ "Spanner": "Chave inglesa",
"Santa": "Papai-noel",
"Prepends ¯\\_(ツ)_/¯ to a plain-text message": "Adiciona ¯ \\ _ (ツ) _ / ¯ no início de uma mensagem de texto simples",
"User %(userId)s is already in the room": "O usuário %(userId)s já está na sala",
- "The user must be unbanned before they can be invited.": "O usuário não deve estar banido para poder ser convidado.",
- "Show display name changes": "Mostrar alterações no nome de exibição",
- "Verify this user by confirming the following emoji appear on their screen.": "Verifique este usuário confirmando o emoticon a seguir exibido em sua tela.",
- "Verify this user by confirming the following number appears on their screen.": "Confirme este usuário confirmando se o número a seguir aparece na tela.",
+ "The user must be unbanned before they can be invited.": "O banimento do usuário precisa ser removido antes de ser convidado.",
+ "Show display name changes": "Mostrar alterações de nome e sobrenome",
+ "Verify this user by confirming the following emoji appear on their screen.": "Confirme este usuário confirmando os emojis a seguir exibidos na tela dele.",
+ "Verify this user by confirming the following number appears on their screen.": "Confirme este usuário, comparando os números a seguir que serão exibidos na sua e na tela dele.",
"Thumbs up": "Joinha",
"Umbrella": "Guarda-chuva",
"Hourglass": "Ampulheta",
@@ -1057,7 +1057,7 @@
"Book": "Livro",
"Pencil": "Lápis",
"Paperclip": "Clipe de papel",
- "Scissors": "Tesouras",
+ "Scissors": "Tesoura",
"Key": "Chave",
"Hammer": "Martelo",
"Telephone": "Telefone",
@@ -1068,7 +1068,7 @@
"Rocket": "Foguete",
"Trophy": "Troféu",
"Ball": "Bola",
- "Guitar": "Violão",
+ "Guitar": "Guitarra",
"Trumpet": "Trombeta",
"Bell": "Sino",
"Anchor": "Âncora",
@@ -1080,17 +1080,17 @@
"We've sent you an email to verify your address. Please follow the instructions there and then click the button below.": "Enviamos um e-mail para você confirmar seu endereço. Por favor, siga as instruções e clique no botão abaixo.",
"Email Address": "Endereço de e-mail",
"Are you sure? You will lose your encrypted messages if your keys are not backed up properly.": "Você tem certeza? Você perderá suas mensagens criptografadas se não for feito o backup correto de suas chaves.",
- "Encrypted messages are secured with end-to-end encryption. Only you and the recipient(s) have the keys to read these messages.": "As mensagens criptografadas são protegidas com criptografia de ponta a ponta. Somente você e o(s) destinatário(s) têm as chaves para ler essas mensagens.",
+ "Encrypted messages are secured with end-to-end encryption. Only you and the recipient(s) have the keys to read these messages.": "As mensagens estão protegidas com a criptografia de ponta a ponta. Somente você e o(s) destinatário(s) têm as chaves para ler essas mensagens.",
"Restore from Backup": "Restaurar do Backup",
"Back up your keys before signing out to avoid losing them.": "Faça o backup das suas chaves antes de sair, para evitar perdê-las.",
"Backing up %(sessionsRemaining)s keys...": "Fazendo o backup das chaves de %(sessionsRemaining)s...",
"All keys backed up": "O Backup de todas as chaves foi realizado",
"Start using Key Backup": "Comece a usar o Backup de chave",
"Add an email address to configure email notifications": "Adicione um endereço de e-mail para configurar notificações por e-mail",
- "Unable to verify phone number.": "Não é possível verificar o número de telefone.",
- "Verification code": "Código de verificação",
+ "Unable to verify phone number.": "Não foi possível confirmar o número de telefone.",
+ "Verification code": "Código de confirmação",
"Phone Number": "Número de telefone",
- "Profile picture": "Foto de Perfil",
+ "Profile picture": "Foto de perfil",
"Upgrade to your own domain": "Atualize para seu próprio domínio",
"Set a new account password...": "Definir uma nova senha da conta...",
"Email addresses": "Endereços de e-mail",
@@ -1101,7 +1101,7 @@
"Deactivating your account is a permanent action - be careful!": "Desativar sua conta é uma ação permanente - tenha cuidado!",
"General": "Geral",
"Credits": "Créditos",
- "For help with using %(brand)s, click here.": "Para ajuda com o uso do %(brand)s, clique aqui.",
+ "For help with using %(brand)s, click here.": "Para obter ajuda com o uso do %(brand)s, clique aqui.",
"For help with using %(brand)s, click here or start a chat with our bot using the button below.": "Para obter ajuda com o uso do %(brand)s, clique aqui ou inicie um bate-papo com nosso bot usando o botão abaixo.",
"Chat with %(brand)s Bot": "Converse com o bot do %(brand)s",
"Help & About": "Ajuda & Sobre",
@@ -1113,7 +1113,7 @@
"Timeline": "Linha do Tempo",
"Room list": "Lista de Salas",
"Autocomplete delay (ms)": "Atraso no preenchimento automático (ms)",
- "Ignored users": "Usuários ignorados",
+ "Ignored users": "Usuários bloqueados",
"Bulk options": "Opções em massa",
"Accept all %(invitedRooms)s invites": "Aceite todos os convites de %(invitedRooms)s",
"Key backup": "Backup da chave",
@@ -1128,7 +1128,7 @@
"Developer options": "Opções de desenvolvedor",
"Room Addresses": "Endereços da sala",
"Change room avatar": "Alterar a foto da sala",
- "Change room name": "Alterar nome da sala",
+ "Change room name": "Alterar o nome da sala",
"Change main address for the room": "Alterar o endereço principal da sala",
"Change history visibility": "Alterar a visibilidade do histórico",
"Change permissions": "Alterar permissões",
@@ -1138,19 +1138,19 @@
"Send messages": "Enviar mensagens",
"Invite users": "Convidar usuários",
"Use Single Sign On to continue": "Use \"Single Sign On\" para continuar",
- "Confirm adding this email address by using Single Sign On to prove your identity.": "Confirme a inclusão deste endereço de correio eletrônico usando o Single Sign On para comprovar sua identidade.",
+ "Confirm adding this email address by using Single Sign On to prove your identity.": "Confirme a inclusão deste endereço de e-mail usando o Single Sign On para comprovar sua identidade.",
"Single Sign On": "Autenticação Única",
- "Confirm adding email": "Confirmar a inclusão de email",
- "Click the button below to confirm adding this email address.": "Clique no botão abaixo para confirmar a adição deste endereço de email.",
+ "Confirm adding email": "Confirmar a inclusão de e-mail",
+ "Click the button below to confirm adding this email address.": "Clique no botão abaixo para confirmar a adição deste endereço de e-mail.",
"Confirm": "Confirmar",
- "Add Email Address": "Adicionar endereço de email",
+ "Add Email Address": "Adicionar endereço de e-mail",
"Confirm adding phone number": "Confirmar adição de número de telefone",
"Add Phone Number": "Adicionar número de telefone",
- "Whether you're using %(brand)s on a device where touch is the primary input mechanism": "Se estiver usando %(brand)s em um aparelho onde touch é o mecanismo primário de entrada de dados",
- "Whether or not you're using the 'breadcrumbs' feature (avatars above the room list)": "Se você está usando ou não a funcionalidade 'breadcrumbs' (fotos acima da lista de salas)",
- "Whether you're using %(brand)s as an installed Progressive Web App": "Se estiver usando %(brand)s como uma Progressive Web App (PWA)",
+ "Whether you're using %(brand)s on a device where touch is the primary input mechanism": "Se estiver usando o %(brand)s em um aparelho onde a tela principal é touch",
+ "Whether or not you're using the 'breadcrumbs' feature (avatars above the room list)": "Se você está usando ou não o recurso 'breadcrumbs' (fotos acima da lista de salas)",
+ "Whether you're using %(brand)s as an installed Progressive Web App": "Se estiver usando o %(brand)s como um Progressive Web App (PWA)",
"Your user agent": "Seu agente de usuária(o)",
- "Call failed due to misconfigured server": "A chamada caiu por conta de má configuração no servidor",
+ "Call failed due to misconfigured server": "A chamada falhou por conta de má configuração no servidor",
"Please ask the administrator of your homeserver (%(homeserverDomain)s) to configure a TURN server in order for calls to work reliably.": "Por favor, peça ao administrador do seu servidor (%(homeserverDomain)s) para configurar um servidor TURN, de modo que as chamadas funcionem de maneira estável.",
"Alternatively, you can try to use the public server at turn.matrix.org, but this will not be as reliable, and it will share your IP address with that server. You can also manage this in Settings.": "Alternativamente, você pode tentar usar o servidor público em turn.matrix.org. No entanto, ele não é tão confiável e compartilhará o seu IP com esse servidor. Você também pode configurar isso nas Configurações.",
"Try using turn.matrix.org": "Tente utilizar turn.matrix.org",
@@ -1165,10 +1165,10 @@
"Name or Matrix ID": "Nome ou ID Matrix",
"Room name or address": "Nome ou endereço da sala",
"Identity server has no terms of service": "O servidor de identidade não tem termos de serviço",
- "This action requires accessing the default identity server to validate an email address or phone number, but the server does not have any terms of service.": "Esta ação requer acesso ao servidor de identidade padrão para poder validar um endereço de email ou número de telefone, mas este servidor não tem nenhum termo de uso.",
+ "This action requires accessing the default identity server to validate an email address or phone number, but the server does not have any terms of service.": "Esta ação requer acesso ao servidor de identidade padrão para poder validar um endereço de e-mail ou número de telefone, mas este servidor não tem nenhum termo de uso.",
"Only continue if you trust the owner of the server.": "Continue apenas se você confia em quem possui este servidor.",
"Trust": "Confiança",
- "%(name)s is requesting verification": "%(name)s está solicitando verificação",
+ "%(name)s is requesting verification": "%(name)s está solicitando confirmação",
"Use your account to sign in to the latest version": "Use sua conta para logar na última versão",
"We’re excited to announce Riot is now Element": "Estamos muito felizes em anunciar que Riot agora é Element",
"Riot is now Element!": "Riot agora é Element!",
@@ -1185,85 +1185,85 @@
"Sends a message as html, without interpreting it as markdown": "Envia uma mensagem como HTML, sem interpretá-la como markdown",
"You do not have the required permissions to use this command.": "Você não tem as permissões necessárias para usar este comando.",
"Error upgrading room": "Erro atualizando a sala",
- "Double check that your server supports the room version chosen and try again.": "Verifique mais uma ver se seu servidor suporta a versão de sala escolhida e tente novamente.",
- "Changes the avatar of the current room": "Altera a imagem da sala atual",
- "Changes your avatar in this current room only": "Muda sua imagem de perfil apenas nesta sala",
- "Changes your avatar in all rooms": "Muda sua imagem de perfil em todas as salas",
+ "Double check that your server supports the room version chosen and try again.": "Verifique se seu servidor suporta a versão de sala escolhida e tente novamente.",
+ "Changes the avatar of the current room": "Altera a foto da sala atual",
+ "Changes your avatar in this current room only": "Altera a sua foto de perfil apenas nesta sala",
+ "Changes your avatar in all rooms": "Altera a sua foto de perfil em todas as salas",
"Failed to set topic": "Não foi possível definir a descrição",
"Use an identity server": "Usar um servidor de identidade",
- "Use an identity server to invite by email. Manage in Settings.": "Use um servidor de identidade para convidar pessoas por email. Gerencie nas Configurações.",
+ "Use an identity server to invite by email. Manage in Settings.": "Use um servidor de identidade para convidar pessoas por e-mail. Gerencie nas Configurações.",
"Joins room with given address": "Entra em uma sala com o endereço fornecido",
"Unrecognised room address:": "Endereço de sala não reconhecido:",
- "Unbans user with given ID": "Desfaz o banimento de usuária(o) com ID definido",
+ "Unbans user with given ID": "Remove o banimento do usuário com o ID indicado",
"Command failed": "O comando falhou",
"Could not find user in room": "Não encontrei este(a) usuário(a) na sala",
- "Adds a custom widget by URL to the room": "Adiciona um widget personalizado por URL na sala",
- "Please supply a widget URL or embed code": "Por favor, forneça uma URL de widget ou código de integração",
- "Please supply a https:// or http:// widget URL": "Por favor, forneça uma URL de widget com https:// ou http://",
+ "Adds a custom widget by URL to the room": "Adiciona um widget personalizado na sala por meio de um link",
+ "Please supply a widget URL or embed code": "Forneça o link de um widget ou de um código de incorporação",
+ "Please supply a https:// or http:// widget URL": "Forneça o link de um widget com https:// ou http://",
"You cannot modify widgets in this room.": "Você não pode modificar widgets nesta sala.",
- "Verifies a user, session, and pubkey tuple": "Verifica um(a) usuário(a), e a tupla de chave pública",
+ "Verifies a user, session, and pubkey tuple": "Confirma um usuário, sessão, e chave criptografada pública",
"Unknown (user, session) pair:": "Par (usuária(o), sessão) desconhecido:",
- "Session already verified!": "Sessão já verificada!",
- "WARNING: Session already verified, but keys do NOT MATCH!": "ATENÇÃO: Sessão já verificada, mas as chaves NÃO SE CORRESPONDEM!",
- "WARNING: KEY VERIFICATION FAILED! The signing key for %(userId)s and session %(deviceId)s is \"%(fprint)s\" which does not match the provided key \"%(fingerprint)s\". This could mean your communications are being intercepted!": "ATENÇÃO: A VERIFICAÇÃO DA CHAVE FALHOU! A chave de assinatura para %(userId)s e sessão %(deviceId)s é \"%(fprint)s\", o que não corresponde à chave fornecida \"%(fingerprint)s\". Isso pode significar que suas comunicações estejam sendo interceptadas por terceiros!",
- "The signing key you provided matches the signing key you received from %(userId)s's session %(deviceId)s. Session marked as verified.": "A chave de assinatura que você forneceu corresponde à chave de assinatura que você recebeu da sessão %(deviceId)s da(do) usuária(o) %(userId)s. Esta sessão foi marcada como verificada.",
+ "Session already verified!": "Sessão já confirmada!",
+ "WARNING: Session already verified, but keys do NOT MATCH!": "ATENÇÃO: Sessão já confirmada, mas as chaves NÃO SÃO IGUAIS!",
+ "WARNING: KEY VERIFICATION FAILED! The signing key for %(userId)s and session %(deviceId)s is \"%(fprint)s\" which does not match the provided key \"%(fingerprint)s\". This could mean your communications are being intercepted!": "ATENÇÃO: A CONFIRMAÇÃO DA CHAVE FALHOU! A chave de assinatura para %(userId)s e sessão %(deviceId)s é \"%(fprint)s\", o que não corresponde à chave fornecida \"%(fingerprint)s\". Isso pode significar que suas comunicações estejam sendo interceptadas por terceiros!",
+ "The signing key you provided matches the signing key you received from %(userId)s's session %(deviceId)s. Session marked as verified.": "A chave de assinatura que você forneceu corresponde à chave de assinatura que você recebeu da sessão %(deviceId)s do usuário %(userId)s. Esta sessão foi marcada como confirmada.",
"Sends the given message coloured as a rainbow": "Envia a mensagem colorida como arco-íris",
"Sends the given emote coloured as a rainbow": "Envia o emoji colorido como um arco-íris",
"Displays list of commands with usages and descriptions": "Exibe a lista de comandos com usos e descrições",
- "Displays information about a user": "Exibe informação sobre um(a) usuário(a)",
+ "Displays information about a user": "Exibe informação sobre um usuário",
"Send a bug report with logs": "Envia um relatório de erros com os logs",
"Opens chat with the given user": "Abre um chat com determinada pessoa",
"Sends a message to the given user": "Envia uma mensagem com determinada pessoa",
"%(senderName)s made no change.": "%(senderName)s não fez nenhuma alteração.",
"%(senderDisplayName)s changed the room name from %(oldRoomName)s to %(newRoomName)s.": "%(senderDisplayName)s alterou o nome da sala de %(oldRoomName)s para %(newRoomName)s.",
- "%(senderName)s added the alternative addresses %(addresses)s for this room.|other": "%(senderName)s adicionou os endereços alternativos %(addresses)s para esta sala.",
- "%(senderName)s added the alternative addresses %(addresses)s for this room.|one": "%(senderName)s adicionou o endereço alternativo %(addresses)s para esta sala.",
- "%(senderName)s removed the alternative addresses %(addresses)s for this room.|other": "%(senderName)s removeu os endereços alternativos %(addresses)s para esta sala.",
- "%(senderName)s removed the alternative addresses %(addresses)s for this room.|one": "%(senderName)s removeu o endereço alternativo %(addresses)s para esta sala.",
+ "%(senderName)s added the alternative addresses %(addresses)s for this room.|other": "%(senderName)s adicionou os endereços alternativos %(addresses)s desta sala.",
+ "%(senderName)s added the alternative addresses %(addresses)s for this room.|one": "%(senderName)s adicionou o endereço alternativo %(addresses)s desta sala.",
+ "%(senderName)s removed the alternative addresses %(addresses)s for this room.|other": "%(senderName)s removeu os endereços alternativos %(addresses)s desta sala.",
+ "%(senderName)s removed the alternative addresses %(addresses)s for this room.|one": "%(senderName)s removeu o endereço alternativo %(addresses)s desta sala.",
"%(senderName)s changed the alternative addresses for this room.": "%(senderName)s alterou os endereços alternativos desta sala.",
- "%(senderName)s changed the main and alternative addresses for this room.": "%(senderName)s alterou os endereços principal e alternativos para esta sala.",
+ "%(senderName)s changed the main and alternative addresses for this room.": "%(senderName)s alterou os endereços principal e alternativos desta sala.",
"%(senderName)s changed the addresses for this room.": "%(senderName)s alterou os endereços desta sala.",
"%(senderName)s placed a voice call.": "%(senderName)s iniciou uma chamada de voz.",
"%(senderName)s placed a voice call. (not supported by this browser)": "%(senderName)s iniciou uma chamada de voz. (não suportada por este navegador)",
"%(senderName)s placed a video call.": "%(senderName)s iniciou uma chamada de vídeo.",
"%(senderName)s placed a video call. (not supported by this browser)": "%(senderName)s iniciou uma chamada de vídeo. (não suportada por este navegador)",
- "%(senderName)s revoked the invitation for %(targetDisplayName)s to join the room.": "%(senderName)s cancelou o convite a %(targetDisplayName)s para entrar na sala.",
- "%(senderName)s removed the rule banning users matching %(glob)s": "%(senderName)s removeu a regra que bane usuárias(os) que correspondem a %(glob)s",
+ "%(senderName)s revoked the invitation for %(targetDisplayName)s to join the room.": "%(senderName)s cancelou o convite para %(targetDisplayName)s entrar na sala.",
+ "%(senderName)s removed the rule banning users matching %(glob)s": "%(senderName)s removeu a regra que bane usuários que correspondem a %(glob)s",
"%(senderName)s removed the rule banning rooms matching %(glob)s": "%(senderName)s removeu a regra que bane salas que correspondem a %(glob)s",
"%(senderName)s removed the rule banning servers matching %(glob)s": "%(senderName)s removeu a regra que bane servidores que correspondem a %(glob)s",
"%(senderName)s removed a ban rule matching %(glob)s": "%(senderName)s removeu uma regra de banimento correspondendo a %(glob)s",
"%(senderName)s updated an invalid ban rule": "%(senderName)s atualizou uma regra de banimento inválida",
- "%(senderName)s updated the rule banning users matching %(glob)s for %(reason)s": "%(senderName)s atualizou a regra de banimento de usuárias(os) correspondendo a %(glob)s por %(reason)s",
- "%(senderName)s updated the rule banning rooms matching %(glob)s for %(reason)s": "%(senderName)s atualizou a regra banindo salas correspondendo a %(glob)s por %(reason)s",
- "%(senderName)s updated the rule banning servers matching %(glob)s for %(reason)s": "%(senderName)s atualizou a regra banindo servidores correspondendo a %(glob)s por %(reason)s",
- "%(senderName)s updated a ban rule matching %(glob)s for %(reason)s": "%(senderName)s atualizou uma regra de banimento correspondendo a %(glob)s por %(reason)s",
- "%(senderName)s created a rule banning users matching %(glob)s for %(reason)s": "%(senderName)s criou uma regra banindo usuárias(os) correspondentes a %(glob)s por %(reason)s",
- "%(senderName)s created a rule banning rooms matching %(glob)s for %(reason)s": "%(senderName)s criou uma regra banindo salas correspondendo a %(glob)s por %(reason)s",
- "%(senderName)s created a rule banning servers matching %(glob)s for %(reason)s": "%(senderName)s criou uma regra banindo servidores correspondendo a %(glob)s por %(reason)s",
- "%(senderName)s created a ban rule matching %(glob)s for %(reason)s": "%(senderName)s criou uma regra de banimento correspondendo a %(glob)s por %(reason)s",
- "%(senderName)s changed a rule that was banning users matching %(oldGlob)s to matching %(newGlob)s for %(reason)s": "%(senderName)s alterou uma regra que estava banindo usuárias(os) correspondendo a %(oldGlob)s para corresponder a %(newGlob)s por %(reason)s",
- "%(senderName)s changed a rule that was banning rooms matching %(oldGlob)s to matching %(newGlob)s for %(reason)s": "%(senderName)s alterou uma regra que estava banindo salas correspondendo a %(oldGlob)s para corresponder a %(newGlob)s por %(reason)s",
- "%(senderName)s changed a rule that was banning servers matching %(oldGlob)s to matching %(newGlob)s for %(reason)s": "%(senderName)s alterou uma regra que estava banindo servidores correspondendo a %(oldGlob)s para corresponder a %(newGlob)s por %(reason)s",
- "%(senderName)s updated a ban rule that was matching %(oldGlob)s to matching %(newGlob)s for %(reason)s": "%(senderName)s alterou uma regra de banimento correspondendo a %(oldGlob)s para corresponder a %(newGlob)s por %(reason)s",
+ "%(senderName)s updated the rule banning users matching %(glob)s for %(reason)s": "%(senderName)s atualizou a regra de banimento de usuários correspondendo a %(glob)s devido à %(reason)s",
+ "%(senderName)s updated the rule banning rooms matching %(glob)s for %(reason)s": "%(senderName)s atualizou a regra que bane salas que correspondem a %(glob)s devido à %(reason)s",
+ "%(senderName)s updated the rule banning servers matching %(glob)s for %(reason)s": "%(senderName)s atualizou a regra que bane servidores que correspondem a %(glob)s devido à %(reason)s",
+ "%(senderName)s updated a ban rule matching %(glob)s for %(reason)s": "%(senderName)s atualizou uma regra de banimento correspondendo a %(glob)s devido à %(reason)s",
+ "%(senderName)s created a rule banning users matching %(glob)s for %(reason)s": "%(senderName)s criou uma regra que bane usuários que correspondem a %(glob)s devido à %(reason)s",
+ "%(senderName)s created a rule banning rooms matching %(glob)s for %(reason)s": "%(senderName)s criou uma regra que bane salas que correspondem a %(glob)s devido à %(reason)s",
+ "%(senderName)s created a rule banning servers matching %(glob)s for %(reason)s": "%(senderName)s criou uma regra que bane servidores que correspondem a %(glob)s devido à %(reason)s",
+ "%(senderName)s created a ban rule matching %(glob)s for %(reason)s": "%(senderName)s criou uma regra de banimento correspondendo a %(glob)s devido à %(reason)s",
+ "%(senderName)s changed a rule that was banning users matching %(oldGlob)s to matching %(newGlob)s for %(reason)s": "%(senderName)s alterou uma regra que bania usuários que correspondiam a %(oldGlob)s para corresponder a %(newGlob)s devido à %(reason)s",
+ "%(senderName)s changed a rule that was banning rooms matching %(oldGlob)s to matching %(newGlob)s for %(reason)s": "%(senderName)s alterou uma regra que bania salas que correspondiam a %(oldGlob)s para corresponder a %(newGlob)s devido à %(reason)s",
+ "%(senderName)s changed a rule that was banning servers matching %(oldGlob)s to matching %(newGlob)s for %(reason)s": "%(senderName)s alterou uma regra que bania servidores que correspondiam a %(oldGlob)s para corresponder a %(newGlob)s devido à %(reason)s",
+ "%(senderName)s updated a ban rule that was matching %(oldGlob)s to matching %(newGlob)s for %(reason)s": "%(senderName)s alterou uma regra que bania o que correspondia a %(oldGlob)s para corresponder a %(newGlob)s devido à %(reason)s",
"Light": "Claro",
"Dark": "Escuro",
- "You signed in to a new session without verifying it:": "Você entrou em uma nova sessão sem verificá-la:",
- "Verify your other session using one of the options below.": "Verifique suas outras sessões usando uma das opções abaixo.",
- "%(name)s (%(userId)s) signed in to a new session without verifying it:": "%(name)s (%(userId)s) entrou em uma nova sessão sem verificá-la:",
- "Ask this user to verify their session, or manually verify it below.": "Peça a esta(e) usuária(o) para verificar sua sessão, ou verifiquem manualmente abaixo.",
+ "You signed in to a new session without verifying it:": "Você entrou em uma nova sessão sem confirmá-la:",
+ "Verify your other session using one of the options below.": "Confirme suas outras sessões usando uma das opções abaixo.",
+ "%(name)s (%(userId)s) signed in to a new session without verifying it:": "%(name)s (%(userId)s) entrou em uma nova sessão sem confirmá-la:",
+ "Ask this user to verify their session, or manually verify it below.": "Peça a este usuário para confirmar a sessão dele, ou confirme-a manualmente abaixo.",
"Not Trusted": "Não confiável",
- "Manually Verify by Text": "Verificada manualmente por texto",
- "Interactively verify by Emoji": "Verificar interativamente por emojis",
- "Done": "Feito",
+ "Manually Verify by Text": "Confirme manualmente por texto",
+ "Interactively verify by Emoji": "Confirme interativamente por emojis",
+ "Done": "Fechar",
"Cannot reach homeserver": "Não consigo acessar o servidor",
"Ensure you have a stable internet connection, or get in touch with the server admin": "Verifique se está com uma conexão de internet estável, ou entre em contato com os administradores do servidor",
"Your %(brand)s is misconfigured": "O %(brand)s está mal configurado",
- "Ask your %(brand)s admin to check your config for incorrect or duplicate entries.": "Peça aos administradores do %(brand)s que verifique suas configurações por entradas incorretas ou duplicadas.",
+ "Ask your %(brand)s admin to check your config for incorrect or duplicate entries.": "Entre em contato com o administrador do %(brand)s para verificar se há entradas inválidas ou duplicadas nas suas configurações.",
"Cannot reach identity server": "Não consigo acessar o servidor de identidade",
- "You can register, but some features will be unavailable until the identity server is back online. If you keep seeing this warning, check your configuration or contact a server admin.": "Você pode se registrar, mas algumas funcionalidades não estarão disponíveis até que o servidor de identidade esteja de volta online. Se você continuar vendo este alerta, verifique sua configuração ou entre em contato com um dos administradores do servidor.",
- "You can reset your password, but some features will be unavailable until the identity server is back online. If you keep seeing this warning, check your configuration or contact a server admin.": "Você pode trocar sua senha, mas algumas das funcionalidades não estarão mais disponíveis até que o servidor de identidade esteja de volta ao ar. Se você seguir vendo este alerta, verifique suas configurações ou entre em contato com um dos administradores do servidor.",
- "You can log in, but some features will be unavailable until the identity server is back online. If you keep seeing this warning, check your configuration or contact a server admin.": "Você pode fazer login, mas algumas funcionalidades estarão indisponíveis até que o servidor de identidade estiver de volta. Se você continuar vendo esta mensagem, verifique suas configurações ou entre em contato com os administradores do servidor.",
- "No homeserver URL provided": "Nenhuma URL de provedor fornecida",
+ "You can register, but some features will be unavailable until the identity server is back online. If you keep seeing this warning, check your configuration or contact a server admin.": "Você pode se registrar, mas alguns recursos não estarão disponíveis até que o servidor de identidade esteja no ar novamente. Se você continuar vendo este alerta, verifique sua configuração ou entre em contato com um dos administradores do servidor.",
+ "You can reset your password, but some features will be unavailable until the identity server is back online. If you keep seeing this warning, check your configuration or contact a server admin.": "Você pode trocar sua senha, mas alguns recursos não estarão disponíveis até que o servidor de identidade esteja no ar novamente. Se você seguir vendo este alerta, verifique suas configurações ou entre em contato com um dos administradores do servidor.",
+ "You can log in, but some features will be unavailable until the identity server is back online. If you keep seeing this warning, check your configuration or contact a server admin.": "Você pode fazer login, mas alguns recursos estarão indisponíveis até que o servidor de identidade estiver no ar novamente. Se você continuar vendo este alerta, verifique suas configurações ou entre em contato com os administradores do servidor.",
+ "No homeserver URL provided": "Nenhum endereço fornecido do servidor local",
"Unexpected error resolving homeserver configuration": "Erro inesperado buscando a configuração do servidor",
"Unexpected error resolving identity server configuration": "Erro inesperado buscando a configuração do servidor de identidade",
"The message you are trying to send is too large.": "A mensagem que você está tentando enviar é muito grande.",
@@ -1283,28 +1283,28 @@
"%(num)s days from now": "dentro de %(num)s dias",
"%(name)s (%(userId)s)": "%(name)s (%(userId)s)",
"The user's homeserver does not support the version of the room.": "O servidor desta(e) usuária(o) não suporta a versão desta sala.",
- "Help us improve %(brand)s": "Ajude-nos a melhorar %(brand)s",
+ "Help us improve %(brand)s": "Ajude-nos a melhorar o %(brand)s",
"Send anonymous usage data which helps us improve %(brand)s. This will use a cookie.": "Envie dados anônimos de uso que nos ajudam a melhorar o %(brand)s. Isso necessitará do uso de um cookie.",
"I want to help": "Quero ajudar",
"Review where you’re logged in": "Revisar onde você está logada(o)",
- "Verify all your sessions to ensure your account & messages are safe": "Verifique todas as suas sessões para garantir que sua conta e mensagens estão seguras",
+ "Verify all your sessions to ensure your account & messages are safe": "Confirme todas as suas sessões para garantir que sua conta e mensagens estão seguras",
"Review": "Revisar",
"Later": "Mais tarde",
"Your homeserver has exceeded its user limit.": "Seu servidor ultrapassou seu limite de usuárias(os).",
- "Your homeserver has exceeded one of its resource limits.": "Seu servidor excedeu um de seus limites de recursos.",
+ "Your homeserver has exceeded one of its resource limits.": "Seu servidor local excedeu um de seus limites de recursos.",
"Contact your server admin.": "Entre em contato com sua(seu) administrador(a) do servidor.",
"Ok": "Ok",
"Set password": "Definir senha",
"To return to your account in future you need to set a password": "Para retornar à sua conta no futuro, você precisa definir uma senha",
"Set up encryption": "Configurar a criptografia",
"Encryption upgrade available": "Atualização de criptografia disponível",
- "Verify this session": "Verificar esta sessão",
+ "Verify this session": "Confirmar esta sessão",
"Upgrade": "Atualizar",
- "Verify": "Verificar",
- "Verify yourself & others to keep your chats safe": "Verifique a sua conta e as dos seus contatos, para manter suas conversas seguras",
+ "Verify": "Confirmar",
+ "Verify yourself & others to keep your chats safe": "Confirme a sua conta e as dos seus contatos, para manter suas conversas seguras",
"Other users may not trust it": "Outras(os) usuárias(os) podem não confiar nela",
"New login. Was this you?": "Novo login. Foi você?",
- "Verify the new login accessing your account: %(name)s": "Verifique o novo login acessando sua conta: %(name)s",
+ "Verify the new login accessing your account: %(name)s": "Verifique o novo login na sua conta: %(name)s",
"Restart": "Reiniciar",
"Upgrade your %(brand)s": "Atualize o seu %(brand)s",
"A new version of %(brand)s is available!": "Uma nova versão do %(brand)s está disponível!",
@@ -1312,63 +1312,63 @@
"You joined the call": "Você entrou na chamada",
"%(senderName)s joined the call": "%(senderName)s entrou na chamada",
"Call in progress": "Chamada em andamento",
- "You left the call": "Você abandonou a chamada",
+ "You left the call": "Você saiu da chamada",
"%(senderName)s left the call": "%(senderName)s saiu da chamada",
"Call ended": "Chamada encerrada",
"You started a call": "Você iniciou uma chamada",
"%(senderName)s started a call": "%(senderName)s iniciou uma chamada",
- "Waiting for answer": "Esperando por uma resposta",
+ "Waiting for answer": "Aguardando a resposta",
"%(senderName)s is calling": "%(senderName)s está chamando",
"* %(senderName)s %(emote)s": "* %(senderName)s %(emote)s",
"%(senderName)s: %(message)s": "%(senderName)s: %(message)s",
"%(senderName)s: %(reaction)s": "%(senderName)s: %(reaction)s",
"%(senderName)s: %(stickerName)s": "%(senderName)s: %(stickerName)s",
- "New spinner design": "Novo design do spinner",
+ "New spinner design": "Nova aparência do símbolo de carregamento",
"Multiple integration managers": "Múltiplos gestores de integrações",
- "Try out new ways to ignore people (experimental)": "Tente novas maneiras de ignorar pessoas (experimental)",
+ "Try out new ways to ignore people (experimental)": "Tente novas maneiras de bloquear pessoas (experimental)",
"Support adding custom themes": "Permite adicionar temas personalizados",
- "Enable advanced debugging for the room list": "Habilitar análise (debugging) avançada para a lista de salas",
+ "Enable advanced debugging for the room list": "Ativar a depuração avançada para a lista de salas",
"Show info about bridges in room settings": "Exibir informações sobre bridges nas configurações das salas",
"Font size": "Tamanho da fonte",
"Use custom size": "Usar tamanho personalizado",
"Use a more compact ‘Modern’ layout": "Usar um layout mais compacto 'Moderno'",
- "Show typing notifications": "Mostrar notificações de digitação",
+ "Show typing notifications": "Mostrar quando alguém estiver digitando",
"Match system theme": "Se adaptar ao tema do sistema",
"Use a system font": "Usar uma fonte do sistema",
"System font name": "Nome da fonte do sistema",
- "Never send encrypted messages to unverified sessions from this session": "Nunca envie mensagens criptografadas para sessões não verificadas desta sessão",
- "Never send encrypted messages to unverified sessions in this room from this session": "Nunca envie mensagens criptografadas para sessões não verificadas nesta sala, desta sessão",
+ "Never send encrypted messages to unverified sessions from this session": "Nunca envie mensagens criptografadas a partir desta sessão para sessões não confirmadas",
+ "Never send encrypted messages to unverified sessions in this room from this session": "Nunca envie mensagens criptografadas a partir desta sessão para sessões não confirmadas nessa sala",
"Order rooms by name": "Ordenar salas por nome",
"Show rooms with unread notifications first": "Mostrar primeiro as salas com notificações não lidas",
"Show shortcuts to recently viewed rooms above the room list": "Mostrar atalhos para salas recentemente visualizadas acima da lista de salas",
"Show hidden events in timeline": "Mostrar eventos ocultos na timeline",
- "Low bandwidth mode": "Modo de baixo uso de internet",
+ "Low bandwidth mode": "Modo de baixo uso de dados",
"Allow fallback call assist server turn.matrix.org when your homeserver does not offer one (your IP address would be shared during a call)": "Permitir a assistência do servidor de chamadas reserva turn.matrix.org quando seu servidor não oferecer este serviço (seu endereço IP será transmitido quando você ligar)",
"Send read receipts for messages (requires compatible homeserver to disable)": "Enviar confirmação de leitura para mensagens (necessita um servidor compatível para desativar)",
"Show previews/thumbnails for images": "Mostrar miniaturas e resumos para imagens",
"Enable message search in encrypted rooms": "Ativar busca de mensagens em salas criptografadas",
"How fast should messages be downloaded.": "Com qual rapidez as mensagens devem ser baixadas.",
"Manually verify all remote sessions": "Verificar manualmente todas as sessões remotas",
- "IRC display name width": "Largura do nome IRC",
- "Enable experimental, compact IRC style layout": "Ativar o layout compacto IRC experimental",
+ "IRC display name width": "Largura do nome e sobrenome nas mensagens",
+ "Enable experimental, compact IRC style layout": "Ativar o layout compacto experimental nas mensagens",
"When rooms are upgraded": "Quando salas são atualizadas",
- "My Ban List": "Minha lista de banimentos",
+ "My Ban List": "Minha lista de banidos",
"This is your list of users/servers you have blocked - don't leave the room!": "Esta é a sua lista de usuárias(os)/servidores que você bloqueou - não saia da sala!",
- "Unknown caller": "Pessoa desconhecida chamando",
+ "Unknown caller": "Pessoa desconhecida ligando",
"Incoming voice call": "Recebendo chamada de voz",
"Incoming video call": "Recebendo chamada de vídeo",
"Incoming call": "Recebendo chamada",
- "Verify this session by completing one of the following:": "Verifique esta sessão completando um dos seguintes:",
+ "Verify this session by completing one of the following:": "Confirme esta sessão completando um dos seguintes:",
"Scan this unique code": "Escaneie este código único",
"or": "ou",
- "Compare unique emoji": "Compare um emoji único",
+ "Compare unique emoji": "Comparar emojis únicos",
"Compare a unique set of emoji if you don't have a camera on either device": "Compare um conjunto único de emojis se você não tem uma câmera em nenhum dos dois aparelhos",
"Start": "Iniciar",
- "Confirm the emoji below are displayed on both sessions, in the same order:": "Confirme que o emoji abaixo está sendo exibido nas duas sessões, na mesma ordem:",
+ "Confirm the emoji below are displayed on both sessions, in the same order:": "Confirme que os emojis abaixo estão sendo exibidos nas duas sessões, na mesma ordem:",
"Verify this session by confirming the following number appears on its screen.": "Verifique esta sessão confirmando que o seguinte número aparece na sua tela.",
- "Waiting for your other session, %(deviceName)s (%(deviceId)s), to verify…": "Esperando pela outra sessão, %(deviceName)s (%(deviceId)s), verificar…",
- "Waiting for your other session to verify…": "Esperando sua outra sessão verificar…",
- "Waiting for %(displayName)s to verify…": "Esperando por %(displayName)s verificar…",
+ "Waiting for your other session, %(deviceName)s (%(deviceId)s), to verify…": "Aguardando a outra sessão, %(deviceName)s (%(deviceId)s), confirmar…",
+ "Waiting for your other session to verify…": "Aguardando a outra sessão confirmar…",
+ "Waiting for %(displayName)s to verify…": "Aguardando %(displayName)s confirmar…",
"Cancelling…": "Cancelando…",
"They match": "São coincidentes",
"They don't match": "Elas não são correspondentes",
@@ -1384,19 +1384,19 @@
"Channel: %(channelName)s": "Canal: %(channelName)s",
"Show less": "Mostrar menos",
"Show more": "Mostrar mais",
- "Changing password will currently reset any end-to-end encryption keys on all sessions, making encrypted chat history unreadable, unless you first export your room keys and re-import them afterwards. In future this will be improved.": "Ao mudar a senha, você apagará quaisquer chaves de criptografia ponta-a-ponta existentes em todas as sessões, fazendo com que o histórico de conversas criptografadas fique ilegível, a não ser que você exporte as salas das chaves criptografadas antes de mudar a senha e então as importe novamente depois. No futuro, isso será melhorado.",
- "Your homeserver does not support cross-signing.": "Seu servidor não suporta assinatura cruzada.",
- "Cross-signing and secret storage are enabled.": "Assinaturas cruzadas e armazenamento secreto estão habilitadas.",
- "Your account has a cross-signing identity in secret storage, but it is not yet trusted by this session.": "Sua conta tem uma identidade de assinatura cruzada em um armazenamento secreto, mas ainda não é considerada confiável por esta sessão.",
- "Cross-signing and secret storage are not yet set up.": "A assinatura cruzada e o armazenamento seguro ainda não foram configurados.",
- "Reset cross-signing and secret storage": "Reinicializar a assinatura cruzada e o armazenamento secreto",
- "Bootstrap cross-signing and secret storage": "Inicializar a assinatura cruzada e o armazenamento secreto",
+ "Changing password will currently reset any end-to-end encryption keys on all sessions, making encrypted chat history unreadable, unless you first export your room keys and re-import them afterwards. In future this will be improved.": "Ao mudar a senha, você apagará todas as chaves de criptografia de ponta a ponta existentes em todas as sessões, fazendo com que o histórico de conversas criptografadas fique ilegível, a não ser que você exporte as salas das chaves criptografadas antes de mudar a senha e então as importe novamente depois. No futuro, isso será melhorado.",
+ "Your homeserver does not support cross-signing.": "Seu servidor não suporta a autoverificação.",
+ "Cross-signing and secret storage are enabled.": "A autoverificação e o armazenamento secreto estão ativados.",
+ "Your account has a cross-signing identity in secret storage, but it is not yet trusted by this session.": "Sua conta tem uma identidade autoverificada em armazenamento secreto, mas ainda não é considerada confiável por esta sessão.",
+ "Cross-signing and secret storage are not yet set up.": "A autoverificação e o armazenamento seguro ainda não foram configurados.",
+ "Reset cross-signing and secret storage": "Refazer a autoverificação e o armazenamento secreto",
+ "Bootstrap cross-signing and secret storage": "Fazer a autoverificação e o armazenamento secreto",
"well formed": "bem formado",
"unexpected type": "tipo inesperado",
- "Cross-signing public keys:": "Chaves públicas de assinatura cruzada:",
+ "Cross-signing public keys:": "Chaves públicas de autoverificação:",
"in memory": "na memória",
"not found": "não encontradas",
- "Cross-signing private keys:": "Chaves privadas de assinatura cruzada:",
+ "Cross-signing private keys:": "Chaves privadas de autoverificação:",
"in secret storage": "em armazenamento secreto",
"Self signing private key:": "Chave privada auto-assinada:",
"cached locally": "armazenado localmente",
@@ -1405,7 +1405,7 @@
"Session backup key:": "Chave de cópia (backup) da sessão:",
"Secret storage public key:": "Chave pública do armazenamento secreto:",
"in account data": "nos dados de conta",
- "Homeserver feature support:": "Funcionalidades suportadas pelo servidor:",
+ "Homeserver feature support:": "Recursos suportados pelo servidor:",
"exists": "existe",
"Your homeserver does not support session management.": "Seu servidor não suporta gerenciamento de sessões.",
"Unable to load session list": "Não foi possível carregar a lista de sessões",
@@ -1419,19 +1419,19 @@
"Delete %(count)s sessions|other": "Apagar %(count)s sessões",
"Delete %(count)s sessions|one": "Apagar %(count)s sessão",
"ID": "ID",
- "Public Name": "Nome Público",
- "Individually verify each session used by a user to mark it as trusted, not trusting cross-signed devices.": "Verificar individualmente cada sessão usada por um(a) usuário(a) para marcá-la como confiável, sem confiar em aparelhos assinados com assinatura cruzada.",
- "Securely cache encrypted messages locally for them to appear in search results, using ": "Armazene mensagens criptografadas localmente para que elas apareçam nas buscas, usando ",
+ "Public Name": "Nome público",
+ "Individually verify each session used by a user to mark it as trusted, not trusting cross-signed devices.": "Verifique individualmente cada sessão usada por um usuário para marcá-la como confiável, em vez de confirmar em aparelhos autoverificados.",
+ "Securely cache encrypted messages locally for them to appear in search results, using ": "Armazene mensagens criptografadas localmente para que elas apareçam nas buscas, usando· ",
" to store messages from ": " para armazenar mensagens de ",
"rooms.": "salas.",
"Manage": "Gerenciar",
"Securely cache encrypted messages locally for them to appear in search results.": "Armazene mensagens criptografadas de forma segura localmente para que possam aparecer nos resultados das buscas.",
"Enable": "Ativar",
- "%(brand)s is missing some components required for securely caching encrypted messages locally. If you'd like to experiment with this feature, build a custom %(brand)s Desktop with search components added.": "%(brand)s não está com alguns dos componentes necessários para armazenar com segurança mensagens criptografadas localmente. Se você quer fazer testes com esta funcionalidade, construa uma versão Desktop do %(brand)s com componentes de busca ativos.",
- "%(brand)s can't securely cache encrypted messages locally while running in a web browser. Use %(brand)s Desktop for encrypted messages to appear in search results.": "%(brand)s não consegue armazenar de forma segura as mensagens criptografadas localmente enquando funciona em um navegador web. Use %(brand)s Desktop para que mensagens criptografadas sejam exibidas nos resultados de buscas.",
+ "%(brand)s is missing some components required for securely caching encrypted messages locally. If you'd like to experiment with this feature, build a custom %(brand)s Desktop with search components added.": "%(brand)s precisa de componentes adicionais para pesquisar as mensagens criptografadas armazenadas localmente. Se quiser testar esse recurso, construa uma versão do %(brand)s para Computador com componentes de busca ativados.",
+ "%(brand)s can't securely cache encrypted messages locally while running in a web browser. Use %(brand)s Desktop for encrypted messages to appear in search results.": "%(brand)s não consegue pesquisar as mensagens criptografadas armazenadas localmente em um navegador de internet. Use o %(brand)s para Computador para que as mensagens criptografadas sejam exibidas nos resultados de buscas.",
"Connecting to integration manager...": "Conectando ao gestor de integrações...",
"Cannot connect to integration manager": "Não foi possível conectar ao gerenciador de integrações",
- "The integration manager is offline or it cannot reach your homeserver.": "O gerenciador de integrações está offline ou não consegue acesso ao seu servidor.",
+ "The integration manager is offline or it cannot reach your homeserver.": "Ou o gerenciador de integrações está desconectado, ou ele não conseguiu acessar o seu servidor.",
"This session is backing up your keys. ": "Esta sessão está fazendo a cópia (backup) das suas chaves. ",
"This session is not backing up your keys, but you do have an existing backup you can restore from and add to going forward.": "Esta sessão não está fazendo cópia (backup) de suas chaves, mas você tem uma cópia existente que pode restaurar e adicionar para continuar.",
"Connect this session to key backup before signing out to avoid losing any keys that may only be on this session.": "Conecte esta sessão à cópia de segurança (backup) das chaves antes de fazer logout para evitar perder quaisquer chaves que possam estar apenas nesta sessão.",
@@ -1439,40 +1439,40 @@
"not stored": "não armazenado",
"Backup has a valid signature from this user": "A cópia de segurança (backup) tem uma assinatura válida deste(a) usuário(a)",
"Backup has a invalid signature from this user": "A cópia de segurança (backup) tem uma assinatura inválida deste(a) usuário(a)",
- "Backup has a signature from unknown user with ID %(deviceId)s": "A cópia de segurança tem uma assinatura de um(a) usuário desconhecido com ID %(deviceId)s",
+ "Backup has a signature from unknown user with ID %(deviceId)s": "A cópia de segurança tem uma assinatura de um usuário desconhecido com ID %(deviceId)s",
"Backup has a signature from unknown session with ID %(deviceId)s": "A cópia de segurança tem uma assinatura de uma sessão desconhecida com ID %(deviceId)s",
"Backup has a valid signature from this session": "A cópia de segurança (backup) tem uma assinatura válida desta sessão",
"Backup has an invalid signature from this session": "A cópia de segurança (backup) tem uma assinatura inválida desta sessão",
- "Backup has a valid signature from verified session ": "A cópia de segurança (backup) tem uma assinatura válida da sessão verificada",
- "Backup has a valid signature from unverified session ": "A cópia de segurança tem uma assinatura válida de uma sessão não verificada",
- "Backup has an invalid signature from verified session ": "A cópia de segurança tem uma assinatura inválida de uma sessão verificada",
- "Backup has an invalid signature from unverified session ": "A cópia de segurança (backup) tem uma assinatura inválida de uma sessão não verificada",
+ "Backup has a valid signature from verified session ": "A cópia de segurança (backup) tem uma assinatura válida da sessão confirmada",
+ "Backup has a valid signature from unverified session ": "A cópia de segurança tem uma assinatura válida de uma sessão não confirmada",
+ "Backup has an invalid signature from verified session ": "A cópia de segurança tem uma assinatura inválida de uma sessão confirmada",
+ "Backup has an invalid signature from unverified session ": "A cópia de segurança (backup) tem uma assinatura inválida de uma sessão não confirmada",
"Backup is not signed by any of your sessions": "A cópia de segurança (backup) não foi assinada por nenhuma de suas sessões",
"This backup is trusted because it has been restored on this session": "Esta cópia de segurança (backup) é confiável, pois foi restaurada nesta sessão",
"Backup key stored: ": "Chave de segurança (backup) armazenada: ",
"Your keys are not being backed up from this session.": "Suas chaves não estão sendo copiadas desta sessão.",
- "wait and try again later": "espere e tente novamente mais tarde",
+ "wait and try again later": "aguarde e tente novamente mais tarde",
"Please verify the room ID or address and try again.": "Por favor, verifique o ID ou endereço da sala e tente novamente.",
- "Ignoring people is done through ban lists which contain rules for who to ban. Subscribing to a ban list means the users/servers blocked by that list will be hidden from you.": "É possível ignorar pessoas através de listas de banimento que contém regras sobre quem banir. Colocar alguém na lista de banimento significa que as pessoas ou servidores bloqueadas pela lista não serão visíveis por você.",
+ "Ignoring people is done through ban lists which contain rules for who to ban. Subscribing to a ban list means the users/servers blocked by that list will be hidden from you.": "É possível bloquear pessoas através de listas de banimento que contêm regras sobre quem banir de salas. Colocar alguém na lista de banimento significa que as pessoas ou servidores bloqueados pela lista não serão visualizados por você.",
"Session key:": "Chave da sessão:",
- "Your server admin has disabled end-to-end encryption by default in private rooms & Direct Messages.": "O/a administrador/a desativou criptografia ponta-a-ponta por padrão em salas privadas e conversas diretas.",
- "Manage the names of and sign out of your sessions below or verify them in your User Profile.": "Gerencie os nomes de suas sessões e saia das mesmas abaixo ou verifique-as no seu Perfil de Usuária(o).",
- "A session's public name is visible to people you communicate with": "Um nome público de uma sessão é visível a pessoas com as quais você já se comunica",
+ "Your server admin has disabled end-to-end encryption by default in private rooms & Direct Messages.": "O administrador do servidor desativou a criptografia de ponta a ponta por padrão em salas privadas e em conversas.",
+ "Manage the names of and sign out of your sessions below or verify them in your User Profile.": "Gerencie os nomes de suas sessões e saia das mesmas abaixo ou verifique-as no seu Perfil de Usuário.",
+ "A session's public name is visible to people you communicate with": "O nome público de uma sessão é visível para as pessoas com quem você se comunica",
"Enable room encryption": "Ativar criptografia nesta sala",
"Enable encryption?": "Ativar criptografia?",
- "Once enabled, encryption for a room cannot be disabled. Messages sent in an encrypted room cannot be seen by the server, only by the participants of the room. Enabling encryption may prevent many bots and bridges from working correctly. Learn more about encryption.": "Uma vez ativada, a criptografia da sala não poderá ser desabilitada. Mensagens enviadas em uma sala criptografada não podem ser vistas pelo servidor, apenas pelas/os participantes da sala. Habilitar a criptografia poderá impedir que vários bots e bridges funcionem corretamente. Saiba mais sobre criptografia.",
+ "Once enabled, encryption for a room cannot be disabled. Messages sent in an encrypted room cannot be seen by the server, only by the participants of the room. Enabling encryption may prevent many bots and bridges from working correctly. Learn more about encryption.": "Uma vez ativada, a criptografia da sala não poderá ser desativada. Mensagens enviadas em uma sala criptografada não podem ser lidas pelo servidor, apenas pelos participantes da sala. Ativar a criptografia poderá impedir que vários bots e bridges funcionem corretamente. Saiba mais sobre criptografia.",
"Encryption": "Criptografia",
- "Once enabled, encryption cannot be disabled.": "Uma vez ativada, a criptografia não poderá ser desabilitada.",
+ "Once enabled, encryption cannot be disabled.": "Uma vez ativada, a criptografia não poderá ser desativada.",
"Encrypted": "Criptografada",
- "Click the link in the email you received to verify and then click continue again.": "Clique no link no email que você recebeu para verificar e então clique novamente em continuar.",
- "Verify the link in your inbox": "Verifique o link na sua caixa de emails",
- "This room is end-to-end encrypted": "Esta sala é criptografada ponta-a-ponta",
- "Your key share request has been sent - please check your other sessions for key share requests.": "Sua solicitação de compartilhamento de chaves foi enviada - por favor, verifique a existência de solicitações de compartilhamento de chaves em suas outras sessões .",
- "Key share requests are sent to your other sessions automatically. If you rejected or dismissed the key share request on your other sessions, click here to request the keys for this session again.": "Solicitações de compartilhamento de chaves são enviadas para suas outras sessões automaticamente. Se você rejeitou ou ignorou a solicitação de compartilhamento de chaves em suas outras sessões, clique aqui para solicitar as chaves para esta sessão novamente.",
+ "Click the link in the email you received to verify and then click continue again.": "Clique no link no e-mail que você recebeu para confirmar e então clique novamente em continuar.",
+ "Verify the link in your inbox": "Verifique o link na sua caixa de e-mails",
+ "This room is end-to-end encrypted": "Esta sala é criptografada de ponta a ponta",
+ "Your key share request has been sent - please check your other sessions for key share requests.": "Sua solicitação de compartilhamento de chaves foi enviada - por favor, confirme a existência de solicitações de compartilhamento de chaves em suas outras sessões.",
+ "Key share requests are sent to your other sessions automatically. If you rejected or dismissed the key share request on your other sessions, click here to request the keys for this session again.": "Solicitações de compartilhamento de chaves são enviadas para suas outras sessões automaticamente. Se você recusou ou ignorou a solicitação de compartilhamento de chaves em suas outras sessões, clique aqui para solicitar as chaves para esta sessão novamente.",
"If your other sessions do not have the key for this message you will not be able to decrypt them.": "Se suas outras sessões não possuem a chave para esta mensagem, você não será capaz de descriptografá-la.",
"Re-request encryption keys from your other sessions.": "Solicitar novamente as chaves de criptografia das suas outras sessões.",
"This message cannot be decrypted": "Esta mensagem não pode ser descriptografada",
- "Encrypted by an unverified session": "Criptografada por uma sessão não verificada",
+ "Encrypted by an unverified session": "Criptografada por uma sessão não confirmada",
"Unencrypted": "Descriptografada",
"Encrypted by a deleted session": "Criptografada por uma sessão já apagada",
"The authenticity of this encrypted message can't be guaranteed on this device.": "A autenticidade desta mensagem criptografada não pode ser garantida neste aparelho.",
@@ -1481,58 +1481,58 @@
"Start chatting": "Começar a conversa",
"Try again later, or ask a room admin to check if you have access.": "Tente novamente mais tarde, ou peça a um(a) administrador(a) da sala para verificar se você tem acesso.",
"Never lose encrypted messages": "Nunca perca mensagens criptografadas",
- "Messages in this room are secured with end-to-end encryption. Only you and the recipient(s) have the keys to read these messages.": "Mensagens nesta sala estão seguras com criptografia ponta-a-ponta. Apenas você e a(s) demais pessoa(s) desta sala têm a chave para ler estas mensagens.",
+ "Messages in this room are secured with end-to-end encryption. Only you and the recipient(s) have the keys to read these messages.": "As mensagens nesta sala estão protegidas com a criptografia de ponta a ponta. Apenas você e a(s) demais pessoa(s) desta sala têm a chave para ler estas mensagens.",
"Upgrading this room will shut down the current instance of the room and create an upgraded room with the same name.": "Atualizar esta sala irá fechar a instância atual da sala e criar uma sala atualizada com o mesmo nome.",
"Hint: Begin your message with // to start it with a slash.": "Dica: Inicie sua mensagem com // para iniciar com uma barra.",
- "Start Verification": "Iniciar verificação",
- "Messages in this room are end-to-end encrypted.": "Mensagens nesta sala são criptografadas ponta-a-ponta.",
- "Messages in this room are not end-to-end encrypted.": "Mensagens nesta sala não são criptografadas ponta-a-ponta.",
+ "Start Verification": "Iniciar confirmação",
+ "Messages in this room are end-to-end encrypted.": "As mensagens nesta sala estão criptografadas de ponta a ponta.",
+ "Messages in this room are not end-to-end encrypted.": "As mensagens nesta sala não estão criptografadas de ponta a ponta.",
"In encrypted rooms, your messages are secured and only you and the recipient have the unique keys to unlock them.": "Em salas criptografadas, suas mensagens estão seguras e apenas você e a pessoa que a recebe têm as chaves únicas que permitem a sua leitura.",
- "Verify User": "Verificar usuária(o)",
- "For extra security, verify this user by checking a one-time code on both of your devices.": "Para maior segurança, verifique esta(e) usuária(o) verificando um código único em ambos aparelhos.",
- "You are about to remove %(count)s messages by %(user)s. This cannot be undone. Do you wish to continue?|other": "Você está a ponto de remover %(count)s mensagens de %(user)s. Isso não poderá ser desfeito. Quer continuar?",
+ "Verify User": "Confirmar usuário",
+ "For extra security, verify this user by checking a one-time code on both of your devices.": "Para maior segurança, confirme este usuário comparando um código único em ambos os aparelhos.",
+ "You are about to remove %(count)s messages by %(user)s. This cannot be undone. Do you wish to continue?|other": "Você apagará para todos as %(count)s mensagens de %(user)s na sala. Isso não pode ser desfeito. Deseja continuar?",
"You are about to remove %(count)s messages by %(user)s. This cannot be undone. Do you wish to continue?|one": "Você está a ponto de remover 1 mensagem de %(user)s. Isso não poderá ser desfeito. Quer continuar?",
- "This client does not support end-to-end encryption.": "Este cliente não suporte criptografia ponta-a-ponta.",
- "The session you are trying to verify doesn't support scanning a QR code or emoji verification, which is what %(brand)s supports. Try with a different client.": "A sessão que você está tentando verificar não permite escanear QR code ou verificação via emojis, que é o que %(brand)s permite. Tente um cliente diferente.",
- "Verify by scanning": "Verificar através de QR Code",
- "If you can't scan the code above, verify by comparing unique emoji.": "Se você não consegue escanear o código acima, verifique comparando os emojis únicos.",
- "Verify by comparing unique emoji.": "Verificar comparando emoji único.",
- "Verify by emoji": "Verificar por emoji",
- "Verify all users in a room to ensure it's secure.": "Verificar todas(os) as(os) usuárias(os) em uma sala para se certificar que ela é segura.",
- "In encrypted rooms, verify all users to ensure it’s secure.": "Em salas criptografadas, verificar todas(os) as(os) usuárias(os) para garantir que elas são seguras.",
- "Start verification again from the notification.": "Iniciar verificação novamente, após a notificação.",
- "Start verification again from their profile.": "Iniciar a verificação novamente a partir do seu perfil.",
- "Encryption enabled": "Criptografia habilitada",
- "Messages in this room are end-to-end encrypted. Learn more & verify this user in their user profile.": "Mensagens nesta sala são criptografadas ponta-a-ponta. Saiba mais e verifique o este(a) usuário(a) em seu perfil.",
- "Encryption not enabled": "Criptografia não habilitada",
+ "This client does not support end-to-end encryption.": "A sua versão do aplicativo não suporta a criptografia de ponta a ponta.",
+ "The session you are trying to verify doesn't support scanning a QR code or emoji verification, which is what %(brand)s supports. Try with a different client.": "A sessão que você deseja confirmar não é compatível com o escaneamento de código QR ou a confirmação via emojis do %(brand)s. Tente confirmar a partir de outro aplicativo do Element.",
+ "Verify by scanning": "Confirmar através de QR Code",
+ "If you can't scan the code above, verify by comparing unique emoji.": "Se você não consegue escanear o código acima, confirme comparando emojis únicos.",
+ "Verify by comparing unique emoji.": "Confirmar comparando emojis únicos.",
+ "Verify by emoji": "Confirmar por emojis",
+ "Verify all users in a room to ensure it's secure.": "Verifique todos os usuários em uma sala para se certificar de que ela está segura.",
+ "In encrypted rooms, verify all users to ensure it’s secure.": "Em salas criptografadas, verifique todos os usuários para garantir que a sala está segura.",
+ "Start verification again from the notification.": "Iniciar a confirmação novamente, após a notificação.",
+ "Start verification again from their profile.": "Iniciar a confirmação novamente, a partir do perfil deste usuário.",
+ "Encryption enabled": "Criptografia ativada",
+ "Messages in this room are end-to-end encrypted. Learn more & verify this user in their user profile.": "As mensagens nesta sala estão criptografadas de ponta a ponta. Lembre-se de confirmar este usuário no perfil dele/dela.",
+ "Encryption not enabled": "Criptografia desativada",
"The encryption used by this room isn't supported.": "A criptografia usada nesta sala não é suportada.",
- "%(name)s wants to verify": "%(name)s deseja verificar",
- "Smileys & People": "Emoticons e Pessoas",
+ "%(name)s wants to verify": "%(name)s solicita confirmação",
+ "Smileys & People": "Sorrisos e pessoas",
"Widgets do not use message encryption.": "Widgets não usam criptografia de mensagens.",
"Please create a new issue on GitHub so that we can investigate this bug.": "Por favor, crie um novo bilhete de erro no GitHub para que possamos investigar esta falha.",
- "Enter the name of a new server you want to explore.": "Entre com o nome do novo servidor que você quer explorar.",
+ "Enter the name of a new server you want to explore.": "Digite o nome do novo servidor que você deseja explorar.",
"Please tell us what went wrong or, better, create a GitHub issue that describes the problem.": "Por favor, diga-nos o que aconteceu de errado ou, ainda melhor, crie um bilhete de erro no GitHub que descreva o problema.",
- "Clearing all data from this session is permanent. Encrypted messages will be lost unless their keys have been backed up.": "Apagar todos os dados desta sessão é uma ação permanente. Mensagens criptografadas serão perdidas, a não ser que suas chaves tenham sido copiadas para o backup.",
+ "Clearing all data from this session is permanent. Encrypted messages will be lost unless their keys have been backed up.": "Apagar todos os dados desta sessão é uma ação permanente. Mensagens criptografadas serão perdidas, a não ser que as chaves delas tenham sido copiadas para o backup.",
"Set a room address to easily share your room with other people.": "Defina um endereço de sala para facilmente compartilhar sua sala com outras pessoas.",
- "You can’t disable this later. Bridges & most bots won’t work yet.": "Você não poderá desabilitar depois. Pontes e a maioria dos bots não funcionarão no momento.",
- "Enable end-to-end encryption": "Ativar criptografia ponta-a-ponta",
+ "You can’t disable this later. Bridges & most bots won’t work yet.": "Você não poderá desativar isso mais tarde. Pontes e a maioria dos bots não funcionarão.",
+ "Enable end-to-end encryption": "Ativar a criptografia de ponta a ponta",
"Create a public room": "Criar uma sala pública",
"Create a private room": "Criar uma sala privada",
- "Block users on other matrix homeservers from joining this room (This setting cannot be changed later!)": "Impedir usuárias(os) de outros servidores matrix de entrar nesta sala (Esta configuração não poderá ser desfeita depois!)",
- "You've previously used a newer version of %(brand)s with this session. To use this version again with end to end encryption, you will need to sign out and back in again.": "Você usou antes uma versão mais nova do %(brand)s com esta sessão. Para usar esta versão novamente, com criptografia ponta-a-ponta, você terá que sair e entrar novamente.",
- "Verify this user to mark them as trusted. Trusting users gives you extra peace of mind when using end-to-end encrypted messages.": "Verificar esta(e) usuária(o) para marcá-la(o) como confiável. Usuárias(os) de confiança dão a você mais tranquilidade mental quando estiver usando mensagens criptografadas.",
- "Verify this device to mark it as trusted. Trusting this device gives you and other users extra peace of mind when using end-to-end encrypted messages.": "Verifique este aparelho para marcá-lo como confiável. Confiar neste aparelho dá a você e às(aos) outras(os) usuárias(os) maior tranquilidade mental quando estiverem usando mensagens criptografadas.",
- "We couldn't create your DM. Please check the users you want to invite and try again.": "Não conseguimos criar sua mensagem direta. Por favor, verifique as(os) usuárias(os) que você quer convidar e tente novamente.",
- "Start a conversation with someone using their name, username (like ) or email address.": "Comece uma conversa com alguém usando seu nome, nome de usuária (como ) ou endereço de email.",
+ "Block users on other matrix homeservers from joining this room (This setting cannot be changed later!)": "Impedir usuários de outros servidores na rede Matrix de entrarem nesta sala (Essa configuração não pode ser alterada posteriormente!)",
+ "You've previously used a newer version of %(brand)s with this session. To use this version again with end to end encryption, you will need to sign out and back in again.": "Você já usou uma versão mais recente do %(brand)s nesta sessão. Para usar esta versão novamente com a criptografia de ponta a ponta, você terá que se desconectar e entrar novamente.",
+ "Verify this user to mark them as trusted. Trusting users gives you extra peace of mind when using end-to-end encrypted messages.": "Confirme este usuário para torná-lo confiável. Confiar nos usuários fornece segurança adicional ao trocar mensagens criptografadas de ponta a ponta.",
+ "Verify this device to mark it as trusted. Trusting this device gives you and other users extra peace of mind when using end-to-end encrypted messages.": "Confirme este aparelho para torná-lo confiável. Confiar neste aparelho fornecerá segurança adicional para você e aos outros ao trocarem mensagens criptografadas de ponta a ponta.",
+ "We couldn't create your DM. Please check the users you want to invite and try again.": "Não conseguimos criar sua mensagem direta. Por favor, verifique os usuários que você deseja convidar e tente novamente.",
+ "Start a conversation with someone using their name, username (like ) or email address.": "Comece uma conversa com alguém usando o seu respectivo nome e sobrenome, nome de usuário (por exemplo: ) ou endereço de e-mail.",
"a new master key signature": "uma nova chave mestra de assinatura",
- "a new cross-signing key signature": "uma nova chave de assinatura cruzada",
+ "a new cross-signing key signature": "uma nova chave de autoverificação",
"a key signature": "uma assinatura de chave",
"I don't want my encrypted messages": "Não quero minhas mensagens criptografadas",
"You'll lose access to your encrypted messages": "Você perderá acesso às suas mensagens criptografadas",
"Session key": "Chave da sessão",
- "Verify session": "Verificar sessão",
+ "Verify session": "Confirmar sessão",
"We recommend you change your password and recovery key in Settings immediately": "Nós recomendamos que você altere imediatamente sua senha e chave de recuperação nas Configurações",
- "Use this session to verify your new one, granting it access to encrypted messages:": "Use esta sessão para verificar a sua nova sessão, dando a ela acesso às mensagens criptografadas:",
+ "Use this session to verify your new one, granting it access to encrypted messages:": "Use esta sessão para confirmar a sua nova sessão, dando a ela acesso às mensagens criptografadas:",
"You’re already signed in and good to go here, but you can also grab the latest versions of the app on all platforms at element.io/get-started.": "Você já está logada(o) e pode começar a usar à vontade, mas você também pode buscar pelas últimas versões do app em todas as plataformas em element.io/get-started.",
"Go to Element": "Ir a Element",
"We’re excited to announce Riot is now Element!": "Estamos muito felizes de anunciar que agora Riot é Element!",
@@ -1541,43 +1541,43 @@
"Reporting this message will send its unique 'event ID' to the administrator of your homeserver. If messages in this room are encrypted, your homeserver administrator will not be able to read the message text or view any files or images.": "Reportar esta mensagem enviará o seu 'event ID' único para o/a administrador/a do seu Homeserver. Se as mensagens nesta sala são criptografadas, o/a administrador/a não conseguirá ler o texto da mensagem nem ver nenhuma imagem ou arquivo.",
"Sign out and remove encryption keys?": "Fazer logout e remover as chaves de criptografia?",
"Some session data, including encrypted message keys, is missing. Sign out and sign in to fix this, restoring keys from backup.": "Alguns dados de sessão, incluindo chaves de mensagens criptografadas, estão faltando. Faça logout e entre novamente para resolver isso, restaurando as chaves do backup.",
- "Verify other session": "Verificar outra sessão",
- "A widget would like to verify your identity": "Um Widget quer verificar sua identidade",
- "A widget located at %(widgetUrl)s would like to verify your identity. By allowing this, the widget will be able to verify your user ID, but not perform actions as you.": "Um widget localizado em %(widgetUrl)s deseja verificar sua identidade. Permitindo isso, o widget poderá verificar seu ID de usuária(o), mas não poderá fazer permissões passando-se por você.",
+ "Verify other session": "Confirmar outra sessão",
+ "A widget would like to verify your identity": "Um widget deseja confirmar sua identidade",
+ "A widget located at %(widgetUrl)s would like to verify your identity. By allowing this, the widget will be able to verify your user ID, but not perform actions as you.": "Um widget localizado em %(widgetUrl)s deseja confirmar sua identidade. Permitindo isso, o widget poderá verificar sua ID de usuário, mas não poderá realizar nenhuma ação em seu nome.",
"Wrong Recovery Key": "Chave de recuperação errada",
"Invalid Recovery Key": "Chave de recuperação inválida",
- "Unable to access secret storage. Please verify that you entered the correct recovery passphrase.": "Não foi possível acessar o armazenamento secreto. Por favor, verifique que você entrou com a frase de recuperação correta.",
+ "Unable to access secret storage. Please verify that you entered the correct recovery passphrase.": "Não foi possível acessar o armazenamento secreto. Por favor, verifique que você digitou a frase de recuperação correta.",
"Enter your Security Phrase or Use your Security Key to continue.": "Entre com sua Frase de Segurança ou use sua Chave de Segurança para continuar.",
"Security Key": "Chave de Segurança",
"Use your Security Key to continue.": "Use sua Chave de Segurança para continuar.",
- "Recovery key mismatch": "A chave de segurança não corresponde à correta",
- "Backup could not be decrypted with this recovery key: please verify that you entered the correct recovery key.": "O backup não pôde ser descriptografado com esta chave de recuperação: por favor, verifique se você entrou com a chave de recuperação correta.",
- "Backup could not be decrypted with this recovery passphrase: please verify that you entered the correct recovery passphrase.": "O backup não pôde ser descriptografado com esta frase de recuperação: por favor, verifique se você entrou com a frase de recuperação correta.",
+ "Recovery key mismatch": "Chave de recuperação incorreta",
+ "Backup could not be decrypted with this recovery key: please verify that you entered the correct recovery key.": "O backup não pôde ser descriptografado com esta chave de recuperação: por favor, verifique se você digitou a chave de recuperação correta.",
+ "Backup could not be decrypted with this recovery passphrase: please verify that you entered the correct recovery passphrase.": "O backup não pôde ser descriptografado com esta frase de recuperação: por favor, verifique se você digitou a frase de recuperação correta.",
"Warning: you should only set up key backup from a trusted computer.": "Atenção: você só deve configurar a cópia de segurança (backup) das chaves em um computador de sua confiança.",
- "Enter recovery key": "Entre com a chave de recuperação",
+ "Enter recovery key": "Digite a chave de recuperação",
"Warning: You should only set up key backup from a trusted computer.": "Atenção: Você só deve configurar a cópia de segurança (backup) das chaves em um computador de sua confiança.",
"If you've forgotten your recovery key you can set up new recovery options": "Se você esqueceu sua chave de recuperação, pode configurar novas opções de recuperação",
"Missing captcha public key in homeserver configuration. Please report this to your homeserver administrator.": "Está faltando a chave pública do captcha no Servidor (homeserver). Por favor, reporte isso aos(às) administradores(as) do servidor.",
"Enter the location of your Element Matrix Services homeserver. It may use your own domain name or be a subdomain of element.io.": "Entre com a localização do seu Servidor Matrix. Pode ser seu próprio domínio ou ser um subdomínio de element.io.",
"Create your Matrix account on %(serverName)s": "Criar sua conta Matrix em %(serverName)s",
"Create your Matrix account on ": "Crie sua conta Matrix em ",
- "Welcome to %(appName)s": "Desejamos boas vindas ao %(appName)s",
+ "Welcome to %(appName)s": "Bem-vinda/o ao %(appName)s",
"Liberate your communication": "Liberte sua comunicação",
- "Send a Direct Message": "Envie uma mensagem direta",
- "Explore Public Rooms": "Explore as salas públicas",
+ "Send a Direct Message": "Enviar uma mensagem",
+ "Explore Public Rooms": "Explorar salas públicas",
"Create a Group Chat": "Criar um chat de grupo",
"Explore rooms": "Explorar salas",
- "Data from an older version of %(brand)s has been detected. This will have caused end-to-end cryptography to malfunction in the older version. End-to-end encrypted messages exchanged recently whilst using the older version may not be decryptable in this version. This may also cause messages exchanged with this version to fail. If you experience problems, log out and back in again. To retain message history, export and re-import your keys.": "Detectamos uma versão mais antiga do %(brand)s. Isso fará com que a criptografia ponta-a-ponta não funcione corretamente. Mensagens criptografadas ponta-a-ponta trocadas recentemente enquanto você usava a versão mais antiga talvez não sejam descriptografáveis nesta versão. Isso poderá também fazer com que mensagens trocadas nesta sessão falhem na outra. Se você experimentar problemas, por favor faça logout e entre novamente. Para manter o histórico de mensagens, exporte e reimporte suas chaves.",
+ "Data from an older version of %(brand)s has been detected. This will have caused end-to-end cryptography to malfunction in the older version. End-to-end encrypted messages exchanged recently whilst using the older version may not be decryptable in this version. This may also cause messages exchanged with this version to fail. If you experience problems, log out and back in again. To retain message history, export and re-import your keys.": "Detectamos uma versão mais antiga do %(brand)s. Isso fará com que a criptografia de ponta a ponta não funcione corretamente. As mensagens criptografadas de ponta a ponta trocadas recentemente, enquanto você usava a versão mais antiga, talvez não sejam descriptografáveis na nova versão. Isso também poderá fazer com que as mensagens trocadas nesta sessão falhem na mais atual. Se você tiver problemas, desconecte-se e entre novamente. Para manter o histórico de mensagens, exporte e reimporte suas chaves.",
"%(creator)s created and configured the room.": "%(creator)s criou e configurou esta sala.",
- "If you can't find the room you're looking for, ask for an invite or Create a new room.": "Se você não consegue encontrar a sala que está buscando, peça para ser convidada(o) ou então crie uma sala nova.",
- "Verify this login": "Verificar este login",
- "Changing your password will reset any end-to-end encryption keys on all of your sessions, making encrypted chat history unreadable. Set up Key Backup or export your room keys from another session before resetting your password.": "Alterar a sua senha implicará na perda de quaisquer chaves de criptografia ponta-a-ponta existentes em todas as suas sessões, fazendo com que o histórico de mensagens criptografadas se torne ilegível. Faça uma cópia (backup) das suas chaves ou exporte as chaves de outra sessão antes de alterar sua senha.",
+ "If you can't find the room you're looking for, ask for an invite or Create a new room.": "Se você não conseguir encontrar a sala que está procurando, peça um convite para a sala ou Crie uma nova sala.",
+ "Verify this login": "Confirmar este login",
+ "Changing your password will reset any end-to-end encryption keys on all of your sessions, making encrypted chat history unreadable. Set up Key Backup or export your room keys from another session before resetting your password.": "Alterar a sua senha redefinirá todas as chaves de criptografia de ponta a ponta existentes em todas as suas sessões, tornando o histórico de mensagens criptografadas ilegível. Faça uma cópia (backup) das suas chaves, ou exporte as chaves de outra sessão antes de alterar a sua senha.",
"Create account": "Criar conta",
"Create your account": "Criar sua conta",
- "Use Recovery Key or Passphrase": "Use a Chave ou a Frase de Recuperação",
- "Use Recovery Key": "Use a Chave de Recuperação",
- "Confirm your identity by verifying this login from one of your other sessions, granting it access to encrypted messages.": "Confirme sua identidade através da verificação deste login em qualquer uma de suas outras sessões, garantindo a elas acesso a mensagens criptografadas.",
- "Your new session is now verified. It has access to your encrypted messages, and other users will see it as trusted.": "Sua nova sessão está agora verificada. Ela tem acesso às suas mensagens criptografadas, e outras(os) usuárias(os) poderão ver esta sessão como confiável.",
+ "Use Recovery Key or Passphrase": "Use a chave de recuperação, ou a frase de recuperação",
+ "Use Recovery Key": "Usar a chave de recuperação",
+ "Confirm your identity by verifying this login from one of your other sessions, granting it access to encrypted messages.": "Confirme sua identidade através da confirmação deste login em qualquer uma de suas outras sessões, garantindo a elas acesso a mensagens criptografadas.",
+ "Your new session is now verified. It has access to your encrypted messages, and other users will see it as trusted.": "Sua nova sessão está agora confirmada. Ela tem acesso às suas mensagens criptografadas, e outros usuários poderão ver esta sessão como confiável.",
"Without completing security on this session, it won’t have access to encrypted messages.": "Sem completar os procedimentos de segurança nesta sessão, você não terá acesso a mensagens criptografadas.",
"Regain access to your account and recover encryption keys stored in this session. Without them, you won’t be able to read all of your secure messages in any session.": "Recupere acesso à sua conta e restaure as chaves de criptografia armazenadas nesta sessão. Sem elas, você não conseguirá ler todas as suas mensagens seguras em nenhuma sessão.",
"Warning: Your personal data (including encryption keys) is still stored in this session. Clear it if you're finished using this session, or want to sign in to another account.": "Atenção: Seus dados pessoais (incluindo chaves de criptografia) ainda estão armazenados nesta sessão. Apague-os quando tiver finalizado esta sessão, ou se quer entrar com outra conta.",
@@ -1588,7 +1588,7 @@
"We’ll generate a Security Key for you to store somewhere safe, like a password manager or a safe.": "Nós geramos uma Chave de Segurança para você. Por favor, guarde-a em um lugar seguro, como um gerenciador de senhas ou um cofre.",
"Use a secret phrase only you know, and optionally save a Security Key to use for backup.": "Use uma frase secreta que apenas você conhece, e opcionalmente salve uma Chave de Segurança para usar como cópia de segurança (backup).",
"Restore your key backup to upgrade your encryption": "Restaurar a sua cópia segura (backup) de chaves para atualizar a sua criptografia",
- "Upgrade this session to allow it to verify other sessions, granting them access to encrypted messages and marking them as trusted for other users.": "Atualize esta sessão para permitir que ela verifique outras sessões, dando a elas acesso às mensagens criptografadas e marcando-as como confiáveis para as(os) demais usuárias(os).",
+ "Upgrade this session to allow it to verify other sessions, granting them access to encrypted messages and marking them as trusted for other users.": "Atualize esta sessão para permitir que ela confirme outras sessões, dando a elas acesso às mensagens criptografadas e marcando-as como confiáveis para os seus contatos.",
"Store your Security Key somewhere safe, like a password manager or a safe, as it’s used to safeguard your encrypted data.": "Guarde sua Chave de Segurança em algum lugar seguro, como por exemplo um gestor de senhas ou um cofre, já que esta chave é a proteção para seus dados criptografados.",
"If you cancel now, you may lose encrypted messages & data if you lose access to your logins.": "Se você cancelar agora, poderá perder mensagens e dados criptografados se você perder acesso aos seus logins atuais.",
"Upgrade your encryption": "Atualizar sua criptografia",
@@ -1597,7 +1597,7 @@
"Set up with a recovery key": "Configurar com uma chave de recuperação",
"Your recovery key is a safety net - you can use it to restore access to your encrypted messages if you forget your recovery passphrase.": "Sua chave de recuperação é uma rede de proteção - você pode usá-la para restaurar o acesso às suas mensagens criptografadas se você esquecer sua frase de recuperação.",
"Your recovery key": "Sua chave de recuperação",
- "Your recovery key has been copied to your clipboard, paste it to:": "Sua chave de recuperação foi copiada para sua área de transferência. Cole-a para:",
+ "Your recovery key has been copied to your clipboard, paste it to:": "Sua chave de recuperação foi copiada para sua área de transferência. Cole-a em:",
"Your recovery key is in your Downloads folder.": "Sua chave de recuperação está na sua pasta de Downloads.",
"Without setting up Secure Message Recovery, you won't be able to restore your encrypted message history if you log out or use another session.": "Sem configurar a Recuperação Segura de Mensagens, você não será capaz de restaurar seu histórico de mensagens criptografadas e fizer logout ou usar outra sessão.",
"Make a copy of your recovery key": "Fazer uma cópia de sua chave de recuperação",
@@ -1607,20 +1607,20 @@
"This session is encrypting history using the new recovery method.": "Esta sessão está criptografando o histórico de mensagens usando o novo método de restauração.",
"This session has detected that your recovery passphrase and key for Secure Messages have been removed.": "Esta sessão detectou que sua frase e chave de recuperação para Mensagens Seguras foram removidas.",
"If you did this accidentally, you can setup Secure Messages on this session which will re-encrypt this session's message history with a new recovery method.": "Se você fez isso acidentalmente, você pode configurar Mensagens Seguras nesta sessão, o que vai re-criptografar o histórico de mensagens desta sessão com um novo método de recuperação.",
- "If disabled, messages from encrypted rooms won't appear in search results.": "Se desabilitado, as mensagens de salas criptografadas não aparecerão em resultados de buscas.",
- "%(brand)s is securely caching encrypted messages locally for them to appear in search results:": "%(brand)s está armazenando de forma segura as mensagens criptografadas localmente, para que possam aparecer em resultados das buscas:",
+ "If disabled, messages from encrypted rooms won't appear in search results.": "Se desativado, as mensagens de salas criptografadas não aparecerão em resultados de buscas.",
+ "%(brand)s is securely caching encrypted messages locally for them to appear in search results:": "%(brand)s está armazenando de forma segura as mensagens criptografadas localmente, para que possam aparecer nos resultados das buscas:",
"%(doneRooms)s out of %(totalRooms)s": "%(doneRooms)s de %(totalRooms)s",
"Jump to start/end of the composer": "Pule para o início/fim do compositor",
"Click the button below to confirm adding this phone number.": "Clique no botão abaixo para confirmar a adição deste número de telefone.",
"Clear notifications": "Limpar notificações",
"There are advanced notifications which are not shown here.": "Existem notificações avançadas que não são mostradas aqui.",
- "Enable desktop notifications for this session": "Ativar notificações na área de trabalho para esta sessão",
- "Mentions & Keywords": "Menções & Palavras-Chave",
- "Notification options": "Opções de notificação",
- "Leave Room": "Sair da Sala",
+ "Enable desktop notifications for this session": "Ativar notificações na área de trabalho nesta sessão",
+ "Mentions & Keywords": "Apenas @menções e palavras-chave",
+ "Notification options": "Alterar notificações",
+ "Leave Room": "Sair da sala",
"Forget Room": "Esquecer Sala",
"Favourited": "Favoritado",
- "You cancelled verifying %(name)s": "Você cancelou a verificação do %(name)s",
+ "You cancelled verifying %(name)s": "Você cancelou a confirmação de %(name)s",
"You accepted": "Você aceitou",
"%(name)s accepted": "%(name)s aceitou",
"You declined": "Você recusou",
@@ -1629,7 +1629,7 @@
"%(name)s cancelled": "%(name)s cancelou",
"Accepting …": "Aceitando…",
"Declining …": "Recusando…",
- "You sent a verification request": "Você enviou uma solicitação de verificação",
+ "You sent a verification request": "Você enviou uma solicitação de confirmação",
"Show all": "Mostrar tudo",
"Reactions": "Reações",
" reacted with %(content)s": " reagiu com %(content)s",
@@ -1643,16 +1643,16 @@
"edited": "editado",
"Can't load this message": "Não foi possível carregar esta mensagem",
"Submit logs": "Enviar registros",
- "Frequently Used": "Usado Frequentemente",
- "Animals & Nature": "Animais e Natureza",
- "Food & Drink": "Alimentação e Bebida",
+ "Frequently Used": "Mais usados",
+ "Animals & Nature": "Animais e natureza",
+ "Food & Drink": "Comidas e bebidas",
"Activities": "Atividades",
- "Travel & Places": "Viagens & Lugares",
+ "Travel & Places": "Viagem e lugares",
"Objects": "Objetos",
"Symbols": "Símbolos",
"Flags": "Bandeiras",
"Categories": "Categorias",
- "Quick Reactions": "Reações Rápidas",
+ "Quick Reactions": "Reações rápidas",
"Cancel search": "Cancelar busca",
"Any of the following data may be shared:": "Qualquer um dos seguintes dados pode ser compartilhado:",
"Your theme": "Seu tema",
@@ -1660,7 +1660,7 @@
"Widget ID": "ID do widget",
"Widget added by": "Widget adicionado por",
"This widget may use cookies.": "Este widget pode usar cookies.",
- "Maximize apps": "Maximizar apps",
+ "Maximize apps": "Maximizar app",
"More options": "Mais opções",
"Join": "Entrar",
"Rotate Left": "Girar para a esquerda",
@@ -1697,7 +1697,7 @@
"Confirm account deactivation": "Confirmar desativação da conta",
"Server did not return valid authentication information.": "O servidor não retornou informações de autenticação válidas.",
"View Servers in Room": "Ver Servidores na Sala",
- "Verification Requests": "Solicitações de verificação",
+ "Verification Requests": "Solicitações de confirmação",
"Integrations are disabled": "As integrações estão desativadas",
"Integrations not allowed": "As integrações não estão permitidas",
"End": "Fim",
@@ -1724,16 +1724,16 @@
"Other published addresses:": "Outros endereços publicados:",
"New published address (e.g. #alias:server)": "Novo endereço publicado (por exemplo, #apelido:server)",
"Local Addresses": "Endereços locais",
- "%(name)s cancelled verifying": "%(name)s cancelou a verificação",
- "Your display name": "Seu nome de exibição",
- "Your avatar URL": "A URL da sua foto de perfil",
+ "%(name)s cancelled verifying": "%(name)s cancelou a confirmação",
+ "Your display name": "Seu nome e sobrenome",
+ "Your avatar URL": "Link da sua foto de perfil",
"Your user ID": "Sua ID de usuário",
- "%(brand)s URL": "URL de %(brand)s",
+ "%(brand)s URL": "Link do %(brand)s",
"Using this widget may share data with %(widgetDomain)s & your Integration Manager.": "Se você usar esse widget, os dados poderão ser compartilhados com %(widgetDomain)s & seu Gerenciador de Integrações.",
"Using this widget may share data with %(widgetDomain)s.": "Se você usar esse widget, os dados poderão ser compartilhados com %(widgetDomain)s.",
"%(severalUsers)smade no changes %(count)s times|other": "%(severalUsers)s não fizeram alterações %(count)s vezes",
"%(severalUsers)smade no changes %(count)s times|one": "%(severalUsers)s não fizeram alterações",
- "%(oneUser)smade no changes %(count)s times|other": "%(oneUser)s não fez alteraçõe s%(count)s vezes",
+ "%(oneUser)smade no changes %(count)s times|other": "%(oneUser)s não fez alterações %(count)s vezes",
"%(oneUser)smade no changes %(count)s times|one": "%(oneUser)s não fez alterações",
"Power level": "Nível de permissão",
"Please provide a room address": "Digite um endereço para a sala",
@@ -1747,14 +1747,14 @@
"Topic (optional)": "Descrição (opcional)",
"There was a problem communicating with the server. Please try again.": "Ocorreu um problema na comunicação com o servidor. Por favor, tente novamente.",
"Server did not require any authentication": "O servidor não exigiu autenticação",
- "Verifying this user will mark their session as trusted, and also mark your session as trusted to them.": "Se você verificar esse usuário, a sessão será marcada como confiável para você e para ele.",
- "Verifying this device will mark it as trusted, and users who have verified with you will trust this device.": "Verificar este aparelho o marcará como confiável, e os usuários que confirmaram com você também confiarão neste aparelho.",
+ "Verifying this user will mark their session as trusted, and also mark your session as trusted to them.": "Se você confirmar esse usuário, a sessão será marcada como confiável para você e para ele.",
+ "Verifying this device will mark it as trusted, and users who have verified with you will trust this device.": "Confirmar este aparelho o marcará como confiável para você e para os usuários que se confirmaram com você.",
"Keep going...": "Continue...",
"The username field must not be blank.": "O campo do nome de usuário não pode ficar em branco.",
"Username": "Nome de usuário",
"Use an email address to recover your account": "Use um endereço de e-mail para recuperar sua conta",
"Enter email address (required on this homeserver)": "Digite o endereço de e-mail (necessário neste servidor)",
- "Doesn't look like a valid email address": "Este não parece ser um endereço de email válido",
+ "Doesn't look like a valid email address": "Este não parece ser um endereço de e-mail válido",
"Passwords don't match": "As senhas não correspondem",
"Other users can invite you to rooms using your contact details": "Outros usuários podem convidá-lo para salas usando seus detalhes de contato",
"Enter phone number (required on this homeserver)": "Digite o número de celular (necessário neste servidor)",
@@ -1767,21 +1767,21 @@
"You cannot sign in to your account. Please contact your homeserver admin for more information.": "Você não pôde se conectar na sua conta. Entre em contato com o administrador do servidor para obter mais informações.",
"Confirm adding this phone number by using Single Sign On to prove your identity.": "Confirme a adição deste número de telefone usando o Login Único para provar sua identidade.",
"Use an identity server to invite by email. Click continue to use the default identity server (%(defaultIdentityServerName)s) or manage in Settings.": "Use um servidor de identidade para convidar por e-mail. Clique em continuar para usar o servidor de identidade padrão (%(defaultIdentityServerName)s) ou gerencie nas Configurações.",
- "You might have configured them in a client other than %(brand)s. You cannot tune them in %(brand)s but they still apply.": "Você pode ter configurado estas opções em um cliente que não seja %(brand)s. Você não pode ajustar essas opções no %(brand)s, mas elas ainda se aplicam.",
- "Enable audible notifications for this session": "Ativar notificações sonoras para esta sessão",
- "Display Name": "Nome em exibição",
- "Identity Server URL must be HTTPS": "O URL do Servidor de Identidade deve ser HTTPS",
+ "You might have configured them in a client other than %(brand)s. You cannot tune them in %(brand)s but they still apply.": "Você pode ter configurado estas opções em um aplicativo que não seja o %(brand)s. Você não pode ajustar essas opções no %(brand)s, mas elas ainda se aplicam.",
+ "Enable audible notifications for this session": "Ativar o som de notificações nesta sessão",
+ "Display Name": "Nome e sobrenome",
+ "Identity Server URL must be HTTPS": "O link do servidor de identidade deve começar com HTTPS",
"Not a valid Identity Server (status code %(code)s)": "Servidor de Identidade inválido (código de status %(code)s)",
"Could not connect to Identity Server": "Não foi possível conectar-se ao Servidor de Identidade",
"Checking server": "Verificando servidor",
- "Change identity server": "Mudar o servidor de identidade",
+ "Change identity server": "Alterar o servidor de identidade",
"Disconnect from the identity server and connect to instead?": "Desconectar-se do servidor de identidade e conectar-se em em vez disso?",
"Terms of service not accepted or the identity server is invalid.": "Termos de serviço não aceitos ou o servidor de identidade é inválido.",
"The identity server you have chosen does not have any terms of service.": "O servidor de identidade que você escolheu não possui nenhum termo de serviço.",
"Disconnect identity server": "Desconectar servidor de identidade",
"Disconnect from the identity server ?": "Desconectar-se do servidor de identidade ?",
"Disconnect": "Desconectar",
- "You should remove your personal data from identity server before disconnecting. Unfortunately, identity server is currently offline or cannot be reached.": "Você deve remover seus dados pessoais do servidor de identidade antes de desconectar. Infelizmente, o servidor de identidade está atualmente offline ou não pode ser acessado.",
+ "You should remove your personal data from identity server before disconnecting. Unfortunately, identity server is currently offline or cannot be reached.": "Você deve remover seus dados pessoais do servidor de identidade antes de desconectar. Infelizmente, o servidor de identidade ou está desconectado no momento, ou não pode ser acessado.",
"You should:": "Você deveria:",
"check your browser plugins for anything that might block the identity server (such as Privacy Badger)": "verifique se há extensões no seu navegador que possam bloquear o servidor de identidade (por exemplo, Privacy Badger)",
"contact the administrators of identity server ": "entre em contato com os administradores do servidor de identidade ",
@@ -1797,7 +1797,7 @@
"Disconnecting from your identity server will mean you won't be discoverable by other users and you won't be able to invite others by email or phone.": "Desconectar-se do servidor de identidade significa que você não poderá ser descoberto por outros usuários e não poderá convidar outras pessoas por e-mail ou número de celular.",
"Using an identity server is optional. If you choose not to use an identity server, you won't be discoverable by other users and you won't be able to invite others by email or phone.": "Usar um servidor de identidade é opcional. Se você optar por não usar um servidor de identidade, não poderá ser descoberto por outros usuários e não poderá convidar outras pessoas por e-mail ou por número de celular.",
"Do not use an identity server": "Não usar um servidor de identidade",
- "Enter a new identity server": "Digitar um novo servidor de identidade",
+ "Enter a new identity server": "Digite um novo servidor de identidade",
"Change": "Alterar",
"Manage integrations": "Gerenciar integrações",
"New version available. Update now.": "Nova versão disponível. Atualize agora.",
@@ -1808,21 +1808,21 @@
"Invalid theme schema.": "Esquema inválido de tema.",
"Error downloading theme information.": "Erro ao baixar as informações do tema.",
"Theme added!": "Tema adicionado!",
- "Custom theme URL": "URL do tema personalizado",
+ "Custom theme URL": "Link do tema personalizado",
"Add theme": "Adicionar tema",
"Message layout": "Aparência da mensagem",
"Compact": "Compacto",
"Modern": "Moderno",
- "Set the name of a font installed on your system & %(brand)s will attempt to use it.": "Defina o nome de uma fonte instalada no seu sistema e %(brand)s tentará usá-la.",
+ "Set the name of a font installed on your system & %(brand)s will attempt to use it.": "Defina o nome de uma fonte instalada no seu sistema e o %(brand)s tentará usá-la.",
"Customise your appearance": "Personalize sua aparência",
- "Appearance Settings only affect this %(brand)s session.": "As Configurações de aparência afetam apenas esta sessão do %(brand)s.",
- "Your password was successfully changed. You will not receive push notifications on other sessions until you log back in to them": "Sua senha foi alterada com sucesso. Você não receberá notificações por push em outras sessões até fazer login novamente nelas",
- "Agree to the identity server (%(serverName)s) Terms of Service to allow yourself to be discoverable by email address or phone number.": "Concordar com os Termos de Serviço do servidor de identidade (%(serverName)s), para permitir aos seus contatos encontrarem-na(no) por endereço de e-mail ou por número de celular.",
+ "Appearance Settings only affect this %(brand)s session.": "As configurações de aparência afetam apenas esta sessão do %(brand)s.",
+ "Your password was successfully changed. You will not receive push notifications on other sessions until you log back in to them": "Sua senha foi alterada com sucesso. Você não receberá notificações pop-up em outras sessões até fazer login novamente nelas",
+ "Agree to the identity server (%(serverName)s) Terms of Service to allow yourself to be discoverable by email address or phone number.": "Concorde com os Termos de Serviço do servidor de identidade (%(serverName)s), para que você possa ser descoberto por endereço de e-mail ou por número de celular.",
"Discovery": "Contatos",
- "Deactivate account": "Desativar conta",
+ "Deactivate account": "Desativar minha conta",
"Clear cache and reload": "Limpar cache e recarregar",
"To report a Matrix-related security issue, please read the Matrix.org Security Disclosure Policy.": "Para relatar um problema de segurança relacionado à tecnologia Matrix, leia a Política de Divulgação de Segurança da Matrix.org.",
- "Always show the window menu bar": "Sempre mostrar a barra de menu na janela",
+ "Always show the window menu bar": "Mostrar a barra de menu na janela",
"Show tray icon and minimize window to it on close": "Mostrar ícone na barra de tarefas, que permanece visível ao fechar a janela",
"Read Marker lifetime (ms)": "Duração do marcador de leitura (ms)",
"Read Marker off-screen lifetime (ms)": "Vida útil do marcador de leitura fora da tela (ms)",
@@ -1830,13 +1830,13 @@
"Send %(eventType)s events": "Enviar eventos de %(eventType)s",
"Roles & Permissions": "Papeis & Permissões",
"Select the roles required to change various parts of the room": "Selecione as permissões necessárias para alterar várias partes da sala",
- "Emoji picker": "Seletor de emoji",
+ "Emoji picker": "Enviar emoji",
"Room %(name)s": "Sala %(name)s",
"No recently visited rooms": "Não há salas visitadas recentemente",
"Custom Tag": "Etiqueta personalizada",
"Joining room …": "Entrando na sala…",
"Loading …": "Carregando…",
- "Rejecting invite …": "Rejeitando convite…",
+ "Rejecting invite …": "Recusando o convite…",
"Join the conversation with an account": "Participar da conversa com uma conta",
"Sign Up": "Inscrever-se",
"Loading room preview": "Carregando visualização da sala",
@@ -1844,7 +1844,7 @@
"Reason: %(reason)s": "Razão: %(reason)s",
"Forget this room": "Esquecer esta sala",
"Re-join": "Entrar novamente",
- "You were banned from %(roomName)s by %(memberName)s": "Você foi banida(o) de %(roomName)s por %(memberName)s",
+ "You were banned from %(roomName)s by %(memberName)s": "Você foi banido de %(roomName)s por %(memberName)s",
"Something went wrong with your invite to %(roomName)s": "Ocorreu um erro no seu convite para %(roomName)s",
"An error (%(errcode)s) was returned while trying to validate your invite. You could try to pass this information on to a room admin.": "Ocorreu um erro (%(errcode)s) ao validar seu convite. Você pode passar essas informações para um administrador da sala.",
"You can only join it with a working invite.": "Você só pode participar com um convite válido.",
@@ -1852,33 +1852,33 @@
"You can still join it because this is a public room.": "Você ainda pode entrar, porque esta é uma sala pública.",
"Join the discussion": "Participar da discussão",
"This invite to %(roomName)s was sent to %(email)s which is not associated with your account": "Este convite para %(roomName)s foi enviado para %(email)s, que não está associado à sua conta",
- "Link this email with your account in Settings to receive invites directly in %(brand)s.": "Vincule esse e-mail à sua conta em Configurações, para receber convites diretamente em %(brand)s.",
+ "Link this email with your account in Settings to receive invites directly in %(brand)s.": "Vincule esse e-mail à sua conta em Configurações, para receber convites diretamente no %(brand)s.",
"This invite to %(roomName)s was sent to %(email)s": "Este convite para %(roomName)s foi enviado para %(email)s",
- "Use an identity server in Settings to receive invites directly in %(brand)s.": "Use um servidor de identidade em Configurações para receber convites diretamente em %(brand)s.",
- "Share this email in Settings to receive invites directly in %(brand)s.": "Compartilhe este e-mail em Configurações para receber convites diretamente em %(brand)s.",
+ "Use an identity server in Settings to receive invites directly in %(brand)s.": "Use um servidor de identidade em Configurações para receber convites diretamente no %(brand)s.",
+ "Share this email in Settings to receive invites directly in %(brand)s.": "Compartilhe este e-mail em Configurações para receber convites diretamente no %(brand)s.",
"Do you want to chat with %(user)s?": "Deseja conversar com %(user)s?",
" wants to chat": " quer conversar",
"Do you want to join %(roomName)s?": "Deseja se juntar a %(roomName)s?",
" invited you": " convidou você",
- "Reject & Ignore user": "Rejeitar e ignorar usuário",
+ "Reject & Ignore user": "Recusar e bloquear usuário",
"You're previewing %(roomName)s. Want to join it?": "Você está visualizando %(roomName)s. Deseja participar?",
"%(roomName)s can't be previewed. Do you want to join it?": "%(roomName)s não pode ser visualizado. Deseja participar?",
"This room doesn't exist. Are you sure you're at the right place?": "Esta sala não existe. Tem certeza de que você está no lugar certo?",
"Securely back up your keys to avoid losing them. Learn more.": "Faça backup de suas chaves com segurança para evitar perdê-las. Saiba mais.",
"Not now": "Agora não",
- "Don't ask me again": "Não me pergunte novamente",
+ "Don't ask me again": "Não pergunte novamente",
"Appearance": "Aparência",
- "Show rooms with unread messages first": "Mostrar salas com mensagens não lidas primeiro",
+ "Show rooms with unread messages first": "Mostrar salas não lidas em primeiro",
"Show previews of messages": "Mostrar pré-visualizações de mensagens",
"Sort by": "Ordenar por",
- "Activity": "Atividade",
+ "Activity": "Atividade recente",
"A-Z": "A-Z",
"Unknown Command": "Comando desconhecido",
"Unrecognised command: %(commandText)s": "Comando não reconhecido: %(commandText)s",
"You can use /help to list available commands. Did you mean to send this as a message?": "Você pode usar /help para listar os comandos disponíveis. Você quis enviar isso como uma mensagem?",
"Send as message": "Enviar como mensagem",
"Room Topic": "Descrição da sala",
- "React": "Reagir",
+ "React": "Adicionar reação",
"If you run into any bugs or have feedback you'd like to share, please let us know on GitHub.": "Se você encontrar algum erro ou tiver um comentário que gostaria de compartilhar, informe-nos no GitHub.",
"Resend %(unsentCount)s reaction(s)": "Reenviar %(unsentCount)s reações",
"Notification settings": "Configurar notificações",
@@ -1887,7 +1887,7 @@
"Switch to dark mode": "Alternar para o modo escuro",
"Security & privacy": "Segurança & privacidade",
"All settings": "Todas as configurações",
- "You're signed out": "Você foi desconectada(o)",
+ "You're signed out": "Você está desconectada/o",
"Clear personal data": "Limpar dados pessoais",
"Command Autocomplete": "Preenchimento automático de comandos",
"Community Autocomplete": "Preenchimento automático da comunidade",
@@ -1918,31 +1918,31 @@
"Collapse room list section": "Esconder seção da lista de salas",
"Expand room list section": "Mostrar seção da lista de salas",
"The person who invited you already left the room.": "A pessoa que convidou você já saiu da sala.",
- "The person who invited you already left the room, or their server is offline.": "A pessoa que convidou você já saiu da sala, ou o servidor dela está offline.",
- "Use an Integration Manager (%(serverName)s) to manage bots, widgets, and sticker packs.": "Use o Gerenciador de Integrações em (%(serverName)s) para gerenciar bots, widgets e pacotes de adesivos.",
- "Use an Integration Manager to manage bots, widgets, and sticker packs.": "Use o Gerenciador de Integrações para gerenciar bots, widgets e pacotes de adesivos.",
+ "The person who invited you already left the room, or their server is offline.": "A pessoa que convidou você já saiu da sala, ou o servidor dela está desconectado.",
+ "Use an Integration Manager (%(serverName)s) to manage bots, widgets, and sticker packs.": "Use o Gerenciador de Integrações em (%(serverName)s) para gerenciar bots, widgets e pacotes de figurinhas.",
+ "Use an Integration Manager to manage bots, widgets, and sticker packs.": "Use o Gerenciador de Integrações para gerenciar bots, widgets e pacotes de figurinhas.",
"Integration Managers receive configuration data, and can modify widgets, send room invites, and set power levels on your behalf.": "O Gerenciador de Integrações recebe dados de configuração e pode modificar widgets, enviar convites para salas e definir níveis de permissão em seu nome.",
"Keyboard Shortcuts": "Atalhos do teclado",
"Customise your experience with experimental labs features. Learn more.": "Personalize sua experiência com os recursos experimentais. Saiba mais.",
- "Ignored/Blocked": "Ignorado/Bloqueado",
- "Error adding ignored user/server": "Erro ao adicionar usuário/servidor ignorado",
- "Something went wrong. Please try again or view your console for hints.": "Algo deu errado. Por favor, tente novamente ou veja seu console para obter dicas.",
+ "Ignored/Blocked": "Bloqueado",
+ "Error adding ignored user/server": "Erro ao adicionar usuário/servidor bloqueado",
+ "Something went wrong. Please try again or view your console for hints.": "Não foi possível carregar. Por favor, tente novamente ou veja seu console para obter dicas.",
"Error subscribing to list": "Erro ao inscrever-se na lista",
- "Error removing ignored user/server": "Erro ao remover usuário/servidor ignorado",
+ "Error removing ignored user/server": "Erro ao remover usuário/servidor bloqueado",
"Error unsubscribing from list": "Erro ao cancelar a inscrição da lista",
"Please try again or view your console for hints.": "Por favor, tente novamente ou veja seu console para obter dicas.",
- "None": "Nenhum",
+ "None": "Nenhuma",
"Server rules": "Regras do servidor",
"User rules": "Regras do usuário",
- "You have not ignored anyone.": "Você não ignorou ninguém.",
- "You are currently ignoring:": "Você está atualmente ignorando:",
+ "You have not ignored anyone.": "Você não bloqueou ninguém.",
+ "You are currently ignoring:": "Você está bloqueando:",
"You are not subscribed to any lists": "Você não está inscrito em nenhuma lista",
"Unsubscribe": "Desinscrever-se",
"View rules": "Ver regras",
"You are currently subscribed to:": "No momento, você está inscrito em:",
"⚠ These settings are meant for advanced users.": "⚠ Essas configurações são destinadas a usuários avançados.",
- "Add users and servers you want to ignore here. Use asterisks to have %(brand)s match any characters. For example, @bot:* would ignore all users that have the name 'bot' on any server.": "Adicione aqui os usuários e servidores que você deseja ignorar. Use asteriscos para fazer com que o %(brand)s corresponda a qualquer caractere. Por exemplo, @bot:* ignorará todos os usuários em qualquer servidor que tenham 'bot' no nome.",
- "Server or user ID to ignore": "Servidor ou ID de usuário para ignorar",
+ "Add users and servers you want to ignore here. Use asterisks to have %(brand)s match any characters. For example, @bot:* would ignore all users that have the name 'bot' on any server.": "Adicione aqui os usuários e servidores que você deseja bloquear. Use asteriscos para fazer com que o %(brand)s corresponda a qualquer caractere. Por exemplo, @bot:* bloqueará todos os usuários em qualquer servidor que tenham 'bot' no nome.",
+ "Server or user ID to ignore": "Servidor ou ID de usuário para bloquear",
"Subscribe": "Inscrever-se",
"Session ID:": "ID da sessão:",
"Message search": "Pesquisa de mensagens",
@@ -1952,28 +1952,28 @@
"Upgrade the room": "Atualizar a sala",
"Kick users": "Remover usuários",
"Ban users": "Banir usuários",
- "Remove messages": "Remover mensagens",
- "Notify everyone": "Notificar todo mundo",
- "Your email address hasn't been verified yet": "Seu endereço de e-mail ainda não foi verificado",
+ "Remove messages": "Apagar mensagens dos outros",
+ "Notify everyone": "Notificar todos",
+ "Your email address hasn't been verified yet": "Seu endereço de e-mail ainda não foi confirmado",
"Revoke": "Revogar",
"Share": "Compartilhar",
"Unable to revoke sharing for phone number": "Não foi possível revogar o compartilhamento do número de celular",
"Unable to share phone number": "Não foi possível compartilhar o número de celular",
- "Please enter verification code sent via text.": "Digite o código de verificação enviado por mensagem de texto.",
+ "Please enter verification code sent via text.": "Digite o código de confirmação enviado por mensagem de texto.",
"Remove %(email)s?": "Remover %(email)s?",
"Remove %(phone)s?": "Remover %(phone)s?",
- "A text message has been sent to +%(msisdn)s. Please enter the verification code it contains.": "Digite o código de verificação enviado por mensagem de texto para +%(msisdn)s.",
- "This user has not verified all of their sessions.": "Este usuário não verificou todas suas próprias sessões.",
- "You have not verified this user.": "Você não verificou este usuário.",
- "You have verified this user. This user has verified all of their sessions.": "Você confirmou este usuário. Este usuário verificou todas as próprias sessões.",
+ "A text message has been sent to +%(msisdn)s. Please enter the verification code it contains.": "Digite o código de confirmação enviado por mensagem de texto para +%(msisdn)s.",
+ "This user has not verified all of their sessions.": "Este usuário não confirmou todas as próprias sessões.",
+ "You have not verified this user.": "Você não confirmou este usuário.",
+ "You have verified this user. This user has verified all of their sessions.": "Você confirmou este usuário. Este usuário confirmou todas as próprias sessões.",
"Someone is using an unknown session": "Alguém está usando uma sessão desconhecida",
- "Everyone in this room is verified": "Todo mundo nesta sala está verificado",
+ "Everyone in this room is verified": "Todos nesta sala estão confirmados",
"Edit message": "Editar mensagem",
"Mod": "Moderador",
"Scroll to most recent messages": "Ir para as mensagens mais recentes",
"Close preview": "Fechar a visualização",
- "Send a reply…": "Enviar uma resposta…",
- "Send a message…": "Enviar uma mensagem…",
+ "Send a reply…": "Digite sua resposta…",
+ "Send a message…": "Digite uma mensagem…",
"Bold": "Negrito",
"Italics": "Itálico",
"Strikethrough": "Riscado",
@@ -2003,38 +2003,38 @@
"Your homeserver": "Seu servidor local",
"Trusted": "Confiável",
"Not trusted": "Não confiável",
- "%(count)s verified sessions|other": "%(count)s sessões verificadas",
- "%(count)s verified sessions|one": "1 sessão verificada",
- "Hide verified sessions": "Esconder sessões verificadas",
+ "%(count)s verified sessions|other": "%(count)s sessões confirmadas",
+ "%(count)s verified sessions|one": "1 sessão confirmada",
+ "Hide verified sessions": "Esconder sessões confirmadas",
"%(count)s sessions|other": "%(count)s sessões",
"%(count)s sessions|one": "%(count)s sessão",
"Hide sessions": "Esconder sessões",
"No recent messages by %(user)s found": "Nenhuma mensagem recente de %(user)s foi encontrada",
- "Remove recent messages by %(user)s": "Remover mensagens recentes de %(user)s",
- "Remove %(count)s messages|other": "Remover %(count)s mensagens",
+ "Remove recent messages by %(user)s": "Apagar mensagens de %(user)s na sala",
+ "Remove %(count)s messages|other": "Apagar %(count)s mensagens para todos",
"Remove %(count)s messages|one": "Remover 1 mensagem",
- "Remove recent messages": "Remover mensagens recentes",
+ "Remove recent messages": "Apagar mensagens desta pessoa na sala",
"%(role)s in %(roomName)s": "%(role)s em %(roomName)s",
"Deactivate user?": "Desativar usuário?",
"Deactivate user": "Desativar usuário",
"Failed to deactivate user": "Falha ao desativar o usuário",
"Security": "Segurança",
- "You've successfully verified your device!": "Você verificou o seu aparelho com êxito!",
- "Verification timed out.": "O tempo de verificação se esgotou.",
- "You cancelled verification on your other session.": "Você cancelou a verificação em sua outra sessão.",
- "%(displayName)s cancelled verification.": "%(displayName)s cancelou a verificação.",
- "You cancelled verification.": "Você cancelou a verificação.",
- "Verification cancelled": "Verificação cancelada",
- "Compare emoji": "Comparar emojis",
+ "You've successfully verified your device!": "Você confirmou o seu aparelho com êxito!",
+ "Verification timed out.": "O tempo de confirmação se esgotou.",
+ "You cancelled verification on your other session.": "Você cancelou a confirmação em sua outra sessão.",
+ "%(displayName)s cancelled verification.": "%(displayName)s cancelou a confirmação.",
+ "You cancelled verification.": "Você cancelou a confirmação.",
+ "Verification cancelled": "Confirmação cancelada",
+ "Compare emoji": "Compare os emojis",
"Show image": "Mostrar imagem",
- "You have ignored this user, so their message is hidden. Show anyways.": "Você ignorou este usuário, portanto, a mensagem dele está oculta. Mostrar mesmo assim.",
- "You verified %(name)s": "Você verificou %(name)s",
+ "You have ignored this user, so their message is hidden. Show anyways.": "Você bloqueou este usuário, portanto, a mensagem dele foi escondida. Mostrar mesmo assim.",
+ "You verified %(name)s": "Você confirmou %(name)s",
"Use an identity server to invite by email. Use the default (%(defaultIdentityServerName)s) or manage in Settings.": "Use um servidor de identidade para convidar por e-mail. Use o padrão (%(defaultIdentityServerName)s) ou um servidor personalizado em Configurações.",
"Use an identity server to invite by email. Manage in Settings.": "Use um servidor de identidade para convidar por e-mail. Gerencie o servidor em Configurações.",
- "Destroy cross-signing keys?": "Destruir chaves de assinatura cruzada?",
- "Waiting for partner to confirm...": "Esperando a outra pessoa confirmar...",
+ "Destroy cross-signing keys?": "Destruir chaves autoverificadas?",
+ "Waiting for partner to confirm...": "Aguardando seu contato confirmar...",
"Enable 'Manage Integrations' in Settings to do this.": "Para fazer isso, ative 'Gerenciar Integrações' nas Configurações.",
- "Your %(brand)s doesn't allow you to use an Integration Manager to do this. Please contact an admin.": "Seu %(brand)s não permite que você use o Gerenciador de Integrações para fazer isso. Entre em contato com um administrador.",
+ "Your %(brand)s doesn't allow you to use an Integration Manager to do this. Please contact an admin.": "Seu %(brand)s não permite que você use o Gerenciador de Integrações para fazer isso. Entre em contato com o administrador.",
"Confirm to continue": "Confirme para continuar",
"Click the button below to confirm your identity.": "Clique no botão abaixo para confirmar sua identidade.",
"Failed to invite the following users to chat: %(csvUsers)s": "Falha ao convidar os seguintes usuários para a conversa: %(csvUsers)s",
@@ -2044,7 +2044,7 @@
"The following users might not exist or are invalid, and cannot be invited: %(csvNames)s": "Os seguintes usuários não puderam ser convidados porque não existem ou são inválidos: %(csvNames)s",
"Recent Conversations": "Conversas recentes",
"Suggestions": "Sugestões",
- "Invite someone using their name, username (like ), email address or share this room.": "Convide alguém com seu nome, nome de usuário (por exemplo: ), endereço de e-mail ou compartilhe esta sala.",
+ "Invite someone using their name, username (like ), email address or share this room.": "Convide alguém buscando o seu respectivo nome e sobrenome, nome de usuário (por exemplo: ), endereço de e-mail ou compartilhe esta sala.",
"Use your account to sign in to the latest version of the app at ": "Use sua conta para fazer login na versão mais recente do aplicativo em ",
"Report bugs & give feedback": "Relatar erros & enviar comentários",
"Room Settings - %(roomName)s": "Configurações da sala - %(roomName)s",
@@ -2060,7 +2060,7 @@
"Your browser likely removed this data when running low on disk space.": "O seu navegador provavelmente removeu esses dados quando o espaço de armazenamento ficou insuficiente.",
"Integration Manager": "Gerenciador de Integrações",
"Find others by phone or email": "Encontre outras pessoas por telefone ou e-mail",
- "Use bots, bridges, widgets and sticker packs": "Use bots, pontes, widgets e pacotes de adesivos",
+ "Use bots, bridges, widgets and sticker packs": "Use bots, pontes, widgets e pacotes de figurinhas",
"Terms of Service": "Termos de serviço",
"To continue you need to accept the terms of this service.": "Para continuar, você precisa aceitar os termos deste serviço.",
"Service": "Serviço",
@@ -2076,20 +2076,20 @@
"Upload %(count)s other files|one": "Enviar %(count)s outros arquivos",
"Cancel All": "Cancelar tudo",
"Upload Error": "Erro no envio",
- "Verification Request": "Solicitação de verificação",
+ "Verification Request": "Solicitação de confirmação",
"Remember my selection for this widget": "Lembrar minha escolha para este widget",
"Deny": "Rejeitar",
"Wrong file type": "Tipo errado de arquivo",
"Address (optional)": "Endereço (opcional)",
- "Report Content": "Reportar conteúdo",
+ "Report Content": "Denunciar conteúdo",
"Update status": "Atualizar status",
"Set status": "Definir status",
"Hide": "Esconder",
"Help": "Ajuda",
- "Remove for everyone": "Remover para todo mundo",
+ "Remove for everyone": "Remover para todos",
"Remove for me": "Remover para mim",
"User Status": "Status do usuário",
- "This homeserver would like to make sure you are not a robot.": "Este servidor local gostaria se certificar de que você não é um robô.",
+ "This homeserver would like to make sure you are not a robot.": "Este servidor local quer se certificar de que você não é um robô.",
"Confirm your identity by entering your account password below.": "Confirme sua identidade digitando sua senha abaixo.",
"Unable to validate homeserver/identity server": "Não foi possível validar seu servidor local/servidor de identidade",
"Server Name": "Nome do servidor",
@@ -2098,9 +2098,9 @@
"Password is allowed, but unsafe": "Esta senha é permitida, mas não é segura",
"Not sure of your password? Set a new one": "Esqueceu sua senha? Defina uma nova",
"Set an email for account recovery. Use email to optionally be discoverable by existing contacts.": "Defina um e-mail para poder recuperar a conta. Este e-mail também pode ser usado para encontrar seus contatos.",
- "Enter your custom homeserver URL What does this mean?": "Digite o URL de um servidor local O que isso significa?",
- "Homeserver URL": "URL do servidor local",
- "Identity Server URL": "URL do servidor de identidade",
+ "Enter your custom homeserver URL What does this mean?": "Digite o endereço de um servidor local O que isso significa?",
+ "Homeserver URL": "Endereço do servidor local",
+ "Identity Server URL": "Endereço do servidor de identidade",
"Other servers": "Outros servidores",
"Free": "Gratuito",
"Find other public servers or use a custom server": "Encontre outros servidores públicos ou use um servidor personalizado",
@@ -2122,10 +2122,10 @@
"Search rooms": "Buscar salas",
"You have %(count)s unread notifications in a prior version of this room.|other": "Você tem %(count)s notificações não lidas em uma versão anterior desta sala.",
"You have %(count)s unread notifications in a prior version of this room.|one": "Você tem %(count)s notificações não lidas em uma versão anterior desta sala.",
- "Feedback": "Feedback",
+ "Feedback": "Fale conosco",
"User menu": "Menu do usuário",
"Could not load user profile": "Não foi possível carregar o perfil do usuário",
- "Session verified": "Sessão verificada",
+ "Session verified": "Sessão confirmada",
"Your Matrix account on %(serverName)s": "Sua conta Matrix em %(serverName)s",
"Your Matrix account on ": "Sua conta Matrix em ",
"No identity server is configured: add one in server settings to reset your password.": "Nenhum servidor de identidade está configurado: adicione um nas configurações do servidor para redefinir sua senha.",
@@ -2149,5 +2149,139 @@
"Navigation": "Navegação",
"Calls": "Chamadas",
"Esc": "Esc",
- "Enter": "Enter"
+ "Enter": "Enter",
+ "Change notification settings": "Alterar configuração de notificações",
+ "Your server isn't responding to some requests.": "Seu servidor não está respondendo a algumas solicitações.",
+ "Ban list rules - %(roomName)s": "Regras da lista de banidos - %(roomName)s",
+ "Personal ban list": "Lista pessoal de banidos",
+ "Your personal ban list holds all the users/servers you personally don't want to see messages from. After ignoring your first user/server, a new room will show up in your room list named 'My Ban List' - stay in this room to keep the ban list in effect.": "Sua lista pessoal de banidos contém todos os usuários/servidores dos quais você não deseja mais receber mensagens. Depois de bloquear o primeiro usuário/servidor, uma nova sala será exibida na sua lista de salas chamada 'Minha lista de banidos' - permaneça nesta sala para manter a lista de banidos em vigor.",
+ "Subscribing to a ban list will cause you to join it!": "Inscrever-se em uma lista de banidos significa participar dela!",
+ "If this isn't what you want, please use a different tool to ignore users.": "Se isso não for o que você deseja, use outra ferramenta para bloquear os usuários.",
+ "Room ID or address of ban list": "ID da sala ou endereço da lista de banidos",
+ "Uploaded sound": "Som enviado",
+ "Sounds": "Sons",
+ "Notification sound": "Som de notificação",
+ "Unable to revoke sharing for email address": "Não foi possível revogar o compartilhamento do endereço de e-mail",
+ "Unable to share email address": "Não foi possível compartilhar o endereço de e-mail",
+ "Direct message": "Enviar mensagem",
+ "Incoming Verification Request": "Recebendo solicitação de confirmação",
+ "Recently Direct Messaged": "Conversas recentes",
+ "Direct Messages": "Conversas",
+ "Your account is not secure": "Sua conta não está segura",
+ "Server isn't responding": "O servidor não está respondendo",
+ "Your server isn't responding to some of your requests. Below are some of the most likely reasons.": "Seu servidor não está respondendo a algumas de suas solicitações. Abaixo estão alguns dos motivos mais prováveis.",
+ "The server (%(serverName)s) took too long to respond.": "O servidor (%(serverName)s) demorou muito para responder.",
+ "Your firewall or anti-virus is blocking the request.": "Seu firewall ou o antivírus está bloqueando a solicitação.",
+ "The server is offline.": "O servidor está fora do ar.",
+ "The server is not configured to indicate what the problem is (CORS).": "O servidor não está configurado para indicar qual é o problema (CORS).",
+ "Recent changes that have not yet been received": "Alterações recentes que ainda não foram recebidas",
+ "This will allow you to return to your account after signing out, and sign in on other sessions.": "Isso permitirá que você retorne à sua conta depois de se desconectar e fazer login em outras sessões.",
+ "Missing session data": "Dados de sessão ausentes",
+ "Be found by phone or email": "Seja encontrada/o por número de celular ou por e-mail",
+ "Looks good!": "Muito bem!",
+ "Security Phrase": "Frase de segurança",
+ "Restoring keys from backup": "Restaurando chaves do backup",
+ "Fetching keys from server...": "Obtendo chaves do servidor...",
+ "%(completed)s of %(total)s keys restored": "%(completed)s de %(total)s chaves restauradas",
+ "Incorrect recovery passphrase": "Frase de recuperação incorreta",
+ "Keys restored": "Chaves restauradas",
+ "Successfully restored %(sessionCount)s keys": "%(sessionCount)s chaves foram restauradas com sucesso",
+ "Enter recovery passphrase": "Digite a senha de recuperação",
+ "Resend edit": "Reenviar edição",
+ "Resend removal": "Reenviar a exclusão",
+ "Share Permalink": "Compartilhar link",
+ "Reload": "Recarregar",
+ "Take picture": "Tirar uma foto",
+ "Country Dropdown": "Selecione o país",
+ "You can use the custom server options to sign into other Matrix servers by specifying a different homeserver URL. This allows you to use %(brand)s with an existing Matrix account on a different homeserver.": "Você pode usar as opções personalizadas do servidor para entrar em outros servidores Matrix especificando um endereço de servidor local diferente. Isso permite que você use o %(brand)s com uma conta Matrix existente em um servidor local diferente.",
+ "No identity server is configured so you cannot add an email address in order to reset your password in the future.": "Nenhum servidor de identidade está configurado, portanto você não pode adicionar um endereço de e-mail para redefinir sua senha no futuro.",
+ "Enter your custom identity server URL What does this mean?": "Digite o endereço do servidor de identidade personalizado O que isso significa?",
+ "Join millions for free on the largest public server": "Junte-se a milhões de pessoas gratuitamente no maior servidor público",
+ "Premium": "Premium",
+ "Premium hosting for organisations Learn more": "Hospedagem premium para organizações Saiba mais",
+ "Self-verification request": "Solicitação de auto-verificação",
+ "Switch theme": "Escolha um tema",
+ "Signing In...": "Entrando...",
+ "Log in to your new account.": "Entrar em sua nova conta.",
+ "You can now close this window or log in to your new account.": "Agora você pode fechar esta janela ou entrar na sua nova conta.",
+ "Registration Successful": "Registro bem-sucedido",
+ "Notification Autocomplete": "Notificação do preenchimento automático",
+ "Changes to who can read history will only apply to future messages in this room. The visibility of existing history will be unchanged.": "Alterações em quem pode ler o histórico de conversas aplica-se apenas para mensagens futuras nesta sala. A visibilidade do histórico existente não será alterada.",
+ "Ask %(displayName)s to scan your code:": "Peça para %(displayName)s escanear o seu código:",
+ "Almost there! Is %(displayName)s showing the same shield?": "Quase lá! Este escudo também aparece para %(displayName)s?",
+ "You've successfully verified %(displayName)s!": "Você confirmou %(displayName)s com sucesso!",
+ "Confirm this user's session by comparing the following with their User Settings:": "Confirme a sessão deste usuário comparando o seguinte com as configurações deste usuário:",
+ "Report Content to Your Homeserver Administrator": "Denunciar conteúdo ao administrador do seu servidor principal",
+ "Cross-signing": "Autoverificação",
+ "Discovery options will appear once you have added an email above.": "As opções de descoberta aparecerão assim que você adicione um e-mail acima.",
+ "Error updating flair": "Falha ao atualizar o ícone",
+ "There was an error updating the flair for this room. The server may not allow it or a temporary error occurred.": "Ocorreu um erro ao atualizar o ícone nesta sala. O servidor pode não permitir ou ocorreu um erro temporário.",
+ "Deactivating this user will log them out and prevent them from logging back in. Additionally, they will leave all the rooms they are in. This action cannot be reversed. Are you sure you want to deactivate this user?": "Desativar este usuário irá desconectá-lo e impedi-lo de fazer o login novamente. Além disso, ele sairá de todas as salas em que estiver. Esta ação não pode ser revertida. Tem certeza de que deseja desativar este usuário?",
+ "Deleting cross-signing keys is permanent. Anyone you have verified with will see security alerts. You almost certainly don't want to do this, unless you've lost every device you can cross-sign from.": "Apagar chaves de autoverificação é permanente. Qualquer pessoa com quem você se confirmou receberá alertas de segurança. Não é aconselhável fazer isso, a menos que você tenha perdido todos os aparelhos nos quais fez a autoverificação.",
+ "Clear cross-signing keys": "Limpar chaves autoverificadas",
+ "a device cross-signing signature": "um aparelho autoverificado",
+ "Homeserver URL does not appear to be a valid Matrix homeserver": "O endereço do servidor local não parece indicar um servidor local válido na Matrix",
+ "Identity server URL does not appear to be a valid identity server": "O endereço do servidor de identidade não parece indicar um servidor de identidade válido",
+ "This homeserver does not support login using email address.": "Este servidor local não suporta login usando endereço de e-mail.",
+ "or another cross-signing capable Matrix client": "ou outro cliente Matrix com capacidade de autoverificação",
+ "For a large amount of messages, this might take some time. Please don't refresh your client in the meantime.": "Quando há muitas mensagens, isso pode levar algum tempo. Por favor, não recarregue o seu cliente enquanto isso.",
+ "Warning: Upgrading a room will not automatically migrate room members to the new version of the room. We'll post a link to the new room in the old version of the room - room members will have to click this link to join the new room.": "Atenção: ao atualizar uma sala, os membros da sala não são migrados automaticamente para a versão atualizada da sala. Publicaremos um link da nova sala na versão antiga da sala - os membros da sala terão que clicar neste link para entrar na nova sala.",
+ "Upgrade this room to the recommended room version": "Atualizar a versão desta sala",
+ "this room": "esta sala",
+ "View older messages in %(roomName)s.": "Ler mensagens antigas em %(roomName)s.",
+ "Error changing power level": "Erro ao alterar a permissão do usuário",
+ "Complete": "Concluir",
+ "Discovery options will appear once you have added a phone number above.": "As opções de descoberta aparecerão assim que você adicione um número de telefone acima.",
+ "No other published addresses yet, add one below": "Nenhum endereço publicado ainda, adicione um abaixo",
+ "Set addresses for this room so users can find this room through your homeserver (%(localDomain)s)": "Defina endereços para esta sala, de modo que os usuários possam encontrar esta sala em seu servidor local (%(localDomain)s)",
+ "One of the following may be compromised:": "Um dos seguintes pode estar comprometido:",
+ "The homeserver the user you’re verifying is connected to": "O servidor local no qual o usuário que você está confirmando está conectado",
+ "Yours, or the other users’ internet connection": "A sua conexão de internet ou a dos outros usuários",
+ "Yours, or the other users’ session": "A sua sessão ou a dos outros usuários",
+ "Got it": "Ok, entendi",
+ "%(brand)s encountered an error during upload of:": "%(brand)s encontrou um erro durante o envio de:",
+ "Upload completed": "Envio concluído",
+ "Cancelled signature upload": "Envio cancelado da assinatura",
+ "Unable to upload": "Falha no envio",
+ "Signature upload success": "Envio bem-sucedido da assinatura",
+ "Signature upload failed": "O envio da assinatura falhou",
+ "Manually export keys": "Exportar chaves manualmente",
+ "Are you sure you want to sign out?": "Deseja mesmo sair?",
+ "Session name": "Nome da sessão",
+ "If they don't match, the security of your communication may be compromised.": "Se eles não corresponderem, a segurança da sua comunicação pode estar comprometida.",
+ "Your homeserver doesn't seem to support this feature.": "O seu servidor local não parece suportar este recurso.",
+ "Message edits": "Edições na mensagem",
+ "Your password": "Sua senha",
+ "This session, or the other session": "Esta sessão, ou a outra sessão",
+ "The internet connection either session is using": "A conexão de internet que cada sessão está usando",
+ "New session": "Nova sessão",
+ "If you didn’t sign in to this session, your account may be compromised.": "Se você não fez login nesta sessão, sua conta pode estar comprometida.",
+ "This wasn't me": "Não foi eu",
+ "Please fill why you're reporting.": "Por favor, descreva porque você está reportando.",
+ "Send report": "Enviar relatório",
+ "A browser extension is preventing the request.": "Uma extensão do navegador está impedindo a solicitação.",
+ "The server has denied your request.": "O servidor recusou a sua solicitação.",
+ "No files visible in this room": "Não há arquivos nesta sala",
+ "Attach files from chat or just drag and drop them anywhere in a room.": "Anexe arquivos na conversa, ou simplesmente arraste e solte arquivos em qualquer lugar na sala.",
+ "You have no visible notifications in this room.": "Não há notificações nesta sala.",
+ "Your new account (%(newAccountId)s) is registered, but you're already logged into a different account (%(loggedInUserId)s).": "Sua nova conta (%(newAccountId)s) foi registrada, mas você já está conectado a uma conta diferente (%(loggedInUserId)s).",
+ "%(brand)s Desktop": "%(brand)s para Computador",
+ "%(brand)s iOS": "%(brand)s para iOS",
+ "%(brand)s Android": "%(brand)s para Android",
+ "Failed to re-authenticate due to a homeserver problem": "Falha em autenticar novamente devido à um problema no servidor local",
+ "Failed to re-authenticate": "Falha em autenticar novamente",
+ "Enter your password to sign in and regain access to your account.": "Digite sua senha para entrar e recuperar o acesso à sua conta.",
+ "Sign in and regain access to your account.": "Entre e recupere o acesso à sua conta.",
+ "Enter a Security Phrase": "Digite uma frase de segurança",
+ "Enter your account password to confirm the upgrade:": "Digite a senha da sua conta para confirmar a atualização:",
+ "You'll need to authenticate with the server to confirm the upgrade.": "Você precisará se autenticar no servidor para confirmar a atualização.",
+ "Enter a security phrase only you know, as it’s used to safeguard your data. To be secure, you shouldn’t re-use your account password.": "Digite uma frase de segurança que só você conheça, usada para proteger segredos em seu servidor.",
+ "Use a different passphrase?": "Usar uma frase secreta diferente?",
+ "Enter your recovery passphrase a second time to confirm it.": "Digite sua senha de recuperação uma segunda vez para confirmá-la.",
+ "Confirm your recovery passphrase": "Confirme a sua frase de recuperação",
+ "Page Up": "Page Up",
+ "Page Down": "Page Down",
+ "You've successfully verified %(deviceName)s (%(deviceId)s)!": "Você confirmou %(deviceName)s (%(deviceId)s) com êxito!",
+ "Verified": "Confirmado",
+ "Close dialog or context menu": "Fechar caixa de diálogo ou menu"
}
diff --git a/src/i18n/strings/ru.json b/src/i18n/strings/ru.json
index 5e29bfed09..e0be2f9820 100644
--- a/src/i18n/strings/ru.json
+++ b/src/i18n/strings/ru.json
@@ -99,7 +99,7 @@
"%(senderName)s invited %(targetName)s.": "%(senderName)s пригласил %(targetName)s.",
"%(targetName)s joined the room.": "%(targetName)s вошёл в комнату.",
"%(senderName)s kicked %(targetName)s.": "%(senderName)s выгнал(а) %(targetName)s.",
- "%(targetName)s left the room.": "%(targetName)s покидает комнату.",
+ "%(targetName)s left the room.": "%(targetName)s покинул(а) комнату.",
"%(senderName)s made future room history visible to all room members, from the point they are invited.": "%(senderName)s сделал(а) историю разговора видимой для всех собеседников с момента их приглашения.",
"%(senderName)s made future room history visible to all room members, from the point they joined.": "%(senderName)s сделал(а) историю разговора видимой для всех собеседников с момента их входа в комнату.",
"%(senderName)s made future room history visible to all room members.": "%(senderName)s сделал(а) историю разговора видимой для всех собеседников.",
@@ -112,7 +112,7 @@
"Sent messages will be stored until your connection has returned.": "Отправленные сообщения будут сохранены, пока соединение не восстановится.",
"There are no visible files in this room": "В этой комнате нет видимых файлов",
"Set a display name:": "Введите отображаемое имя:",
- "This server does not support authentication with a phone number.": "Этот сервер не поддерживает аутентификацию с помощью номера телефона.",
+ "This server does not support authentication with a phone number.": "Этот сервер не поддерживает аутентификацию по номеру телефона.",
"An error occurred: %(error_string)s": "Произошла ошибка: %(error_string)s",
"%(weekDayName)s %(time)s": "%(weekDayName)s %(time)s",
"Upload an avatar:": "Загрузите аватар:",
@@ -194,7 +194,7 @@
"OK": "OK",
"Only people who have been invited": "Только приглашённые участники",
"Passwords can't be empty": "Пароли не могут быть пустыми",
- "Please check your email and click on the link it contains. Once this is done, click continue.": "Проверьте свою электронную почту и нажмите на содержащуюся ссылку. После этого нажмите кнопку Продолжить.",
+ "Please check your email and click on the link it contains. Once this is done, click continue.": "Проверьте свою электронную почту и нажмите на ссылку в письме. После этого нажмите кнопку Продолжить.",
"Power level must be positive integer.": "Уровень прав должен быть положительным целым числом.",
"Profile": "Профиль",
"Reason": "Причина",
@@ -266,7 +266,7 @@
"Register": "Зарегистрироваться",
"Results from DuckDuckGo": "Результаты от DuckDuckGo",
"Save": "Сохранить",
- "Searches DuckDuckGo for results": "Для поиска используется DuckDuckGo",
+ "Searches DuckDuckGo for results": "Поиск с помощью DuckDuckGo",
"Server error": "Ошибка сервера",
"Server may be unavailable, overloaded, or search timed out :(": "Сервер может быть недоступен, перегружен или поиск прекращен по тайм-ауту :(",
"Server may be unavailable, overloaded, or you hit a bug.": "Возможно, сервер недоступен, перегружен или случилась ошибка.",
@@ -306,7 +306,7 @@
"Unknown error": "Неизвестная ошибка",
"Incorrect password": "Неверный пароль",
"Unable to restore session": "Восстановление сессии не удалось",
- "If you have previously used a more recent version of %(brand)s, your session may be incompatible with this version. Close this window and return to the more recent version.": "Если вы использовали более новую версию %(brand)s, то ваша сессия может быть несовместима с текущей. Закройте это окно и вернитесь к использованию более новой версии.",
+ "If you have previously used a more recent version of %(brand)s, your session may be incompatible with this version. Close this window and return to the more recent version.": "Если вы использовали более новую версию %(brand)s, то ваша сессия может быть несовместима с этой версией. Закройте это окно и вернитесь к более новой версии.",
"Unknown Address": "Неизвестный адрес",
"ex. @bob:example.com": "например @bob:example.com",
"Add User": "Добавить пользователя",
@@ -380,7 +380,7 @@
"(no answer)": "(нет ответа)",
"(unknown failure: %(reason)s)": "(неизвестная ошибка: %(reason)s)",
"Not a valid %(brand)s keyfile": "Недействительный файл ключей %(brand)s",
- "Your browser does not support the required cryptography extensions": "Ваш браузер не поддерживает требуемые криптографические расширения",
+ "Your browser does not support the required cryptography extensions": "Ваш браузер не поддерживает необходимые криптографические расширения",
"Authentication check failed: incorrect password?": "Ошибка аутентификации: возможно, неправильный пароль?",
"Do you want to set an email address?": "Хотите указать email?",
"This will allow you to reset your password and receive notifications.": "Это позволит при необходимости сбросить пароль и получать уведомления.",
@@ -602,7 +602,7 @@
"Unknown for %(duration)s": "Неизвестно %(duration)s",
"There's no one else here! Would you like to invite others or stop warning about the empty room?": "Здесь никого нет! Хотите пригласить кого-нибудь или выключить предупреждение о пустой комнате?",
"Something went wrong when trying to get your communities.": "Что-то пошло не так при попытке получить список ваших сообществ.",
- "This homeserver doesn't offer any login flows which are supported by this client.": "Этот домашний сервер не поддерживает метод входа, поддерживаемый клиентом.",
+ "This homeserver doesn't offer any login flows which are supported by this client.": "Этот домашний сервер не предлагает ни один метод входа, поддерживаемый клиентом.",
"Call Failed": "Звонок не удался",
"Send": "Отправить",
"collapse": "свернуть",
@@ -637,7 +637,7 @@
"Community IDs cannot be empty.": "ID сообществ не могут быть пустыми.",
"In reply to": "В ответ на",
"%(oldDisplayName)s changed their display name to %(displayName)s.": "%(oldDisplayName)s изменил отображаемое имя на %(displayName)s.",
- "Failed to set direct chat tag": "Не удалось установить тег прямого чата",
+ "Failed to set direct chat tag": "Не удалось установить тег диалога",
"Failed to remove tag %(tagName)s from room": "Не удалось удалить тег %(tagName)s из комнаты",
"Failed to add tag %(tagName)s to room": "Не удалось добавить тег %(tagName)s в комнату",
"Clear filter": "Очистить фильтр",
@@ -647,7 +647,7 @@
"Code": "Код",
"If you've submitted a bug via GitHub, debug logs can help us track down the problem. Debug logs contain application usage data including your username, the IDs or aliases of the rooms or groups you have visited and the usernames of other users. They do not contain messages.": "Если вы отправили ошибку через GitHub, журналы отладки могут помочь нам выявить проблему. Журналы отладки содержат данные об использовании приложения, включая ваше имя пользователя, идентификаторы или псевдонимы комнат или групп, которые вы посетили, а также имена других пользователей. Они не содержат сообщений.",
"Submit debug logs": "Отправить отладочные журналы",
- "Opens the Developer Tools dialog": "Открывает Инструменты разработчика",
+ "Opens the Developer Tools dialog": "Открывает инструменты разработчика",
"Seen by %(displayName)s (%(userName)s) at %(dateTime)s": "Прочитано %(displayName)s (%(userName)s) в %(dateTime)s",
"Unable to join community": "Не удалось присоединиться к сообществу",
"Unable to leave community": "Не удалось покинуть сообщество",
@@ -791,7 +791,7 @@
"Send Logs": "Отправить логи",
"Clear Storage and Sign Out": "Очистить хранилище и выйти",
"Refresh": "Обновить",
- "We encountered an error trying to restore your previous session.": "Произошла ошибка при попытке восстановить предыдущий сеанс.",
+ "We encountered an error trying to restore your previous session.": "Произошла ошибка при попытке восстановить предыдущую сессию.",
"Clearing your browser's storage may fix the problem, but will sign you out and cause any encrypted chat history to become unreadable.": "Очистка хранилища вашего браузера может устранить проблему, но при этом ваша сессия будет завершена, и зашифрованная история чата станет нечитаемой.",
"Unable to load event that was replied to, it either does not exist or you do not have permission to view it.": "Не удается загрузить событие, на которое был дан ответ. Либо оно не существует, либо у вас нет разрешения на его просмотр.",
"Enable widget screenshots on supported widgets": "Включить скриншоты виджетов для поддерживаемых виджетов",
@@ -975,7 +975,7 @@
"Developer options": "Параметры разработчика",
"General": "Общие",
"Set a new account password...": "Установить новый пароль учётной записи...",
- "Legal": "Законный",
+ "Legal": "Правовая информация",
"Room avatar": "Аватар комнаты",
"The following users may not exist": "Следующих пользователей может не существовать",
"Invite anyway and never warn me again": "Пригласить и больше не предупреждать",
@@ -1089,11 +1089,11 @@
"Prepends ¯\\_(ツ)_/¯ to a plain-text message": "Добавляет смайл ¯\\_(ツ)_/¯ в начало сообщения",
"Changes your display nickname in the current room only": "Изменяет ваш псевдоним только для текущей комнаты",
"Gets or sets the room topic": "Читает или устанавливает тему комнаты",
- "%(senderDisplayName)s made the room public to whoever knows the link.": "%(senderDisplayName)s делает комнату публичной для всех кто знает ссылку.",
- "%(senderDisplayName)s made the room invite only.": "%(senderDisplayName)s делает комнату доступной только по приглашению.",
+ "%(senderDisplayName)s made the room public to whoever knows the link.": "%(senderDisplayName)s сделал(а) комнату публичной для всех, кто знает ссылку.",
+ "%(senderDisplayName)s made the room invite only.": "%(senderDisplayName)s сделал(а) комнату доступной только по приглашению.",
"%(senderDisplayName)s changed the join rule to %(rule)s": "%(senderDisplayName)s меняет правило входа на \"%(rule)s\"",
- "%(senderDisplayName)s has allowed guests to join the room.": "%(senderDisplayName)s разрешает гостям присоединяться к комнате.",
- "%(senderDisplayName)s has prevented guests from joining the room.": "%(senderDisplayName)s запрещает гостям присоединяться к комнате.",
+ "%(senderDisplayName)s has allowed guests to join the room.": "%(senderDisplayName)s разрешил(а) гостям входить в комнату.",
+ "%(senderDisplayName)s has prevented guests from joining the room.": "%(senderDisplayName)s запретил(а) гостям входить в комнату.",
"%(senderDisplayName)s changed guest access to %(rule)s": "%(senderDisplayName)s меняет гостевой доступ на \"%(rule)s\"",
"User %(userId)s is already in the room": "Пользователь %(userId)s уже находится в комнате",
"The user must be unbanned before they can be invited.": "Пользователь должен быть разблокирован прежде чем может быть приглашён.",
@@ -1141,14 +1141,14 @@
"The file '%(fileName)s' failed to upload.": "Файл '%(fileName)s' не был загружен.",
"The server does not support the room version specified.": "Сервер не поддерживает указанную версию комнаты.",
"Name or Matrix ID": "Имя или Matrix ID",
- "Warning: Upgrading a room will not automatically migrate room members to the new version of the room. We'll post a link to the new room in the old version of the room - room members will have to click this link to join the new room.": "Предупреждение: Обновление номера не приведет к автоматическому переходу участников комнаты на новую версию комнаты. Мы разместим ссылку на новую комнату в старой версии комнаты - участники комнаты должны будут нажать эту ссылку для присоединения к новой комнате.",
+ "Warning: Upgrading a room will not automatically migrate room members to the new version of the room. We'll post a link to the new room in the old version of the room - room members will have to click this link to join the new room.": "Предупреждение: Модернизация комнаты не приведет к автоматическому переходу участников комнаты на новую версию комнаты. Мы разместим ссылку на новую комнату в старой версии комнаты - участники комнаты должны будут нажать эту ссылку для присоединения к новой комнате.",
"Changes your avatar in this current room only": "Меняет ваш аватар только в этой комнате",
"Unbans user with given ID": "Разблокирует пользователя с заданным ID",
"Adds a custom widget by URL to the room": "Добавляет пользовательский виджет по URL-адресу в комнате",
"Please supply a https:// or http:// widget URL": "Пожалуйста, укажите https:// или http:// адрес URL виджета",
"You cannot modify widgets in this room.": "Вы не можете изменять виджеты в этой комнате.",
- "Sends the given message coloured as a rainbow": "Посылает сообщение, окрашенное в цвет радуги",
- "Sends the given emote coloured as a rainbow": "Посылает данную эмоцию, окрашенную в цвет радуги",
+ "Sends the given message coloured as a rainbow": "Отправляет сообщение, окрашенное в цвета радуги",
+ "Sends the given emote coloured as a rainbow": "Отправляет эмоцию, окрашенную в цвета радуги",
"%(senderName)s revoked the invitation for %(targetDisplayName)s to join the room.": "%(senderName)s отозвал/а приглашение %(targetDisplayName)s присоединиться к комнате.",
"No homeserver URL provided": "URL-адрес домашнего сервера не указан",
"Unexpected error resolving homeserver configuration": "Неожиданная ошибка в настройках домашнего сервера",
@@ -1159,7 +1159,7 @@
"Upgrade to your own domain": "Обновление до собственного домена",
"Credits": "Благодарности",
"Bulk options": "Групповые опции",
- "Upgrade this room to the recommended room version": "Обновите комнату до рекомендованной версии",
+ "Upgrade this room to the recommended room version": "Модернизируйте комнату до рекомендованной версии",
"this room": "эта комната",
"View older messages in %(roomName)s.": "Просмотр старых сообщений в %(roomName)s.",
"Change history visibility": "Изменить видимость истории",
@@ -1195,7 +1195,7 @@
"Try to join anyway": "Постарайся присоединиться в любом случае",
"Do you want to chat with %(user)s?": "Хотите пообщаться с %(user)s?",
"Do you want to join %(roomName)s?": "Хотите присоединиться к %(roomName)s?",
- " invited you": " приглашает вас",
+ " invited you": " пригласил(а) вас",
"You're previewing %(roomName)s. Want to join it?": "Вы просматриваете %(roomName)s. Хотите присоединиться?",
"%(roomName)s can't be previewed. Do you want to join it?": "%(roomName)s не может быть предварительно просмотрена. Вы хотите присоединиться к ней?",
"This room doesn't exist. Are you sure you're at the right place?": "Эта комната не существует. Вы уверены, что находитесь в правильном месте?",
@@ -1207,7 +1207,7 @@
"Don't ask me again": "Больше не спрашивать",
"Upgrading this room will shut down the current instance of the room and create an upgraded room with the same name.": "Обновление этой комнаты отключит текущий экземпляр комнаты и создаст обновлённую комнату с тем же именем.",
"This room has already been upgraded.": "Эта комната уже была обновлена.",
- "This room is running room version , which this homeserver has marked as unstable.": "Эта комната работает под управлением версии комнаты , которую этот сервер пометил как unstable.",
+ "This room is running room version , which this homeserver has marked as unstable.": "Версия этой комнаты — , этот домашний сервер считает её нестабильной.",
"Add some now": "Добавить сейчас",
"Failed to revoke invite": "Не удалось отменить приглашение",
"Could not revoke the invite. The server may be experiencing a temporary problem or you do not have sufficient permissions to revoke the invite.": "Не удалось отозвать приглашение. Возможно, на сервере возникла вре́менная проблема или у вас недостаточно прав для отзыва приглашения.",
@@ -1217,7 +1217,7 @@
"Error updating flair": "Ошибка обновления стиля",
"There was an error updating the flair for this room. The server may not allow it or a temporary error occurred.": "При обновлении стиля для этой комнаты произошла ошибка. Сервер может не разрешить это или произошла временная ошибка.",
"reacted with %(shortName)s": "отреагировал с %(shortName)s",
- "edited": "отредактировано",
+ "edited": "изменено",
"Maximize apps": "Развернуть приложения",
"Rotate Left": "Повернуть влево",
"Rotate counter-clockwise": "Повернуть против часовой стрелки",
@@ -1330,7 +1330,7 @@
"Invalid base_url for m.identity_server": "Неверный base_url для m.identity_server",
"Identity server URL does not appear to be a valid identity server": "URL-адрес сервера идентификации не является действительным сервером идентификации",
"General failure": "Общая ошибка",
- "This homeserver does not support login using email address.": "Этот сервер не поддерживает вход с использованием адреса электронной почты.",
+ "This homeserver does not support login using email address.": "Этот сервер не поддерживает вход по адресу электронной почты.",
"Failed to perform homeserver discovery": "Не удалось выполнить обнаружение сервера",
"Sign in with single sign-on": "Войти в систему с помощью единой точки входа",
"Create account": "Создать учётную запись",
@@ -1370,7 +1370,7 @@
"%(senderName)s made no change.": "%(senderName)s не внёс изменений.",
"Loading room preview": "Загрузка предпросмотра комнаты",
"Show all": "Показать все",
- "Edited at %(date)s. Click to view edits.": "Отредактировано в %(date)s. Нажмите, чтобы посмотреть историю редактирования.",
+ "Edited at %(date)s. Click to view edits.": "Изменено %(date)s. Нажмите для посмотра истории изменений.",
"%(severalUsers)smade no changes %(count)s times|other": "%(severalUsers)sне внёс изменений %(count)s раз",
"%(severalUsers)smade no changes %(count)s times|one": "%(severalUsers)sне внёс изменений",
"%(oneUser)smade no changes %(count)s times|other": "%(oneUser)sне внёс изменений %(count)s раз",
@@ -1378,7 +1378,7 @@
"Please tell us what went wrong or, better, create a GitHub issue that describes the problem.": "Пожалуйста, расскажите нам что пошло не так, либо, ещё лучше, создайте отчёт в GitHub с описанием проблемы.",
"Removing…": "Удаление…",
"Clear all data": "Очистить все данные",
- "Your homeserver doesn't seem to support this feature.": "Ваш сервер похоже не поддерживает эту возможность.",
+ "Your homeserver doesn't seem to support this feature.": "Ваш сервер, похоже, не поддерживает эту возможность.",
"Message edits": "Правки сообщения",
"Upgrading this room requires closing down the current instance of the room and creating a new room in its place. To give room members the best possible experience, we will:": "Модернизация этой комнаты требует закрытие комнаты в текущем состояние и создания новой комнаты вместо неё. Чтобы упростить процесс для участников, будет сделано:",
"Identity Server": "Сервер идентификаций",
@@ -1433,7 +1433,7 @@
"Use an identity server": "Используйте сервер идентификации",
"Use an identity server to invite by email. Click continue to use the default identity server (%(defaultIdentityServerName)s) or manage in Settings.": "Используйте сервер идентификации что бы пригласить по электронной почте Нажмите Продолжить, чтобы использовать стандартный сервер идентифицации(%(defaultIdentityServerName)s) или изменить в Настройках.",
"Use an identity server to invite by email. Manage in Settings.": "Используйте сервер идентификации что бы пригласить по электронной почте Управление в настройках.",
- "Allow fallback call assist server turn.matrix.org when your homeserver does not offer one (your IP address would be shared during a call)": "Разрешить резервный вызов поддержки сервера turn.matrix.org, когда ваш домашний сервер не предлагает такой поддержки (ваш IP-адрес будет использоваться во время вызова)",
+ "Allow fallback call assist server turn.matrix.org when your homeserver does not offer one (your IP address would be shared during a call)": "Использовать резервный сервер помощи звонкам turn.matrix.org, когда ваш домашний сервер не поддерживает эту возможность (ваш IP-адрес будет использоваться во время вызова)",
"Add Email Address": "Добавить адрес Email",
"Add Phone Number": "Добавить номер телефона",
"Changes the avatar of the current room": "Меняет аватарку текущей комнаты",
@@ -1569,7 +1569,7 @@
"Symbols": "Символы",
"Flags": "Флаги",
"React": "Реакция",
- "Cancel search": "Отмена поиска",
+ "Cancel search": "Отменить поиск",
"Room %(name)s": "Комната %(name)s",
"Recent rooms": "Недавние комнаты",
"No identity server is configured so you cannot add an email address in order to reset your password in the future.": "Сервер идентификации не настроен, поэтому вы не можете добавить адрес электронной почты, чтобы в будущем сбросить пароль.",
@@ -1590,7 +1590,7 @@
"Error subscribing to list": "Ошибка при подписке на список",
"Error upgrading room": "Ошибка обновления комнаты",
"Match system theme": "Тема системы",
- "Show tray icon and minimize window to it on close": "Показать иконку в панели задач и свернуть окно при закрытии",
+ "Show tray icon and minimize window to it on close": "Показать иконку в трее и сворачивать окно при закрытии",
"Show typing notifications": "Показывать уведомления о наборе",
"Delete %(count)s sessions|other": "Удалить %(count)s сессий",
"Enable desktop notifications for this session": "Включить уведомления для рабочего стола для этой сессии",
@@ -1607,7 +1607,7 @@
"If you cancel now, you won't complete verifying your other session.": "Если вы отмените сейчас, вы не завершите проверку вашей другой сессии.",
"Verify this session": "Проверьте эту сессию",
"Verifies a user, session, and pubkey tuple": "Проверяет пользователя, сессию и публичные ключи",
- "Unknown (user, session) pair:": "Неизвестная (пользователь:сессия) пара:",
+ "Unknown (user, session) pair:": "Неизвестная пара (пользователь, сессия):",
"Session already verified!": "Сессия уже подтверждена!",
"Never send encrypted messages to unverified sessions from this session": "Никогда не отправлять зашифрованные сообщения непроверенным сессиям в этой сессии",
"Never send encrypted messages to unverified sessions in this room from this session": "Никогда не отправлять зашифрованные сообщения непроверенным сессиям в этой комнате и в этой сессии",
@@ -1621,10 +1621,10 @@
"Setting up keys": "Настройка ключей",
"Encryption upgrade available": "Доступно обновление шифрования",
"Set up encryption": "Настройка шифрования",
- "Double check that your server supports the room version chosen and try again.": "Дважды проверьте, что ваш сервер поддерживает версию комнаты и попробуйте снова.",
- "WARNING: Session already verified, but keys do NOT MATCH!": "ВНИМАНИЕ:Сессия уже подтверждена, но ключи НЕ совпадают!",
+ "Double check that your server supports the room version chosen and try again.": "Убедитесь, что ваш сервер поддерживает выбранную версию комнаты и попробуйте снова.",
+ "WARNING: Session already verified, but keys do NOT MATCH!": "ВНИМАНИЕ: сессия уже подтверждена, но ключи НЕ совпадают!",
"WARNING: KEY VERIFICATION FAILED! The signing key for %(userId)s and session %(deviceId)s is \"%(fprint)s\" which does not match the provided key \"%(fingerprint)s\". This could mean your communications are being intercepted!": "ВНИМАНИЕ: ПРОВЕРКА КЛЮЧА НЕ ПРОШЛА! Ключом подписи для %(userId)s и сессии %(deviceId)s является \"%(fprint)s\", что не соответствует указанному ключу \"%(fingerprint)s\". Это может означать, что ваши сообщения перехватываются!",
- "The signing key you provided matches the signing key you received from %(userId)s's session %(deviceId)s. Session marked as verified.": "Ключ подписи, который вы предоставили, соответствует ключу подписи, который вы получили от %(userId)s's сессии %(deviceId)s. Сессия отмечена как подтверждена.",
+ "The signing key you provided matches the signing key you received from %(userId)s's session %(deviceId)s. Session marked as verified.": "Ключ подписи, который вы предоставили, соответствует ключу подписи, который вы получили от пользователя %(userId)s и сессии %(deviceId)s. Сессия отмечена как подтверждённая.",
"%(senderName)s placed a voice call.": "%(senderName)s сделал голосовой вызов.",
"%(senderName)s placed a voice call. (not supported by this browser)": "%(senderName)s сделал голосовой вызов. (не поддерживается этим браузером)",
"%(senderName)s placed a video call.": "%(senderName)s сделал видео вызов.",
@@ -1717,22 +1717,22 @@
"Order rooms by name": "Сортировать комнаты по названию",
"Show rooms with unread notifications first": "Показывать в начале комнаты с непрочитанными уведомлениями",
"Show shortcuts to recently viewed rooms above the room list": "Показывать ссылки на недавние комнаты над списком комнат",
- "Manually verify all remote sessions": "Подтверждать все удалённые сессии вручную",
- "Your homeserver does not support cross-signing.": "Ваш домашний сервер не поддерживает кросс-подпись.",
- "Cross-signing and secret storage are enabled.": "Кросс-подпись и хранилище секретов разрешены.",
+ "Manually verify all remote sessions": "Подтверждать вручную все сессии на других устройствах",
+ "Your homeserver does not support cross-signing.": "Ваш домашний сервер не поддерживает кросс-подписи.",
+ "Cross-signing and secret storage are enabled.": "Кросс-подпись и секретное хранилище разрешены.",
"Customise your experience with experimental labs features. Learn more.": "Попробуйте экспериментальные возможности. Подробнее.",
- "Cross-signing and secret storage are not yet set up.": "Кросс-подпись и хранилище секретов ещё не настроены.",
- "Reset cross-signing and secret storage": "Сбросить кросс-подпись и хранилище секретов",
+ "Cross-signing and secret storage are not yet set up.": "Кросс-подпись и секретное хранилище ещё не настроены.",
+ "Reset cross-signing and secret storage": "Сбросить кросс-подпись и секретное хранилище",
"Cross-signing public keys:": "Публичные ключи для кросс-подписи:",
"in memory": "в памяти",
"not found": "не найдено",
"Cross-signing private keys:": "Приватные ключи для кросс-подписи:",
- "in secret storage": "в хранилище секретов",
+ "in secret storage": "в секретном хранилище",
"cached locally": "сохранено локально",
"not found locally": "не найдено локально",
"User signing private key:": "Приватный ключ подписи пользователей:",
"Session backup key:": "Резервная копия сессионного ключа:",
- "Secret storage public key:": "Публичный ключ хранилища секретов:",
+ "Secret storage public key:": "Публичный ключ секретного хранилища:",
"in account data": "в данных учётной записи",
"Homeserver feature support:": "Поддержка со стороны домашнего сервера:",
"exists": "существует",
@@ -1778,11 +1778,11 @@
"You've successfully verified %(displayName)s!": "Вы успешно подтвердили %(displayName)s!",
"Got it": "Понятно",
"Compare emoji": "Сравните смайлы",
- "Activate selected button": "Активировать выбранную кнопку",
- "Toggle right panel": "Переключить правую панель",
- "Toggle this dialog": "Переключить этот диалог",
- "Cancel autocomplete": "Отменить автодополнение",
- "Esc": "",
+ "Activate selected button": "Нажать выбранную кнопку",
+ "Toggle right panel": "Показать/скрыть правую панель",
+ "Toggle this dialog": "Показать/скрыть этот диалог",
+ "Cancel autocomplete": "Отменить автозаполнение",
+ "Esc": "Esc",
"Enter": "Enter",
"Delete %(count)s sessions|one": "Удалить %(count)s сессий",
"Use Single Sign On to continue": "Воспользуйтесь единой точкой входа для продолжения",
@@ -1798,8 +1798,8 @@
"Verify this session by confirming the following number appears on its screen.": "Подтвердите эту сессию, убедившись, что следующее число отображается на экране.",
"Waiting for your other session, %(deviceName)s (%(deviceId)s), to verify…": "Ожидание других ваших сессий, %(deviceName)s %(deviceId)s, для подтверждения…",
"From %(deviceName)s (%(deviceId)s)": "От %(deviceName)s (%(deviceId)s)",
- "Your account has a cross-signing identity in secret storage, but it is not yet trusted by this session.": "У вашей учётной записи есть кросс-подпись в хранилище секретов, но она пока не является доверенной в этой сессии.",
- "Bootstrap cross-signing and secret storage": "Инициализировать кросс-подпись и хранилище секретов",
+ "Your account has a cross-signing identity in secret storage, but it is not yet trusted by this session.": "У вашей учётной записи есть кросс-подпись в секретное хранилище, но она пока не является доверенной в этой сессии.",
+ "Bootstrap cross-signing and secret storage": "Инициализация кросс-подпись и секретного хранилища",
"well formed": "корректный",
"unexpected type": "непредвиденный тип",
"Self signing private key:": "Самоподписанный приватный ключ:",
@@ -1962,7 +1962,7 @@
"Send a bug report with logs": "Отправить отчёт об ошибке с логами",
"Individually verify each session used by a user to mark it as trusted, not trusting cross-signed devices.": "Отдельно подтверждать каждую сессию пользователя как доверенную, не доверяя кросс-подписанным устройствам.",
"Securely cache encrypted messages locally for them to appear in search results, using ": "Кэшировать шифрованные сообщения локально, чтобы они выводились в результатах поиска, используя: ",
- " to store messages from ": " чтобы сохранить сообщения от ",
+ " to store messages from ": " хранить сообщения от ",
"Securely cache encrypted messages locally for them to appear in search results.": "Безопасно кэшировать шифрованные сообщения локально, чтобы они появлялись в результатах поиска.",
"%(brand)s is missing some components required for securely caching encrypted messages locally. If you'd like to experiment with this feature, build a custom %(brand)s Desktop with search components added.": "Отсутствуют некоторые необходимые компоненты для %(brand)s, чтобы безопасно кэшировать шифрованные сообщения локально. Если вы хотите попробовать эту возможность, соберите самостоятельно %(brand)s Desktop с добавлением поисковых компонентов.",
"not stored": "не сохранено",
@@ -2001,13 +2001,13 @@
"Joins room with given address": "Присоединиться к комнате с указанным адресом",
"Opens chat with the given user": "Открыть чат с данным пользователем",
"Sends a message to the given user": "Отправить сообщение данному пользователю",
- "You signed in to a new session without verifying it:": "Вы вошли в новый сеанс, не подтвердив его:",
- "Verify your other session using one of the options below.": "Проверьте другой сеанс, используя один из вариантов ниже.",
+ "You signed in to a new session without verifying it:": "Вы вошли в новую сессию, не подтвердив её:",
+ "Verify your other session using one of the options below.": "Подтвердите другую сессию, используя один из вариантов ниже.",
"Help us improve %(brand)s": "Помогите нам улучшить %(brand)s",
"Send anonymous usage data which helps us improve %(brand)s. This will use a cookie.": "Отправьте анонимные данные об использовании, которые помогут нам улучшить %(brand)s. Для этого будеть использоваться cookie.",
"I want to help": "Я хочу помочь",
"Review where you’re logged in": "Проверьте, где вы вошли",
- "Verify all your sessions to ensure your account & messages are safe": "Проверьте все свои сеансы, чтобы убедиться, что ваша учетная запись и сообщения в безопасности",
+ "Verify all your sessions to ensure your account & messages are safe": "Подтвердите все свои сессии, чтобы убедиться, что ваша учетная запись и сообщения в безопасности",
"Your homeserver has exceeded its user limit.": "Ваш домашний сервер превысил свой лимит пользователей.",
"Your homeserver has exceeded one of its resource limits.": "Ваш домашний сервер превысил один из своих лимитов ресурсов.",
"Are you sure you want to cancel entering passphrase?": "Вы уверены, что хотите отменить ввод пароля?",
@@ -2067,7 +2067,7 @@
"Enable experimental, compact IRC style layout": "Включите экспериментальный, компактный стиль IRC",
"Unknown caller": "Неизвестный абонент",
"Incoming call": "Входящий звонок",
- "Waiting for your other session to verify…": "В ожидании вашего другого сеанса, чтобы проверить…",
+ "Waiting for your other session to verify…": "Ожидание вашей другой сессии для начала подтверждения…",
"%(brand)s can't securely cache encrypted messages locally while running in a web browser. Use %(brand)s Desktop for encrypted messages to appear in search results.": "%(brand)s не может безопасно кэшировать зашифрованные сообщения локально во время работы в веб-браузере. Используйте %(brand)s Desktop, чтобы зашифрованные сообщения появились в результатах поиска.",
"There are advanced notifications which are not shown here.": "Есть расширенные уведомления, которые здесь не отображаются.",
"You might have configured them in a client other than %(brand)s. You cannot tune them in %(brand)s but they still apply.": "Возможно, вы настроили их на клиенте, отличном от %(brand)s. Вы не можете настроить их на %(brand)s, но они все еще применяются.",
@@ -2159,7 +2159,7 @@
"Message deleted": "Сообщение удалено",
"Message deleted by %(name)s": "Сообщение удалено %(name)s",
"Message deleted on %(date)s": "Сообщение удалено %(date)s",
- "Edited at %(date)s": "Отредактировано %(date)s",
+ "Edited at %(date)s": "Изменено %(date)s",
"Click to view edits": "Нажмите для просмотра правок",
"Can't load this message": "Не удалось загрузить это сообщение",
"Submit logs": "Отправить логи",
@@ -2175,5 +2175,250 @@
"Reminder: Your browser is unsupported, so your experience may be unpredictable.": "Напоминание: ваш браузер не поддерживается, возможны непредвиденные проблемы.",
"Notification settings": "Настройки уведомлений",
"Switch to light mode": "Переключить в светлый режим",
- "Switch to dark mode": "Переключить в тёмный режим"
+ "Switch to dark mode": "Переключить в тёмный режим",
+ "The person who invited you already left the room.": "Пригласивший вас человек уже покинул комнату.",
+ "The person who invited you already left the room, or their server is offline.": "Пригласивший вас человек уже покинул комнату, либо сервер оффлайн.",
+ "Change notification settings": "Изменить настройки уведомлений",
+ "IRC display name width": "Ширина отображаемого имени IRC",
+ "Your server isn't responding to some requests.": "Ваш сервер не отвечает на некоторые запросы.",
+ "Add users and servers you want to ignore here. Use asterisks to have %(brand)s match any characters. For example, @bot:* would ignore all users that have the name 'bot' on any server.": "%(brand)sДобавьте сюда пользователей и сервера, которые вы хотите игнорировать. Используйте звездочки, чтобы %(brand)s соответствовали любым символам. Например, @bot:* будет игнорировать всех пользователей, имеющих имя \" bot \" на любом сервере.",
+ "Room ID or address of ban list": "ID комнаты или адрес списка блокировок",
+ "To link to this room, please add an address.": "Для связи с этой комнатой, пожалуйста, добавьте адрес.",
+ "Key share requests are sent to your other sessions automatically. If you rejected or dismissed the key share request on your other sessions, click here to request the keys for this session again.": "Запросы на общий доступ к ключам автоматически отправляются в другие сессии. Если вы отклонили или пропустили запрос на общий доступ к ключам в других сессиях, нажмите здесь, чтобы перезапросить ключи для этой сессии.",
+ "The authenticity of this encrypted message can't be guaranteed on this device.": "Подлинность этого зашифрованного сообщения не может быть гарантирована на этом устройстве.",
+ "No recently visited rooms": "Нет недавно посещенных комнат",
+ "Use default": "Использовать по умолчанию",
+ "There was an error updating the room's alternative addresses. It may not be allowed by the server or a temporary failure occurred.": "Произошла ошибка при обновлении альтернативных адресов комнаты. Это может быть запрещено сервером или произошел временный сбой.",
+ "There was an error creating that address. It may not be allowed by the server or a temporary failure occurred.": "При создании этого адреса произошла ошибка. Это может быть запрещено сервером или произошел временный сбой.",
+ "There was an error removing that address. It may no longer exist or a temporary error occurred.": "Произошла ошибка при удалении этого адреса. Возможно, он больше не существует или произошла временная ошибка.",
+ "Using this widget may share data with %(widgetDomain)s & your Integration Manager.": "Используя этот виджет, вы можете делиться данными с %(widgetDomain)s и вашим Менеджером Интеграции.",
+ "Using this widget may share data with %(widgetDomain)s.": "Используя этот виджет, вы можете делиться данными с %(widgetDomain)s.",
+ "Can't find this server or its room list": "Не можем найти этот сервер или его список комнат",
+ "Deleting cross-signing keys is permanent. Anyone you have verified with will see security alerts. You almost certainly don't want to do this, unless you've lost every device you can cross-sign from.": "Удаление ключей кросс-подписи является мгновенным и необратимым действием. Любой, с кем вы прошли проверку, увидит предупреждения безопасности. Вы почти наверняка не захотите этого делать, если только не потеряете все устройства, с которых можно совершать кросс-подпись.",
+ "Clearing all data from this session is permanent. Encrypted messages will be lost unless their keys have been backed up.": "Очистка всех данных этой сессии является необратимым действием. Зашифрованные сообщения будут потеряны, если их ключи не были сохранены.",
+ "You've previously used a newer version of %(brand)s with this session. To use this version again with end to end encryption, you will need to sign out and back in again.": "Ранее вы использовали более новую версию %(brand)s в этой сессии. Чтобы снова использовать эту версию со сквозным шифрованием, вам нужно будет выйти из учётной записи и снова войти.",
+ "There was a problem communicating with the server. Please try again.": "Возникла проблема со связью с сервером. Пожалуйста, попробуйте еще раз.",
+ "Server did not require any authentication": "Сервер не требует проверки подлинности",
+ "Server did not return valid authentication information.": "Сервер не вернул существующую аутентификационную информацию.",
+ "Verification Requests": "Запрос на проверку",
+ "Verifying this user will mark their session as trusted, and also mark your session as trusted to them.": "Подтверждение этого пользователя сделает его сессию доверенной у вас, а также сделает вашу сессию доверенной у него.",
+ "Verify this device to mark it as trusted. Trusting this device gives you and other users extra peace of mind when using end-to-end encrypted messages.": "Подтвердите это устройство, чтобы сделать его доверенным. Доверие этому устройству дает вам и другим пользователям дополнительное спокойствие при использовании зашифрованных сообщений.",
+ "Verifying this device will mark it as trusted, and users who have verified with you will trust this device.": "Проверка этого устройства пометит его как доверенное, и пользователи, которые проверили его вместе с вами, будут доверять этому устройству.",
+ "Integrations are disabled": "Интеграции отключены",
+ "Integrations not allowed": "Интеграции не разрешены",
+ "Your %(brand)s doesn't allow you to use an Integration Manager to do this. Please contact an admin.": "Ваш %(brand)s не позволяет вам использовать для этого Менеджер Интеграции. Пожалуйста, свяжитесь с администратором.",
+ "To continue, use Single Sign On to prove your identity.": "Чтобы продолжить, используйте единый вход, чтобы подтвердить свою личность.",
+ "Confirm to continue": "Подтвердите, чтобы продолжить",
+ "Click the button below to confirm your identity.": "Нажмите кнопку ниже, чтобы подтвердить свою личность.",
+ "Failed to invite the following users to chat: %(csvUsers)s": "Не удалось пригласить в чат этих пользователей: %(csvUsers)s",
+ "We couldn't create your DM. Please check the users you want to invite and try again.": "Мы не смогли создать ваши ЛС. Пожалуйста, проверьте пользователей, которых вы хотите пригласить, и повторите попытку.",
+ "Something went wrong trying to invite the users.": "Пытаясь пригласить пользователей, что-то пошло не так.",
+ "We couldn't invite those users. Please check the users you want to invite and try again.": "Мы не могли пригласить этих пользователей. Пожалуйста, проверьте пользователей, которых вы хотите пригласить, и повторите попытку.",
+ "Failed to find the following users": "Не удалось найти этих пользователей",
+ "The following users might not exist or are invalid, and cannot be invited: %(csvNames)s": "Следующие пользователи могут не существовать или быть недействительными и не могут быть приглашены: %(csvNames)s",
+ "Recently Direct Messaged": "Недавно отправленные личные сообщения",
+ "Go": "Вперёд",
+ "Invite someone using their name, username (like ), email address or share this room.": "Пригласите кого-нибудь, используя свое имя, имя пользователя (например, ), адрес электронной почты или поделиться этой комнатой.",
+ "a new master key signature": "новая подпись мастер-ключа",
+ "a new cross-signing key signature": "новый ключ подписи для кросс-подписи",
+ "a device cross-signing signature": "подпись устройства для кросс-подписи",
+ "%(brand)s encountered an error during upload of:": "%(brand)s обнаружил ошибку при загрузке файла:",
+ "Confirm by comparing the following with the User Settings in your other session:": "Подтвердите, сравнив следующие параметры с настройками пользователя в другой вашей сессии:",
+ "Confirm this user's session by comparing the following with their User Settings:": "Подтвердите сессию этого пользователя, сравнив следующие параметры с его пользовательскими настройками:",
+ "If they don't match, the security of your communication may be compromised.": "Если они не совпадают, безопасность вашего общения может быть поставлена под угрозу.",
+ "Your password": "Ваш пароль",
+ "This session, or the other session": "Эта сессия или другая сессия",
+ "The internet connection either session is using": "Подключение к интернету, используемое любой из сессий",
+ "We recommend you change your password and recovery key in Settings immediately": "Мы рекомендуем вам немедленно изменить свой пароль и ключ восстановления в настройках",
+ "New session": "Новая сессия",
+ "Use this session to verify your new one, granting it access to encrypted messages:": "Используйте эту сессию для проверки новой сессии, чтобы предоставить ей доступ к зашифрованным сообщениям:",
+ "If you didn’t sign in to this session, your account may be compromised.": "Если вы не входили в эту сессию, ваша учетная запись может быть скомпрометирована.",
+ "This wasn't me": "Это был не я",
+ "Use your account to sign in to the latest version of the app at ": "Используйте свою учетную запись для входа в последнюю версию приложения по адресу ",
+ "You’re already signed in and good to go here, but you can also grab the latest versions of the app on all platforms at element.io/get-started.": "Вы уже вошли в систему и можете остаться здесь, но вы также можете получить последние версии приложения на всех платформах по адресу element.io/get-started.",
+ "Go to Element": "Перейти к Element",
+ "We’re excited to announce Riot is now Element!": "Мы рады сообщить, что Riot теперь стал Element!",
+ "Learn more at element.io/previously-riot": "Узнайте больше на сайте element.io/previously-riot",
+ "Automatically invite users": "Автоматически приглашать пользователей",
+ "Upgrade private room": "Модернизировать приватную комнату",
+ "Upgrade public room": "Модернизировать публичную комнату",
+ "Upgrading a room is an advanced action and is usually recommended when a room is unstable due to bugs, missing features or security vulnerabilities.": "Модернизация комнаты - это расширенное действие, которое обычно рекомендуется, когда комната нестабильна из-за ошибок, отсутствующих функций или уязвимостей безопасности.",
+ "This usually only affects how the room is processed on the server. If you're having problems with your %(brand)s, please report a bug.": "Обычно это влияет только на то, как комната обрабатывается на сервере. Если у вас возникли проблемы с вашим %(brand)s, пожалуйста, сообщите об ошибке.",
+ "You'll upgrade this room from to .": "Вы модернизируете эту комнату с до .",
+ "You're all caught up.": "Нет непрочитанных сообщений.",
+ "Server isn't responding": "Сервер не отвечает",
+ "Your server isn't responding to some of your requests. Below are some of the most likely reasons.": "Ваш сервер не отвечает на некоторые ваши запросы. Ниже приведены вероятные причины.",
+ "The server (%(serverName)s) took too long to respond.": "Сервер (%(serverName)s) слишком долго не отвечал.",
+ "Your firewall or anti-virus is blocking the request.": "Ваш брандмауэр или антивирус блокирует запрос.",
+ "A browser extension is preventing the request.": "Расширение браузера блокирует запрос.",
+ "The server is offline.": "Сервер оффлайн.",
+ "The server has denied your request.": "Сервер отклонил ваш запрос.",
+ "Your area is experiencing difficulties connecting to the internet.": "Ваше подключение к Интернету нестабильно или отсутствует.",
+ "A connection error occurred while trying to contact the server.": "Произошла ошибка при подключении к серверу.",
+ "The server is not configured to indicate what the problem is (CORS).": "Сервер не настроен должным образом, чтобы определить проблему (CORS).",
+ "Recent changes that have not yet been received": "Последние изменения, которые еще не были получены",
+ "This will allow you to return to your account after signing out, and sign in on other sessions.": "Это позволит вам вернуться в свою учетную запись после выхода из системы и войти в другие сессии.",
+ "Verify other session": "Проверьте другую сессию",
+ "Verification Request": "Запрос на подтверждение",
+ "Wrong file type": "Неправильный тип файла",
+ "Looks good!": "Выглядит неплохо!",
+ "Wrong Recovery Key": "Неверный ключ восстановления",
+ "Invalid Recovery Key": "Неверный ключ восстановления",
+ "Security Phrase": "Секретная фраза",
+ "Unable to access secret storage. Please verify that you entered the correct recovery passphrase.": "Невозможно получить доступ к секретному хранилищу. Пожалуйста, убедитесь, что вы ввели правильную парольную фразу восстановления.",
+ "Enter your Security Phrase or Use your Security Key to continue.": "Введите свою секретную фразу или Используйте ваш ключ безопасности, чтобы продолжить.",
+ "Security Key": "Ключ безопасности",
+ "Use your Security Key to continue.": "Чтобы продолжить, используйте свой ключ безопасности.",
+ "Restoring keys from backup": "Восстановление ключей из резервной копии",
+ "Fetching keys from server...": "Получение ключей с сервера...",
+ "%(completed)s of %(total)s keys restored": "%(completed)s из %(total)s ключей восстановлено",
+ "Recovery key mismatch": "Несоответствие ключа восстановления",
+ "Backup could not be decrypted with this recovery key: please verify that you entered the correct recovery key.": "Резервная копия не может быть расшифрована с помощью этого ключа восстановления: пожалуйста, убедитесь, что вы ввели правильный ключ восстановления.",
+ "Incorrect recovery passphrase": "Неверная парольная фраза восстановления",
+ "Backup could not be decrypted with this recovery passphrase: please verify that you entered the correct recovery passphrase.": "Резервная копия не может быть расшифрована с помощью этой парольной фразы восстановления: пожалуйста, убедитесь, что вы ввели правильную парольную фразу восстановления.",
+ "Keys restored": "Ключи восстановлены",
+ "Successfully restored %(sessionCount)s keys": "Успешно восстановлено %(sessionCount)s ключей",
+ "Enter recovery key": "Введите ключ восстановления",
+ "Warning: You should only set up key backup from a trusted computer.": "Предупреждение: вы должны настроивать резервное копирование ключей только с доверенного компьютера.",
+ "If you've forgotten your recovery key you can set up new recovery options": "Если вы забыли свой ключ восстановления, вы можете настроить новые параметры восстановления",
+ "Address (optional)": "Адрес (необязательно)",
+ "Confirm your identity by entering your account password below.": "Подтвердите свою личность, введя пароль учетной записи ниже.",
+ "Enter the location of your Element Matrix Services homeserver. It may use your own domain name or be a subdomain of element.io.": "Укажите путь к вашему серверу Element Matrix Services. Он может использовать ваше собственное доменное имя или быть поддоменом element.io.",
+ "Sign in with SSO": "Вход с помощью SSO",
+ "Self-verification request": "Запрос самопроверки",
+ "Delete the room address %(alias)s and remove %(name)s from the directory?": "Удалить адрес комнаты %(alias)s и удалить %(name)s из каталога?",
+ "delete the address.": "удалить адрес.",
+ "Switch theme": "Сменить тему",
+ "User menu": "Меню пользователя",
+ "Verify this login": "Подтвердите эту сессию",
+ "Session verified": "Сессия подтверждена",
+ "Changing your password will reset any end-to-end encryption keys on all of your sessions, making encrypted chat history unreadable. Set up Key Backup or export your room keys from another session before resetting your password.": "Изменение пароля приведет к сбросу всех сквозных ключей шифрования во всех ваших сессиях, и зашифрованная история чата станет недоступна. Перед сбросом пароля настройте резервное копирование ключей или экспортируйте ключи от комнат из другой сессии.",
+ "You have been logged out of all sessions and will no longer receive push notifications. To re-enable notifications, sign in again on each device.": "Вы вышли из всех сессий и больше не будете получать push-уведомления. Чтобы снова включить уведомления, войдите в систему еще раз на каждом устройстве.",
+ "Syncing...": "Синхронизация…",
+ "Signing In...": "Выполняется вход...",
+ "If you've joined lots of rooms, this might take a while": "Если вы присоединились к большому количеству комнат, это может занять некоторое время",
+ "Use Recovery Key or Passphrase": "Используйте ключ восстановления или парольную фразу",
+ "Use Recovery Key": "Используйте ключ восстановления",
+ "Confirm your identity by verifying this login from one of your other sessions, granting it access to encrypted messages.": "Подтвердите свою личность, подтвердив эту сессию в одной из ваших других сессий, чтобы предоставить ей доступ к зашифрованным сообщениям.",
+ "This requires the latest %(brand)s on your other devices:": "Для этого требуется последняя версия %(brand)s на других ваших устройствах:",
+ "%(brand)s Web": "Веб-версия %(brand)s",
+ "%(brand)s Desktop": "Настольный клиент %(brand)s",
+ "%(brand)s iOS": "iOS клиент %(brand)s",
+ "%(brand)s X for Android": "%(brand)s X для Android",
+ "or another cross-signing capable Matrix client": "или другой, поддерживаемый кросс-подпись Matrix клиент",
+ "Your new session is now verified. It has access to your encrypted messages, and other users will see it as trusted.": "Ваша новая сессия теперь подтверждена. У неё есть доступ к вашим зашифрованным сообщениям, и другие пользователи будут считать её доверенной.",
+ "Your new session is now verified. Other users will see it as trusted.": "Ваша новая сессия теперь проверена. Другие пользователи будут считать её доверенной.",
+ "Without completing security on this session, it won’t have access to encrypted messages.": "Без подтверждения этой сессии, у неё не будет доступа к зашифрованным сообщениям.",
+ "Regain access to your account and recover encryption keys stored in this session. Without them, you won’t be able to read all of your secure messages in any session.": "Восстановите доступ к своей учетной записи и восстановите ключи шифрования, хранящиеся в этой сессии. Без них вы не сможете прочитать никакие защищённые сообщения ни в одной сессии.",
+ "Warning: Your personal data (including encryption keys) is still stored in this session. Clear it if you're finished using this session, or want to sign in to another account.": "Предупреждение: ваши личные данные (включая ключи шифрования) всё ещё хранятся в этой сессии. Удалите их, если вы хотите завершить эту сессию или войти в другую учетную запись.",
+ "Confirm encryption setup": "Подтвердите настройку шифрования",
+ "Click the button below to confirm setting up encryption.": "Нажмите кнопку ниже, чтобы подтвердить настройку шифрования.",
+ "Safeguard against losing access to encrypted messages & data by backing up encryption keys on your server.": "Защитите себя от потери доступа к зашифрованным сообщениям и данным, создав резервные копии ключей шифрования на вашем сервере.",
+ "Generate a Security Key": "Создание ключа безопасности",
+ "We’ll generate a Security Key for you to store somewhere safe, like a password manager or a safe.": "Мы создадим ключ безопасности для вас, чтобы вы могли хранить его в надежном месте, например, в менеджере паролей или сейфе.",
+ "Enter a Security Phrase": "Введите секретную фразу",
+ "Use a secret phrase only you know, and optionally save a Security Key to use for backup.": "Используйте секретную фразу, известную только вам, и при необходимости сохраните ключ безопасности для резервного копирования.",
+ "Enter your account password to confirm the upgrade:": "Введите пароль своей учетной записи для подтверждения обновления:",
+ "Restore your key backup to upgrade your encryption": "Восстановите резервную копию ключа для обновления шифрования",
+ "Restore": "Восстановление",
+ "You'll need to authenticate with the server to confirm the upgrade.": "Вам нужно будет пройти аутентификацию на сервере,чтобы подтвердить обновление.",
+ "Upgrade this session to allow it to verify other sessions, granting them access to encrypted messages and marking them as trusted for other users.": "Модернизируйте эту сессию, чтобы она могла проверять другие сессии, предоставляя им доступ к зашифрованным сообщениям и помечая их как доверенные для других пользователей.",
+ "Enter a security phrase only you know, as it’s used to safeguard your data. To be secure, you shouldn’t re-use your account password.": "Введите секретную фразу, известную только вам, поскольку она используется для защиты ваших данных. Для безопасности фраза должна отличаться от пароля вашей учетной записи.",
+ "Use a different passphrase?": "Используйте другой пароль?",
+ "Confirm your recovery passphrase": "Подтвердите пароль для восстановления",
+ "Store your Security Key somewhere safe, like a password manager or a safe, as it’s used to safeguard your encrypted data.": "Храните ключ безопасности в надежном месте, например в менеджере паролей или сейфе, так как он используется для защиты ваших зашифрованных данных.",
+ "Copy": "Копировать",
+ "Unable to query secret storage status": "Невозможно запросить состояние секретного хранилища",
+ "If you cancel now, you may lose encrypted messages & data if you lose access to your logins.": "Если вы отмените сейчас, вы можете потерять зашифрованные сообщения и данные, если потеряете доступ к своим логинам.",
+ "You can also set up Secure Backup & manage your keys in Settings.": "Вы также можете настроить безопасное резервное копирование и управлять своими ключами в настройках.",
+ "Set up Secure backup": "Настройка безопасного резервного копирования",
+ "Upgrade your encryption": "Обновите свое шифрование",
+ "Set a Security Phrase": "Задайте секретную фразу",
+ "Confirm Security Phrase": "Подтвердите секретную фразу",
+ "Save your Security Key": "Сохраните свой ключ безопасности",
+ "Unable to set up secret storage": "Невозможно настроить секретное хранилище",
+ "We'll store an encrypted copy of your keys on our server. Secure your backup with a recovery passphrase.": "Мы будем хранить зашифрованную копию ваших ключей на нашем сервере. Защитите свою резервную копию с помощью пароля восстановления.",
+ "Set up with a recovery key": "Настройка с помощью ключа восстановления",
+ "Repeat your recovery passphrase...": "Настройка с помощью ключа восстановления повторите свой пароль восстановления...",
+ "Your recovery key is a safety net - you can use it to restore access to your encrypted messages if you forget your recovery passphrase.": "Ваш ключ восстановления - это защитная сетка - вы можете использовать его для восстановления доступа к зашифрованным сообщениям, если забудете пароль восстановления.",
+ "Keep a copy of it somewhere secure, like a password manager or even a safe.": "Храните его копию в надежном месте, например, в менеджере паролей или даже в сейфе.",
+ "Your recovery key": "Ваш ключ восстановления",
+ "Your recovery key has been copied to your clipboard, paste it to:": "Ваш ключ восстановления был скопирован в буфер обмена, вставьте его в:",
+ "Your recovery key is in your Downloads folder.": "Ваш ключ восстановления находится в папке Загрузки.",
+ "Without setting up Secure Message Recovery, you won't be able to restore your encrypted message history if you log out or use another session.": "Без настройки безопасного восстановления сообщений вы не сможете восстановить свою зашифрованную историю сообщений, если выйдете из системы или воспользуетесь другой сессией.",
+ "Secure your backup with a recovery passphrase": "Защитите свою резервную копию с помощью пароля восстановления",
+ "Make a copy of your recovery key": "Сделайте копию вашего ключа восстановления",
+ "Create key backup": "Создать резервную копию ключа",
+ "This session is encrypting history using the new recovery method.": "Эта сессия шифрует историю с помощью нового метода восстановления.",
+ "This session has detected that your recovery passphrase and key for Secure Messages have been removed.": "Эта сессия обнаружила, что ваша парольная фраза восстановления и ключ для защищенных сообщений были удалены.",
+ "If you did this accidentally, you can setup Secure Messages on this session which will re-encrypt this session's message history with a new recovery method.": "Если вы сделали это по ошибке, вы можете настроить безопасные сообщения в этой сессии, которая перешифрует историю сообщений в этой сессии с помощью нового метода восстановления.",
+ "If disabled, messages from encrypted rooms won't appear in search results.": "Если этот параметр отключен, сообщения из зашифрованных комнат не будут отображаться в результатах поиска.",
+ "Disable": "Отключить",
+ "Not currently indexing messages for any room.": "В настоящее время не индексируются сообщения ни для одной комнаты.",
+ "Currently indexing: %(currentRoom)s": "В настоящее время идёт индексация: %(currentRoom)s",
+ "%(brand)s is securely caching encrypted messages locally for them to appear in search results:": "%(brand)s надежно кэширует зашифрованные сообщения локально, чтобы они появлялись в результатах поиска:",
+ "Space used:": "Занято места:",
+ "Indexed messages:": "Индексированные сообщения:",
+ "Indexed rooms:": "Индексированные комнаты:",
+ "%(doneRooms)s out of %(totalRooms)s": "%(doneRooms)s из %(totalRooms)s",
+ "Message downloading sleep time(ms)": "Пауза между загрузками сообщений (в мс)",
+ "Navigation": "Навигация",
+ "Calls": "Звонки",
+ "Room List": "Список комнат",
+ "Autocomplete": "Автодополнение",
+ "Alt": "Alt",
+ "Alt Gr": "Правый Alt",
+ "Shift": "Shift",
+ "Super": "Super/Meta",
+ "Ctrl": "Ctrl",
+ "Toggle Bold": "Жирный шрифт",
+ "Toggle Italics": "Курсивный шрифт",
+ "Toggle Quote": "Цитата",
+ "New line": "Новая строка",
+ "Navigate recent messages to edit": "Выбор последних сообщений для редактирования",
+ "Jump to start/end of the composer": "Переход к началу/концу строки",
+ "Navigate composer history": "Просмотр истории сообщений",
+ "Cancel replying to a message": "Отмена ответа на сообщение",
+ "Toggle microphone mute": "Включить/выключить микрофон",
+ "Toggle video on/off": "Включить/выключить видео",
+ "Scroll up/down in the timeline": "Прокрутка чата вверх/вниз",
+ "Dismiss read marker and jump to bottom": "Убрать маркер прочтения и перейти в конец",
+ "Jump to oldest unread message": "Перейти к самому старому непрочитанному сообщению",
+ "Upload a file": "Загрузить файл",
+ "Jump to room search": "Перейти к поиску комнат",
+ "Navigate up/down in the room list": "Перемещение вверх/вниз по списку комнат",
+ "Select room from the room list": "Выбрать комнату из списка комнат",
+ "Collapse room list section": "Свернуть секцию списка комнат",
+ "Expand room list section": "Раскрыть секцию списка комнат",
+ "Clear room list filter field": "Очистить фильтр списка комнат",
+ "Previous/next unread room or DM": "Предыдущая/следующая непрочитанная комната или ЛС",
+ "Previous/next room or DM": "Предыдущая/следующая комната или ЛС",
+ "Toggle the top left menu": "Переключение верхнего левого меню",
+ "Close dialog or context menu": "Закрыть диалоговое окно или контекстное меню",
+ "Move autocomplete selection up/down": "Перемещение выбора автозаполнения вверх/вниз",
+ "Page Up": "Page Up",
+ "Page Down": "Page Down",
+ "Space": "Пробел",
+ "End": "End",
+ "No files visible in this room": "Нет видимых файлов в этой комнате",
+ "Attach files from chat or just drag and drop them anywhere in a room.": "Прикрепите файлы из чата или просто перетащите их в комнату.",
+ "You’re all caught up": "Нет непрочитанных сообщений",
+ "You have no visible notifications in this room.": "Нет видимых уведомлений в этой комнате.",
+ "%(brand)s Android": "%(brand)s Android",
+ "Master private key:": "Приватный мастер-ключ:",
+ "Show message previews for reactions in DMs": "Показывать превью сообщений для реакций в ЛС",
+ "Show message previews for reactions in all rooms": "Показывать предварительный просмотр сообщений для реакций во всех комнатах",
+ "Explore public rooms": "Просмотреть публичные комнаты",
+ "Uploading logs": "Загрузка журналов",
+ "Downloading logs": "Скачивание журналов",
+ "Can't see what you’re looking for?": "Не видите то, что ищете?",
+ "Explore all public rooms": "Просмотреть все публичные комнаты",
+ "%(count)s results|other": "%(count)s результатов",
+ "Preparing to download logs": "Подготовка к загрузке журналов",
+ "Download logs": "Скачать журналы",
+ "Unexpected server error trying to leave the room": "Неожиданная ошибка сервера при попытке покинуть комнату",
+ "Error leaving room": "Ошибка при выходе из комнаты",
+ "Communities v2 prototypes. Requires compatible homeserver. Highly experimental - use with caution.": "Прототипы сообщества v2. Требуется совместимый домашний сервер. Очень экспериментально - используйте с осторожностью.",
+ "Explore rooms in %(communityName)s": "Посмотреть комнаты в %(communityName)s",
+ "Set up Secure Backup": "Настроить безопасное резервное копирование"
}
diff --git a/src/i18n/strings/sk.json b/src/i18n/strings/sk.json
index 063a3ff9ba..667768fd57 100644
--- a/src/i18n/strings/sk.json
+++ b/src/i18n/strings/sk.json
@@ -1769,5 +1769,34 @@
"This room is end-to-end encrypted": "Táto miestnosť je E2E šifrovaná",
"Everyone in this room is verified": "Všetci v tejto miestnosti sú overení",
"Edit message": "Upraviť správu",
- "Mod": "Moderátor"
+ "Mod": "Moderátor",
+ "Are you sure you want to cancel entering passphrase?": "Naozaj chcete zrušiť zadávanie prístupovej frázy?",
+ "%(num)s minutes from now": "o %(num)s minút",
+ "%(num)s hours from now": "o %(num)s hodín",
+ "%(num)s days from now": "o %(num)s dní",
+ "The person who invited you already left the room.": "Osoba ktorá Vás pozvala už opustila miestnosť.",
+ "The person who invited you already left the room, or their server is offline.": "Osoba ktorá Vás pozvala už opustila miestnosť, alebo je ich server offline.",
+ "* %(senderName)s %(emote)s": "* %(senderName)s %(emote)s",
+ "Change notification settings": "Upraviť nastavenia upozornení",
+ "Enable advanced debugging for the room list": "Zapnúť pokročilé ladenie pre zoznam miestností",
+ "Securely cache encrypted messages locally for them to appear in search results, using ": "Bezpečne uchovávať šifrované správy na tomto zariadení, aby sa v nich dalo vyhľadávať pomocou ",
+ " to store messages from ": " na uchovanie správ z ",
+ "rooms.": "miestnosti.",
+ "Your personal ban list holds all the users/servers you personally don't want to see messages from. After ignoring your first user/server, a new room will show up in your room list named 'My Ban List' - stay in this room to keep the ban list in effect.": "Váš osobný zoznam blokácií obsahuje všetkých používateľov a servery, ktoré nechcete vidieť. Po ignorovaní prvého používateľa/servera sa vytvorí nová miestnosť 'Môj zoznam blokácií' - zostaňte v ňom, aby zoznam platil.",
+ "Discovery options will appear once you have added an email above.": "Možnosti nastavenia verejného profilu sa objavia po pridaní e-mailovej adresy vyššie.",
+ "Discovery options will appear once you have added a phone number above.": "Možnosti nastavenia verejného profilu sa objavia po pridaní telefónneho čísla vyššie.",
+ "Your key share request has been sent - please check your other sessions for key share requests.": "Požiadavka na zdieľanie kľúčov bola odoslaná - prosím skontrolujte si svoje relácie, či vám prišla.",
+ "No recently visited rooms": "Žiadne nedávno navštívené miestnosti",
+ "People": "Ľudia",
+ "Appearance": "Vzhľad",
+ "Show rooms with unread messages first": "Najprv ukázať miestnosti s neprečítanými správami",
+ "All rooms": "Všetky miestnosti",
+ "Hide advanced": "Skryť pokročilé možnosti",
+ "Show advanced": "Ukázať pokročilé možnosti",
+ "Explore rooms": "Preskúmať miestnosti",
+ "Search rooms": "Hľadať miestnosti",
+ "Security & privacy": "Bezpečnosť & súkromie",
+ "All settings": "Všetky nastavenia",
+ "Feedback": "Spätná väzba",
+ "Indexed rooms:": "Indexované miestnosti:"
}
diff --git a/src/i18n/strings/sl.json b/src/i18n/strings/sl.json
index 764b80e449..985e4a39d1 100644
--- a/src/i18n/strings/sl.json
+++ b/src/i18n/strings/sl.json
@@ -9,5 +9,7 @@
"Sign In": "Prijava",
"powered by Matrix": "poganja Matrix",
"Custom Server Options": "Možnosti strežnika po meri",
- "Your language of choice": "Vaš jezik po izbiri"
+ "Your language of choice": "Vaš jezik po izbiri",
+ "Use Single Sign On to continue": "Uporabi Single Sign On za prijavo",
+ "Confirm adding this email address by using Single Sign On to prove your identity.": ""
}
diff --git a/src/i18n/strings/sq.json b/src/i18n/strings/sq.json
index 3750d4d768..c156e3bad3 100644
--- a/src/i18n/strings/sq.json
+++ b/src/i18n/strings/sq.json
@@ -2389,5 +2389,38 @@
"* %(senderName)s %(emote)s": "* %(senderName)s %(emote)s",
"Custom Tag": "Etiketë Vetjake",
"The person who invited you already left the room.": "Personi që ju ftoi ka dalë nga dhoma tashmë.",
- "The person who invited you already left the room, or their server is offline.": "Personi që ju ftoi, ka dalë nga dhoma tashmë, ose shërbyesi i tij është jashtë funksionimi."
+ "The person who invited you already left the room, or their server is offline.": "Personi që ju ftoi, ka dalë nga dhoma tashmë, ose shërbyesi i tij është jashtë funksionimi.",
+ "Change notification settings": "Ndryshoni rregullime njoftimesh",
+ "Your server isn't responding to some requests.": "Shërbyesi juaj s’po u përgjigjet ca kërkesave.",
+ "Server isn't responding": "Shërbyesi s’po përgjigjet",
+ "Your server isn't responding to some of your requests. Below are some of the most likely reasons.": "Shërbyesi juaj s’po u përgjigjet disa kërkesave nga ju. Më poshtë gjenden disa nga arsyet më të mundshme.",
+ "The server (%(serverName)s) took too long to respond.": "Shërbyesi (%(serverName)s) e zgjati shumë përgjigjen.",
+ "Your firewall or anti-virus is blocking the request.": "Kërkesën po e bllokon firewall-i ose anti-virus-i juaj.",
+ "A browser extension is preventing the request.": "Kërkesën po e pengon një zgjerim i shfletuesit.",
+ "The server is offline.": "Shërbyesi është jashtë funksionimi.",
+ "The server has denied your request.": "Shërbyesi e ka hedhur poshtë kërkesën tuaj.",
+ "Your area is experiencing difficulties connecting to the internet.": "Zona juaj po ka probleme lidhjeje në internet.",
+ "A connection error occurred while trying to contact the server.": "Ndodhi një gabim teksa provohej lidhja me shërbyesin.",
+ "The server is not configured to indicate what the problem is (CORS).": "Shërbyesi s’është formësuar të tregojë se cili është problemi (CORS).",
+ "Recent changes that have not yet been received": "Ndryshime tani së fundi që s’janë marrë ende",
+ "No files visible in this room": "S’ka kartela të dukshme në këtë dhomë",
+ "Attach files from chat or just drag and drop them anywhere in a room.": "Bashkëngjitni kartela prej fjalosjeje ose thjesht tërhiqini dhe lërini kudo qoftë brenda dhomës.",
+ "You have no visible notifications in this room.": "S’ka njoftime të dukshme për ju në këtë dhomë.",
+ "Master private key:": "Kyç privat i përgjithshëm:",
+ "%(brand)s Android": "%(brand)s Android",
+ "Show message previews for reactions in DMs": "Shfaq paraparje mesazhi për reagime në MD",
+ "Show message previews for reactions in all rooms": "Shfaq paraparje mesazhi për reagime në krejt dhomat",
+ "Uploading logs": "Po ngarkohen regjistra",
+ "Downloading logs": "Po shkarkohen regjistra",
+ "Explore public rooms": "Eksploroni dhoma publike",
+ "Can't see what you’re looking for?": "S’shihni ç’po kërkoni?",
+ "Explore all public rooms": "Eksploroni krejt dhomat publike",
+ "%(count)s results|other": "%(count)s përfundime",
+ "Preparing to download logs": "Po bëhet gati për shkarkim regjistrash",
+ "Download logs": "Shkarko regjistra",
+ "Unexpected server error trying to leave the room": "Gabim i papritur shërbyesi në përpjekje për dalje nga dhoma",
+ "Error leaving room": "Gabim në dalje nga dhoma",
+ "Communities v2 prototypes. Requires compatible homeserver. Highly experimental - use with caution.": "Prototipe bashkësie v2. Lyp shërbyes Home të përputhshëm. Tejet eksperimentale - përdoreni me kujdes.",
+ "Explore rooms in %(communityName)s": "Eksploroni dhoma në %(communityName)s",
+ "Set up Secure Backup": "Ujdisni Kopjeruajtje të Sigurt"
}
diff --git a/src/i18n/strings/sr.json b/src/i18n/strings/sr.json
index 9aee401085..bce9fe6728 100644
--- a/src/i18n/strings/sr.json
+++ b/src/i18n/strings/sr.json
@@ -978,5 +978,70 @@
"All settings": "Сва подешавања",
"Feedback": "Повратни подаци",
"General failure": "Општа грешка",
- "Copy": "Копирај"
+ "Copy": "Копирај",
+ "Go Back": "Назад",
+ "We’re excited to announce Riot is now Element": "Са радошћу објављујемо да је Рајот (Riot) сада Елемент (Element)",
+ "Riot is now Element!": "Рајот (Riot) је сада Елемент!",
+ "Send a bug report with logs": "Пошаљи извештај о грешци са записницима",
+ "Light": "Светла",
+ "Dark": "Тамна",
+ "a few seconds ago": "пре неколико секунди",
+ "about a minute ago": "пре једног минута",
+ "%(num)s minutes ago": "пре %(num)s минута",
+ "about an hour ago": "пре једног часа",
+ "%(num)s hours ago": "пре %(num)s часова",
+ "about a day ago": "пре једног дана",
+ "%(num)s days ago": "пре %(num)s дана",
+ "Font size": "Величина фонта",
+ "Use custom size": "Користи прилагођену величину",
+ "Use a more compact ‘Modern’ layout": "Користи збијенији распоред звани „Модерн“",
+ "Match system theme": "Прати тему система",
+ "Use a system font": "Користи системски фонт",
+ "System font name": "Назив системског фонта",
+ "Show rooms with unread notifications first": "Прво прикажи собе са непрочитаним обавештењима",
+ "Enable experimental, compact IRC style layout": "Омогући пробни, збијенији распоред у IRC стилу",
+ "Got It": "Разумем",
+ "Light bulb": "Сијалица",
+ "Algorithm: ": "Алгоритам: ",
+ "Go back": "Назад",
+ "Hey you. You're the best!": "Хеј! Само напред!",
+ "Custom font size can only be between %(min)s pt and %(max)s pt": "Прилагођена величина фонта може бити између %(min)s и %(max)s тачака",
+ "Theme added!": "Тема додата!",
+ "Custom theme URL": "Адреса прилагођене теме",
+ "Add theme": "Додај тему",
+ "Theme": "Тема",
+ "Customise your appearance": "Прилагодите изглед",
+ "Appearance Settings only affect this %(brand)s session.": "Подешавања изгледа се примењују само на %(brand)s сесију.",
+ "Help & About": "Помоћ и подаци о програму",
+ "Preferences": "Поставке",
+ "Voice & Video": "Глас и видео",
+ "Unable to revoke sharing for email address": "Не могу да опозовем дељење ове мејл адресе",
+ "Revoke": "Опозови",
+ "Unable to revoke sharing for phone number": "Не могу да опозовем дељење броја телефона",
+ "Send a reply…": "Пошаљи одговор…",
+ "No recently visited rooms": "Нема недавно посећених соба",
+ "Appearance": "Изглед",
+ "Show rooms with unread messages first": "Прво прикажи собе са непрочитаним порукама",
+ "Show previews of messages": "Прикажи претпрегледе порука",
+ "Sort by": "Поређај по",
+ "Activity": "Активности",
+ "A-Z": "А-Ш",
+ "Send as message": "Пошаљи у облику поруке",
+ "Failed to revoke invite": "Неуспех при отказивању позивнице",
+ "Revoke invite": "Откажи позивницу",
+ "Got it": "Разумем",
+ "Categories": "Категорије",
+ "Your theme": "Ваша тема",
+ "Looks good": "Изгледа добро",
+ "Show advanced": "Прикажи напредно",
+ "Recent Conversations": "Недавни разговори",
+ "Recently Direct Messaged": "Недавно послате непосредне поруке",
+ "Start a conversation with someone using their name, username (like ) or email address.": "Започните разговор са неким користећи њихово име, корисничко име (као нпр.: ) или мејл адресу.",
+ "Go": "Напред",
+ "Go to Element": "Иди у Елемент",
+ "We’re excited to announce Riot is now Element!": "Са одушевљењем објављујемо да је Рајот (Riot) сада Елемент (Element)!",
+ "Learn more at element.io/previously-riot": "Сазнајте више на страници element.io/previously-riot",
+ "Looks good!": "Изгледа добро!",
+ "Send a Direct Message": "Пошаљи непосредну поруку",
+ "Switch theme": "Промени тему"
}
diff --git a/src/i18n/strings/sv.json b/src/i18n/strings/sv.json
index 83fd3fc5da..9dd4c69840 100644
--- a/src/i18n/strings/sv.json
+++ b/src/i18n/strings/sv.json
@@ -12,7 +12,7 @@
"Microphone": "Mikrofon",
"Camera": "Kamera",
"Advanced": "Avancerat",
- "Always show message timestamps": "Visa alltid tidsstämpel för meddelanden",
+ "Always show message timestamps": "Visa alltid tidsstämplar för meddelanden",
"Authentication": "Autentisering",
"%(items)s and %(lastItem)s": "%(items)s och %(lastItem)s",
"and %(count)s others...|other": "och %(count)s andra...",
@@ -25,11 +25,11 @@
"An error has occurred.": "Ett fel har inträffat.",
"Are you sure?": "Är du säker?",
"Are you sure you want to leave the room '%(roomName)s'?": "Vill du lämna rummet '%(roomName)s'?",
- "Autoplay GIFs and videos": "Spela automatiskt upp GIFar och videor",
+ "Autoplay GIFs and videos": "Spela automatiskt upp GIF:ar och videor",
"Are you sure you want to reject the invitation?": "Är du säker på att du vill avböja inbjudan?",
"%(senderName)s banned %(targetName)s.": "%(senderName)s bannade %(targetName)s.",
"Banned users": "Bannade användare",
- "Bans user with given id": "Bannar användare med givet id",
+ "Bans user with given id": "Bannar användaren med givet ID",
"Ban": "Banna",
"Attachment": "Bilaga",
"Call Timeout": "Samtalstimeout",
@@ -57,7 +57,7 @@
"/ddg is not a command": "/ddg är inte ett kommando",
"Deactivate Account": "Inaktivera konto",
"Decrypt %(text)s": "Dekryptera %(text)s",
- "Deops user with given id": "Degraderar användare med givet id",
+ "Deops user with given id": "Degraderar användaren med givet ID",
"Default": "Standard",
"Disinvite": "Häv inbjudan",
"Displays action": "Visar åtgärd",
@@ -86,7 +86,7 @@
"Failed to send request.": "Det gick inte att sända begäran.",
"Failed to set display name": "Det gick inte att ange visningsnamn",
"Failed to unban": "Det gick inte att avbanna",
- "Failed to verify email address: make sure you clicked the link in the email": "Det gick inte att bekräfta epostadressen, klicka på länken i epostmeddelandet",
+ "Failed to verify email address: make sure you clicked the link in the email": "Det gick inte att bekräfta e-postadressen: set till att du klickade på länken i e-postmeddelandet",
"Favourite": "Favorit",
"Accept": "Godkänn",
"Access Token:": "Åtkomsttoken:",
@@ -103,7 +103,7 @@
"Error: Problem communicating with the given homeserver.": "Fel: Det gick inte att kommunicera med den angivna hemservern.",
"Failed to fetch avatar URL": "Det gick inte att hämta avatar-URL",
"Failed to upload profile picture!": "Det gick inte att ladda upp profilbild!",
- "Failure to create room": "Det gick inte att skapa rum",
+ "Failure to create room": "Det gick inte att skapa rummet",
"Favourites": "Favoriter",
"Fill screen": "Fyll skärmen",
"Filter room members": "Filtrera rumsmedlemmar",
@@ -129,7 +129,7 @@
"%(senderName)s invited %(targetName)s.": "%(senderName)s bjöd in %(targetName)s.",
"Invited": "Inbjuden",
"Invites": "Inbjudningar",
- "Invites user with given id to current room": "Bjuder in användare med givet id till nuvarande rum",
+ "Invites user with given id to current room": "Bjuder in användare med givet ID till detta rum",
"Sign in with": "Logga in med",
"Join as voice or video.": "Gå med som röst eller video.",
"Join Room": "Gå med i rum",
@@ -137,7 +137,7 @@
"Jump to first unread message.": "Hoppa till första olästa meddelande.",
"%(senderName)s kicked %(targetName)s.": "%(senderName)s kickade %(targetName)s.",
"Kick": "Kicka",
- "Kicks user with given id": "Kickar användaren med givet id",
+ "Kicks user with given id": "Kickar användaren med givet ID",
"Labs": "Labb",
"Last seen": "Senast sedd",
"Leave room": "Lämna rummet",
@@ -185,7 +185,7 @@
"%(senderName)s removed their display name (%(oldDisplayName)s).": "%(senderName)s tog bort sitt visningsnamn (%(oldDisplayName)s).",
"%(senderName)s removed their profile picture.": "%(senderName)s tog bort sin profilbild.",
"Remove": "Ta bort",
- "%(senderName)s requested a VoIP conference.": "%(senderName)s begärde en VoIP-konferens.",
+ "%(senderName)s requested a VoIP conference.": "%(senderName)s begärde ett VoIP-gruppsamtal.",
"Results from DuckDuckGo": "Resultat från DuckDuckGo",
"Return to login screen": "Tillbaka till login-skärmen",
"%(brand)s does not have permission to send you notifications - please check your browser settings": "%(brand)s har inte tillstånd att skicka aviseringar - kontrollera webbläsarens inställningar",
@@ -203,16 +203,16 @@
"Seen by %(userName)s at %(dateTime)s": "Sedd av %(userName)s %(dateTime)s",
"Send Reset Email": "Skicka återställningsmeddelande",
"%(senderDisplayName)s sent an image.": "%(senderDisplayName)s skickade en bild.",
- "%(senderName)s sent an invitation to %(targetDisplayName)s to join the room.": "%(senderName)s bjöd in %(targetDisplayName)s med i rummet.",
+ "%(senderName)s sent an invitation to %(targetDisplayName)s to join the room.": "%(senderName)s bjöd in %(targetDisplayName)s att gå med i rummet.",
"Server error": "Serverfel",
"Server may be unavailable, overloaded, or search timed out :(": "Servern kan vara otillgänglig, överbelastad, eller så tog sökningen för lång tid :(",
- "Server may be unavailable, overloaded, or you hit a bug.": "Servern kan vara otillgänglig, överbelastad, eller så stötte du på en bugg.",
+ "Server may be unavailable, overloaded, or you hit a bug.": "Servern kan vara otillgänglig eller överbelastad, eller så stötte du på en bugg.",
"Server unavailable, overloaded, or something else went wrong.": "Servern är otillgänglig, överbelastad, eller så gick något annat fel.",
"Session ID": "Sessions-ID",
"%(senderName)s set a profile picture.": "%(senderName)s satte en profilbild.",
"%(senderName)s set their display name to %(displayName)s.": "%(senderName)s bytte sitt visningnamn till %(displayName)s.",
"Settings": "Inställningar",
- "Show timestamps in 12 hour format (e.g. 2:30pm)": "Visa tidsstämplar i 12-timmarsformat (t.ex. 2:30pm)",
+ "Show timestamps in 12 hour format (e.g. 2:30pm)": "Visa tidsstämplar i 12-timmarsformat (t.ex. 2:30em)",
"Signed Out": "Loggade ut",
"Sign in": "Logga in",
"Sign out": "Logga ut",
@@ -235,13 +235,13 @@
"Edit": "Ändra",
"Enable automatic language detection for syntax highlighting": "Aktivera automatisk språkdetektering för syntaxmarkering",
"Publish this room to the public in %(domain)s's room directory?": "Publicera rummet i den offentliga rumskatalogen på %(domain)s?",
- "AM": "a.m.",
- "PM": "p.m.",
+ "AM": "FM",
+ "PM": "EM",
"Submit": "Lämna in",
"The maximum permitted number of widgets have already been added to this room.": "Den största tillåtna mängden widgetar har redan tillsats till rummet.",
"The phone number entered looks invalid": "Det angivna telefonnumret är ogiltigt",
- "This email address is already in use": "Den här epostadressen används redan",
- "This email address was not found": "Den här epostadressen finns inte",
+ "This email address is already in use": "Den här e-postadressen används redan",
+ "This email address was not found": "Den här e-postadressen finns inte",
"The email address linked to your account must be entered.": "Epostadressen som är kopplad till ditt konto måste anges.",
"Online": "Online",
"Unnamed room": "Namnlöst rum",
@@ -262,25 +262,25 @@
"Thu": "Tors",
"Fri": "Fre",
"Sat": "Lör",
- "Jan": "jan",
- "Feb": "feb",
- "Mar": "mar",
- "Apr": "apr",
- "May": "maj",
- "Jun": "jun",
- "Jul": "jul",
- "Aug": "aug",
- "Sep": "sep",
- "Oct": "okt",
- "Nov": "nov",
- "Dec": "dec",
- "Invite to Community": "Bjud in till community",
+ "Jan": "Jan",
+ "Feb": "Feb",
+ "Mar": "Mar",
+ "Apr": "Apr",
+ "May": "Maj",
+ "Jun": "Jun",
+ "Jul": "Jul",
+ "Aug": "Aug",
+ "Sep": "Sep",
+ "Oct": "Okt",
+ "Nov": "Nov",
+ "Dec": "Dec",
+ "Invite to Community": "Bjud in till gemenskap",
"Unable to enable Notifications": "Det går inte att aktivera aviseringar",
"The information being sent to us to help make %(brand)s better includes:": "Informationen som skickas till oss för att förbättra %(brand)s inkluderar:",
"VoIP is unsupported": "VoIP stöds ej",
"Failed to invite": "Inbjudan misslyckades",
"You need to be logged in.": "Du måste vara inloggad.",
- "You need to be able to invite users to do that.": "Du måste kunna bjuda in användare för att göra det.",
+ "You need to be able to invite users to do that.": "Du behöver kunna bjuda in användare för att göra det där.",
"You are not in this room.": "Du är inte i det här rummet.",
"You do not have permission to do that in this room.": "Du har inte behörighet att göra det i det här rummet.",
"Fetching third party location failed": "Det gick inte att hämta platsdata från tredje part",
@@ -320,7 +320,7 @@
"An error occurred whilst saving your email notification preferences.": "Ett fel uppstod då epostaviseringsinställningarna sparades.",
"Explore Room State": "Utforska rumläget",
"Source URL": "Käll-URL",
- "Failed to add tag %(tagName)s to room": "Det gick inte att lägga till \"%(tagName)s\" till rummet",
+ "Failed to add tag %(tagName)s to room": "Det gick inte att lägga till etiketten \"%(tagName)s\" till rummet",
"Filter results": "Filtrera resultaten",
"Members": "Medlemmar",
"No update available.": "Ingen uppdatering tillgänglig.",
@@ -383,7 +383,7 @@
"Off": "Av",
"%(brand)s does not know how to join a room on this network": "%(brand)s kan inte gå med i ett rum på det här nätverket",
"Mentions only": "Endast omnämnande",
- "Failed to remove tag %(tagName)s from room": "Det gick inte att radera taggen %(tagName)s från rummet",
+ "Failed to remove tag %(tagName)s from room": "Det gick inte att radera etiketten %(tagName)s från rummet",
"You can now return to your account after signing out, and sign in on other devices.": "Du kan nu återgå till ditt konto efter att ha loggat ut och logga in på andra enheter.",
"Enable email notifications": "Aktivera epostaviseringar",
"Download this file": "Ladda ner filen",
@@ -404,17 +404,17 @@
"The platform you're on": "Plattformen du använder",
"Your homeserver's URL": "Din hemservers URL",
"Every page you use in the app": "Varje sida du använder i appen",
- "Whether or not you're using the Richtext mode of the Rich Text Editor": "Om du använder Richtext-läget i Rich-Text-editorn eller inte",
+ "Whether or not you're using the Richtext mode of the Rich Text Editor": "Om du använder Richtext-läget i Richtext-redigeraren eller inte",
"e.g. ": "t.ex. ",
- "Your device resolution": "Din enhetsupplösning",
+ "Your device resolution": "Din skärmupplösning",
"You cannot place VoIP calls in this browser.": "Du kan inte ringa VoIP-samtal i den här webbläsaren.",
- "Your email address does not appear to be associated with a Matrix ID on this Homeserver.": "Din epostadress verkar inte vara kopplad till något Matrix-ID på den här hemservern.",
+ "Your email address does not appear to be associated with a Matrix ID on this Homeserver.": "Din e-postadress verkar inte vara kopplad till något Matrix-ID på den här hemservern.",
"Restricted": "Begränsad",
- "Failed to invite the following users to the %(roomName)s room:": "Det gick inte att bjuda in följande användare till %(roomName)s-rummet:",
- "Unable to create widget.": "Det går inte att skapa widget.",
+ "Failed to invite the following users to the %(roomName)s room:": "Det gick inte att bjuda in följande användare till rummet %(roomName)s:",
+ "Unable to create widget.": "Det gick inte att skapa widgeten.",
"Ignored user": "Ignorerad användare",
"You are now ignoring %(userId)s": "Du ignorerar nu %(userId)s",
- "Unignored user": "Oignorerad användare",
+ "Unignored user": "Avignorerad användare",
"You are no longer ignoring %(userId)s": "Du ignorerar inte längre %(userId)s",
"%(oldDisplayName)s changed their display name to %(displayName)s.": "%(oldDisplayName)s bytte sitt visningsnamn till %(displayName)s.",
"%(senderName)s unbanned %(targetName)s.": "%(senderName)s avbannade %(targetName)s.",
@@ -517,7 +517,7 @@
"%(senderDisplayName)s changed the avatar for %(roomName)s": "%(senderDisplayName)s bytte avatar för %(roomName)s",
"%(senderDisplayName)s removed the room avatar.": "%(senderDisplayName)s tog bort rummets avatar.",
"%(senderDisplayName)s changed the room avatar to ": "%(senderDisplayName)s ändrade rummets avatar till ",
- "Automatically replace plain text Emoji": "Ersätt text-emojis automatiskt",
+ "Automatically replace plain text Emoji": "Ersätt automatiskt textemotikoner med emojier",
"%(weekDayName)s %(time)s": "%(weekDayName)s %(time)s",
"%(weekDayName)s, %(monthName)s %(day)s %(time)s": "%(weekDayName)s, %(day)s %(monthName)s %(time)s",
"%(weekDayName)s, %(monthName)s %(day)s %(fullYear)s": "%(weekDayName)s, %(day)s %(monthName)s %(fullYear)s",
@@ -550,7 +550,7 @@
"Failed to invite users to %(groupId)s": "Det gick inte att bjuda in användare till %(groupId)s",
"This room is not public. You will not be able to rejoin without an invite.": "Detta rum är inte offentligt. Du kommer inte kunna gå med igen utan en inbjudan.",
"Ignores a user, hiding their messages from you": "Ignorerar en användare och döljer dess meddelanden för dig",
- "Stops ignoring a user, showing their messages going forward": "Slutar ignorera en användare och visar dess meddelanden för framöver",
+ "Stops ignoring a user, showing their messages going forward": "Slutar ignorera en användare och visar dess meddelanden framöver",
"Opens the Developer Tools dialog": "Öppna dialogrutan Utvecklarverktyg",
"Notify the whole room": "Meddela hela rummet",
"Room Notification": "Rumsavisering",
@@ -563,7 +563,7 @@
"(could not connect media)": "(det gick inte ansluta media)",
" (unsupported)": " (stöds ej)",
"Drop file here to upload": "Släpp fil här för att ladda upp",
- "Ongoing conference call%(supportedText)s.": "Pågående konferenssamtal%(supportedText)s.",
+ "Ongoing conference call%(supportedText)s.": "Pågående gruppsamtal%(supportedText)s.",
"%(senderName)s sent an image": "%(senderName)s skickade en bild",
"%(senderName)s sent a video": "%(senderName)s skickade en video",
"%(senderName)s uploaded a file": "%(senderName)s laddade upp en fil",
@@ -608,14 +608,14 @@
"Failed to add the following rooms to %(groupId)s:": "Det gick inte att lägga till följande rum till %(groupId)s:",
"Missing roomId.": "Rums-ID saknas.",
"This room is not recognised.": "Detta rum känns inte igen.",
- "Usage": "Användning",
- "Verified key": "Verifierad nyckel",
- "VoIP conference started.": "VoIP-konferens startad.",
- "VoIP conference finished.": "VoIP-konferens avslutad.",
- "%(senderName)s made future room history visible to unknown (%(visibility)s).": "%(senderName)s gjorde framtida rumshistorik synligt för okänd (%(visibility)s).",
- "Where this page includes identifiable information, such as a room, user or group ID, that data is removed before being sent to the server.": "Där denna sida innehåller identifierbar information, till exempel ett rums-, användar- eller grupp-ID, tas data bort innan den skickas till servern.",
- "The remote side failed to pick up": "Mottagaren kunde inte svara",
- "Jump to read receipt": "Hoppa till läskvitto",
+ "Usage": "Användande",
+ "Verified key": "Verifierade nyckeln",
+ "VoIP conference started.": "VoIP-gruppsamtal startat.",
+ "VoIP conference finished.": "VoIP-gruppsamtal avslutat.",
+ "%(senderName)s made future room history visible to unknown (%(visibility)s).": "%(senderName)s satte framtida rumshistorik till okänd synlighet (%(visibility)s).",
+ "Where this page includes identifiable information, such as a room, user or group ID, that data is removed before being sent to the server.": "Där denna sida innehåller identifierbar information, till exempel ett rums-, användar- eller grupp-ID, tas datan bort innan den skickas till servern.",
+ "The remote side failed to pick up": "Mottagaren svarade inte",
+ "Jump to read receipt": "Hoppa till läsindikation",
"This process allows you to export the keys for messages you have received in encrypted rooms to a local file. You will then be able to import the file into another Matrix client in the future, so that client will also be able to decrypt these messages.": "Denna process låter dig exportera nycklarna för meddelanden som du har fått i krypterade rum till en lokal fil. Du kommer sedan att kunna importera filen i en annan Matrix-klient i framtiden, så att den klienten också kan dekryptera meddelandena.",
"Unknown for %(duration)s": "Okänt i %(duration)s",
"Unknown": "Okänt",
@@ -659,69 +659,69 @@
"%(severalUsers)schanged their avatar %(count)s times|one": "%(severalUsers)sändrade sin avatar",
"%(oneUser)schanged their avatar %(count)s times|other": "%(oneUser)sändrade sin avatar %(count)s gånger",
"%(oneUser)schanged their avatar %(count)s times|one": "%(oneUser)sändrade sin avatar",
- "%(items)s and %(count)s others|other": "%(items)s och %(count)s andra",
- "%(items)s and %(count)s others|one": "%(items)s och en annan",
+ "%(items)s and %(count)s others|other": "%(items)s och %(count)s till",
+ "%(items)s and %(count)s others|one": "%(items)s och en till",
"collapse": "fäll ihop",
"expand": "fäll ut",
"In reply to": "Som svar på",
- "Who would you like to add to this community?": "Vem vill du lägga till i denna community?",
- "Warning: any person you add to a community will be publicly visible to anyone who knows the community ID": "Varning: En person du lägger till i en community kommer att vara synlig för alla som känner till community-ID:t",
- "Invite new community members": "Bjud in nya community-medlemmar",
- "Which rooms would you like to add to this community?": "Vilka rum vill du lägga till i denna community?",
- "Show these rooms to non-members on the community page and room list?": "Visa dessa rum för icke-medlemmar på community-sidan och -rumslistan?",
- "Add rooms to the community": "Lägg till rum i communityn",
- "Add to community": "Lägg till i community",
- "Failed to invite users to community": "Det gick inte att bjuda in användare till communityn",
- "Mirror local video feed": "Speglad lokal-video",
+ "Who would you like to add to this community?": "Vem vill du lägga till i denna gemenskap?",
+ "Warning: any person you add to a community will be publicly visible to anyone who knows the community ID": "Varning: En person du lägger till i en gemenskap kommer att vara synlig för alla som känner till gemenskaps-ID:t",
+ "Invite new community members": "Bjud in nya gemenskapsmedlemmar",
+ "Which rooms would you like to add to this community?": "Vilka rum vill du lägga till i denna gemenskap?",
+ "Show these rooms to non-members on the community page and room list?": "Visa dessa rum för icke-medlemmar på gemenskapssidan och -rumslistan?",
+ "Add rooms to the community": "Lägg till rum i gemenskapen",
+ "Add to community": "Lägg till i gemenskap",
+ "Failed to invite users to community": "Det gick inte att bjuda in användare till gemenskapen",
+ "Mirror local video feed": "Spegla den lokala videoströmmen",
"Community Invites": "Community-inbjudningar",
- "Invalid community ID": "Ogiltigt community-ID",
- "'%(groupId)s' is not a valid community ID": "%(groupId)s är inte ett giltigt community-ID",
- "New community ID (e.g. +foo:%(localDomain)s)": "Nytt community-ID (t.ex. +foo:%(localDomain)s)",
- "Remove from community": "Ta bort från community",
- "Disinvite this user from community?": "Ta bort användarens inbjudan till community?",
- "Remove this user from community?": "Ta bort användaren från community?",
- "Failed to remove user from community": "Det gick inte att ta bort användaren från community",
- "Filter community members": "Filtrera community-medlemmar",
- "Removing a room from the community will also remove it from the community page.": "Om du tar bort ett rum från communityn tas det även bort från communityns sida.",
- "Failed to remove room from community": "Det gick inte att ta bort rum från community",
- "Only visible to community members": "Endast synlig för community-medlemmar",
- "Filter community rooms": "Filtrera community-rum",
- "Community IDs cannot be empty.": "Community-ID kan inte vara tomt.",
- "Community IDs may only contain characters a-z, 0-9, or '=_-./'": "Community-ID får endast innehålla tecknen a-z, 0-9 och '=_-./'",
- "Something went wrong whilst creating your community": "Något gick fel när din community skapades",
- "Create Community": "Skapa community",
- "Community Name": "Community-namn",
- "Community ID": "Community-ID",
- "View Community": "Visa community",
- "
HTML for your community's page
\n
\n Use the long description to introduce new members to the community, or distribute\n some important links\n
\n
\n You can even use 'img' tags\n
\n": "
HTML för din community-sida
\n
\n Använd den långa beskrivningen för att introducera nya medlemmar till communityn, eller dela\n några viktiga länkar\n
\n
\n Du kan även använda 'img'-taggar\n
\n",
- "Add rooms to the community summary": "Lägg till rum i community-översikten",
- "Add users to the community summary": "Lägg till användare i community-översikten",
- "Failed to update community": "Det gick inte att uppdatera community",
- "Unable to join community": "Det gick inte att gå med i communityn",
- "Leave Community": "Lämna community",
- "Unable to leave community": "Det gick inte att lämna community",
- "Community Settings": "Community-inställningar",
- "Changes made to your community name and avatar might not be seen by other users for up to 30 minutes.": "Det kan dröja upp till 30 minuter innan ändringar på communityns namn och avatar blir synliga för andra användare.",
- "These rooms are displayed to community members on the community page. Community members can join the rooms by clicking on them.": "Dessa rum visas för community-medlemmar på community-sidan. Community-medlemmar kan gå med i rummen genom att klicka på dem.",
- "Add rooms to this community": "Lägg till rum i denna community",
- "%(inviter)s has invited you to join this community": "%(inviter)s har bjudit in dig till denna community",
- "Join this community": "Gå med i denna community",
- "Leave this community": "Lämna denna community",
- "You are an administrator of this community": "Du är administratör för denna community",
- "You are a member of this community": "Du är medlem i denna community",
- "Who can join this community?": "Vem kan gå med i denna community?",
- "Your community hasn't got a Long Description, a HTML page to show to community members. Click here to open settings and give it one!": "Din community har ingen lång beskrivning eller HTML-sida att visa för medlemmar. Klicka här för att öppna inställningar och lägga till det!",
- "Community %(groupId)s not found": "Community %(groupId)s hittades inte",
- "To set up a filter, drag a community avatar over to the filter panel on the far left hand side of the screen. You can click on an avatar in the filter panel at any time to see only the rooms and people associated with that community.": "För att skapa ett filter, dra en community-avatar till filterpanelen längst till vänster på skärmen. Du kan när som helst klicka på en avatar i filterpanelen för att bara se rum och personer som är associerade med den communityn.",
- "Create a new community": "Skapa en ny community",
- "Create a community to group together users and rooms! Build a custom homepage to mark out your space in the Matrix universe.": "Skapa en community för att gruppera användare och rum! Bygg en anpassad hemsida för att markera er plats i Matrix-universumet.",
- "Invite to this community": "Bjud in till denna community",
- "Something went wrong when trying to get your communities.": "Något gick fel vid hämtning av dina communityn.",
- "You're not currently a member of any communities.": "Du är för närvarande inte medlem i någon community.",
- "Communities": "Communityn",
- "Your Communities": "Dina communityn",
- "Did you know: you can use communities to filter your %(brand)s experience!": "Visste du att: du kan använda communityn för att filtrera din %(brand)s-upplevelse!",
- "Error whilst fetching joined communities": "Fel vid hämtning av anslutna communityn",
+ "Invalid community ID": "Ogiltigt gemenskaps-ID",
+ "'%(groupId)s' is not a valid community ID": "%(groupId)s är inte ett giltigt gemenskaps-ID",
+ "New community ID (e.g. +foo:%(localDomain)s)": "Nytt gemenskaps-ID (t.ex. +foo:%(localDomain)s)",
+ "Remove from community": "Ta bort från gemenskapen",
+ "Disinvite this user from community?": "Ta bort användarens inbjudan till gemenskapen?",
+ "Remove this user from community?": "Ta bort användaren från gemenskapen?",
+ "Failed to remove user from community": "Det gick inte att ta bort användaren från gemenskapen",
+ "Filter community members": "Filtrera gemenskapsmedlemmar",
+ "Removing a room from the community will also remove it from the community page.": "Om du tar bort ett rum från gemenskapen tas det även bort från gemenskapens sida.",
+ "Failed to remove room from community": "Det gick inte att ta bort rummet från gemenskapen",
+ "Only visible to community members": "Endast synlig för gemenskapsmedlemmar",
+ "Filter community rooms": "Filtrera gemenskapsrum",
+ "Community IDs cannot be empty.": "Gemenskaps-ID kan inte vara tomt.",
+ "Community IDs may only contain characters a-z, 0-9, or '=_-./'": "Gemenskaps-ID får endast innehålla tecknen a-z, 0-9 och '=_-./'",
+ "Something went wrong whilst creating your community": "Något gick fel när din gemenskap skapades",
+ "Create Community": "Skapa gemenskap",
+ "Community Name": "Gemenskapsnamn",
+ "Community ID": "Gemenskaps-ID",
+ "View Community": "Visa gemenskap",
+ "
HTML for your community's page
\n
\n Use the long description to introduce new members to the community, or distribute\n some important links\n
\n
\n You can even use 'img' tags\n
\n": "
HTML för din gemenskapssida
\n
\n Använd den långa beskrivningen för att introducera nya medlemmar till gemenskapen, eller dela\n några viktiga länkar\n
\n
\n Du kan även använda 'img'-taggar\n
\n",
+ "Add rooms to the community summary": "Lägg till rum i gemenskapsöversikten",
+ "Add users to the community summary": "Lägg till användare i gemenskapsöversikten",
+ "Failed to update community": "Det gick inte att uppdatera gemenskapen",
+ "Unable to join community": "Det gick inte att gå med i gemenskapen",
+ "Leave Community": "Lämna gemenskapen",
+ "Unable to leave community": "Det gick inte att lämna gemenskap",
+ "Community Settings": "Gemenskapsinställningar",
+ "Changes made to your community name and avatar might not be seen by other users for up to 30 minutes.": "Det kan dröja upp till 30 minuter innan ändringar på gemenskapens namn och avatar blir synliga för andra användare.",
+ "These rooms are displayed to community members on the community page. Community members can join the rooms by clicking on them.": "Dessa rum visas för gemenskapsmedlemmar på gemenskapssidan. Gemenskapsmedlemmar kan gå med i rummen genom att klicka på dem.",
+ "Add rooms to this community": "Lägg till rum i denna gemenskap",
+ "%(inviter)s has invited you to join this community": "%(inviter)s har bjudit in dig till denna gemenskap",
+ "Join this community": "Gå med i denna gemenskap",
+ "Leave this community": "Lämna denna gemenskap",
+ "You are an administrator of this community": "Du är administratör för denna gemenskap",
+ "You are a member of this community": "Du är medlem i denna gemenskap",
+ "Who can join this community?": "Vem kan gå med i denna gemenskap?",
+ "Your community hasn't got a Long Description, a HTML page to show to community members. Click here to open settings and give it one!": "Din gemenskap har ingen lång beskrivning eller HTML-sida att visa för medlemmar. Klicka här för att öppna inställningarna och lägga till det!",
+ "Community %(groupId)s not found": "Gemenskapen %(groupId)s hittades inte",
+ "To set up a filter, drag a community avatar over to the filter panel on the far left hand side of the screen. You can click on an avatar in the filter panel at any time to see only the rooms and people associated with that community.": "För att skapa ett filter, dra en gemenskapsavatar till filterpanelen längst till vänster på skärmen. Du kan när som helst klicka på en avatar i filterpanelen för att bara se rum och personer som är associerade med den gemenskapen.",
+ "Create a new community": "Skapa en ny gemenskap",
+ "Create a community to group together users and rooms! Build a custom homepage to mark out your space in the Matrix universe.": "Skapa en gemenskap för att gruppera användare och rum! Bygg en anpassad hemsida för att markera er plats i Matrix-universumet.",
+ "Invite to this community": "Bjud in till denna gemenskap",
+ "Something went wrong when trying to get your communities.": "Något gick fel vid hämtning av dina gemenskaper.",
+ "You're not currently a member of any communities.": "Du är för närvarande inte medlem i någon gemenskap.",
+ "Communities": "Gemenskaper",
+ "Your Communities": "Dina gemenskaper",
+ "Did you know: you can use communities to filter your %(brand)s experience!": "Visste du att: du kan använda gemenskaper för att filtrera din %(brand)s-upplevelse!",
+ "Error whilst fetching joined communities": "Fel vid hämtning av anslutna gemenskaper",
"Featured Rooms:": "Utvalda rum:",
"Featured Users:": "Utvalda användare:",
"Everyone": "Alla",
@@ -741,7 +741,7 @@
"You will not be able to undo this change as you are promoting the user to have the same power level as yourself.": "Du kommer inte att kunna ångra den här ändringen eftersom du höjer användaren till samma behörighetsnivå som dig själv.",
"unknown caller": "okänd uppringare",
"To use it, just wait for autocomplete results to load and tab through them.": "För att använda detta, vänta på att autokompletteringen laddas och tabba igenom resultatet.",
- "Enable inline URL previews by default": "Aktivera URL-förhandsvisning som standard",
+ "Enable inline URL previews by default": "Aktivera inbäddad URL-förhandsvisning som standard",
"Enable URL previews for this room (only affects you)": "Aktivera URL-förhandsvisning för detta rum (påverkar bara dig)",
"Enable URL previews by default for participants in this room": "Aktivera URL-förhandsvisning som standard för deltagare i detta rum",
"You have enabled URL previews by default.": "Du har aktiverat URL-förhandsvisning som standard.",
@@ -788,16 +788,16 @@
"Please forget all messages I have sent when my account is deactivated (Warning: this will cause future users to see an incomplete view of conversations)": "Glöm alla meddelanden som jag har skickat när mitt konto inaktiveras (Varning: detta kommer att göra så att framtida användare får se ofullständiga konversationer)",
"To continue, please enter your password:": "För att fortsätta, ange ditt lösenord:",
"If you've submitted a bug via GitHub, debug logs can help us track down the problem. Debug logs contain application usage data including your username, the IDs or aliases of the rooms or groups you have visited and the usernames of other users. They do not contain messages.": "Om du har anmält en bugg via GitHub, kan felsökningsloggar hjälpa oss spåra problemet. Felsökningsloggarna innehåller användningsdata för applikationen inklusive ditt användarnamn, ID eller alias för rum och grupper du besökt och användarnamn för andra användare. De innehåller inte meddelanden.",
- "%(brand)s collects anonymous analytics to allow us to improve the application.": "%(brand)s samlar in anonym analysdata för att vi ska kunna förbättra applikationen.",
- "Privacy is important to us, so we don't collect any personal or identifiable data for our analytics.": "Integritet är viktig för oss, så vi samlar inte in några personliga eller identifierbara uppgifter för våra analyser.",
- "Learn more about how we use analytics.": "Läs mer om hur vi använder analysdata.",
- "Analytics": "Analysdata",
- "Send analytics data": "Skicka analysdata",
+ "%(brand)s collects anonymous analytics to allow us to improve the application.": "%(brand)s samlar in anonym statistik för att vi ska kunna förbättra applikationen.",
+ "Privacy is important to us, so we don't collect any personal or identifiable data for our analytics.": "Integritet är viktig för oss, så vi samlar inte in några personliga eller identifierbara uppgifter i våran statistik.",
+ "Learn more about how we use analytics.": "Läs mer om hur vi använder statistik.",
+ "Analytics": "Statistik",
+ "Send analytics data": "Skicka statistik",
"Passphrases must match": "Passfraser måste matcha",
"Passphrase must not be empty": "Lösenfras får inte vara tom",
"Confirm passphrase": "Bekräfta lösenfrasen",
"%(senderName)s changed the pinned messages for the room.": "%(senderName)s ändrade fastnålade meddelanden för rummet.",
- "Message Pinning": "Nåla fast meddelanden",
+ "Message Pinning": "Fastnålning av meddelanden",
"Unpin Message": "Ta bort fastnålning",
"No pinned messages.": "Inga fastnålade meddelanden.",
"Pinned Messages": "Fastnålade meddelanden",
@@ -806,15 +806,15 @@
"This process allows you to import encryption keys that you had previously exported from another Matrix client. You will then be able to decrypt any messages that the other client could decrypt.": "Denna process möjliggör import av krypteringsnycklar som tidigare exporterats från en annan Matrix-klient. Du kommer då kunna dekryptera alla meddelanden som den andra klienten kunde dekryptera.",
"The export file will be protected with a passphrase. You should enter the passphrase here, to decrypt the file.": "Den exporterade filen kommer vara skyddad med en lösenfras. Du måste ange lösenfrasen här, för att dekryptera filen.",
"Flair": "Emblem",
- "Showing flair for these communities:": "Visar emblem för dessa communityn:",
- "This room is not showing flair for any communities": "Detta rum visar inte emblem för några communityn",
- "Display your community flair in rooms configured to show it.": "Visa ditt community-emblem i rum som är konfigurerade för att visa det.",
+ "Showing flair for these communities:": "Visar emblem för dessa gemenskaper:",
+ "This room is not showing flair for any communities": "Detta rum visar inte emblem för några gemenskaper",
+ "Display your community flair in rooms configured to show it.": "Visa ditt gemenskapsemblem i rum som är konfigurerade för att visa det.",
"Share Link to User": "Dela länk till användare",
"Share room": "Dela rum",
"Share Room": "Dela rum",
"Link to most recent message": "Länk till senaste meddelandet",
"Share User": "Dela användare",
- "Share Community": "Dela community",
+ "Share Community": "Dela gemenskap",
"Share Room Message": "Dela rumsmeddelande",
"Link to selected message": "Länk till valt meddelande",
"COPY": "KOPIERA",
@@ -825,7 +825,7 @@
"A call is currently being placed!": "Ett samtal håller på att upprättas!",
"A call is already in progress!": "Ett samtal pågår redan!",
"Permission Required": "Behörighet krävs",
- "You do not have permission to start a conference call in this room": "Du har inte behörighet att starta ett konferenssamtal i detta rum",
+ "You do not have permission to start a conference call in this room": "Du har inte behörighet att starta ett gruppsamtal i detta rum",
"This event could not be displayed": "Den här händelsen kunde inte visas",
"In encrypted rooms, like this one, URL previews are disabled by default to ensure that your homeserver (where the previews are generated) cannot gather information about links you see in this room.": "I krypterade rum, som detta, är URL-förhandsvisning inaktiverad som standard för att säkerställa att din hemserver (där förhandsvisningar genereras) inte kan samla information om länkar du ser i rummet.",
"The email field must not be blank.": "Epost-fältet får inte vara tomt.",
@@ -838,9 +838,9 @@
"When someone puts a URL in their message, a URL preview can be shown to give more information about that link such as the title, description, and an image from the website.": "När någon postar en URL i sitt meddelande, kan URL-förhandsvisning ge mer information om länken, såsom titel, beskrivning, och en bild från webbplatsen.",
"You can't send any messages until you review and agree to our terms and conditions.": "Du kan inte skicka några meddelanden innan du granskar och godkänner våra villkor.",
"System Alerts": "Systemvarningar",
- "Sorry, your homeserver is too old to participate in this room.": "Tyvärr, din hemserver är för gammal för att delta i detta rum.",
- "Please contact your homeserver administrator.": "Vänligen kontakta din hemserver-administratör.",
- "Please contact your service administrator to continue using the service.": "Kontakta din serviceadministratör för att fortsätta använda tjänsten.",
+ "Sorry, your homeserver is too old to participate in this room.": "Tyvärr, din hemserver är för gammal för att delta i det här rummet.",
+ "Please contact your homeserver administrator.": "Vänligen kontakta din hemserveradministratör.",
+ "Please contact your service administrator to continue using the service.": "Kontakta din tjänstadministratör för att fortsätta använda tjänsten.",
"This homeserver has hit its Monthly Active User limit.": "Hemservern har nått sin månatliga gräns för användaraktivitet.",
"This homeserver has exceeded one of its resource limits.": "Hemservern har överskridit en av sina resursgränser.",
"Your message wasn't sent because this homeserver has hit its Monthly Active User Limit. Please contact your service administrator to continue using the service.": "Ditt meddelande skickades inte för hemservern har nått sin månatliga gräns för användaraktivitet. Kontakta din serviceadministratör för att fortsätta använda servicen.",
@@ -861,7 +861,7 @@
"Stop users from speaking in the old version of the room, and post a message advising users to move to the new room": "Hindra användare från att prata i den gamla rumsversionen och posta ett meddelande som rekommenderar användare att flytta till det nya rummet",
"Put a link back to the old room at the start of the new room so people can see old messages": "Sätta en länk tillbaka till det gamla rummet i början av det nya rummet så att folk kan se gamla meddelanden",
"Forces the current outbound group session in an encrypted room to be discarded": "Tvingar den aktuella utgående gruppsessionen i ett krypterat rum att överges",
- "Unable to connect to Homeserver. Retrying...": "Det gick inte att ansluta till hemserver. Försöker igen ...",
+ "Unable to connect to Homeserver. Retrying...": "Det gick inte att ansluta till hemservern. Försöker igen…",
"%(senderName)s set the main address for this room to %(address)s.": "%(senderName)s satte huvudadressen för detta rum till %(address)s.",
"%(senderName)s removed the main address for this room.": "%(senderName)s tog bort huvudadressen för detta rum.",
"Add some now": "Lägg till några nu",
@@ -869,39 +869,39 @@
"Before submitting logs, you must create a GitHub issue to describe your problem.": "Innan du skickar in loggar måste du skapa en GitHub-bugg för att beskriva problemet.",
"Updating %(brand)s": "Uppdaterar %(brand)s",
"Open Devtools": "Öppna Devtools",
- "Show developer tools": "Visa utvecklingsverktyg",
- "You are an administrator of this community. You will not be able to rejoin without an invite from another administrator.": "Du är administratör för denna community. Du kommer inte kunna gå med igen utan en inbjudan från en annan administratör.",
+ "Show developer tools": "Visa utvecklarverktyg",
+ "You are an administrator of this community. You will not be able to rejoin without an invite from another administrator.": "Du är administratör för denna gemenskap. Du kommer inte kunna gå med igen utan en inbjudan från en annan administratör.",
"The file '%(fileName)s' exceeds this homeserver's size limit for uploads": "Filen '%(fileName)s' överstiger denna hemserverns storleksgräns för uppladdningar",
"Unable to load! Check your network connectivity and try again.": "Kan inte ladda! Kolla din nätverksuppkoppling och försök igen.",
"Whether or not you're logged in (we don't record your username)": "Om du är inloggad eller inte (vi sparar inte ditt användarnamn)",
"Failed to invite users to the room:": "Kunde inte bjuda in användare till rummet:",
- "Upgrades a room to a new version": "Uppgraderar ett num till en ny version",
- "Gets or sets the room topic": "Ger eller sätter ämnet för ett rum",
+ "Upgrades a room to a new version": "Uppgraderar ett rum till en ny version",
+ "Gets or sets the room topic": "Hämtar eller sätter ämnet för ett rum",
"This room has no topic.": "Det här rummet har inget ämne.",
- "Sets the room name": "Sätter rumnamnet",
+ "Sets the room name": "Sätter rumsnamnet",
"%(senderDisplayName)s upgraded this room.": "%(senderDisplayName)s uppgraderade det här rummet.",
- "%(senderDisplayName)s made the room public to whoever knows the link.": "%(senderDisplayName)s gjorde rummet publikt för alla som kan länken.",
+ "%(senderDisplayName)s made the room public to whoever knows the link.": "%(senderDisplayName)s gjorde rummet publikt för alla som har länken.",
"%(senderDisplayName)s has allowed guests to join the room.": "%(senderDisplayName)s har tillåtit gäster att gå med i rummet.",
"%(senderDisplayName)s changed the join rule to %(rule)s": "%(senderDisplayName)s ändrade regeln för att gå med till %(rule)s",
"%(senderDisplayName)s has prevented guests from joining the room.": "%(senderDisplayName)s har nekat gäster att gå med i rummet.",
- "%(senderDisplayName)s changed guest access to %(rule)s": "%(senderDisplayName)s ändrade gäst-åtkomst till %(rule)s",
+ "%(senderDisplayName)s changed guest access to %(rule)s": "%(senderDisplayName)s ändrade gäståtkomst till %(rule)s",
"%(displayName)s is typing …": "%(displayName)s skriver …",
"%(names)s and %(count)s others are typing …|other": "%(names)s och %(count)s andra skriver …",
"%(names)s and %(count)s others are typing …|one": "%(names)s och en till skriver …",
"%(names)s and %(lastPerson)s are typing …": "%(names)s och %(lastPerson)s skriver …",
- "Unrecognised address": "Okänd address",
- "You do not have permission to invite people to this room.": "Du har inte tillåtelse att bjuda in användare till det här rummet.",
- "User %(user_id)s does not exist": "Användare %(user_id)s existerar inte",
- "User %(user_id)s may or may not exist": "Användare %(user_id)s existerar möjligtvis",
- "Unknown server error": "Okänt server-fel",
- "Use a few words, avoid common phrases": "Använd ett par ord, undvik vanliga fraser",
- "No need for symbols, digits, or uppercase letters": "Symboler, siffror eller stora bokstäver krävs ej",
+ "Unrecognised address": "Okänd adress",
+ "You do not have permission to invite people to this room.": "Du har inte behörighet att bjuda in användare till det här rummet.",
+ "User %(user_id)s does not exist": "Användaren %(user_id)s existerar inte",
+ "User %(user_id)s may or may not exist": "Användaren %(user_id)s kanske eller kanske inte existerar",
+ "Unknown server error": "Okänt serverfel",
+ "Use a few words, avoid common phrases": "Använd några ord, undvik vanliga fraser",
+ "No need for symbols, digits, or uppercase letters": "Specialtecken, siffror eller stora bokstäver behövs inte",
"Avoid repeated words and characters": "Undvik upprepade ord och bokstäver",
"Avoid sequences": "Undvik sekvenser",
- "Avoid recent years": "Undvik senare år",
+ "Avoid recent years": "Undvik nyliga år",
"Avoid years that are associated with you": "Undvik årtal som associeras med dig",
"Avoid dates and years that are associated with you": "Undvik datum och årtal som associeras med dig",
- "Capitalization doesn't help very much": "Kapitalisering hjälper inte särskilt mycket",
+ "Capitalization doesn't help very much": "Versaler hjälper inte särskilt mycket",
"All-uppercase is almost as easy to guess as all-lowercase": "Endast stora bokstäver är nästan lika enkelt att gissa som endast små bokstäver",
"Reversed words aren't much harder to guess": "Ord skrivna baklänges är inte mycket svårare att gissa",
"Predictable substitutions like '@' instead of 'a' don't help very much": "Förutsägbara ersättningar som '@' istället för 'a' hjälper inte särskilt mycket",
@@ -909,32 +909,32 @@
"Repeats like \"aaa\" are easy to guess": "Upprepningar som \"aaa\" är enkla att gissa",
"Repeats like \"abcabcabc\" are only slightly harder to guess than \"abc\"": "Upprepningar som \"abcabcabc\" är bara aningen svårare att gissa än \"abc\"",
"Sequences like abc or 6543 are easy to guess": "Sekvenser som abc eller 6543 är enkla att gissa",
- "Recent years are easy to guess": "Senare årtal är enka att gissa",
+ "Recent years are easy to guess": "Nyliga årtal är enkla att gissa",
"Dates are often easy to guess": "Datum är ofta enkla att gissa",
- "This is a top-10 common password": "Det här är ett av de topp 10 vanligaste lösenorden",
- "This is a top-100 common password": "Det här är ett av de topp 100 vanligaste lösenorden",
+ "This is a top-10 common password": "Det här är ett av de 10 vanligaste lösenorden",
+ "This is a top-100 common password": "Det här är ett av de 100 vanligaste lösenorden",
"This is a very common password": "Det här är ett väldigt vanligt lösenord",
"This is similar to a commonly used password": "Det här liknar ett vanligt lösenord",
"A word by itself is easy to guess": "Enstaka ord är enkla att gissa",
"Names and surnames by themselves are easy to guess": "Enstaka för- och efternamn är enkla att gissa",
- "Common names and surnames are easy to guess": "Vanliga namn och efternamn är enkla att gissa",
- "Straight rows of keys are easy to guess": "Tangenter i rad på tangentbordet är enkla att gissa",
+ "Common names and surnames are easy to guess": "Vanliga för- och efternamn är enkla att gissa",
+ "Straight rows of keys are easy to guess": "Raka rader på tangentbordet är enkla att gissa",
"Short keyboard patterns are easy to guess": "Korta tangentbordsmönster är enkla att gissa",
- "There was an error joining the room": "Det gick fel när vi försökte gå med i rummet",
- "Changes your display nickname in the current room only": "Ändrar ditt visningsnamn endast i det aktuella rummet",
- "Use a longer keyboard pattern with more turns": "Använd ett längre tangentbordsmönster med fler varv",
+ "There was an error joining the room": "Ett fel inträffade vid försök att gå med i rummet",
+ "Changes your display nickname in the current room only": "Ändrar ditt visningsnamn endast i detta rum",
+ "Use a longer keyboard pattern with more turns": "Använd ett längre tangentbordsmönster med fler riktningsbyten",
"Custom user status messages": "Anpassade användarstatusmeddelanden",
- "Enable Emoji suggestions while typing": "Aktivera Emoji-förslag medan du skriver",
+ "Enable Emoji suggestions while typing": "Aktivera emojiförslag medan du skriver",
"Show a placeholder for removed messages": "Visa en platshållare för borttagna meddelanden",
"Show join/leave messages (invites/kicks/bans unaffected)": "Visa \"gå med\"/lämna-meddelanden (inbjudningar/kickningar/banningar opåverkat)",
"Show avatar changes": "Visa avatarändringar",
"Show display name changes": "Visa visningsnamnsändringar",
- "Show read receipts sent by other users": "Visa läskvitton som skickats av andra användare",
- "Show avatars in user and room mentions": "Visa avatarer i användar- och rumsnämningar",
- "Enable big emoji in chat": "Aktivera stor emoji i chatt",
+ "Show read receipts sent by other users": "Visa läsindikationer som skickats av andra användare",
+ "Show avatars in user and room mentions": "Visa avatarer i användar- och rumsbenämningar",
+ "Enable big emoji in chat": "Aktivera stora emojier i chatt",
"Send typing notifications": "Skicka \"skriver\"-statusar",
- "Enable Community Filter Panel": "Aktivera community-filterpanel",
- "Allow Peer-to-Peer for 1:1 calls": "Tillåt peer-to-peer kommunikation för 1:1 samtal",
+ "Enable Community Filter Panel": "Aktivera gemenskapsfilterpanel",
+ "Allow Peer-to-Peer for 1:1 calls": "Tillåt peer-to-peer-kommunikation för 1:1-samtal",
"Messages containing my username": "Meddelanden som innehåller mitt användarnamn",
"Messages containing @room": "Meddelanden som innehåller @room",
"Encrypted messages in one-to-one chats": "Krypterade meddelanden i privata chattar",
@@ -1062,7 +1062,7 @@
"Join millions for free on the largest public server": "Bli medlem gratis på den största offentliga servern",
"Premium": "Premium",
"Premium hosting for organisations Learn more": "Premium-hosting för organisationer Läs mer",
- "Other": "Andra",
+ "Other": "Annat",
"Find other public servers or use a custom server": "Hitta andra offentliga servrar eller använd en anpassad server",
"Your Matrix account on %(serverName)s": "Ditt Matrix-konto på %(serverName)s",
"Sign in instead": "Logga in istället",
@@ -1081,9 +1081,9 @@
"%(senderDisplayName)s enabled flair for %(groups)s in this room.": "%(senderDisplayName)s aktiverade emblem för %(groups)s i detta rum.",
"%(senderDisplayName)s disabled flair for %(groups)s in this room.": "%(senderDisplayName)s inaktiverade emblem för %(groups)s i detta rum.",
"%(senderDisplayName)s enabled flair for %(newGroups)s and disabled flair for %(oldGroups)s in this room.": "%(senderDisplayName)s aktiverade emblem för %(newGroups)s och inaktiverade emblem för %(oldGroups)s i detta rum.",
- "User %(userId)s is already in the room": "Användare %(userId)s är redan i rummet",
- "The user must be unbanned before they can be invited.": "Användare behöver avbannas innan de kan bjudas in.",
- "Group & filter rooms by custom tags (refresh to apply changes)": "Gruppera och filtrera rum med anpassade taggar (ladda om för att visa ändringar)",
+ "User %(userId)s is already in the room": "Användaren %(userId)s är redan i rummet",
+ "The user must be unbanned before they can be invited.": "Användaren behöver avbannas innan den kan bjudas in.",
+ "Group & filter rooms by custom tags (refresh to apply changes)": "Gruppera och filtrera rum med anpassade etiketter (ladda om för att visa ändringar)",
"Render simple counters in room header": "Rendera enkla räknare i rumsrubriken",
"Yes": "Ja",
"No": "Nej",
@@ -1124,7 +1124,7 @@
"Please supply a https:// or http:// widget URL": "Ange en widget-URL med https:// eller http://",
"You cannot modify widgets in this room.": "Du kan inte ändra widgets i detta rum.",
"%(senderName)s revoked the invitation for %(targetDisplayName)s to join the room.": "%(senderName)s återkallade inbjudan för %(targetDisplayName)s att gå med i rummet.",
- "Show a reminder to enable Secure Message Recovery in encrypted rooms": "Visa en påminnelse för att sätta på säker meddelande återhämtning i krypterade rum",
+ "Show a reminder to enable Secure Message Recovery in encrypted rooms": "Visa en påminnelse att sätta på säker meddelandeåterställning i krypterade rum",
"The other party cancelled the verification.": "Den andra parten avbröt verifieringen.",
"Verified!": "Verifierad!",
"You've successfully verified this user.": "Du har verifierat den här användaren.",
@@ -1160,7 +1160,7 @@
"Unable to load backup status": "Det går inte att ladda backupstatus",
"Guest": "Gäst",
"Could not load user profile": "Kunde inte ladda användarprofil",
- "Whether or not you're using the 'breadcrumbs' feature (avatars above the room list)": "Om du använder 'breadcrumbs' eller inte (avatarer ovanför rumslistan)",
+ "Whether or not you're using the 'breadcrumbs' feature (avatars above the room list)": "Om du använder 'brödsmulor' eller inte (avatarer ovanför rumslistan)",
"Replying With Files": "Svarar med filer",
"At this time it is not possible to reply with a file. Would you like to upload this file without replying?": "Just nu är det inte möjligt att svara med en fil. Vill du ladda upp filen utan att svara?",
"The file '%(fileName)s' failed to upload.": "Filen '%(fileName)s' kunde inte laddas upp.",
@@ -1208,26 +1208,26 @@
"Upload %(count)s other files|one": "Ladda upp %(count)s annan fil",
"Cancel All": "Avbryt alla",
"Upload Error": "Uppladdningsfel",
- "Name or Matrix ID": "Namn eller Martix-ID",
- "Your %(brand)s is misconfigured": "%(brand)s är felkonfigurerat",
+ "Name or Matrix ID": "Namn eller Matrix-ID",
+ "Your %(brand)s is misconfigured": "Din %(brand)s är felkonfigurerad",
"Call failed due to misconfigured server": "Anrop misslyckades på grund av felkonfigurerad server",
"Try using turn.matrix.org": "Prova att använda turn.matrix.org",
"The server does not support the room version specified.": "Servern stöder inte den angivna rumsversionen.",
"Messages": "Meddelanden",
"Actions": "Åtgärder",
- "Sends a message as plain text, without interpreting it as markdown": "Skickar ett meddelande som vanlig text, utan att tolka det som markdown",
+ "Sends a message as plain text, without interpreting it as markdown": "Skickar ett meddelande som vanlig text, utan att tolka det som Markdown",
"You do not have the required permissions to use this command.": "Du har inte de behörigheter som krävs för att använda det här kommandot.",
- "Changes your avatar in this current room only": "Ändrar din avatar endast i det aktuella rummet",
+ "Changes your avatar in this current room only": "Ändrar din avatar endast i detta rum",
"Changes your avatar in all rooms": "Ändrar din avatar i alla rum",
"Use an identity server": "Använd en identitetsserver",
- "Unbans user with given ID": "Avbannar användare med givet id",
- "Sends the given message coloured as a rainbow": "Skickar angivet meddelandet färgat som en regnbåge",
- "Sends the given emote coloured as a rainbow": "Skickar angiven emoji färgad som en regnbåge",
- "Displays list of commands with usages and descriptions": "Visar lista över kommandon med beskrivningar",
+ "Unbans user with given ID": "Avbannar användaren med givet ID",
+ "Sends the given message coloured as a rainbow": "Skickar angivet meddelande i regnbågsfärg",
+ "Sends the given emote coloured as a rainbow": "Skickar angiven emoji i regnbågsfärg",
+ "Displays list of commands with usages and descriptions": "Visar lista över kommandon med användande beskrivningar",
"%(senderName)s made no change.": "%(senderName)s gjorde ingen ändring.",
"Cannot reach homeserver": "Kan inte nå hemservern",
"Ensure you have a stable internet connection, or get in touch with the server admin": "Se till att du har en stabil internetanslutning, eller kontakta serveradministratören",
- "Ask your %(brand)s admin to check your config for incorrect or duplicate entries.": "Be din %(brand)s-administratör att kontrollera din konfiguration efter felaktiga eller duplicerade poster.",
+ "Ask your %(brand)s admin to check your config for incorrect or duplicate entries.": "Be din %(brand)s-administratör att kolla din konfiguration efter felaktiga eller duplicerade poster.",
"Cannot reach identity server": "Kan inte nå identitetsservern",
"You can register, but some features will be unavailable until the identity server is back online. If you keep seeing this warning, check your configuration or contact a server admin.": "Du kan registrera dig, men vissa funktioner kommer inte att vara tillgängliga förrän identitetsservern är online igen. Om du fortsätter att se den här varningen, kontrollera din konfiguration eller kontakta en serveradministratör.",
"You can reset your password, but some features will be unavailable until the identity server is back online. If you keep seeing this warning, check your configuration or contact a server admin.": "Du kan återställa ditt lösenord, men vissa funktioner kommer inte att vara tillgängliga förrän identitetsservern är online igen. Om du fortsätter att se den här varningen, kontrollera din konfiguration eller kontakta en serveradministratör.",
@@ -1237,7 +1237,7 @@
"Multiple integration managers": "Flera integrationshanterare",
"Show hidden events in timeline": "Visa dolda händelser i tidslinjen",
"Low bandwidth mode": "Läge för låg bandbredd",
- "Send read receipts for messages (requires compatible homeserver to disable)": "Skicka läskvitton för meddelanden (kräver kompatibel hemserver för att inaktivera)",
+ "Send read receipts for messages (requires compatible homeserver to disable)": "Skicka läsindikationer för meddelanden (kräver kompatibel hemserver för att inaktivera)",
"When rooms are upgraded": "När rum uppgraderas",
"Accept to continue:": "Acceptera för att fortsätta:",
"ID": "ID",
@@ -1304,7 +1304,7 @@
"Join the conversation with an account": "Gå med i konversationen med ett konto",
"Sign Up": "Registrera dig",
"Sign In": "Logga in",
- "Prompt before sending invites to potentially invalid matrix IDs": "Fråga innan inbjudningar skickas till potentiellt ogiltiga matrix-IDn",
+ "Prompt before sending invites to potentially invalid matrix IDs": "Fråga innan inbjudningar skickas till potentiellt ogiltiga Matrix-ID:n",
"Show all": "Visa alla",
"reacted with %(shortName)s": "reagerade med %(shortName)s",
"Edited at %(date)s. Click to view edits.": "Ändrad %(date)s. Klicka för att visa ändringar.",
@@ -1312,32 +1312,32 @@
"Sign in to your Matrix account on ": "Logga in med ditt Matrix-konto på ",
"Please install Chrome, Firefox, or Safari for the best experience.": "Installera Chrome, Firefox, eller Safari för den bästa upplevelsen.",
"Couldn't load page": "Det gick inte att ladda sidan",
- "Want more than a community? Get your own server": "Vill du ha mer än en community? Skaffa din egen server",
- "This homeserver does not support communities": "Denna hemserver stöder inte communityn",
+ "Want more than a community? Get your own server": "Vill du ha mer än en gemenskap? Skaffa din egen server",
+ "This homeserver does not support communities": "Denna hemserver stöder inte gemenskaper",
"Explore": "Utforska",
"Filter": "Filtrera",
"Filter rooms…": "Filtrera rum…",
"Please ask the administrator of your homeserver (%(homeserverDomain)s) to configure a TURN server in order for calls to work reliably.": "Be administratören för din hemserver (%(homeserverDomain)s) att konfigurera en TURN-server för att samtal ska fungera pålitligt.",
"Alternatively, you can try to use the public server at turn.matrix.org, but this will not be as reliable, and it will share your IP address with that server. You can also manage this in Settings.": "Alternativt kan du testa att använda den offentliga servern turn.matrix.org, men det är inte lika pålitligt och det kommer att dela din IP-adress med den servern. Du kan också hantera detta under Inställningar.",
"Warning: Upgrading a room will not automatically migrate room members to the new version of the room. We'll post a link to the new room in the old version of the room - room members will have to click this link to join the new room.": "Varning: Uppgradering av ett rum flyttar inte automatiskt rumsmedlemmar till den nya versionen av rummet. Vi lägger ut en länk till det nya rummet i den gamla versionen av rummet - rumsmedlemmar måste klicka på den här länken för att gå med i det nya rummet.",
- "Changes the avatar of the current room": "Ändrar avataren i det aktuella rummet",
- "Use an identity server to invite by email. Click continue to use the default identity server (%(defaultIdentityServerName)s) or manage in Settings.": "Använd en identitetsserver för att bjuda in via epost. Klicka på Fortsätt för att använda standardidentitetsservern (%(defaultIdentityServerName)s) eller hantera det i Inställningar.",
- "Use an identity server to invite by email. Manage in Settings.": "Använd en identitetsserver för att bjuda in via epost. Hantera det i inställningar.",
+ "Changes the avatar of the current room": "Ändrar avataren i detta rum",
+ "Use an identity server to invite by email. Click continue to use the default identity server (%(defaultIdentityServerName)s) or manage in Settings.": "Använd en identitetsserver för att bjuda in via e-post. Klicka på Fortsätt för att använda standardidentitetsservern (%(defaultIdentityServerName)s) eller hantera det i Inställningar.",
+ "Use an identity server to invite by email. Manage in Settings.": "Använd en identitetsserver för att bjuda in via e-post. Hantera det i inställningar.",
"Unexpected error resolving homeserver configuration": "Oväntat fel vid inläsning av hemserverkonfiguration",
"Unexpected error resolving identity server configuration": "Oväntat fel vid inläsning av identitetsserverkonfiguration",
- "Allow fallback call assist server turn.matrix.org when your homeserver does not offer one (your IP address would be shared during a call)": "Tillåt samtalsserver turn.matrix.org som reserv när din hemserver inte erbjuder en (din IP-adress delades under ett samtal)",
+ "Allow fallback call assist server turn.matrix.org when your homeserver does not offer one (your IP address would be shared during a call)": "Tillåt assistansservern turn.matrix.org för samtal som reserv när din hemserver inte erbjuder en (din IP-adress kommer delas under ett samtal)",
"Unable to load key backup status": "Det går inte att ladda status för nyckelsäkerhetskopiering",
"Restore from Backup": "Återställ från säkerhetskopiering",
"Backing up %(sessionsRemaining)s keys...": "Säkerhetskopierar %(sessionsRemaining)s nycklar...",
"All keys backed up": "Alla nycklar säkerhetskopierade",
"Add Email Address": "Lägg till e-postadress",
"Add Phone Number": "Lägg till telefonnummer",
- "Identity server has no terms of service": "Identitetsserver har inga användarvillkor",
- "This action requires accessing the default identity server to validate an email address or phone number, but the server does not have any terms of service.": "Den här åtgärden kräver åtkomst till standardidentitetsservern för att validera en e-postadress eller telefonnummer, men servern har inga användarvillkor.",
+ "Identity server has no terms of service": "Identitetsservern har inga användarvillkor",
+ "This action requires accessing the default identity server to validate an email address or phone number, but the server does not have any terms of service.": "Den här åtgärden kräver åtkomst till standardidentitetsservern för att validera en e-postadress eller ett telefonnummer, men servern har inga användarvillkor.",
"Trust": "Förtroende",
"%(name)s (%(userId)s)": "%(name)s (%(userId)s)",
- "Try out new ways to ignore people (experimental)": "Testa nya sätt att ignorera personer (experimentalt)",
- "Show previews/thumbnails for images": "Visa förhandsvisning/tumnagel för bilder",
+ "Try out new ways to ignore people (experimental)": "Testa nya sätt att ignorera personer (experimentellt)",
+ "Show previews/thumbnails for images": "Visa förhandsvisning/miniatyr för bilder",
"Custom (%(level)s)": "Anpassad (%(level)s)",
"Error upgrading room": "Fel vid uppgradering av rum",
"Double check that your server supports the room version chosen and try again.": "Dubbelkolla att din server stöder den valda rumsversionen och försök igen.",
@@ -1354,8 +1354,8 @@
"Connecting to integration manager...": "Ansluter till integrationshanterare...",
"Cannot connect to integration manager": "Det går inte att ansluta till integrationshanterare",
"The integration manager is offline or it cannot reach your homeserver.": "Integrationshanteraren är offline eller kan inte nå din hemserver.",
- "Use an Integration Manager (%(serverName)s) to manage bots, widgets, and sticker packs.": "Använd en Integrationshanterare (%(serverName)s) för att hantera bots, widgets och klistermärkespaket.",
- "Use an Integration Manager to manage bots, widgets, and sticker packs.": "Använd en Integrationshanterare för att hantera bots, widgets och klistermärkespaket.",
+ "Use an Integration Manager (%(serverName)s) to manage bots, widgets, and sticker packs.": "Använd en integrationshanterare (%(serverName)s) för att hantera bottar, widgets och dekalpaket.",
+ "Use an Integration Manager to manage bots, widgets, and sticker packs.": "Använd en integrationshanterare för att hantera bottar, widgets och dekalpaket.",
"Manage integrations": "Hantera integrationer",
"Integration Managers receive configuration data, and can modify widgets, send room invites, and set power levels on your behalf.": "Integrationshanterare får konfigurationsdata och kan ändra widgetar, skicka ruminbjudningar och ställa in behörighetsnivåer via ditt konto.",
"Close preview": "Stäng förhandsvisning",
@@ -1458,16 +1458,16 @@
"Your user agent": "Din användaragent",
"If you cancel now, you won't complete verifying the other user.": "Om du avbryter nu kommer du inte att verifiera den andra användaren.",
"If you cancel now, you won't complete verifying your other session.": "Om du avbryter nu kommer du inte att verifiera din andra session.",
- "Cancel entering passphrase?": "Avbryta att ange lösenfras?",
+ "Cancel entering passphrase?": "Avbryta inmatning av lösenfras?",
"Setting up keys": "Sätter upp nycklar",
"Verify this session": "Verifiera denna session",
"Encryption upgrade available": "Krypteringsuppgradering tillgänglig",
- "Set up encryption": "Ställ in kryptering",
+ "Set up encryption": "Sätt upp kryptering",
"Sign In or Create Account": "Logga in eller skapa konto",
"Use your account or create a new one to continue.": "Använd ditt konto eller skapa ett nytt för att fortsätta.",
"Create Account": "Skapa konto",
- "Verifies a user, session, and pubkey tuple": "Verifierar en användar-, session- och pubkey-tupel",
- "Unknown (user, session) pair:": "Okänt par (användare, session):",
+ "Verifies a user, session, and pubkey tuple": "Verifierar en användar-, sessions- och pubkey-tupel",
+ "Unknown (user, session) pair:": "Okänt (användare, session)-par:",
"Session already verified!": "Sessionen är redan verifierad!",
"WARNING: Session already verified, but keys do NOT MATCH!": "VARNING: Sessionen har redan verifierats, men nycklarna MATCHAR INTE!",
"Unable to revoke sharing for email address": "Det gick inte att återkalla delning för e-postadress",
@@ -1519,7 +1519,151 @@
"Page Down": "Page Down",
"Esc": "Esc",
"Enter": "Enter",
- "Space": "Space",
+ "Space": "Mellanslag",
"End": "End",
- "You have been logged out of all sessions and will no longer receive push notifications. To re-enable notifications, sign in again on each device.": "Du har blivit utloggad från alla dina sessioner och kommer inte längre att motta pushnotiser. För att återaktivera pushnotiser, logga in igen på varje enhet."
+ "You have been logged out of all sessions and will no longer receive push notifications. To re-enable notifications, sign in again on each device.": "Du har blivit utloggad från alla dina sessioner och kommer inte längre att motta pushnotiser. För att återaktivera pushnotiser, logga in igen på varje enhet.",
+ "Use Single Sign On to continue": "Använd single sign-on för att fortsätta",
+ "Confirm adding this email address by using Single Sign On to prove your identity.": "Bekräfta tilläggning av e-postadressen genom att använda single sign-on för att bevisa din identitet.",
+ "Single Sign On": "Single sign-on",
+ "Confirm adding email": "Bekräfta tilläggning av e-postadressen",
+ "Click the button below to confirm adding this email address.": "Klicka på knappen nedan för att bekräfta tilläggning av e-postadressen.",
+ "Confirm adding this phone number by using Single Sign On to prove your identity.": "Bekräfta tilläggning av telefonnumret genom att använda single sign-on för att bevisa din identitet.",
+ "Confirm adding phone number": "Bekräfta tilläggning av telefonnumret",
+ "Click the button below to confirm adding this phone number.": "Klicka på knappen nedan för att bekräfta tilläggning av telefonnumret.",
+ "Are you sure you want to cancel entering passphrase?": "Är du säker på att du vill avbryta inmatning av lösenfrasen?",
+ "Go Back": "Gå tillbaka",
+ "Room name or address": "Rummets namn eller adress",
+ "%(name)s is requesting verification": "%(name)s begär verifiering",
+ "Use your account to sign in to the latest version": "Använd ditt konto för att logga in till den senaste versionen",
+ "We’re excited to announce Riot is now Element": "Vi är glada att meddela att Riot är nu Element",
+ "Riot is now Element!": "Riot är nu Element!",
+ "Learn More": "Lär mer",
+ "Sends a message as html, without interpreting it as markdown": "Skicka ett meddelande som HTML, utan att tolka det som Markdown",
+ "Failed to set topic": "Misslyckades med att ställa in ämnet",
+ "Community Autocomplete": "Autokomplettering av gemenskaper",
+ "Joins room with given address": "Går med i rummet med den givna adressen",
+ "Unrecognised room address:": "Okänd rumsadress:",
+ "Command failed": "Kommandot misslyckades",
+ "Could not find user in room": "Kunde inte hitta användaren i rummet",
+ "Please supply a widget URL or embed code": "Ange en widget-URL eller inbäddningskod",
+ "WARNING: KEY VERIFICATION FAILED! The signing key for %(userId)s and session %(deviceId)s is \"%(fprint)s\" which does not match the provided key \"%(fingerprint)s\". This could mean your communications are being intercepted!": "VARNING: NYCKELVERIFIERING MISSLYCKADES! Den signerade nyckeln för %(userId)s och sessionen %(deviceId)s är \"%(fprint)s\" vilket inte matchar den givna nyckeln \"%(fingerprint)s\". Detta kan betyda att kommunikationen är övervakad!",
+ "The signing key you provided matches the signing key you received from %(userId)s's session %(deviceId)s. Session marked as verified.": "Signeringsnyckeln du gav matchar signeringsnyckeln du fick av %(userId)ss session %(deviceId)s. Sessionen markerades som verifierad.",
+ "Displays information about a user": "Visar information om en användare",
+ "Send a bug report with logs": "Skicka en buggrapport med loggar",
+ "Opens chat with the given user": "Öppnar en chatt med den valda användaren",
+ "Sends a message to the given user": "Skickar ett meddelande till den valda användaren",
+ "%(senderDisplayName)s changed the room name from %(oldRoomName)s to %(newRoomName)s.": "%(senderDisplayName)s bytte rummets namn från %(oldRoomName)s till %(newRoomName)s.",
+ "%(senderName)s added the alternative addresses %(addresses)s for this room.|other": "%(senderName)s lade till de alternativa adresserna %(addresses)s till det här rummet.",
+ "%(senderName)s added the alternative addresses %(addresses)s for this room.|one": "%(senderName)s lade till den alternativa adressen %(addresses)s till det här rummet.",
+ "%(senderName)s removed the alternative addresses %(addresses)s for this room.|other": "%(senderName)s tog bort de alternativa adresserna %(addresses)s från det här rummet.",
+ "%(senderName)s removed the alternative addresses %(addresses)s for this room.|one": "%(senderName)s tog bort den alternativa adressen %(addresses)s från det här rummet.",
+ "%(senderName)s changed the alternative addresses for this room.": "%(senderName)s ändrade de alternativa adresserna för det här rummet.",
+ "%(senderName)s changed the main and alternative addresses for this room.": "%(senderName)s ändrade huvudadressen och de alternativa adresserna för det här rummet.",
+ "%(senderName)s changed the addresses for this room.": "%(senderName)s ändrade adresserna för det här rummet.",
+ "%(senderName)s removed a ban rule matching %(glob)s": "%(senderName)s tog bort en bannregel som matchar %(glob)s",
+ "%(senderName)s updated an invalid ban rule": "%(senderName)s uppdaterade en ogiltig bannregel",
+ "%(senderName)s updated the rule banning users matching %(glob)s for %(reason)s": "%(senderName)s uppdaterade regeln som bannar användare som matchar %(glob)s på grund av %(reason)s",
+ "%(senderName)s updated the rule banning rooms matching %(glob)s for %(reason)s": "%(senderName)s uppdaterade regeln som bannar rum som matchar %(glob)s på grund av %(reason)s",
+ "%(senderName)s updated the rule banning servers matching %(glob)s for %(reason)s": "%(senderName)s uppdaterade regeln som bannar servrar som matchar %(glob)s på grund av %(reason)s",
+ "%(senderName)s updated a ban rule matching %(glob)s for %(reason)s": "%(senderName)s uppdaterade en bannregel som matchar %(glob)s på grund av %(reason)s",
+ "Use bots, bridges, widgets and sticker packs": "Använd bottar, bryggor, widgets och dekalpaket",
+ "%(senderName)s created a rule banning users matching %(glob)s for %(reason)s": "%(senderName)s skapade en regel som bannar användare som matchar %(glob)s på grund av %(reason)s",
+ "%(senderName)s created a rule banning rooms matching %(glob)s for %(reason)s": "%(senderName)s skapade en regel som bannar rum som matchar %(glob)s på grund av %(reason)s",
+ "%(senderName)s created a rule banning servers matching %(glob)s for %(reason)s": "%(senderName)s skapade en regel som bannar servrar som matchar %(glob)s på grund av %(reason)s",
+ "%(senderName)s created a ban rule matching %(glob)s for %(reason)s": "%(senderName)s skapade en bannregel som matchar %(glob)s på grund av %(reason)s",
+ "%(senderName)s changed a rule that was banning users matching %(oldGlob)s to matching %(newGlob)s for %(reason)s": "%(senderName)s ändrade en regel som bannade användare som matchade %(oldGlob)s till att matcha %(newGlob)s på grund av %(reason)s",
+ "%(senderName)s changed a rule that was banning rooms matching %(oldGlob)s to matching %(newGlob)s for %(reason)s": "%(senderName)s ändrade en regel som bannade rum som matchade %(oldGlob)s till att matcha %(newGlob)s på grund av %(reason)s",
+ "%(senderName)s changed a rule that was banning servers matching %(oldGlob)s to matching %(newGlob)s for %(reason)s": "%(senderName)s ändrade en regel som bannade servrar som matchade %(oldGlob)s till att matcha %(newGlob)s på grund av %(reason)s",
+ "%(senderName)s updated a ban rule that was matching %(oldGlob)s to matching %(newGlob)s for %(reason)s": "%(senderName)s uppdaterade en bannregel som matchade %(oldGlob)s till att matcha %(newGlob)s på grund av %(reason)s",
+ "Light": "Ljust",
+ "Dark": "Mörkt",
+ "You signed in to a new session without verifying it:": "Du loggade in i en ny session utan att verifiera den:",
+ "Verify your other session using one of the options below.": "Verifiera din andra session med ett av alternativen nedan.",
+ "%(name)s (%(userId)s) signed in to a new session without verifying it:": "%(name)s (%(userId)s) loggade in i en ny session utan att verifiera den:",
+ "Ask this user to verify their session, or manually verify it below.": "Be den här användaren att verifiera sin session, eller verifiera den manuellt nedan.",
+ "Not Trusted": "Inte betrodd",
+ "Manually Verify by Text": "Verifiera manuellt med text",
+ "Interactively verify by Emoji": "Verifiera interaktivt med emoji",
+ "Done": "Klar",
+ "a few seconds ago": "några sekunder sedan",
+ "about a minute ago": "cirka en minut sedan",
+ "%(num)s minutes ago": "%(num)s minuter sedan",
+ "about an hour ago": "cirka en timme sedan",
+ "%(num)s hours ago": "%(num)s timmar sedan",
+ "about a day ago": "cirka en dag sedan",
+ "%(num)s days ago": "%(num)s dagar sedan",
+ "a few seconds from now": "om några sekunder",
+ "about a minute from now": "om cirka en minut",
+ "%(num)s minutes from now": "om %(num)s minuter",
+ "about an hour from now": "om cirka en timme",
+ "%(num)s hours from now": "om %(num)s timmar",
+ "about a day from now": "om cirka en dag",
+ "%(num)s days from now": "om %(num)s dagar",
+ "Unexpected server error trying to leave the room": "Oväntat serverfel vid försök att lämna rummet",
+ "Error leaving room": "Fel när rummet lämnades",
+ "Help us improve %(brand)s": "Hjälp oss att förbättra %(brand)s",
+ "Send anonymous usage data which helps us improve %(brand)s. This will use a cookie.": "Skicka anonym användningsdata vilken hjälper oss att förbättra %(brand)s. Detta kommer att använda en kaka.",
+ "I want to help": "Jag vill hjälpa till",
+ "Review where you’re logged in": "Granska var du är inloggad",
+ "Verify all your sessions to ensure your account & messages are safe": "Verifiera alla dina sessioner för att försäkra att ditt konto och dina meddelanden är säkra",
+ "Review": "Granska",
+ "Later": "Senare",
+ "Your homeserver has exceeded its user limit.": "Din hemserver har överskridit sin användargräns.",
+ "Your homeserver has exceeded one of its resource limits.": "Din hemserver har överskridit en av sina resursgränser.",
+ "Contact your server admin.": "Kontakta din serveradministratör.",
+ "Ok": "OK",
+ "Set password": "Sätt lösenord",
+ "To return to your account in future you need to set a password": "För att komma tillbaka till ditt konto i framtiden behöver du sätta ett lösenord",
+ "Set up": "Sätt upp",
+ "Upgrade": "Uppgradera",
+ "Verify": "Verifiera",
+ "Verify yourself & others to keep your chats safe": "Verifiera dig själv och andra för att hålla dina chattar säkra",
+ "Other users may not trust it": "Andra användare kanske inta litar på den",
+ "New login. Was this you?": "Ny inloggning. Var det du?",
+ "Verify the new login accessing your account: %(name)s": "Verifiera den nya inloggningen på ditt konto: %(name)s",
+ "Restart": "Starta om",
+ "Upgrade your %(brand)s": "Uppgradera din %(brand)s",
+ "A new version of %(brand)s is available!": "En ny version av %(brand)s är tillgänglig!",
+ "The person who invited you already left the room.": "Personen som bjöd in dig har redan lämnat rummet.",
+ "The person who invited you already left the room, or their server is offline.": "Personen som bjöd in dig har redan lämnat rummet, eller så är deras server offline.",
+ "You joined the call": "Du gick med i samtalet",
+ "%(senderName)s joined the call": "%(senderName)s gick med i samtalet",
+ "Call in progress": "Samtal pågår",
+ "You left the call": "Du lämnade samtalet",
+ "%(senderName)s left the call": "%(senderName)s lämnade samtalet",
+ "Call ended": "Samtalet avslutades",
+ "You started a call": "Du startade ett samtal",
+ "%(senderName)s started a call": "%(senderName)s startade ett samtal",
+ "Waiting for answer": "Väntar på svar",
+ "%(senderName)s is calling": "%(senderName)s ringer",
+ "* %(senderName)s %(emote)s": "* %(senderName)s %(emote)s",
+ "%(senderName)s: %(message)s": "%(senderName)s: %(message)s",
+ "%(senderName)s: %(reaction)s": "%(senderName)s: %(reaction)s",
+ "%(senderName)s: %(stickerName)s": "%(senderName)s: %(stickerName)s",
+ "Change notification settings": "Ändra aviseringsinställningar",
+ "Communities v2 prototypes. Requires compatible homeserver. Highly experimental - use with caution.": "Gemenskap-v2-prototyper. Kräver kompatibel hemserver. Väldigt experimentellt - använd varsamt.",
+ "New spinner design": "Ny spinnerdesign",
+ "Support adding custom themes": "Stöd tilläggning av anpassade teman",
+ "Show message previews for reactions in DMs": "Visa meddelandeförhandsvisningar för reaktioner i DM:er",
+ "Show message previews for reactions in all rooms": "Visa meddelandeförhandsvisningar för reaktioner i alla rum",
+ "Enable advanced debugging for the room list": "Aktivera avancerad avbuggning för rumslistan",
+ "Show info about bridges in room settings": "Visa info om bryggor i rumsinställningar",
+ "Font size": "Teckenstorlek",
+ "Use custom size": "Använd anpassad storlek",
+ "Use a more compact ‘Modern’ layout": "Använd ett mer kompakt ‘modernt’ arrangemang",
+ "Show typing notifications": "Visa \"skriver\"-statusar",
+ "Use a system font": "Använd systemets teckensnitt",
+ "System font name": "Namn på systemets teckensnitt",
+ "Never send encrypted messages to unverified sessions from this session": "Skicka aldrig krypterade meddelanden till overifierade sessioner från den här sessionen",
+ "Never send encrypted messages to unverified sessions in this room from this session": "Skicka aldrig krypterade meddelanden till overifierade sessioner i det här rummet från den här sessionen",
+ "Order rooms by name": "Sortera rum efter namn",
+ "Show rooms with unread notifications first": "Visa rum med olästa aviseringar först",
+ "Show shortcuts to recently viewed rooms above the room list": "Visa genvägar till nyligen visade rum över rumslistan",
+ "Enable message search in encrypted rooms": "Aktivera meddelandesökning i krypterade rum",
+ "How fast should messages be downloaded.": "Hur snabbt ska meddelanden laddas ner.",
+ "Manually verify all remote sessions": "Verifiera alla fjärrsessioner manuellt",
+ "IRC display name width": "Bredd för IRC-visningsnamn",
+ "Enable experimental, compact IRC style layout": "Aktivera experimentellt kompakt IRC-likt arrangemang",
+ "Uploading logs": "Laddar upp loggar",
+ "Downloading logs": "Laddar ner loggar"
}
diff --git a/src/i18n/strings/tr.json b/src/i18n/strings/tr.json
index 48c051004a..5a152eeab6 100644
--- a/src/i18n/strings/tr.json
+++ b/src/i18n/strings/tr.json
@@ -223,7 +223,7 @@
"Submit": "Gönder",
"Success": "Başarılı",
"The phone number entered looks invalid": "Girilen telefon numarası geçersiz görünüyor",
- "This email address is already in use": "Bu eposta adresi zaten kullanımda",
+ "This email address is already in use": "Bu e-posta adresi zaten kullanımda",
"This email address was not found": "Bu e-posta adresi bulunamadı",
"The email address linked to your account must be entered.": "Hesabınıza bağlı e-posta adresi girilmelidir.",
"The remote side failed to pick up": "Uzak taraf toplanamadı(alınamadı)",
diff --git a/src/i18n/strings/uk.json b/src/i18n/strings/uk.json
index 2272ed49eb..4499d6d124 100644
--- a/src/i18n/strings/uk.json
+++ b/src/i18n/strings/uk.json
@@ -67,14 +67,14 @@
"Cannot add any more widgets": "Неможливо додати більше віджетів",
"Change Password": "Змінити пароль",
"%(senderName)s changed their profile picture.": "%(senderName)s змінив/ла зображення профілю.",
- "%(senderName)s changed the power level of %(powerLevelDiffText)s.": "%(senderName)s змінив(ла) рівень повноважень %(powerLevelDiffText)s.",
+ "%(senderName)s changed the power level of %(powerLevelDiffText)s.": "%(senderName)s змінив(-ла) рівень повноважень %(powerLevelDiffText)s.",
"%(senderDisplayName)s changed the room name to %(roomName)s.": "%(senderDisplayName)s змінив/ла назву кімнати на %(roomName)s.",
"%(senderDisplayName)s removed the room name.": "%(senderDisplayName)s видалив ім'я кімнати.",
"%(senderDisplayName)s changed the topic to \"%(topic)s\".": "%(senderDisplayName)s змінив тему на %(topic)s.",
"Email": "е-пошта",
"Email address": "Адреса е-пошти",
"Failed to send email": "Помилка відправки е-почти",
- "Edit": "Редагувати",
+ "Edit": "Відредагувати",
"Unpin Message": "Відкріпити повідомлення",
"Register": "Зареєструватися",
"Rooms": "Кімнати",
@@ -82,7 +82,7 @@
"This email address is already in use": "Ця е-пошта вже використовується",
"This phone number is already in use": "Цей телефонний номер вже використовується",
"Fetching third party location failed": "Не вдалось отримати стороннє місцеперебування",
- "Messages in one-to-one chats": "Повідомлення у чатах \"сам на сам\"",
+ "Messages in one-to-one chats": "Повідомлення у балачках віч-на-віч",
"Send Account Data": "Надіслати дані облікового запису",
"Advanced notification settings": "Додаткові налаштування сповіщень",
"Uploading report": "Завантаження звіту",
@@ -109,9 +109,9 @@
"Cancel Sending": "Скасувати надсилання",
"Warning": "Попередження",
"This Room": "Ця кімната",
- "Noisy": "Шумний",
+ "Noisy": "Шумно",
"Error saving email notification preferences": "Помилка при збереженні параметрів сповіщень е-поштою",
- "Messages containing my display name": "Повідомлення, вміщає моє ім'я",
+ "Messages containing my display name": "Повідомлення, що містять моє видиме ім'я",
"Remember, you can always set an email address in user settings if you change your mind.": "Пам'ятайте, що ви завжди можете встановити адресу е-пошти у користувацьких налаштуваннях, якщо передумаєте.",
"Unavailable": "Нема в наявності",
"View Decrypted Source": "Переглянути розшифроване джерело",
@@ -124,7 +124,7 @@
"Explore Room State": "Перегляд статуса кімнати",
"Source URL": "Джерельне посилання",
"Messages sent by bot": "Повідомлення, надіслані ботом",
- "Filter results": "Фільтр результатів",
+ "Filter results": "Відцідити результати",
"Members": "Учасники",
"No update available.": "Оновлення відсутні.",
"Resend": "Перенадіслати",
@@ -163,7 +163,7 @@
"All Rooms": "Усі кімнати",
"Wednesday": "Середа",
"You cannot delete this message. (%(code)s)": "Ви не можете видалити це повідомлення. (%(code)s)",
- "Quote": "Цитувати",
+ "Quote": "Процитувати",
"Send": "Надіслати",
"Send logs": "Надіслати журнали",
"All messages": "Усі повідомлення",
@@ -184,11 +184,11 @@
"Logs sent": "Журнали надіслані",
"Back": "Назад",
"Reply": "Відповісти",
- "Show message in desktop notification": "Показати повідомлення в сповіщення на робочому столі",
+ "Show message in desktop notification": "Показувати повідомлення у стільничних сповіщеннях",
"Unable to join network": "Неможливо приєднатись до мережі",
"Sorry, your browser is not able to run %(brand)s.": "Вибачте, ваш оглядач не спроможний запустити %(brand)s.",
"Uploaded on %(date)s by %(user)s": "Завантажено %(date)s користувачем %(user)s",
- "Messages in group chats": "Повідомлення у групових чатах",
+ "Messages in group chats": "Повідомлення у групових балачках",
"Yesterday": "Вчора",
"Error encountered (%(errorDetail)s).": "Трапилась помилка (%(errorDetail)s).",
"Low Priority": "Неважливі",
@@ -201,7 +201,7 @@
"You can now return to your account after signing out, and sign in on other devices.": "Тепер ви можете повернутися до свого облікового запису після виходу з нього, а також зайти з інших пристроїв.",
"Enable email notifications": "Увімкнути сповіщення е-поштою",
"Event Type": "Тип західу",
- "No rooms to show": "Кімнати відсутні",
+ "No rooms to show": "Відсутні кімнати для показу",
"Download this file": "Звантажити цей файл",
"Pin Message": "Прикріпити повідомлення",
"Failed to change settings": "Не вдалось змінити налаштування",
@@ -298,7 +298,7 @@
"Missing roomId.": "Бракує ідентифікатора кімнати.",
"Failed to send request.": "Не вдалося надіслати запит.",
"This room is not recognised.": "Кімнату не знайдено.",
- "Power level must be positive integer.": "Рівень повноважень мусить бути додатнім цілим числом.",
+ "Power level must be positive integer.": "Рівень повноважень мусить бути додатним цілим числом.",
"You are not in this room.": "Вас немає в цій кімнаті.",
"You do not have permission to do that in this room.": "У вас немає прав виконувати для цього в цій кімнаті.",
"Missing room_id in request": "У запиті бракує room_id",
@@ -326,9 +326,9 @@
"Reason": "Причина",
"%(senderName)s requested a VoIP conference.": "%(senderName)s бажає розпочати дзвінок-конференцію.",
"%(senderName)s invited %(targetName)s.": "%(senderName)s запросив/ла %(targetName)s.",
- "%(oldDisplayName)s changed their display name to %(displayName)s.": "%(oldDisplayName)s змінив/ла своє видиме ім'я на %(displayName)s.",
- "%(senderName)s set their display name to %(displayName)s.": "%(senderName)s вказав/ла своє видиме ім'я: %(displayName)s.",
- "%(senderName)s removed their display name (%(oldDisplayName)s).": "%(senderName)s ліквідував/ла своє видиме ім'я (%(oldDisplayName)s).",
+ "%(oldDisplayName)s changed their display name to %(displayName)s.": "%(oldDisplayName)s змінив(-ла) своє видиме ім'я на %(displayName)s.",
+ "%(senderName)s set their display name to %(displayName)s.": "%(senderName)s зазначив(-ла) своє видиме ім'я: %(displayName)s.",
+ "%(senderName)s removed their display name (%(oldDisplayName)s).": "%(senderName)s видалив(-ла) своє видиме ім'я (%(oldDisplayName)s).",
"%(senderName)s removed their profile picture.": "%(senderName)s вилучав/ла свою світлину профілю.",
"%(senderName)s set a profile picture.": "%(senderName)s встановив/ла світлину профілю.",
"VoIP conference started.": "Розпочато дзвінок-конференцію.",
@@ -348,19 +348,19 @@
"(no answer)": "(немає відповіді)",
"(unknown failure: %(reason)s)": "(невідома помилка: %(reason)s)",
"%(senderName)s ended the call.": "%(senderName)s завершив/ла дзвінок.",
- "%(senderName)s sent an invitation to %(targetDisplayName)s to join the room.": "%(senderName)s надіслав/ла запрошення %(targetDisplayName)s приєднатися до кімнати.",
- "Show developer tools": "Показати інструменти розробки",
+ "%(senderName)s sent an invitation to %(targetDisplayName)s to join the room.": "%(senderName)s надіслав(-ла) запрошення %(targetDisplayName)s приєднатися до кімнати.",
+ "Show developer tools": "Показувати розробницькі засоби",
"Default": "Типово",
- "%(senderName)s made future room history visible to all room members, from the point they are invited.": "%(senderName)s зробив/ла майбутню історію кімнати видимою для всіх учасників, з моменту, коли вони приєдналися.",
- "%(senderName)s made future room history visible to all room members, from the point they joined.": "%(senderName)s зробив/ла майбутню історію кімнати видимою для всіх учасників, з моменту, коли вони приєдналися.",
- "%(senderName)s made future room history visible to all room members.": "%(senderName)s зробив/ла майбутню історію видимою для всіх учасників кімнати.",
- "%(senderName)s made future room history visible to anyone.": "%(senderName)s зробив/ла майбутню історію кімнати видимою для всіх.",
- "%(senderName)s made future room history visible to unknown (%(visibility)s).": "%(senderName)s зробив/ла майбутню історію видимою невідомим (%(visibility)s).",
+ "%(senderName)s made future room history visible to all room members, from the point they are invited.": "%(senderName)s зробив(-ла) майбутню історію кімнати видимою для всіх учасників з моменту, коли вони приєдналися.",
+ "%(senderName)s made future room history visible to all room members, from the point they joined.": "%(senderName)s зробив(-ла) майбутню історію кімнати видимою для всіх учасників з моменту, коли вони приєдналися.",
+ "%(senderName)s made future room history visible to all room members.": "%(senderName)s зробив(-ла) майбутню історію видимою для всіх учасників кімнати.",
+ "%(senderName)s made future room history visible to anyone.": "%(senderName)s зробив(-ла) майбутню історію кімнати видимою для всіх.",
+ "%(senderName)s made future room history visible to unknown (%(visibility)s).": "%(senderName)s зробив(-ла) майбутню історію видимою для невідомого значення (%(visibility)s).",
"%(userId)s from %(fromPowerLevel)s to %(toPowerLevel)s": "%(userId)s з %(fromPowerLevel)s до %(toPowerLevel)s",
- "%(senderName)s changed the pinned messages for the room.": "%(senderName)s змінив/ла прикріплені повідомлення для кімнати.",
- "%(widgetName)s widget modified by %(senderName)s": "%(senderName)s змінив/ла %(widgetName)s",
- "%(widgetName)s widget added by %(senderName)s": "%(senderName)s додав/ла %(widgetName)s",
- "%(widgetName)s widget removed by %(senderName)s": "%(senderName)s вилучив/ла %(widgetName)s",
+ "%(senderName)s changed the pinned messages for the room.": "%(senderName)s змінив(-ла) приколоті повідомлення у кімнаті.",
+ "%(widgetName)s widget modified by %(senderName)s": "%(senderName)s змінив(-ла) знадіб %(widgetName)s",
+ "%(widgetName)s widget added by %(senderName)s": "%(senderName)s додав(-ла) знадіб %(widgetName)s",
+ "%(widgetName)s widget removed by %(senderName)s": "%(senderName)s вилучив(-ла) знадіб %(widgetName)s",
"Failure to create room": "Не вдалося створити кімнату",
"Server may be unavailable, overloaded, or you hit a bug.": "Сервер може бути недоступний, перевантажений, або ж ви натрапили на ваду.",
"Unnamed Room": "Кімната без назви",
@@ -375,10 +375,10 @@
"Please contact your homeserver administrator.": "Будь ласка, зв'яжіться з адміністратором вашого домашнього сервера.",
"Failed to join room": "Не вдалося приєднатися до кімнати",
"Message Pinning": "Закріплені повідомлення",
- "Show timestamps in 12 hour format (e.g. 2:30pm)": "Показувати час у 12-годинному форматі (напр. 2:30 pm)",
+ "Show timestamps in 12 hour format (e.g. 2:30pm)": "Показувати час у 12-годинному форматі (напр. 2:30 пп)",
"Always show encryption icons": "Завжди показувати значки шифрування",
"Enable automatic language detection for syntax highlighting": "Показувати автоматичне визначення мови для підсвічування синтаксису",
- "Automatically replace plain text Emoji": "Автоматично замінювати емоційки в простому тексті",
+ "Automatically replace plain text Emoji": "Автоматично замінювати простотекстові емодзі",
"Mirror local video feed": "Показувати локальне відео віддзеркалено",
"Send analytics data": "Надсилати дані аналітики",
"Enable inline URL previews by default": "Увімкнути вбудований перегляд гіперпосилань за умовчанням",
@@ -394,7 +394,7 @@
"Phone": "Телефон",
"Failed to upload profile picture!": "Не вдалося відвантажити світлину профілю!",
"Upload new:": "Відвантажити нову:",
- "No display name": "Немає імені для показу",
+ "No display name": "Немає видимого імені",
"New passwords don't match": "Нові паролі не збігаються",
"Passwords can't be empty": "Пароль не може бути пустим",
"Export E2E room keys": "Експортувати ключі наскрізного шифрування кімнат",
@@ -404,7 +404,7 @@
"New Password": "Новий пароль",
"Confirm password": "Підтвердження пароля",
"Last seen": "Востаннє в мережі",
- "Failed to set display name": "Не вдалося встановити ім'я для показу",
+ "Failed to set display name": "Не вдалося зазначити видиме ім'я",
"The maximum permitted number of widgets have already been added to this room.": "Максимально дозволену кількість віджетів уже додано до цієї кімнати.",
"Drop File Here": "Киньте файл сюди",
"Drop file here to upload": "Киньте файл сюди, щоб відвантажити",
@@ -415,7 +415,7 @@
"%(senderName)s sent an image": "%(senderName)s надіслав/ла зображення",
"%(senderName)s sent a video": "%(senderName)s надіслав/ла відео",
"%(senderName)s uploaded a file": "%(senderName)s надіслав/ла файл",
- "Options": "Налаштування",
+ "Options": "Параметри",
"Key request sent.": "Запит ключа надіслано.",
"Please select the destination room for this message": "Будь ласка, виберіть кімнату, куди потрібно надіслати це повідомлення",
"Disinvite": "Скасувати запрошення",
@@ -494,7 +494,7 @@
"Your homeserver doesn't seem to support this feature.": "Схоже, що ваш домашній сервер не підтримує цю властивість.",
"Sign out and remove encryption keys?": "Вийти та видалити ключі шифрування?",
"Clear Storage and Sign Out": "Очистити сховище та вийти",
- "Clearing your browser's storage may fix the problem, but will sign you out and cause any encrypted chat history to become unreadable.": "Очищення сховища вашого оглядача може усунути проблему, але воно виведе вас з системи і зробить непрочитною історію ваших зашифрованих листувань.",
+ "Clearing your browser's storage may fix the problem, but will sign you out and cause any encrypted chat history to become unreadable.": "Очищення сховища вашого переглядача може усунути проблему, але воно виведе вас з системи та зробить непрочитною історію ваших зашифрованих листувань.",
"Verification Pending": "Очікується перевірка",
"Upload files (%(current)s of %(total)s)": "Відвантажити файли (%(current)s з %(total)s)",
"Upload files": "Відвантажити файли",
@@ -530,7 +530,7 @@
"Click the button below to confirm adding this email address.": "Клацніть на кнопці нижче щоб підтвердити додавання цієї адреси е-пошти.",
"Confirm": "Підтвердити",
"Confirm adding this phone number by using Single Sign On to prove your identity.": "Підтвердьте додавання цього телефонного номера через використання Single Sign On аби довести вашу ідентичність.",
- "Confirm adding phone number": "Підтвердити додавання телефонного номера",
+ "Confirm adding phone number": "Підтвердьте додавання телефонного номера",
"Click the button below to confirm adding this phone number.": "Клацніть на кнопці нижче щоб підтвердити додавання цього телефонного номера.",
"Whether you're using %(brand)s on a device where touch is the primary input mechanism": "Чи використовуєте ви %(brand)s на пристрої, де основним засобом вводження є дотик",
"Whether you're using %(brand)s as an installed Progressive Web App": "Чи використовуєте ви %(brand)s як встановлений Progressive Web App",
@@ -556,9 +556,9 @@
"Decline (%(counter)s)": "Відхилити (%(counter)s)",
"Language and region": "Мова та регіон",
"Account management": "Керування обліковим записом",
- "Deactivating your account is a permanent action - be careful!": "Деактивація вашого облікового запису є безповоротною дією — будьте обережні!",
- "Deactivate Account": "Деактивувати обліковий запис",
- "Deactivate account": "Знедіяти обліківку",
+ "Deactivating your account is a permanent action - be careful!": "Знедіяння вашого облікового запису є безповоротним — будьте обережні!",
+ "Deactivate Account": "Знедіяти обліковий запис",
+ "Deactivate account": "Знедіяти обліковий запис",
"Legal": "Правова інформація",
"Credits": "Подяки",
"For help with using %(brand)s, click here.": "Якщо необхідна допомога у користуванні %(brand)s'ом, клацніть тут.",
@@ -572,7 +572,7 @@
"Clear notifications": "Очистити сповіщення",
"Add an email address to configure email notifications": "Додати адресу е-пошти для налаштування поштових сповіщень",
"Theme added!": "Тему додано!",
- "Email addresses": "Адреса е-пошти",
+ "Email addresses": "Адреси е-пошти",
"Phone numbers": "Номери телефонів",
"Set a new account password...": "Встановити новий пароль облікового запису…",
"Forget this room": "Забути цю кімнату",
@@ -582,7 +582,7 @@
"This invite to %(roomName)s was sent to %(email)s": "Це запрошення до %(roomName)s було надіслане на %(email)s",
"Use an identity server in Settings to receive invites directly in %(brand)s.": "Використовувати сервер ідентифікації у Налаштуваннях щоб отримувати запрошення прямо у %(brand)s.",
"Are you sure you want to deactivate your account? This is irreversible.": "Ви впевнені у тому, що бажаєте знедіяти ваш обліковий запис? Ця дія безповоротна.",
- "Confirm account deactivation": "Підтвердьте деактивацію облікового запису",
+ "Confirm account deactivation": "Підтвердьте знедіювання облікового запису",
"To continue, please enter your password:": "Щоб продовжити, введіть, будь ласка, ваш пароль:",
"This will make your account permanently unusable. You will not be able to log in, and no one will be able to re-register the same user ID. This will cause your account to leave all rooms it is participating in, and it will remove your account details from your identity server. This action is irreversible.": "Ваш обліковий запис стане назавжди невикористовним. Ви не матимете змоги увійти в нього і ніхто не зможе перереєструватись під цим користувацьким ID. Це призведе до виходу вашого облікового запису з усіх кімнат та до видалення деталей вашого облікового запису з вашого серверу ідентифікації. Ця дія є безповоротною.",
"Verify session": "Звірити сесію",
@@ -630,10 +630,10 @@
"Please enter verification code sent via text.": "Будь ласка, введіть звірювальний код, відправлений у текстовому повідомленні.",
"A text message has been sent to +%(msisdn)s. Please enter the verification code it contains.": "Текстове повідомлення було відправлено на номер +%(msisdn)s. Будь ласка, введіть звірювальний код, який воно містить.",
"Messages in this room are secured with end-to-end encryption. Only you and the recipient(s) have the keys to read these messages.": "Повідомлення у цій кімнаті захищені наскрізним шифруванням. Тільки ви та одержувачі мають ключі для прочитання цих повідомлень.",
- "Messages in this room are end-to-end encrypted.": "Повідомлення у цій кімнаті захищені наскрізним шифруванням.",
- "Messages in this room are not end-to-end encrypted.": "Повідомлення у цій кімнаті не захищені наскрізним шифруванням.",
+ "Messages in this room are end-to-end encrypted.": "Повідомлення у цій кімнаті наскрізно зашифровані.",
+ "Messages in this room are not end-to-end encrypted.": "Повідомлення у цій кімнаті не є наскрізно зашифрованими.",
"Encryption enabled": "Шифрування увімкнено",
- "Messages in this room are end-to-end encrypted. Learn more & verify this user in their user profile.": "Повідомлення у цій кімнаті захищені наскрізним шифруванням. Дізнайтеся більше та звіртеся з цим користувачем через його профіль.",
+ "Messages in this room are end-to-end encrypted. Learn more & verify this user in their user profile.": "Повідомлення у цій кімнаті наскрізно зашифровані. Дізнайтеся більше та звіртеся з цим користувачем через його профіль.",
"You sent a verification request": "Ви відправили звірювальний запит",
"Direct Messages": "Особисті повідомлення",
"Room Settings - %(roomName)s": "Налаштування кімнати - %(roomName)s",
@@ -680,18 +680,18 @@
"%(senderName)s placed a video call.": "%(senderName)s розпочав(-ла) відеовиклик.",
"%(senderName)s placed a video call. (not supported by this browser)": "%(senderName)s розпочав(-ла) відеовиклик. (не підтримується цим переглядачем)",
"%(senderName)s revoked the invitation for %(targetDisplayName)s to join the room.": "%(senderName)s відкликав(-ла) запрошення %(targetDisplayName)s приєднання до кімнати.",
- "%(senderName)s removed the rule banning users matching %(glob)s": "%(senderName)s видалив(ла) правило блокування користувачів по шаблону %(glob)s",
- "%(senderName)s removed the rule banning rooms matching %(glob)s": "%(senderName)s видалив(ла) правило блокування кімнат по шаблону %(glob)s",
- "%(senderName)s removed the rule banning servers matching %(glob)s": "%(senderName)s видалив(ла) правило блокування серверів по шаблону %(glob)s",
- "%(senderName)s removed a ban rule matching %(glob)s": "%(senderName)s видалив(ла) правило блокування по шаблону %(glob)s",
- "%(senderName)s updated an invalid ban rule": "%(senderName)s оновив(ла) неправильне правило блокування",
- "%(senderName)s updated the rule banning users matching %(glob)s for %(reason)s": "%(senderName)s оновив(ла) правило блокування користувачів по шаблону %(glob)s за %(reason)s",
- "%(senderName)s updated the rule banning rooms matching %(glob)s for %(reason)s": "%(senderName)s оновив(ла) правило блокування кімнат по шаблону %(glob)s за %(reason)s",
- "%(senderName)s updated the rule banning servers matching %(glob)s for %(reason)s": "%(senderName)s оновив(ла) правило блокування серверів по шаблону %(glob)s за %(reason)s",
- "%(senderName)s updated a ban rule matching %(glob)s for %(reason)s": "%(senderName)s оновив(ла) правило блокування по шаблону %(glob)s за %(reason)s",
- "%(senderName)s created a rule banning users matching %(glob)s for %(reason)s": "%(senderName)s створив(ла) правило блокування користувачів по шаблону %(glob)s за %(reason)s",
- "%(senderName)s created a rule banning rooms matching %(glob)s for %(reason)s": "%(senderName)s створив(ла) правило блокування кімнат по шаблону %(glob)s за %(reason)s",
- "%(senderName)s created a rule banning servers matching %(glob)s for %(reason)s": "%(senderName)s створив(ла) правило блокування серверів по шаблону %(glob)s за %(reason)s",
+ "%(senderName)s removed the rule banning users matching %(glob)s": "%(senderName)s видалив(-ла) правило блокування користувачів зі збігом з %(glob)s",
+ "%(senderName)s removed the rule banning rooms matching %(glob)s": "%(senderName)s видалив(-ла) правило блокування кімнат зі збігом з %(glob)s",
+ "%(senderName)s removed the rule banning servers matching %(glob)s": "%(senderName)s видалив(-ла) правило блокування серверів зі збігом з %(glob)s",
+ "%(senderName)s removed a ban rule matching %(glob)s": "%(senderName)s видалив(-ла) правило блокування зі збігом з %(glob)s",
+ "%(senderName)s updated an invalid ban rule": "%(senderName)s оновив(-ла) хибне правило блокування",
+ "%(senderName)s updated the rule banning users matching %(glob)s for %(reason)s": "%(senderName)s оновив(-ла) правило блокування користувачів зі збігом з %(glob)s через %(reason)s",
+ "%(senderName)s updated the rule banning rooms matching %(glob)s for %(reason)s": "%(senderName)s оновив(-ла) правило блокування кімнат зі збігом з %(glob)s через %(reason)s",
+ "%(senderName)s updated the rule banning servers matching %(glob)s for %(reason)s": "%(senderName)s оновив(-ла) правило блокування серверів зі збігом з %(glob)s через %(reason)s",
+ "%(senderName)s updated a ban rule matching %(glob)s for %(reason)s": "%(senderName)s оновив(-ла) правило блокування зі збігом з %(glob)s через %(reason)s",
+ "%(senderName)s created a rule banning users matching %(glob)s for %(reason)s": "%(senderName)s створив(-ла) правило блокування користувачів зі збігом з %(glob)s через %(reason)s",
+ "%(senderName)s created a rule banning rooms matching %(glob)s for %(reason)s": "%(senderName)s створив(-ла) правило блокування кімнат зі збігом з %(glob)s через %(reason)s",
+ "%(senderName)s created a rule banning servers matching %(glob)s for %(reason)s": "%(senderName)s створив(-ла) правило блокування серверів зі збігом з %(glob)s через %(reason)s",
"Light": "Світла",
"Dark": "Темна",
"You signed in to a new session without verifying it:": "Ви увійшли в нову сесію, не підтвердивши її:",
@@ -700,12 +700,12 @@
"Ask this user to verify their session, or manually verify it below.": "Попросіть цього користувача підтвердити сесію, або підтвердіть її власноруч нижче.",
"Not Trusted": "Недовірене",
"Manually Verify by Text": "Ручна перевірка за допомогою тексту",
- "Interactively verify by Emoji": "Інтерактивна перевірка з емодзі",
+ "Interactively verify by Emoji": "Інтерактивно звірити за допомогою емодзі",
"Done": "Зроблено",
- "%(displayName)s is typing …": "%(displayName)s друкує…",
- "%(names)s and %(count)s others are typing …|other": "%(names)s та %(count)s інших друкують…",
- "%(names)s and %(count)s others are typing …|one": "%(names)s та ще один(на) друкують…",
- "%(names)s and %(lastPerson)s are typing …": "%(names)s та %(lastPerson)s друкують…",
+ "%(displayName)s is typing …": "%(displayName)s пише…",
+ "%(names)s and %(count)s others are typing …|other": "%(names)s та ще %(count)s учасників пишуть…",
+ "%(names)s and %(count)s others are typing …|one": "%(names)s та ще один учасник пишуть…",
+ "%(names)s and %(lastPerson)s are typing …": "%(names)s та %(lastPerson)s пишуть…",
"Ask your %(brand)s admin to check your config for incorrect or duplicate entries.": "Попросіть адміністратора %(brand)s перевірити конфігураційний файл на наявність неправильних або повторюваних записів.",
"Cannot reach identity server": "Не вдається зв'язатися із сервером ідентифікаціїї",
"No homeserver URL provided": "URL адресу домашнього сервера не вказано",
@@ -782,7 +782,7 @@
"You joined the call": "Ви приєднались до дзвінку",
"%(senderName)s joined the call": "%(senderName)s приєднався(лась) до дзвінку",
"Call in progress": "Дзвінок у процесі",
- "You left the call": "Ви покинули дзвінок",
+ "You left the call": "Ви припинили розмову",
"%(senderName)s left the call": "%(senderName)s покинув(ла) дзвінок",
"Call ended": "Дзвінок завершено",
"You started a call": "Ви почали дзвінок",
@@ -794,7 +794,7 @@
"%(senderName)s: %(reaction)s": "%(senderName)s: %(reaction)s",
"%(senderName)s: %(stickerName)s": "%(senderName)s: %(stickerName)s",
"Custom user status messages": "користувацький статус",
- "Group & filter rooms by custom tags (refresh to apply changes)": "Групувати та фільтрувати кімнати за кастомними тегами (оновіть для застосування змін)",
+ "Group & filter rooms by custom tags (refresh to apply changes)": "Групувати та проціджувати кімнати за нетиповими наличками (оновіть щоб застосувати зміни)",
"Multiple integration managers": "Декілька менджерів інтеграції",
"Try out new ways to ignore people (experimental)": "Спробуйте нові способи ігнорувати людей (експериментальні)",
"Support adding custom themes": "Підтримка користувацьких тем",
@@ -802,17 +802,17 @@
"Show info about bridges in room settings": "Показувати інформацію про мости в налаштуваннях кімнати",
"Font size": "Розмір шрифту",
"Use custom size": "Використовувати нетиповий розмір",
- "Enable Emoji suggestions while typing": "Увімкнути пропонування смайлів при друкуванні",
+ "Enable Emoji suggestions while typing": "Увімкнути пропонування емодзі при друкуванні",
"Use a more compact ‘Modern’ layout": "Використовувати компактнішу \"Сучасну\" тему",
"General": "Загальні",
- "Discovery": "Відкриття",
+ "Discovery": "Виявлення",
"Help & About": "Допомога та про програму",
- "Bug reporting": "Повідомити про помилку",
- "If you've submitted a bug via GitHub, debug logs can help us track down the problem. Debug logs contain application usage data including your username, the IDs or aliases of the rooms or groups you have visited and the usernames of other users. They do not contain messages.": "Якщо ви відправляли помилки через GitHub, журнали можуть допомогти нам виявити проблеми. Журнали відладки, що містять інформацію про використані додатки, включають ваше ім’я користувача, ідентифікатори або псевдоніми кімнат або груп, які ви відвідували, а також імена інших користувачів. Вони не містять повідомлень.",
- "Submit debug logs": "Відправити відладочні журнали (debug logs)",
+ "Bug reporting": "Звітування про вади",
+ "If you've submitted a bug via GitHub, debug logs can help us track down the problem. Debug logs contain application usage data including your username, the IDs or aliases of the rooms or groups you have visited and the usernames of other users. They do not contain messages.": "Якщо ви подали ваду через GitHub, журнали зневадження можуть допомогти нам відстежити проблему. Журнали зневадження містять дані використання застосунку, включно з вашим користувацьким ім’ям, ідентифікаторами або псевдонімами відвіданих вами кімнат або груп, а також іменами інших користувачів. Вони не містять повідомлень.",
+ "Submit debug logs": "Надіслати журнал зневадження",
"Clear cache and reload": "Очистити кеш та перезавантажити",
"To report a Matrix-related security issue, please read the Matrix.org Security Disclosure Policy.": "Щоб повідомити про проблеми безпеки Matrix, будь ласка, прочитайте Політику розкриття інформації Matrix.org.",
- "FAQ": "Часті питання",
+ "FAQ": "ЧаПи",
"Keyboard Shortcuts": "Гарячі клавіші",
"Versions": "Версії",
"%(brand)s version:": "версія %(brand)s:",
@@ -850,8 +850,8 @@
"Room ID or address of ban list": "Ідентифікатор номера або адреса бан-лісту",
"Subscribe": "Підписатись",
"Start automatically after system login": "Автозапуск при вході в систему",
- "Always show the window menu bar": "Завжди показуввати рядок меню",
- "Show tray icon and minimize window to it on close": "Показати іконку в панелі завдань та згорнути вікно при закритті",
+ "Always show the window menu bar": "Завжди показувати рядок меню",
+ "Show tray icon and minimize window to it on close": "Показувати піктограму у лотку та згортати вікно при закритті",
"Preferences": "Параметри",
"Room list": "Перелік кімнат",
"Composer": "Редактор",
@@ -889,9 +889,9 @@
"User menu": "Користувацьке меню",
"If you don't want to set this up now, you can later in Settings.": "Якщо ви не бажаєте налаштовувати це зараз, ви можете зробити це пізніше у налаштуваннях.",
"Go to Settings": "Перейти до налаштувань",
- "Compare unique emoji": "Порівняйте унікальні смайлики",
+ "Compare unique emoji": "Порівняйте унікальні емодзі",
"Cancelling…": "Скасування…",
- "Dog": "Собака",
+ "Dog": "Пес",
"Cat": "Кіт",
"Lion": "Лев",
"Horse": "Кінь",
@@ -899,7 +899,7 @@
"Elephant": "Слон",
"Rabbit": "Кріль",
"Panda": "Панда",
- "Rooster": "Півень",
+ "Rooster": "Когут",
"Penguin": "Пінгвін",
"Turtle": "Черепаха",
"Fish": "Риба",
@@ -913,16 +913,16 @@
"Corn": "Кукурудза",
"Pizza": "Піца",
"Heart": "Серце",
- "Smiley": "Смайлик",
+ "Smiley": "Посмішка",
"Robot": "Робот",
"Hat": "Капелюх",
"Glasses": "Окуляри",
"Spanner": "Гайковий ключ",
"Thumbs up": "Великий палець вгору",
- "Umbrella": "Парасоля",
+ "Umbrella": "Парасолька",
"Hourglass": "Пісковий годинник",
"Clock": "Годинник",
- "Light bulb": "Лампа",
+ "Light bulb": "Лампочка",
"Book": "Книга",
"Pencil": "Олівець",
"Paperclip": "Спиначка",
@@ -935,7 +935,7 @@
"Bicycle": "Велоcипед",
"Aeroplane": "Літак",
"Rocket": "Ракета",
- "Trophy": "Трофей",
+ "Trophy": "Приз",
"Ball": "М'яч",
"Guitar": "Гітара",
"Trumpet": "Труба",
@@ -946,7 +946,7 @@
"Pin": "Кнопка",
"Accept to continue:": "Прийміть для продовження:",
"Flower": "Квітка",
- "Unicorn": "Одноріг",
+ "Unicorn": "Єдиноріг",
"Butterfly": "Метелик",
"Cake": "Пиріг",
"Tree": "Дерево",
@@ -957,9 +957,9 @@
"This bridge is managed by .": "Цей міст керується .",
"Workspace: %(networkName)s": "Робочий простір: %(networkName)s",
"Channel: %(channelName)s": "Канал: %(channelName)s",
- "Show less": "Показати менше",
- "Show more": "Показати більше",
- "Changing password will currently reset any end-to-end encryption keys on all sessions, making encrypted chat history unreadable, unless you first export your room keys and re-import them afterwards. In future this will be improved.": "Якщо ви не експортуєте ключі для цієї комнати і не імпортуєте їх у майбутньому, зміна пароля приведе до скидання всіх ключів наскрізного шифрування і зробить неможилвимим читання історії чату. У майбутньому це буде вдосконалено.",
+ "Show less": "Згорнути",
+ "Show more": "Розгорнути",
+ "Changing password will currently reset any end-to-end encryption keys on all sessions, making encrypted chat history unreadable, unless you first export your room keys and re-import them afterwards. In future this will be improved.": "Змінення пароля призведе до скидання всіх ключів наскрізного шифрування та унеможливить читання історії листування, якщо тільки ви не експортуєте ваші ключі кімнати та не імпортуєте їх згодом. Це буде вдосконалено у майбутньому.",
"Santa": "Санта Клаус",
"Gift": "Подарунок",
"Lock": "Замок",
@@ -992,7 +992,7 @@
"Backup version: ": "Версія резервної копії: ",
"Algorithm: ": "Алгоритм: ",
"Backup key stored: ": "Резервна копія ключа збережена ",
- "Enable audible notifications for this session": "Ввімкнути звукові сповіщення для цього сеансу",
+ "Enable audible notifications for this session": "Увімкнути звукові сповіщення для цього сеансу",
"Save": "Зберегти",
"Checking server": "Перевірка серверу",
"Disconnect": "Відключити",
@@ -1017,13 +1017,13 @@
"Unable to revoke sharing for email address": "Не вдалось відкликати оприлюднювання адреси е-пошти",
"Revoke": "Відкликати",
"Unable to revoke sharing for phone number": "Не вдалось відкликати оприлюднювання телефонного номеру",
- "Filter room members": "Відфільтрувати учасників кімнати",
+ "Filter room members": "Відцідити учасників кімнати",
"Voice call": "Голосовий виклик",
"Video call": "Відеовиклик",
"Not now": "Не зараз",
"Don't ask me again": "Не запитувати мене знову",
"Appearance": "Вигляд",
- "Show rooms with unread messages first": "Показувати вгорі кімнати з непрочитаними повідомленнями",
+ "Show rooms with unread messages first": "Спочатку показувати кімнати з непрочитаними повідомленнями",
"Show previews of messages": "Показувати попередній перегляд повідомлень",
"Sort by": "Упорядкувати за",
"Activity": "Активністю",
@@ -1100,5 +1100,134 @@
"Restore your key backup to upgrade your encryption": "Відновіть резервну копію вашого ключа щоб поліпшити шифрування",
"You'll need to authenticate with the server to confirm the upgrade.": "Ви матимете пройти розпізнання на сервері щоб підтвердити поліпшування.",
"Upgrade this session to allow it to verify other sessions, granting them access to encrypted messages and marking them as trusted for other users.": "Поліпште цей сеанс щоб уможливити звіряння інших сеансів, надаючи їм доступ до зашифрованих повідомлень та позначуючи їх довіреними для інших користувачів.",
- "Upgrade your encryption": "Поліпшити ваше шифрування"
+ "Upgrade your encryption": "Поліпшити ваше шифрування",
+ "Show a placeholder for removed messages": "Показувати позначку-заповнювач для видалених повідомлень",
+ "Show join/leave messages (invites/kicks/bans unaffected)": "Показувати повідомлення про приєднання/залишення (не впливає на запрошення/викидання/заборону)",
+ "Show avatar changes": "Показувати зміни личини",
+ "Show display name changes": "Показувати зміни видимого імені",
+ "Show read receipts sent by other users": "Показувати мітки прочитання, надіслані іншими користувачами",
+ "Show a reminder to enable Secure Message Recovery in encrypted rooms": "Показувати нагадку про ввімкнення відновлювання захищених повідомлень у зашифрованих кімнатах",
+ "Show avatars in user and room mentions": "Показувати личини у згадках користувачів та кімнат",
+ "Never send encrypted messages to unverified sessions from this session": "Ніколи не надсилати зашифровані повідомлення до незвірених сеансів з цього сеансу",
+ "Never send encrypted messages to unverified sessions in this room from this session": "Ніколи не надсилати зашифровані повідомлення до незвірених сеансів у цій кімнаті з цього сеансу",
+ "Enable message search in encrypted rooms": "Увімкнути шукання повідомлень у зашифрованих кімнатах",
+ "IRC display name width": "Ширина видимого імені IRC",
+ "Encrypted messages in one-to-one chats": "Зашифровані повідомлення у балачках віч-на-віч",
+ "Encrypted messages in group chats": "Зашифровані повідомлення у групових балачках",
+ "Secure messages with this user are end-to-end encrypted and not able to be read by third parties.": "Захищені повідомлення з цим користувачем є наскрізно зашифрованими та непрочитними для сторонніх осіб.",
+ "Securely cache encrypted messages locally for them to appear in search results.": "Безпечно локально кешувати зашифровані повідомлення щоб вони з'являлись у результатах пошуку.",
+ "%(brand)s is missing some components required for securely caching encrypted messages locally. If you'd like to experiment with this feature, build a custom %(brand)s Desktop with search components added.": "%(brand)s'ові бракує деяких складників, необхідних для безпечного локального кешування зашифрованих повідомлень. Якщо ви хочете поекспериментувати з цією властивістю, зберіть спеціальну збірку %(brand)s Desktop із доданням пошукових складників.",
+ "%(brand)s can't securely cache encrypted messages locally while running in a web browser. Use %(brand)s Desktop for encrypted messages to appear in search results.": "%(brand)s не може безпечно локально кешувати зашифровані повідомлення під час виконання у переглядачі. Користуйтесь %(brand)s Desktop, в якому зашифровані повідомлення з'являються у результатах пошуку.",
+ "Are you sure? You will lose your encrypted messages if your keys are not backed up properly.": "Ви впевнені? Ви загубите ваші зашифровані повідомлення якщо копія ключів не була зроблена коректно.",
+ "Encrypted messages are secured with end-to-end encryption. Only you and the recipient(s) have the keys to read these messages.": "Зашифровані повідомлення захищені наскрізним шифруванням. Лише ви та отримувачі повідомлень мають ключі для їх читання.",
+ "Display Name": "Видиме ім'я",
+ "wait and try again later": "почекайте та спробуйте пізніше",
+ "Once enabled, encryption for a room cannot be disabled. Messages sent in an encrypted room cannot be seen by the server, only by the participants of the room. Enabling encryption may prevent many bots and bridges from working correctly. Learn more about encryption.": "Якщо ви увімкнете шифрування для кімнати, його неможливо буде вимкнути. Надіслані у зашифровану кімнату повідомлення будуть прочитними тільки для учасників кімнати, натомість для сервера вони будуть непрочитними. Увімкнення шифрування може унеможливити роботу ботів та мостів. Дізнатись більше про шифрування.",
+ "Encrypted": "Зашифроване",
+ "This room is end-to-end encrypted": "Ця кімната є наскрізно зашифрованою",
+ "Encrypted by an unverified session": "Зашифроване незвіреним сеансом",
+ "Encrypted by a deleted session": "Зашифроване видаленим сеансом",
+ "The authenticity of this encrypted message can't be guaranteed on this device.": "Справжність цього зашифрованого повідомлення не може бути гарантованою на цьому пристрої.",
+ "Send an encrypted reply…": "Надіслати зашифровану відповідь…",
+ "Replying": "Відповідання",
+ "Low priority": "Неважливі",
+ "In encrypted rooms, like this one, URL previews are disabled by default to ensure that your homeserver (where the previews are generated) cannot gather information about links you see in this room.": "У зашифрованих кімнатах, подібних до цієї, попередній перегляд посилань є початково вимкненим. Це робиться задля гарантування того, що ваш домашній сервер (на якому генеруються перегляди) не матиме змоги збирати інформацію щодо посилань, які ви бачите у цій кімнаті.",
+ "In encrypted rooms, your messages are secured and only you and the recipient have the unique keys to unlock them.": "У зашифрованих кімнатах ваші повідомлення є захищеними, тож тільки ви та отримувач маєте ключі для їх розблокування.",
+ "In encrypted rooms, verify all users to ensure it’s secure.": "У зашифрованих кімнатах звіряйте усіх користувачів щоб переконатись у безпеці спілкування.",
+ "Failed to copy": "Не вдалось скопіювати",
+ "Your display name": "Ваше видиме ім'я",
+ "COPY": "СКОПІЮВАТИ",
+ "Set a display name:": "Зазначити видиме ім'я:",
+ "Copy": "Скопіювати",
+ "Cancel replying to a message": "Скасувати відповідання на повідомлення",
+ "Page Up": "Page Up",
+ "Page Down": "Page Down",
+ "Esc": "Esc",
+ "Enter": "Enter",
+ "Space": "Пропуск",
+ "End": "End",
+ "Clearing all data from this session is permanent. Encrypted messages will be lost unless their keys have been backed up.": "Видалення даних з цього сеансу є безповоротним. Зашифровані повідомлення будуть втрачені якщо їхні ключі не було продубльовано.",
+ "Verify this user to mark them as trusted. Trusting users gives you extra peace of mind when using end-to-end encrypted messages.": "Звірте цього користувача щоб позначити його довіреним. Довіряння користувачам додає спокою якщо ви користуєтесь наскрізно зашифрованими повідомленнями.",
+ "Verify this device to mark it as trusted. Trusting this device gives you and other users extra peace of mind when using end-to-end encrypted messages.": "Звірте цей пристрій щоб позначити його довіреним. Довіряння цьому пристрою додає вам та іншим користувачам спокою якщо ви користуєтесь наскрізно зашифрованими повідомленнями.",
+ "I don't want my encrypted messages": "Мені не потрібні мої зашифровані повідомлення",
+ "You'll lose access to your encrypted messages": "Ви втратите доступ до ваших зашифрованих повідомлень",
+ "Use this session to verify your new one, granting it access to encrypted messages:": "Використати цей сеанс для звірення вашого нового сеансу, надаючи йому доступ до зашифрованих повідомлень:",
+ "Reporting this message will send its unique 'event ID' to the administrator of your homeserver. If messages in this room are encrypted, your homeserver administrator will not be able to read the message text or view any files or images.": "Скарження на це повідомлення надішле його унікальний 'ідентифікатор події (event ID)' адміністраторові вашого домашнього сервера. Якщо повідомлення у цій кімнаті зашифровані, то адміністратор не зможе бачити ані тексту повідомлень, ані жодних файлів чи зображень.",
+ "Some session data, including encrypted message keys, is missing. Sign out and sign in to fix this, restoring keys from backup.": "Бракує деяких даних сеансу, включно з ключами зашифрованих повідомлень. Вийдіть та зайдіть знову щоб виправити цю проблему, відновлюючи ключі з дубля.",
+ "Data from an older version of %(brand)s has been detected. This will have caused end-to-end cryptography to malfunction in the older version. End-to-end encrypted messages exchanged recently whilst using the older version may not be decryptable in this version. This may also cause messages exchanged with this version to fail. If you experience problems, log out and back in again. To retain message history, export and re-import your keys.": "Було виявлено дані зі старої версії %(brand)s. Це призведе до збоїння наскрізного шифрування у старій версії. Наскрізно зашифровані повідомлення, що обмінювані нещодавно, під час використання старої версії, можуть бути недешифровними у цій версії. Це може призвести до збоїв повідомлень, обмінюваних також і з цією версією. У разі виникнення проблем вийдіть з програми та зайдіть знову. Задля збереження історії повідомлень експортуйте та переімпортуйте ваші ключі.",
+ "Changing your password will reset any end-to-end encryption keys on all of your sessions, making encrypted chat history unreadable. Set up Key Backup or export your room keys from another session before resetting your password.": "Змінення паролю скине усі ключі наскрізного шифрування в усіх ваших сеансах, роблячи зашифровану історію листувань непрочитною. Налагодьте дублювання ключів або експортуйте ключі кімнат з іншого сеансу перед скиданням паролю.",
+ "Confirm your identity by verifying this login from one of your other sessions, granting it access to encrypted messages.": "Підтвердьте вашу особу шляхом звіряння цього входу з одного з інших ваших сеансів, надаючи йому доступ до зашифрованих повідомлень.",
+ "Enable big emoji in chat": "Увімкнути великі емодзі у балачках",
+ "Show typing notifications": "Сповіщати про друкування",
+ "Show rooms with unread notifications first": "Спочатку показувати кімнати з непрочитаними сповіщеннями",
+ "Show shortcuts to recently viewed rooms above the room list": "Показувати нещодавно бачені кімнати вгорі понад переліком кімнат",
+ "Show hidden events in timeline": "Показувати приховані події у часоряді",
+ "Show previews/thumbnails for images": "Показувати попередній перегляд зображень",
+ "Compare a unique set of emoji if you don't have a camera on either device": "Порівняйте унікальну низку емодзі якщо ви не маєте камери на жодному пристрої",
+ "Confirm the emoji below are displayed on both sessions, in the same order:": "Підтвердьте, що нижчевказані емодзі відбиваються в обох сеансах в однаковому порядку:",
+ "Verify this user by confirming the following emoji appear on their screen.": "Звірте цього користувача підтвердженням того, що наступні емодзі з'являються на його екрані.",
+ "Emoji picker": "Обирач емодзі",
+ "The session you are trying to verify doesn't support scanning a QR code or emoji verification, which is what %(brand)s supports. Try with a different client.": "Сеанс, який ви намагаєтесь звірити, не підтримує сканування QR-коду або звіряння за допомогою емодзі, що є підтримувані %(brand)s. Спробуйте використати інший клієнт.",
+ "If you can't scan the code above, verify by comparing unique emoji.": "Якщо ви не можете відсканувати вищезазначений код, звірте порівнянням унікальних емодзі.",
+ "Verify by comparing unique emoji.": "Звірити порівнянням унікальних емодзі.",
+ "Verify by emoji": "Звірити за допомогою емодзі",
+ "Compare emoji": "Порівняти емодзі",
+ "This requires the latest %(brand)s on your other devices:": "Це потребує найостаннішого %(brand)s на ваших інших пристроях:",
+ "%(brand)s Web": "%(brand)s Web",
+ "%(brand)s Desktop": "%(brand)s Desktop",
+ "%(brand)s iOS": "%(brand)s iOS",
+ "%(brand)s Android": "%(brand)s Android",
+ "or another cross-signing capable Matrix client": "або інший здатний до перехресного підписування Matrix-клієнт",
+ "Your new session is now verified. It has access to your encrypted messages, and other users will see it as trusted.": "Ваш новий сеанс тепер є звірений. Він має доступ до ваших зашифрованих повідомлень, а інші користувачі бачитимуть його як довірений.",
+ "Emoji": "Емодзі",
+ "Emoji Autocomplete": "Самодоповнення емодзі",
+ "%(senderName)s created a ban rule matching %(glob)s for %(reason)s": "%(senderName)s створив(-ла) правило блокування зі збігом з %(glob)s через %(reason)s",
+ "%(senderName)s changed a rule that was banning users matching %(oldGlob)s to matching %(newGlob)s for %(reason)s": "%(senderName)s змінив(-ла) правило блокування користувачів зі збігу з %(oldGlob)s на збіг з %(newGlob)s через %(reason)s",
+ "%(senderName)s changed a rule that was banning rooms matching %(oldGlob)s to matching %(newGlob)s for %(reason)s": "%(senderName)s змінив(-ла) правило блокування кімнат зі збігу з %(oldGlob)s на збіг з %(newGlob)s через %(reason)s",
+ "%(senderName)s changed a rule that was banning servers matching %(oldGlob)s to matching %(newGlob)s for %(reason)s": "%(senderName)s змінив(-ла) правило блокування серверів зі збігу з %(oldGlob)s на збіг з %(newGlob)s через %(reason)s",
+ "%(senderName)s updated a ban rule that was matching %(oldGlob)s to matching %(newGlob)s for %(reason)s": "%(senderName)s змінив(-ла) правило блокування зі збігу з %(oldGlob)s на збіг з %(newGlob)s через %(reason)s",
+ "Enable Community Filter Panel": "Увімкнути панель спільнот",
+ "Messages containing my username": "Повідомлення, що містять моє користувацьке ім'я",
+ "Messages containing @room": "Повідомлення, що містять @room",
+ "When rooms are upgraded": "Коли кімнати поліпшено",
+ "Unknown caller": "Невідомий викликач",
+ "The integration manager is offline or it cannot reach your homeserver.": "Менеджер інтеграцій непід'єднаний або не може досягти вашого домашнього сервера.",
+ "Enable desktop notifications for this session": "Увімкнути стільничні сповіщення для цього сеансу",
+ "Profile picture": "Зображення профілю",
+ "Use an Integration Manager (%(serverName)s) to manage bots, widgets, and sticker packs.": "Використовувати менеджер інтеграцій %(serverName)s для керування ботами, знадобами та паками наліпок.",
+ "Use an Integration Manager to manage bots, widgets, and sticker packs.": "Використовувати менеджер інтеграцій для керування ботами, знадобами та паками наліпок.",
+ "Integration Managers receive configuration data, and can modify widgets, send room invites, and set power levels on your behalf.": "Менеджери інтеграцій отримують дані конфігурації та можуть змінювати знадоби, надсилати запрошення у кімнати й встановлювати рівні повноважень від вашого імені.",
+ "Show %(count)s more|other": "Показати ще %(count)s",
+ "Show %(count)s more|one": "Показати ще %(count)s",
+ "Failed to connect to integration manager": "Не вдалось з'єднатись з менеджером інтеграцій",
+ "Show image": "Показати зображення",
+ "You have ignored this user, so their message is hidden. Show anyways.": "Ви ігноруєте цього користувача, тож його повідомлення приховано. Все одно показати.",
+ "Show all": "Показати все",
+ "Add an Integration": "Додати інтеграцію",
+ "Filter community members": "Відцідити учасників спільноти",
+ "Filter community rooms": "Відцідити кімнати спільноти",
+ "Display your community flair in rooms configured to show it.": "Відбивати ваш спільнотний значок у кімнатах, що налаштовані показувати його.",
+ "Using this widget may share data with %(widgetDomain)s & your Integration Manager.": "Користування цим знадобом може призвести до поширення ваших даних з %(widgetDomain)s та вашим менеджером інтеграцій.",
+ "Show advanced": "Показати розширені",
+ "Your %(brand)s doesn't allow you to use an Integration Manager to do this. Please contact an admin.": "Ваш %(brand)s не дозволяє вам використовувати для цього менеджер інтеграцій. Зверніться, будь ласка, до адміністратора.",
+ "Integration Manager": "Менеджер інтеграцій",
+ "Your community hasn't got a Long Description, a HTML page to show to community members. Click here to open settings and give it one!": "Ваша спільнота не має великого опису (HTML-сторінки, показуваної членам спільноти). Клацніть тут щоб відкрити налаштування й створити цей опис!",
+ "Review terms and conditions": "Переглянути умови користування",
+ "Old cryptography data detected": "Виявлено старі криптографічні дані",
+ "Logout": "Вийти",
+ "Your Communities": "Ваші спільноти",
+ "Did you know: you can use communities to filter your %(brand)s experience!": "Чи знаєте ви, що спільноти можна використовувати для припасування %(brand)s під ваші потреби?",
+ "Communities": "Спільноти",
+ "Create a new community": "Створити нову спільноту",
+ "Clear filter": "Очистити цідило",
+ "Syncing...": "Синхронізування…",
+ "Signing In...": "Входження…",
+ "If you've joined lots of rooms, this might take a while": "Якщо ви приєднались до багатьох кімнат, це може зайняти деякий час",
+ "Create account": "Створити обліковий запис",
+ "Failed to fetch avatar URL": "Не вдалось вибрати URL личини",
+ "Clear room list filter field": "Очистити поле цідила списку кімнат",
+ "Cancel autocomplete": "Скасувати самодоповнення",
+ "Debug logs contain application usage data including your username, the IDs or aliases of the rooms or groups you have visited and the usernames of other users. They do not contain messages.": "Журнали зневадження містять дані використання застосунку, включно з вашим користувацьким ім’ям, ідентифікаторами або псевдонімами відвіданих вами кімнат або груп, а також іменами інших користувачів. Вони не містять повідомлень.",
+ "Confirm your account deactivation by using Single Sign On to prove your identity.": "Підтвердьте знедіяння вашого облікового запису через Single Sign On щоб підтвердити вашу особу.",
+ "This account has been deactivated.": "Цей обліковий запис було знедіяно."
}
diff --git a/src/i18n/strings/zh_Hans.json b/src/i18n/strings/zh_Hans.json
index f4ad52a8f2..f1a3af31d7 100644
--- a/src/i18n/strings/zh_Hans.json
+++ b/src/i18n/strings/zh_Hans.json
@@ -3,7 +3,7 @@
"Cryptography": "加密",
"Current password": "当前密码",
"/ddg is not a command": "/ddg 不是一个命令",
- "Deactivate Account": "销毁账号",
+ "Deactivate Account": "停用账号",
"Decrypt %(text)s": "解密 %(text)s",
"Default": "默认",
"Disinvite": "取消邀请",
@@ -162,7 +162,7 @@
"Missing user_id in request": "请求中没有 user_id",
"Moderator": "协管员",
"Mute": "静音",
- "Name": "姓名",
+ "Name": "名称",
"New passwords don't match": "两次输入的新密码不符",
"not specified": "未指定",
"Notifications": "通知",
@@ -175,7 +175,7 @@
"Password": "密码",
"Passwords can't be empty": "密码不能为空",
"Permissions": "权限",
- "Phone": "手机号码",
+ "Phone": "电话号码",
"Cancel": "取消",
"Create new room": "创建新聊天室",
"Custom Server Options": "自定义服务器选项",
@@ -258,7 +258,7 @@
"Save": "保存",
"This room has no local addresses": "此聊天室没有本地地址",
"This doesn't appear to be a valid email address": "这似乎不是有效的邮箱地址",
- "This phone number is already in use": "此手机号码已被使用",
+ "This phone number is already in use": "此电话号码已被使用",
"This room": "此聊天室",
"This room is not accessible by remote Matrix servers": "此聊天室无法被远程 Matrix 服务器访问",
"Unable to create widget.": "无法创建小挂件。",
@@ -280,7 +280,7 @@
"Manage Integrations": "管理集成",
"No users have specific privileges in this room": "此聊天室中没有用户有特殊权限",
"Please check your email and click on the link it contains. Once this is done, click continue.": "请检查你的电子邮箱并点击里面包含的链接。完成时请点击继续。",
- "%(senderName)s removed their profile picture.": "%(senderName)s 移除了他们的头像。",
+ "%(senderName)s removed their profile picture.": "%(senderName)s 移除了头像。",
"%(senderName)s requested a VoIP conference.": "%(senderName)s 已请求发起 VoIP 会议。",
"Seen by %(userName)s at %(dateTime)s": "在 %(dateTime)s 被 %(userName)s 看到",
"%(targetName)s accepted the invitation for %(displayName)s.": "%(targetName)s 接受了 %(displayName)s 的邀请。",
@@ -295,12 +295,12 @@
"%(senderName)s made future room history visible to unknown (%(visibility)s).": "%(senderName)s 设定历史浏览功能为 未知的 (%(visibility)s).",
"AM": "上午",
"PM": "下午",
- "Profile": "个人配置",
+ "Profile": "个人资料",
"Public Chat": "公开的",
"%(roomName)s is not accessible at this time.": "%(roomName)s 此时无法访问。",
"Start authentication": "开始认证",
"The maximum permitted number of widgets have already been added to this room.": "此聊天室可拥有的小挂件数量已达到上限。",
- "The phone number entered looks invalid": "此手机号码似乎无效",
+ "The phone number entered looks invalid": "此电话号码似乎无效",
"The remote side failed to pick up": "对方未能接听",
"This room is not recognised.": "无法识别此聊天室。",
"To get started, please pick a username!": "请点击用户名!",
@@ -337,7 +337,7 @@
"You have disabled URL previews by default.": "你已经默认 禁用 链接预览。",
"You have enabled URL previews by default.": "你已经默认 启用 链接预览。",
"Set a display name:": "设置昵称:",
- "This server does not support authentication with a phone number.": "此服务器不支持使用手机号码认证。",
+ "This server does not support authentication with a phone number.": "此服务器不支持使用电话号码认证。",
"Copied!": "已复制!",
"Failed to copy": "复制失败",
"Sent messages will be stored until your connection has returned.": "已发送的消息会被保存直到你的连接回来。",
@@ -511,7 +511,7 @@
"To use it, just wait for autocomplete results to load and tab through them.": "若要使用自动补全,只要等待自动补全结果加载完成,按 Tab 键切换即可。",
"%(oldDisplayName)s changed their display name to %(displayName)s.": "%(oldDisplayName)s 将他们的昵称修改成了 %(displayName)s 。",
"Stickerpack": "贴图集",
- "You don't currently have any stickerpacks enabled": "您目前没有启用任何贴纸包",
+ "You don't currently have any stickerpacks enabled": "您目前没有启用任何贴图集",
"Key request sent.": "已发送密钥共享请求。",
"You will not be able to undo this change as you are demoting yourself, if you are the last privileged user in the room it will be impossible to regain privileges.": "如果您是房间中最后一位有权限的用户,在您降低自己的权限等级后将无法撤回此修改,因为你将无法重新获得权限。",
"You will not be able to undo this change as you are promoting the user to have the same power level as yourself.": "您将无法撤回此修改,因为您正在将此用户的滥权等级提升至与你相同。",
@@ -788,7 +788,7 @@
"In encrypted rooms, like this one, URL previews are disabled by default to ensure that your homeserver (where the previews are generated) cannot gather information about links you see in this room.": "在启用加密的聊天室中,比如此聊天室,链接预览被默认禁用以确保主服务器(访问链接、生成预览的地方)无法获知聊天室中的链接及其信息。",
"When someone puts a URL in their message, a URL preview can be shown to give more information about that link such as the title, description, and an image from the website.": "当有人发送一条带有链接的消息后,可显示链接的预览,链接预览可包含此链接的网页标题、描述以及图片。",
"The email field must not be blank.": "必须输入电子邮箱。",
- "The phone number field must not be blank.": "必须输入手机号码。",
+ "The phone number field must not be blank.": "必须输入电话号码。",
"The password field must not be blank.": "必须输入密码。",
"Display your community flair in rooms configured to show it.": "在启用“显示徽章”的聊天室中显示本社区的个性徽章。",
"Failed to remove widget": "移除小挂件失败",
@@ -1045,7 +1045,7 @@
"Unable to verify phone number.": "无法验证电话号码。",
"Verification code": "验证码",
"Phone Number": "电话号码",
- "Profile picture": "个人资料头像",
+ "Profile picture": "头像",
"Display Name": "昵称",
"Set a new account password...": "设置一个新的账号密码...",
"Email addresses": "电子邮箱地址",
@@ -1103,7 +1103,7 @@
"Join": "加入",
"That doesn't look like a valid email address": "看起来不像是个有效的电子邮箱地址",
"The following users may not exist": "以下用户可能不存在",
- "Unable to find profiles for the Matrix IDs listed below - would you like to invite them anyway?": "无法找到以下列表中 Matrix ID 的用户资料 - 您还是要邀请他们吗?",
+ "Unable to find profiles for the Matrix IDs listed below - would you like to invite them anyway?": "无法找到以下列表中 Matrix ID 的用户资料 - 您还是要邀请吗?",
"Invite anyway and never warn me again": "还是邀请,不用再提醒我",
"Invite anyway": "还是邀请",
"Before submitting logs, you must create a GitHub issue to describe your problem.": "在提交日志之前,您必须 创建一个GitHub issue 来描述您的问题。",
@@ -1260,11 +1260,11 @@
"Try using turn.matrix.org": "尝试使用 turn.matrix.org",
"Your %(brand)s is misconfigured": "您的 %(brand)s 配置有错误",
"Use Single Sign On to continue": "使用单点登陆继续",
- "Confirm adding this email address by using Single Sign On to prove your identity.": "确认添加此邮件地址,通过使用单点登陆来证明您的身份。",
+ "Confirm adding this email address by using Single Sign On to prove your identity.": "通过使用单点登陆来证明您的身份,并确认添加此邮件地址。",
"Single Sign On": "单点登陆",
"Confirm adding email": "确认使用邮件",
"Click the button below to confirm adding this email address.": "点击下面的按钮,添加此邮箱地址。",
- "Confirm adding this phone number by using Single Sign On to prove your identity.": "通过单点确认添加此电话号码以确认您的身份。",
+ "Confirm adding this phone number by using Single Sign On to prove your identity.": "通过单点登录以证明您的身份,并确认添加此电话号码。",
"Confirm adding phone number": "确认添加电话号码",
"Click the button below to confirm adding this phone number.": "点击下面的按钮,确认添加此电话号码。",
"Whether you're using %(brand)s on a device where touch is the primary input mechanism": "是否在触屏设备上使用 %(brand)s",
@@ -1371,7 +1371,7 @@
"Room name or address": "房间名称或地址",
"Joins room with given address": "使用给定地址加入房间",
"Verify this login": "验证此登录名",
- "Confirm your identity by verifying this login from one of your other sessions, granting it access to encrypted messages.": "通过从其他会话之一验证此登录名并授予其访问加密信息的权限来确认您的身份",
+ "Confirm your identity by verifying this login from one of your other sessions, granting it access to encrypted messages.": "通过从其他会话之一验证此登录名并授予其访问加密信息的权限来确认您的身份。",
"Which officially provided instance you are using, if any": "如果您在使用官方实例,是哪一个",
"Every page you use in the app": "您在应用中使用的每个页面",
"Are you sure you want to cancel entering passphrase?": "确定要取消输入密码?",
@@ -1460,5 +1460,916 @@
"Verify this session by completing one of the following:": "完成以下之一以验证这一会话:",
"or": "或者",
"Start": "开始",
- "Confirm the emoji below are displayed on both sessions, in the same order:": "确认两个会话上都以同样顺序显示了下面的emoji:"
+ "Confirm the emoji below are displayed on both sessions, in the same order:": "确认两个会话上都以同样顺序显示了下面的emoji:",
+ "The person who invited you already left the room.": "邀请您的人已经离开了聊天室。",
+ "The person who invited you already left the room, or their server is offline.": "邀请您的人已经离开了聊天室,或者其服务器为离线状态。",
+ "Change notification settings": "修改通知设置",
+ "Manually verify all remote sessions": "手动验证所有远程会话",
+ "My Ban List": "我的封禁列表",
+ "This is your list of users/servers you have blocked - don't leave the room!": "这是您屏蔽的用户和服务器的列表——请不要离开此聊天室!",
+ "Unknown caller": "未知来电人",
+ "Incoming voice call": "语音来电",
+ "Incoming video call": "视频来电",
+ "Incoming call": "来电",
+ "Waiting for your other session, %(deviceName)s (%(deviceId)s), to verify…": "等待您的另一个会话 %(deviceName)s (%(deviceId)s) 进行验证…",
+ "Waiting for your other session to verify…": "等待您的另一个会话进行验证…",
+ "Waiting for %(displayName)s to verify…": "等待 %(displayName)s 进行验证…",
+ "Cancelling…": "正在取消…",
+ "They match": "它们匹配",
+ "They don't match": "它们不匹配",
+ "To be secure, do this in person or use a trusted way to communicate.": "为了安全,请当面完成或使用信任的方法交流。",
+ "Lock": "锁",
+ "Your server isn't responding to some requests.": "您的服务器没有响应一些请求。",
+ "From %(deviceName)s (%(deviceId)s)": "来自 %(deviceName)s (%(deviceId)s)",
+ "Decline (%(counter)s)": "拒绝 (%(counter)s)",
+ "Accept to continue:": "接受 以继续:",
+ "Upload": "上传",
+ "Show less": "显示更少",
+ "Show more": "显示更多",
+ "Changing password will currently reset any end-to-end encryption keys on all sessions, making encrypted chat history unreadable, unless you first export your room keys and re-import them afterwards. In future this will be improved.": "修改密码会重置所有会话上的端对端加密的密钥,使加密聊天记录不可读,除非您先导出您的聊天室密钥,之后再重新导入。在未来会有所改进。",
+ "Your homeserver does not support cross-signing.": "您的主服务器不支持交叉签名。",
+ "Cross-signing and secret storage are enabled.": "交叉签名和秘密存储已启用。",
+ "Your account has a cross-signing identity in secret storage, but it is not yet trusted by this session.": "您的账户在秘密存储中有交叉签名身份,但并没有被此会话信任。",
+ "Cross-signing and secret storage are not yet set up.": "交叉签名和秘密存储尚未设置。",
+ "Reset cross-signing and secret storage": "重置交叉签名和秘密存储",
+ "Bootstrap cross-signing and secret storage": "自举交叉签名和秘密存储",
+ "unexpected type": "未预期的类型",
+ "Cross-signing public keys:": "交叉签名公钥:",
+ "in memory": "在内存中",
+ "not found": "未找到",
+ "Cross-signing private keys:": "交叉签名私钥:",
+ "in secret storage": "在秘密存储中",
+ "cached locally": "本地缓存",
+ "not found locally": "本地未找到",
+ "Session backup key:": "会话备份密钥:",
+ "Secret storage public key:": "秘密存储公钥:",
+ "in account data": "在账户数据中",
+ "exists": "存在",
+ "Your homeserver does not support session management.": "您的主服务器不支持会话管理。",
+ "Unable to load session list": "无法加载会话列表",
+ "Confirm deleting these sessions": "确认删除这些会话",
+ "Click the button below to confirm deleting these sessions.|other": "点击下方按钮以确认删除这些会话。",
+ "Click the button below to confirm deleting these sessions.|one": "点击下方按钮以确认删除此会话。",
+ "Delete sessions|other": "删除会话",
+ "Delete sessions|one": "删除会话",
+ "Delete %(count)s sessions|other": "删除 %(count)s 个会话",
+ "Delete %(count)s sessions|one": "删除 %(count)s 个会话",
+ "ID": "账号",
+ "Individually verify each session used by a user to mark it as trusted, not trusting cross-signed devices.": "逐一验证用户的每一个会话以将其标记为受信任的,而不信任交叉签名的设备。",
+ "Manage": "管理",
+ "Enable": "启用",
+ "%(brand)s is missing some components required for securely caching encrypted messages locally. If you'd like to experiment with this feature, build a custom %(brand)s Desktop with search components added.": "%(brand)s 缺少安全地在本地缓存加密信息所必须的部件。如果您想实验此功能,请构建一个自定义的带有搜索部件的 %(brand)s 桌面版。",
+ "%(brand)s can't securely cache encrypted messages locally while running in a web browser. Use %(brand)s Desktop for encrypted messages to appear in search results.": "%(brand)s 在浏览器中运行时不能安全地在本地缓存加密信息。请使用%(brand)s 桌面版以使加密信息出现在搜索结果中。",
+ "This session is backing up your keys. ": "此会话正在备份您的密钥。 ",
+ "Connect this session to key backup before signing out to avoid losing any keys that may only be on this session.": "在登出前连接此会话到密钥备份以避免丢失可能仅在此会话上的密钥。",
+ "Connect this session to Key Backup": "将此会话连接到密钥备份",
+ "Backup has a valid signature from this user": "备份有来自此用户的有效签名",
+ "Backup has a invalid signature from this user": "备份有来自此用户的无效签名",
+ "Backup has a signature from unknown user with ID %(deviceId)s": "备份有来自 ID 为 %(deviceId)s 的未知用户的签名",
+ "Backup has a signature from unknown session with ID %(deviceId)s": "备份有来自 ID 为 %(deviceId)s 的未知会话的签名",
+ "Backup has a valid signature from this session": "备份有来自此会话的有效签名",
+ "Backup has an invalid signature from this session": "备份有来自此会话的无效签名",
+ "Backup has a valid signature from verified session ": "备份有来自已验证的会话 的有效签名",
+ "Backup has a valid signature from unverified session ": "备份有来自未验证会话 的无效签名",
+ "Backup has an invalid signature from verified session ": "备份有来自已验证会话 的无效签名",
+ "Backup has an invalid signature from unverified session ": "备份有来自未验证的会话 的 无效签名",
+ "Backup is not signed by any of your sessions": "备份没有被您的任何一个会话签名",
+ "This backup is trusted because it has been restored on this session": "此备份是受信任的因为它被恢复到了此会话上",
+ "Backup key stored: ": "存储的备份密钥: ",
+ "Your keys are not being backed up from this session.": "您的密钥没有被此会话备份。",
+ "Clear notifications": "清除通知",
+ "There are advanced notifications which are not shown here.": "有高级通知没有显示在此处。",
+ "You might have configured them in a client other than %(brand)s. You cannot tune them in %(brand)s but they still apply.": "您可能在非 %(brand)s 的客户端里配置了它们。您在 %(brand)s 里无法修改它们,但它们仍然适用。",
+ "Enable desktop notifications for this session": "为此会话启用桌面通知",
+ "Enable audible notifications for this session": "为此会话启用声音通知",
+ "Identity Server URL must be HTTPS": "身份服务器连接必须是 HTTPS",
+ "Not a valid Identity Server (status code %(code)s)": "不是有效的身份服务器(状态码 %(code)s)",
+ "Could not connect to Identity Server": "无法连接到身份服务器",
+ "Checking server": "检查服务器",
+ "Change identity server": "更改身份服务器",
+ "Disconnect from the identity server and connect to instead?": "从 身份服务器断开连接并连接到 吗?",
+ "Terms of service not accepted or the identity server is invalid.": "服务协议未同意或身份服务器无效。",
+ "The identity server you have chosen does not have any terms of service.": "您选择的身份服务器没有服务协议。",
+ "Disconnect identity server": "断开身份服务器连接",
+ "Disconnect from the identity server ?": "从身份服务器 断开连接吗?",
+ "Disconnect": "断开连接",
+ "You should remove your personal data from identity server before disconnecting. Unfortunately, identity server is currently offline or cannot be reached.": "在断开连接之前,您应该从身份服务器 删除您的个人信息。不幸的是,身份服务器 现在为离线状态或不能到达。",
+ "You should:": "您应该:",
+ "contact the administrators of identity server ": "联系身份服务器 的管理员",
+ "wait and try again later": "等待并稍后重试",
+ "Disconnect anyway": "仍然断开连接",
+ "You are still sharing your personal data on the identity server .": "您仍然在身份服务器 上共享您的个人信息。",
+ "We recommend that you remove your email addresses and phone numbers from the identity server before disconnecting.": "我们推荐您在断开连接前从身份服务器上删除您的邮箱地址和电话号码。",
+ "Identity Server (%(server)s)": "身份服务器(%(server)s)",
+ "not stored": "未存储",
+ "You are currently using to discover and be discoverable by existing contacts you know. You can change your identity server below.": "您正在使用 以发现您认识的现存联系人并被其发现。您可以在下方更改您的身份服务器。",
+ "If you don't want to use to discover and be discoverable by existing contacts you know, enter another identity server below.": "如果您不想使用 以发现您认识的现存联系人并被其发现,请在下方输入另一个身份服务器。",
+ "Identity Server": "身份服务器",
+ "You are not currently using an identity server. To discover and be discoverable by existing contacts you know, add one below.": "您现在没有使用身份服务器。若想发现您认识的现存联系人并被其发现,请在下方添加一个身份服务器。",
+ "Disconnecting from your identity server will mean you won't be discoverable by other users and you won't be able to invite others by email or phone.": "从您的身份服务器断开连接意味着您将不可被别的用户发现,同时您也将不能用邮箱或电话邀请别人。",
+ "Using an identity server is optional. If you choose not to use an identity server, you won't be discoverable by other users and you won't be able to invite others by email or phone.": "使用身份服务器是可选的。如果您选择不使用身份服务器,您将不能被别的用户发现,也不能用邮箱或电话邀请别人。",
+ "Do not use an identity server": "不使用身份服务器",
+ "Enter a new identity server": "输入一个新的身份服务器",
+ "New version available. Update now.": "新版本可用。现在更新。",
+ "Hey you. You're the best!": "嘿呀。您就是最棒的!",
+ "Size must be a number": "大小必须是数字",
+ "Custom font size can only be between %(min)s pt and %(max)s pt": "自定义字体大小只能介于 %(min)s pt 和 %(max)s pt 之间",
+ "Error downloading theme information.": "下载主题信息时发生错误。",
+ "Theme added!": "主题已添加!",
+ "Custom theme URL": "自定义主题链接",
+ "Add theme": "添加主题",
+ "Message layout": "信息布局",
+ "Compact": "紧凑",
+ "Modern": "现代",
+ "Set the name of a font installed on your system & %(brand)s will attempt to use it.": "设置一个安装在您的系统上的字体名称,%(brand)s 会尝试使用它。",
+ "Customise your appearance": "自定义您的外观",
+ "Appearance Settings only affect this %(brand)s session.": "外观设置仅会影响此 %(brand)s 会话。",
+ "Your password was successfully changed. You will not receive push notifications on other sessions until you log back in to them": "您的密码已成功更改。在您重新登录别的会话之前,您将不会在那里收到推送通知",
+ "Agree to the identity server (%(serverName)s) Terms of Service to allow yourself to be discoverable by email address or phone number.": "同意身份服务器(%(serverName)s)的服务协议以允许自己被通过邮件地址或电话号码发现。",
+ "Discovery": "发现",
+ "Clear cache and reload": "清除缓存重新加载",
+ "Keyboard Shortcuts": "键盘快捷键",
+ "Customise your experience with experimental labs features. Learn more.": "通过实验功能自定义您的体验。了解更多。",
+ "Ignored/Blocked": "已忽略/已屏蔽",
+ "Error adding ignored user/server": "添加已忽略的用户/服务器时出现错误",
+ "Error subscribing to list": "订阅列表时出现错误",
+ "Please verify the room ID or address and try again.": "请验证聊天室 ID 或地址并重试。",
+ "Error removing ignored user/server": "移除已忽略用户/服务器时出现错误",
+ "Error unsubscribing from list": "取消订阅列表时出现错误",
+ "None": "无",
+ "Ban list rules - %(roomName)s": "封禁列表规则 - %(roomName)s",
+ "Server rules": "服务器规则",
+ "User rules": "用户规则",
+ "You have not ignored anyone.": "您没有忽略任何人。",
+ "You are currently ignoring:": "您正在忽略:",
+ "You are not subscribed to any lists": "您没有订阅任何列表",
+ "Unsubscribe": "取消订阅",
+ "View rules": "查看规则",
+ "You are currently subscribed to:": "您正在订阅:",
+ "⚠ These settings are meant for advanced users.": "⚠ 这些设置是为高级用户准备的。",
+ "Add users and servers you want to ignore here. Use asterisks to have %(brand)s match any characters. For example, @bot:* would ignore all users that have the name 'bot' on any server.": "在此处添加您想忽略的用户和服务器。使用星号以使 %(brand)s 匹配任何字符。例如,@bot:* 会忽略在任何服务器上以「bot」为名的用户。",
+ "Ignoring people is done through ban lists which contain rules for who to ban. Subscribing to a ban list means the users/servers blocked by that list will be hidden from you.": "忽略人是通过含有封禁规则的封禁列表来完成的。订阅一个封禁列表意味着被该列表阻止的用户/服务器将会对您隐藏。",
+ "Personal ban list": "个人封禁列表",
+ "Your personal ban list holds all the users/servers you personally don't want to see messages from. After ignoring your first user/server, a new room will show up in your room list named 'My Ban List' - stay in this room to keep the ban list in effect.": "您的个人封禁列表包含所有您不想看见信息的用户/服务器。您第一次忽略用户/服务器。后,一个名叫「我的封禁列表」的新聊天室将会显示在您的聊天室列表中——留在该聊天室以保持该封禁列表生效。",
+ "Server or user ID to ignore": "要忽略的服务器或用户 ID",
+ "eg: @bot:* or example.org": "例如: @bot:* 或 example.org",
+ "Subscribed lists": "订阅的列表",
+ "Subscribing to a ban list will cause you to join it!": "订阅一个封禁列表会使您加入它!",
+ "If this isn't what you want, please use a different tool to ignore users.": "如果这不是您想要的,请使用别的的工具来忽略用户。",
+ "Room ID or address of ban list": "封禁列表的聊天室 ID 或地址",
+ "Subscribe": "订阅",
+ "Always show the window menu bar": "总是显示窗口菜单栏",
+ "Show tray icon and minimize window to it on close": "显示托盘图标并在关闭时最小化窗口到托盘",
+ "Session ID:": "会话 ID:",
+ "Session key:": "会话密钥:",
+ "Message search": "信息搜索",
+ "Cross-signing": "交叉签名",
+ "Where you’re logged in": "您在何处登录",
+ "A session's public name is visible to people you communicate with": "会话的公共名称会对和您交流的人显示",
+ "this room": "此聊天室",
+ "View older messages in %(roomName)s.": "查看 %(roomName)s 里更旧的信息。",
+ "Uploaded sound": "已上传的声音",
+ "Sounds": "声音",
+ "Notification sound": "通知声音",
+ "Reset": "重置",
+ "Set a new custom sound": "使用新的自定义声音",
+ "Browse": "浏览",
+ "Upgrade the room": "更新聊天室",
+ "Enable room encryption": "启用聊天室加密",
+ "Error changing power level requirement": "更改权限级别需求时出错",
+ "An error occurred changing the room's power level requirements. Ensure you have sufficient permissions and try again.": "更改此聊天室的权限级别需求时出错。请确保您有足够的权限后重试。",
+ "Error changing power level": "更改权限级别时出错",
+ "An error occurred changing the user's power level. Ensure you have sufficient permissions and try again.": "更改此用户的权限级别时出错。请确保您有足够权限后重试。",
+ "To link to this room, please add an address.": "要链接至此聊天室,请添加一个地址。",
+ "Unable to share email address": "无法共享邮件地址",
+ "Your email address hasn't been verified yet": "您的邮件地址尚未被验证",
+ "Click the link in the email you received to verify and then click continue again.": "请点击您收到的邮件中的链接后再点击继续。",
+ "Verify the link in your inbox": "验证您的收件箱中的链接",
+ "Complete": "完成",
+ "Share": "共享",
+ "Discovery options will appear once you have added an email above.": "您在上方添加邮箱后发现选项将会出现。",
+ "Unable to share phone number": "无法共享电话号码",
+ "Please enter verification code sent via text.": "请输入短信中发送的验证码。",
+ "Discovery options will appear once you have added a phone number above.": "您添加电话号码后发现选项将会出现。",
+ "Remove %(email)s?": "删除 %(email)s 吗?",
+ "Remove %(phone)s?": "删除 %(phone)s 吗?",
+ "A text message has been sent to +%(msisdn)s. Please enter the verification code it contains.": "一封短信已发送至 +%(msisdn)s。请输入其中包含的验证码。",
+ "This user has not verified all of their sessions.": "此用户没有验证其全部会话。",
+ "You have not verified this user.": "您没有验证此用户。",
+ "You have verified this user. This user has verified all of their sessions.": "您验证了此用户。此用户已验证了其全部会话。",
+ "* %(senderName)s %(emote)s": "* %(senderName)s %(emote)s",
+ "%(senderName)s: %(message)s": "%(senderName)s: %(message)s",
+ "%(senderName)s: %(reaction)s": "%(senderName)s: %(reaction)s",
+ "%(senderName)s: %(stickerName)s": "%(senderName)s: %(stickerName)s",
+ "Multiple integration managers": "多个集成管理器",
+ "Try out new ways to ignore people (experimental)": "尝试忽略别人的新方法(实验性)",
+ "Enable advanced debugging for the room list": "为此聊天室列表启用高级调试",
+ "Show info about bridges in room settings": "在聊天室设置中显示桥接信息",
+ "Use a more compact ‘Modern’ layout": "使用更紧凑的「现代」布局",
+ "Show typing notifications": "显示输入通知",
+ "Show shortcuts to recently viewed rooms above the room list": "在聊天室列表上方显示最近浏览过的聊天室的快捷方式",
+ "Show hidden events in timeline": "显示时间线中的隐藏事件",
+ "Low bandwidth mode": "低带宽模式",
+ "Allow fallback call assist server turn.matrix.org when your homeserver does not offer one (your IP address would be shared during a call)": "当您的主服务器没有提供通话辅助服务器时使用备用的 turn.matrix.org 服务器(您的IP地址会在通话期间被共享)",
+ "Send read receipts for messages (requires compatible homeserver to disable)": "为消息发送已读回执(需要兼容的主服务器方可禁用)",
+ "Scan this unique code": "扫描此唯一代码",
+ "Compare unique emoji": "比较唯一表情符号",
+ "Compare a unique set of emoji if you don't have a camera on either device": "若您在两个设备上都没有相机,比较唯一一组表情符号",
+ "Verify this session by confirming the following number appears on its screen.": "确认下方数字显示在屏幕上以验证此会话。",
+ "This bridge is managed by .": "此桥接由 管理。",
+ "Homeserver feature support:": "主服务器功能支持:",
+ "Confirm deleting these sessions by using Single Sign On to prove your identity.|other": "通过单点登录证明您的身份并确认删除这些会话。",
+ "Confirm deleting these sessions by using Single Sign On to prove your identity.|one": "通过单点登录证明您的身份并确认删除此会话。",
+ "Public Name": "公开名称",
+ "Securely cache encrypted messages locally for them to appear in search results.": "在本地安全地缓存加密消息以使其出现在搜索结果中。",
+ "Connecting to integration manager...": "正在连接至集成管理器...",
+ "Cannot connect to integration manager": "不能连接到集成管理器",
+ "The integration manager is offline or it cannot reach your homeserver.": "此集成管理器为离线状态或者其不能访问您的主服务器。",
+ "check your browser plugins for anything that might block the identity server (such as Privacy Badger)": "检查您的浏览器是否安装有可能屏蔽身份服务器的插件(例如 Privacy Badger)",
+ "Use an Integration Manager (%(serverName)s) to manage bots, widgets, and sticker packs.": "使用集成管理器 (%(serverName)s) 以管理机器人、小挂件和贴图集。",
+ "Use an Integration Manager to manage bots, widgets, and sticker packs.": "使用集成管理器以管理机器人、小挂件和贴图集。",
+ "Manage integrations": "管理集成",
+ "Integration Managers receive configuration data, and can modify widgets, send room invites, and set power levels on your behalf.": "集成管理器接收配置数据,并可以以您的名义修改小挂件、发送聊天室邀请及设置权限级别。",
+ "Use between %(min)s pt and %(max)s pt": "请使用介于 %(min)s pt 和 %(max)s pt 之间的大小",
+ "Deactivate account": "停用帐号",
+ "To report a Matrix-related security issue, please read the Matrix.org Security Disclosure Policy.": "要报告 Matrix 相关的安全问题,请阅读 Matrix.org 的安全公开策略。",
+ "Something went wrong. Please try again or view your console for hints.": "出现问题。请重试或查看您的终端以获得提示。",
+ "Please try again or view your console for hints.": "请重试或查看您的终端以获得提示。",
+ "Your server admin has disabled end-to-end encryption by default in private rooms & Direct Messages.": "您的服务器管理员未在私人聊天室和私聊中默认启用端对端加密。",
+ "Manage the names of and sign out of your sessions below or verify them in your User Profile.": "在下方管理会话名称,登出您的会话或在您的用户资料中验证它们。",
+ "This room is bridging messages to the following platforms. Learn more.": "此聊天室正将消息桥接到以下平台。了解更多。",
+ "This room isn’t bridging messages to any platforms. Learn more.": "此聊天室未将消息桥接到任何平台。了解更多。",
+ "Bridges": "桥接",
+ "Someone is using an unknown session": "有人在使用未知会话",
+ "This room is end-to-end encrypted": "此聊天室是端对端加密的",
+ "Everyone in this room is verified": "聊天室中所有人都已被验证",
+ "Edit message": "编辑消息",
+ "Your key share request has been sent - please check your other sessions for key share requests.": "您的密钥共享请求已发送——请检查您别的会话。",
+ "Key share requests are sent to your other sessions automatically. If you rejected or dismissed the key share request on your other sessions, click here to request the keys for this session again.": "密钥共享请求会自动发送至您别的会话。如果您拒绝或忽略了您别的会话上的密钥共享请求,请点击此处重新为此会话请求密钥。",
+ "If your other sessions do not have the key for this message you will not be able to decrypt them.": "如果您别的会话没有此消息的密钥您将不能解密它们。",
+ "Re-request encryption keys from your other sessions.": "从您别的会话重新请求加密密钥。",
+ "This message cannot be decrypted": "此消息无法被解密",
+ "Encrypted by an unverified session": "由未验证的会话加密",
+ "Unencrypted": "未加密",
+ "Encrypted by a deleted session": "由已删除的会话加密",
+ "The authenticity of this encrypted message can't be guaranteed on this device.": "此加密消息的权威性不能在此设备上被保证。",
+ "Scroll to most recent messages": "滚动到最近的消息",
+ "Close preview": "关闭预览",
+ "Emoji picker": "表情符号选择器",
+ "Send a reply…": "发送回复…",
+ "Send a message…": "发送消息…",
+ "Bold": "粗体",
+ "Italics": "斜体",
+ "Strikethrough": "删除线",
+ "Code block": "代码块",
+ "Room %(name)s": "聊天室 %(name)s",
+ "No recently visited rooms": "没有最近访问过的聊天室",
+ "People": "联系人",
+ "Create room": "创建聊天室",
+ "Custom Tag": "自定义标签",
+ "Joining room …": "正在加入聊天室…",
+ "Loading …": "正在加载…",
+ "Rejecting invite …": "正在拒绝邀请…",
+ "Join the conversation with an account": "使用一个账户加入对话",
+ "Sign Up": "注册",
+ "Loading room preview": "正在加载聊天室预览",
+ "You were kicked from %(roomName)s by %(memberName)s": "您被 %(memberName)s 踢出了 %(roomName)s",
+ "Reason: %(reason)s": "原因:%(reason)s",
+ "Forget this room": "忘记此聊天室",
+ "Re-join": "重新加入",
+ "You were banned from %(roomName)s by %(memberName)s": "您被 %(memberName)s 从 %(roomName)s 封禁了",
+ "Something went wrong with your invite to %(roomName)s": "您到 %(roomName)s 的邀请出错",
+ "An error (%(errcode)s) was returned while trying to validate your invite. You could try to pass this information on to a room admin.": "尝试验证您的邀请时返回错误(%(errcode)s)。您可以将此信息转告给聊天室管理员。",
+ "Try to join anyway": "仍然尝试加入",
+ "You can still join it because this is a public room.": "您仍然能加入,因为这是一个公共聊天室。",
+ "Join the discussion": "加入讨论",
+ "This invite to %(roomName)s was sent to %(email)s which is not associated with your account": "这个到 %(roomName)s 的邀请是发送给 %(email)s 的,而此邮箱没有关联您的账户",
+ "Link this email with your account in Settings to receive invites directly in %(brand)s.": "要在 %(brand)s 中直接接收邀请,请在设置中将您的账户连接到此邮箱。",
+ "This invite to %(roomName)s was sent to %(email)s": "这个到 %(roomName)s 的邀请是发送给 %(email)s 的",
+ "Use an identity server in Settings to receive invites directly in %(brand)s.": "要直接在 %(brand)s 中接收邀请,请在设置中使用一个身份服务器。",
+ "Share this email in Settings to receive invites directly in %(brand)s.": "要在 %(brand)s 中直接接收邀请,请在设置中共享此邮箱。",
+ "Do you want to chat with %(user)s?": "您想和 %(user)s 聊天吗?",
+ " wants to chat": " 想聊天",
+ "Start chatting": "开始聊天",
+ "Do you want to join %(roomName)s?": "您想加入 %(roomName)s 吗?",
+ " invited you": " 邀请了您",
+ "Reject & Ignore user": "拒绝并忽略用户",
+ "You're previewing %(roomName)s. Want to join it?": "您正在预览 %(roomName)s。想加入吗?",
+ "%(roomName)s can't be previewed. Do you want to join it?": "%(roomName)s 不能被预览。您想加入吗?",
+ "This room doesn't exist. Are you sure you're at the right place?": "此聊天室不存在。您确定您在正确的地方吗?",
+ "Try again later, or ask a room admin to check if you have access.": "请稍后重试,或询问聊天室管理员以检查您是否有权限。",
+ "%(errcode)s was returned while trying to access the room. If you think you're seeing this message in error, please submit a bug report.": "尝试访问该房间是返回了 %(errcode)s。如果您认为您看到此消息是个错误,请提交一个错误报告。",
+ "Appearance": "外观",
+ "Show rooms with unread messages first": "优先显示有未读消息的聊天室",
+ "Show previews of messages": "显示消息预览",
+ "Sort by": "排序",
+ "Activity": "活动",
+ "A-Z": "字典顺序",
+ "List options": "列表选项",
+ "Jump to first unread room.": "跳转至第一个未读聊天室。",
+ "Jump to first invite.": "跳转至第一个邀请。",
+ "Add room": "添加聊天室",
+ "Show %(count)s more|other": "多显示 %(count)s 个",
+ "Show %(count)s more|one": "多显示 %(count)s 个",
+ "Use default": "使用默认",
+ "Mentions & Keywords": "提及和关键词",
+ "Notification options": "通知选项",
+ "Leave Room": "离开聊天室",
+ "Forget Room": "忘记聊天室",
+ "Favourited": "已收藏",
+ "Room options": "聊天室选项",
+ "%(count)s unread messages including mentions.|other": "包括提及在内有 %(count)s 个未读消息。",
+ "%(count)s unread messages including mentions.|one": "1 个未读提及。",
+ "%(count)s unread messages.|other": "%(count)s 个未读消息。",
+ "%(count)s unread messages.|one": "1 个未读消息。",
+ "Unread messages.": "未读消息。",
+ "This room is public": "此聊天室为公共的",
+ "Away": "离开",
+ "This room has already been upgraded.": "此聊天室已经被升级。",
+ "Unknown Command": "未知命令",
+ "Unrecognised command: %(commandText)s": "未识别的命令:%(commandText)s",
+ "You can use /help to list available commands. Did you mean to send this as a message?": "您可以使用 /help 列出可用命令。您是否要将其作为消息发送?",
+ "Hint: Begin your message with // to start it with a slash.": "提示:以 // 开始您的消息来使其以一个斜杠开始。",
+ "Send as message": "作为消息发送",
+ "Failed to connect to integration manager": "连接至集成管理器失败",
+ "Mark all as read": "标记所有为已读",
+ "There was an error updating the room's alternative addresses. It may not be allowed by the server or a temporary failure occurred.": "更新此聊天室的备用地址时出现错误。可能是服务器不允许,也可能是出现了一个暂时的错误。",
+ "Error creating address": "创建地址时出现错误",
+ "There was an error creating that address. It may not be allowed by the server or a temporary failure occurred.": "创建地址时出现错误。可能是服务器不允许,也可能是出现了一个暂时的错误。",
+ "You don't have permission to delete the address.": "您没有权限删除此地址。",
+ "There was an error removing that address. It may no longer exist or a temporary error occurred.": "删除那个地址时出现错误。可能它已不存在,也可能出现了一个暂时的错误。",
+ "Error removing address": "删除地址时出现错误",
+ "Local address": "本地地址",
+ "Published Addresses": "发布的地址",
+ "Published addresses can be used by anyone on any server to join your room. To publish an address, it needs to be set as a local address first.": "发布的地址可以被任何服务器上的任何人用来加入您的聊天室。要发布一个地址,它必须先被设为一个本地地址。",
+ "Other published addresses:": "其它发布的地址:",
+ "No other published addresses yet, add one below": "还没有别的发布的地址,可在下方添加",
+ "New published address (e.g. #alias:server)": "新的发布的地址(例如 #alias:server)",
+ "Local Addresses": "本地地址",
+ "Set addresses for this room so users can find this room through your homeserver (%(localDomain)s)": "为此聊天室设置地址以便用户通过您的主服务器(%(localDomain)s)找到此聊天室",
+ "Waiting for you to accept on your other session…": "等待您在您别的会话上接受…",
+ "Waiting for %(displayName)s to accept…": "等待 %(displayName)s 接受…",
+ "Accepting…": "正在接受…",
+ "Start Verification": "开始验证",
+ "Messages in this room are end-to-end encrypted.": "此聊天室内的消息是端对端加密的。",
+ "Your messages are secured and only you and the recipient have the unique keys to unlock them.": "您的消息是安全的,只有您和收件人有解开它们的唯一密钥。",
+ "Messages in this room are not end-to-end encrypted.": "此聊天室内的消息未端对端加密。",
+ "In encrypted rooms, your messages are secured and only you and the recipient have the unique keys to unlock them.": "在加密聊天室中,您的消息是安全的,只有您和收件人有解开它们的唯一密钥。",
+ "Verify User": "验证用户",
+ "For extra security, verify this user by checking a one-time code on both of your devices.": "为了更加安全,通过在您二者的设备上检查一次性代码来验证此用户。",
+ "Your messages are not secure": "您的消息不安全",
+ "One of the following may be compromised:": "以下之一可能被损害:",
+ "Your homeserver": "您的主服务器",
+ "The homeserver the user you’re verifying is connected to": "您在验证的用户连接到的主服务器",
+ "Yours, or the other users’ internet connection": "您的或另一位用户的网络连接",
+ "Yours, or the other users’ session": "您的或另一位用户的会话",
+ "Trusted": "受信任的",
+ "Not trusted": "不受信任的",
+ "%(count)s verified sessions|other": "%(count)s 个已验证的会话",
+ "%(count)s verified sessions|one": "1 个已验证的会话",
+ "Hide verified sessions": "隐藏已验证的会话",
+ "%(count)s sessions|other": "%(count)s 个会话",
+ "%(count)s sessions|one": "%(count)s 个会话",
+ "Hide sessions": "隐藏会话",
+ "Direct message": "私聊",
+ "No recent messages by %(user)s found": "没有找到 %(user)s 最近发送的消息",
+ "Try scrolling up in the timeline to see if there are any earlier ones.": "请尝试在时间线中向上滚动以查看是否有更早的。",
+ "Remove recent messages by %(user)s": "删除 %(user)s 最近发送的消息",
+ "You are about to remove %(count)s messages by %(user)s. This cannot be undone. Do you wish to continue?|other": "您将删除 %(user)s 发送的 %(count)s 条消息。此操作不能撤销。您想继续吗?",
+ "You are about to remove %(count)s messages by %(user)s. This cannot be undone. Do you wish to continue?|one": "您将删除 %(user)s 发送的 1 条消息。此操作不能撤销。您想继续吗?",
+ "For a large amount of messages, this might take some time. Please don't refresh your client in the meantime.": "对于大量消息,可能会消耗一段时间。在此期间请不要刷新您的客户端。",
+ "Remove %(count)s messages|other": "删除 %(count)s 条消息",
+ "Remove %(count)s messages|one": "删除 1 条消息",
+ "Remove recent messages": "删除最近消息",
+ "%(role)s in %(roomName)s": "%(roomName)s 中的 %(role)s",
+ "Deactivate user?": "停用用户吗?",
+ "Deactivating this user will log them out and prevent them from logging back in. Additionally, they will leave all the rooms they are in. This action cannot be reversed. Are you sure you want to deactivate this user?": "停用此用户将会使其登出并阻止其再次登入。而且此用户也会离开其所在的所有聊天室。此操作不可逆。您确定要停用此用户吗?",
+ "Deactivate user": "停用用户",
+ "Failed to deactivate user": "停用用户失败",
+ "This client does not support end-to-end encryption.": "此客户端不支持端对端加密。",
+ "Security": "安全",
+ "Verify by scanning": "扫码验证",
+ "Ask %(displayName)s to scan your code:": "请 %(displayName)s 扫描您的代码:",
+ "If you can't scan the code above, verify by comparing unique emoji.": "如果您不能扫描以上代码,请通过比较唯一的表情符号来验证。",
+ "Verify by comparing unique emoji.": "通过比较唯一的表情符号来验证。",
+ "Verify by emoji": "通过表情符号验证",
+ "Almost there! Is your other session showing the same shield?": "快完成了!您的另一个会话显示了同样的盾牌吗?",
+ "Almost there! Is %(displayName)s showing the same shield?": "快完成了!%(displayName)s 显示了同样的盾牌吗?",
+ "Verify all users in a room to ensure it's secure.": "验证聊天室中所有用户以确保其安全。",
+ "In encrypted rooms, verify all users to ensure it’s secure.": "在加密聊天室中,验证所有用户以确保其安全。",
+ "You've successfully verified your device!": "您成功验证了您的设备!",
+ "You've successfully verified %(deviceName)s (%(deviceId)s)!": "您成功验证了 %(deviceName)s (%(deviceId)s)!",
+ "You've successfully verified %(displayName)s!": "您成功验证了 %(displayName)s!",
+ "Verified": "已验证",
+ "Got it": "知道了",
+ "Start verification again from the notification.": "请从提示重新开始验证。",
+ "Start verification again from their profile.": "请从对方资料重新开始验证。",
+ "Verification timed out.": "雅正超时。",
+ "You cancelled verification on your other session.": "您在您别的会话上取消了验证。",
+ "%(displayName)s cancelled verification.": "%(displayName)s 取消了验证。",
+ "You cancelled verification.": "您取消了验证。",
+ "Verification cancelled": "验证已取消",
+ "Compare emoji": "比较表情符号",
+ "Encryption enabled": "加密已启用",
+ "Messages in this room are end-to-end encrypted. Learn more & verify this user in their user profile.": "此聊天室中的消息是端对端加密的。请在其用户资料中了解更多并验证此用户。",
+ "Encryption not enabled": "加密未启用",
+ "The encryption used by this room isn't supported.": "不支持此聊天室使用的加密方式。",
+ "React": "回应",
+ "Message Actions": "消息操作",
+ "Show image": "显示图像",
+ "You have ignored this user, so their message is hidden. Show anyways.": "您已忽略该用户,所以其消息已被隐藏。仍然显示。",
+ "You verified %(name)s": "您验证了 %(name)s",
+ "You cancelled verifying %(name)s": "您取消了 %(name)s 的验证",
+ "%(name)s cancelled verifying": "%(name)s 取消了验证",
+ "You accepted": "您接受了",
+ "%(name)s accepted": "%(name)s 接受了",
+ "You declined": "您拒绝了",
+ "You cancelled": "您取消了",
+ "%(name)s declined": "%(name)s 拒绝了",
+ "%(name)s cancelled": "%(name)s 取消了",
+ "Accepting …": "正在接受…",
+ "Declining …": "正在拒绝…",
+ "%(name)s wants to verify": "%(name)s 想要验证",
+ "You sent a verification request": "您发送了一个验证请求",
+ "Show all": "显示全部",
+ "Reactions": "回应",
+ " reacted with %(content)s": " 回应了 %(content)s",
+ "reacted with %(shortName)s": "回应了 %(shortName)s",
+ "Message deleted": "消息已删除",
+ "Message deleted by %(name)s": "消息被 %(name)s 删除",
+ "Message deleted on %(date)s": "消息于 %(date)s 被删除",
+ "Edited at %(date)s": "编辑于 %(date)s",
+ "Click to view edits": "点击查看编辑",
+ "Edited at %(date)s. Click to view edits.": "编辑于 %(date)s。点击以查看编辑。",
+ "edited": "被编辑过",
+ "Can't load this message": "无法加载此消息",
+ "Submit logs": "提交日志",
+ "Frequently Used": "经常使用",
+ "Smileys & People": "表情和人",
+ "Animals & Nature": "动物和自然",
+ "Food & Drink": "食物和饮料",
+ "Activities": "活动",
+ "Travel & Places": "旅行和地点",
+ "Objects": "物体",
+ "Symbols": "符号",
+ "Flags": "旗帜",
+ "Categories": "类别",
+ "Quick Reactions": "快速回应",
+ "Cancel search": "取消搜索",
+ "Any of the following data may be shared:": "以下数据之一可能被分享:",
+ "Your display name": "您的显示名称",
+ "Your avatar URL": "您的头像链接",
+ "Your user ID": "您的用户 ID",
+ "Your theme": "您的主题",
+ "%(brand)s URL": "%(brand)s 的链接",
+ "Room ID": "聊天室 ID",
+ "Widget ID": "小挂件 ID",
+ "Using this widget may share data with %(widgetDomain)s & your Integration Manager.": "使用此小挂件可能会和 %(widgetDomain)s 及您的集成管理器共享数据 。",
+ "Using this widget may share data with %(widgetDomain)s.": "使用此小挂件可能会和 %(widgetDomain)s 共享数据 。",
+ "Widgets do not use message encryption.": "小挂件不适用消息加密。",
+ "This widget may use cookies.": "此小挂件可能使用 cookie。",
+ "More options": "更多选项",
+ "Please create a new issue on GitHub so that we can investigate this bug.": "请在 GitHub 上创建一个新 issue 以便我们调查此错误。",
+ "Rotate Left": "向左旋转",
+ "Rotate counter-clockwise": "逆时针旋转",
+ "Rotate Right": "向右旋转",
+ "Rotate clockwise": "顺时针旋转",
+ "QR Code": "QR 码",
+ "Room address": "聊天室地址",
+ "e.g. my-room": "例如 my-room",
+ "Some characters not allowed": "一些字符不被允许",
+ "Please provide a room address": "请提供一个聊天室地址",
+ "This address is available to use": "此地址可用",
+ "This address is already in use": "此地址已被使用",
+ "Enter a server name": "输入一个服务器名",
+ "Looks good": "看着不错",
+ "Can't find this server or its room list": "不能找到此服务器或其聊天室列表",
+ "All rooms": "所有聊天室",
+ "Your server": "您的服务器",
+ "Are you sure you want to remove %(serverName)s": "您确定想删除 %(serverName)s 吗",
+ "Remove server": "删除服务器",
+ "Matrix": "Matrix",
+ "Add a new server": "添加一个新服务器",
+ "Enter the name of a new server you want to explore.": "输入您想探索的新服务器名。",
+ "Server name": "服务器名",
+ "Add a new server...": "添加一个新服务器...",
+ "%(networkName)s rooms": "%(networkName)s 的聊天室",
+ "Matrix rooms": "Matrix 聊天室",
+ "Use an identity server to invite by email. Use the default (%(defaultIdentityServerName)s) or manage in Settings.": "使用一个身份服务器以通过邮箱邀请。使用默认(%(defaultIdentityServerName)s)或在设置中管理。",
+ "Use an identity server to invite by email. Manage in Settings.": "使用一个身份服务器以通过邮箱邀请。在设置中管理。",
+ "Close dialog": "关闭对话框",
+ "Please tell us what went wrong or, better, create a GitHub issue that describes the problem.": "请告诉我们哪里出错了,或最好创建一个 GitHub issue 来描述该问题。",
+ "Reminder: Your browser is unsupported, so your experience may be unpredictable.": "提醒:您的浏览器不被支持,所以您的体验可能不可预料。",
+ "GitHub issue": "GitHub issue",
+ "Notes": "提示",
+ "If there is additional context that would help in analysing the issue, such as what you were doing at the time, room IDs, user IDs, etc., please include those things here.": "如果有额外的上下文可以帮助我们分析问题,比如您当时在做什么、房间 ID、用户 ID 等等,请将其列于此处。",
+ "Removing…": "正在删除…",
+ "Destroy cross-signing keys?": "销毁交叉签名密钥?",
+ "Deleting cross-signing keys is permanent. Anyone you have verified with will see security alerts. You almost certainly don't want to do this, unless you've lost every device you can cross-sign from.": "删除交叉签名密钥是永久的。所有您验证过的人都会看到安全警报。除非您丢失了所有可以交叉签名的设备,否则几乎可以确定您不想这么做。",
+ "Clear cross-signing keys": "清楚交叉签名密钥",
+ "Clear all data in this session?": "清除此会话中的所有数据吗?",
+ "Clearing all data from this session is permanent. Encrypted messages will be lost unless their keys have been backed up.": "清除此会话中的所有数据是永久的。加密消息会丢失,除非其密钥已被备份。",
+ "Clear all data": "清除所有数据",
+ "Please enter a name for the room": "请为此聊天室输入一个名称",
+ "Set a room address to easily share your room with other people.": "设置一个聊天室地址以轻松地和别人共享您的聊天室。",
+ "This room is private, and can only be joined by invitation.": "此聊天室是私人的,只能通过邀请加入。",
+ "You can’t disable this later. Bridges & most bots won’t work yet.": "您之后不能禁用此项。桥接和大部分机器人还不能正常工作。",
+ "Enable end-to-end encryption": "启用端对端加密",
+ "Create a public room": "创建一个公共聊天室",
+ "Create a private room": "创建一个私人聊天室",
+ "Topic (optional)": "主题(可选)",
+ "Make this room public": "将此聊天室设为公共的",
+ "Hide advanced": "隐藏高级",
+ "Show advanced": "显示高级",
+ "Block users on other matrix homeservers from joining this room (This setting cannot be changed later!)": "阻止别的 matrix 主服务器上的用户加入此聊天室(此设置之后不能更改!)",
+ "You've previously used a newer version of %(brand)s with this session. To use this version again with end to end encryption, you will need to sign out and back in again.": "您曾在此会话中使用了一个更新版本的 %(brand)s。要再使用此版本并使用端对端加密,您需要登出再重新登录。",
+ "Confirm your account deactivation by using Single Sign On to prove your identity.": "通过单点登录证明您的身份并确认停用您的账户。",
+ "Are you sure you want to deactivate your account? This is irreversible.": "您确定要停用您的账号吗?此操作不可逆。",
+ "Confirm account deactivation": "确认账号停用",
+ "There was a problem communicating with the server. Please try again.": "联系服务器时出现问题。请重试。",
+ "Server did not require any authentication": "服务器不要求任何认证",
+ "Server did not return valid authentication information.": "服务器未返回有效认证信息。",
+ "View Servers in Room": "查看聊天室中的服务器",
+ "Verification Requests": "验证请求",
+ "Verifying this user will mark their session as trusted, and also mark your session as trusted to them.": "验证此用户会将其会话标记为受信任的,并将您的会话对其标记为受信任的。",
+ "Verify this device to mark it as trusted. Trusting this device gives you and other users extra peace of mind when using end-to-end encrypted messages.": "验证此设备以将其标记为受信任的。信任此设备可让您和别的用户在使用端对端加密消息时更加放心。",
+ "Verifying this device will mark it as trusted, and users who have verified with you will trust this device.": "验证此设备会将其标记为受信任的,而验证了您的用户将会信任此设备。",
+ "Integrations are disabled": "集成已禁用",
+ "Enable 'Manage Integrations' in Settings to do this.": "在设置中启用「管理集成」以执行此操作。",
+ "Integrations not allowed": "集成未被允许",
+ "Your %(brand)s doesn't allow you to use an Integration Manager to do this. Please contact an admin.": "您的 %(brand)s 不允许您使用集成管理器来完成此操作。请联系管理员。",
+ "To continue, use Single Sign On to prove your identity.": "要继续,请使用单点登录证明您的身份。",
+ "Confirm to continue": "确认以继续",
+ "Click the button below to confirm your identity.": "点击下方按钮确认您的身份。",
+ "Failed to invite the following users to chat: %(csvUsers)s": "邀请以下用户加入聊天失败:%(csvUsers)s",
+ "Something went wrong trying to invite the users.": "尝试邀请用户时出错。",
+ "We couldn't invite those users. Please check the users you want to invite and try again.": "我们不能邀请这些用户。请检查您想邀请的用户并重试。",
+ "Failed to find the following users": "寻找以下用户失败",
+ "The following users might not exist or are invalid, and cannot be invited: %(csvNames)s": "下列用户可能不存在或无效,因此不能被邀请:%(csvNames)s",
+ "Recent Conversations": "最近对话",
+ "Suggestions": "建议",
+ "Recently Direct Messaged": "最近私聊",
+ "Direct Messages": "私聊",
+ "Start a conversation with someone using their name, username (like ) or email address.": "使用名字,用户名(像是 )或邮件地址和某人开始对话。",
+ "Go": "前往",
+ "Invite someone using their name, username (like ), email address or share this room.": "使用名字,用户名(像是 )或邮件地址邀请某人,或者分享此聊天室。",
+ "a new master key signature": "一个新的主密钥签名",
+ "a new cross-signing key signature": "一个新的交叉签名密钥的签名",
+ "a device cross-signing signature": "一个设备的交叉签名的签名",
+ "a key signature": "一个密钥签名",
+ "Upload completed": "上传完成",
+ "Cancelled signature upload": "已取消签名上传",
+ "Unable to upload": "无法上传",
+ "Signature upload success": "签名上传成功",
+ "Signature upload failed": "签名上传失败",
+ "If the other version of %(brand)s is still open in another tab, please close it as using %(brand)s on the same host with both lazy loading enabled and disabled simultaneously will cause issues.": "如果别的 %(brand)s 版本在别的标签页中仍然开启,请关闭它,因为在同一宿主上同时使用开启了延迟加载和关闭了延迟加载的 %(brand)s 会导致问题。",
+ "Confirm by comparing the following with the User Settings in your other session:": "通过比较下方内容和您别的会话中的用户设置来确认:",
+ "Confirm this user's session by comparing the following with their User Settings:": "通过比较下方内容和对方用户设置来确认此用户会话:",
+ "Session name": "会话名称",
+ "Session key": "会话密钥",
+ "If they don't match, the security of your communication may be compromised.": "如果它们不匹配,您通讯的安全性可能已受损。",
+ "Verify session": "验证会话",
+ "Your homeserver doesn't seem to support this feature.": "您的主服务器似乎不支持此功能。",
+ "Message edits": "消息编辑",
+ "Your account is not secure": "您的账户不安全",
+ "Your password": "您的密码",
+ "This session, or the other session": "此会话,或别的会话",
+ "The internet connection either session is using": "您会话使用的网络连接",
+ "We recommend you change your password and recovery key in Settings immediately": "我们推荐您立刻在设置中更改您的密码和恢复密钥",
+ "New session": "新会话",
+ "Use this session to verify your new one, granting it access to encrypted messages:": "使用此会话以验证您的新会话,并允许其访问加密信息:",
+ "If you didn’t sign in to this session, your account may be compromised.": "如果您没有登录进此会话,您的账户可能已受损。",
+ "This wasn't me": "这不是我",
+ "Use your account to sign in to the latest version of the app at ": "使用您的账户在 登录此应用的最新版",
+ "You’re already signed in and good to go here, but you can also grab the latest versions of the app on all platforms at element.io/get-started.": "您已经登录且一切已就绪,但您也可以在 element.io/get-started 获取此应用在全平台上的最新版。",
+ "Go to Element": "前往 Element",
+ "We’re excited to announce Riot is now Element!": "我们很兴奋地宣布 Riot 现在是 Element 了!",
+ "Learn more at element.io/previously-riot": "访问 element.io/previously-riot 了解更多",
+ "Please fill why you're reporting.": "请填写您为何做此报告。",
+ "Report Content to Your Homeserver Administrator": "向您的主服务器管理员举报内容",
+ "Reporting this message will send its unique 'event ID' to the administrator of your homeserver. If messages in this room are encrypted, your homeserver administrator will not be able to read the message text or view any files or images.": "举报此消息会将其唯一的「事件 ID」发送给您的主服务器的管理员。如果此聊天室中的消息被加密,您的主服务器管理员将不能阅读消息文本,也不能查看任何文件或图片。",
+ "Send report": "发送报告",
+ "Upgrading this room requires closing down the current instance of the room and creating a new room in its place. To give room members the best possible experience, we will:": "更新此聊天室需要关闭此聊天室的当前实力并创建一个新的聊天室代替它。为了给聊天室成员最好的体验,我们会:",
+ "Automatically invite users": "自动邀请用户",
+ "Upgrade private room": "更新私人聊天室",
+ "Upgrade public room": "更新公共聊天室",
+ "Upgrading a room is an advanced action and is usually recommended when a room is unstable due to bugs, missing features or security vulnerabilities.": "更新聊天室是高级操作,通常建议在聊天室由于错误、缺失功能或安全漏洞而不稳定时使用。",
+ "This usually only affects how the room is processed on the server. If you're having problems with your %(brand)s, please report a bug.": "通常这只影响聊天室在服务器上的处理方式。如果您对您的 %(brand)s 有问题,请报告一个错误。",
+ "You'll upgrade this room from to .": "您将把此聊天室从 升级至 。",
+ "You're all caught up.": "全数阅毕。",
+ "Server isn't responding": "服务器未响应",
+ "Your server isn't responding to some of your requests. Below are some of the most likely reasons.": "您的服务器未响应您的一些请求。下方是一些最可能的原因。",
+ "The server (%(serverName)s) took too long to respond.": "服务器(%(serverName)s)花了太长时间响应。",
+ "Your firewall or anti-virus is blocking the request.": "您的防火墙或防病毒软件阻止了该请求。",
+ "A browser extension is preventing the request.": "一个浏览器扩展阻止了该请求。",
+ "The server is offline.": "该服务器为离线状态。",
+ "The server has denied your request.": "该服务器拒绝了您的请求。",
+ "Your area is experiencing difficulties connecting to the internet.": "您的区域难以连接上互联网。",
+ "A connection error occurred while trying to contact the server.": "尝试联系服务器时出现连接错误。",
+ "Recent changes that have not yet been received": "尚未被接受的最近更改",
+ "Sign out and remove encryption keys?": "登出并删除加密密钥?",
+ "This will allow you to return to your account after signing out, and sign in on other sessions.": "这允许您在登出后返回您的账户并在别的会话上登录。",
+ "Command Help": "命令帮助",
+ "To help us prevent this in future, please send us logs.": "要帮助我们防止其以后发生,请给我们发送日志。",
+ "Missing session data": "缺失会话数据",
+ "Some session data, including encrypted message keys, is missing. Sign out and sign in to fix this, restoring keys from backup.": "一些会话数据,包括加密消息密钥,已缺失。要修复此问题,登出并重新登录,然后从备份恢复密钥。",
+ "Your browser likely removed this data when running low on disk space.": "您的浏览器可能在磁盘空间不足时删除了此数据。",
+ "Integration Manager": "集成管理器",
+ "Find others by phone or email": "通过电话或邮箱寻找别人",
+ "Be found by phone or email": "通过电话或邮箱被寻找",
+ "Use bots, bridges, widgets and sticker packs": "使用机器人、桥接、小挂件和贴图集",
+ "Terms of Service": "服务协议",
+ "To continue you need to accept the terms of this service.": "要继续,您需要接受此服务协议。",
+ "Service": "服务",
+ "Summary": "总结",
+ "Document": "文档",
+ "Upload files (%(current)s of %(total)s)": "上传文件(%(total)s 中之 %(current)s)",
+ "Upload files": "上传文件",
+ "Upload all": "全部上传",
+ "This file is too large to upload. The file size limit is %(limit)s but this file is %(sizeOfThisFile)s.": "此文件过大而不能上传。文件大小限制是 %(limit)s 但此文件为 %(sizeOfThisFile)s。",
+ "These files are too large to upload. The file size limit is %(limit)s.": "这些文件过大而不能上传。文件大小限制为 %(limit)s。",
+ "Some files are too large to be uploaded. The file size limit is %(limit)s.": "一些文件过大而不能上传。文件大小限制为 %(limit)s。",
+ "Upload %(count)s other files|other": "上传 %(count)s 个别的文件",
+ "Upload %(count)s other files|one": "上传 %(count)s 个别的文件",
+ "Cancel All": "全部取消",
+ "Upload Error": "上传错误",
+ "Verify other session": "验证别的会话",
+ "Verification Request": "验证请求",
+ "Wrong file type": "错误文件类型",
+ "Looks good!": "看着不错!",
+ "Wrong Recovery Key": "错误的恢复密钥",
+ "Invalid Recovery Key": "无效的恢复密钥",
+ "Security Phrase": "安全密码",
+ "Unable to access secret storage. Please verify that you entered the correct recovery passphrase.": "无法访问秘密存储。请确认您输入了正确的恢复密码。",
+ "Enter your Security Phrase or Use your Security Key to continue.": "输入您的安全密码或使用您的安全密钥以继续。",
+ "Security Key": "安全密钥",
+ "Use your Security Key to continue.": "使用您的安全密钥以继续。",
+ "Restoring keys from backup": "从备份恢复密钥",
+ "Fetching keys from server...": "正在从服务器获取密钥...",
+ "%(completed)s of %(total)s keys restored": "%(total)s 个密钥中之 %(completed)s 个已恢复",
+ "Recovery key mismatch": "恢复密钥不匹配",
+ "Backup could not be decrypted with this recovery key: please verify that you entered the correct recovery key.": "备份不能被此恢复密钥解密:请确认您输入了正确的恢复密钥。",
+ "Incorrect recovery passphrase": "不正确的恢复密码",
+ "Backup could not be decrypted with this recovery passphrase: please verify that you entered the correct recovery passphrase.": "备份不能被此恢复密码解密:请确认您输入了正确的恢复密码。",
+ "Keys restored": "已恢复密钥",
+ "Successfully restored %(sessionCount)s keys": "成功恢复了 %(sessionCount)s 个密钥",
+ "Enter recovery passphrase": "输入恢复密码",
+ "Enter recovery key": "输入恢复密钥",
+ "Warning: You should only set up key backup from a trusted computer.": "警告:您应该只从信任的计算机设置密钥备份。",
+ "If you've forgotten your recovery key you can set up new recovery options": "如果您忘记了恢复密钥,您可以设置新的恢复选项",
+ "Address (optional)": "地址(可选)",
+ "Resend edit": "重新发送编辑",
+ "Resend %(unsentCount)s reaction(s)": "重新发送 %(unsentCount)s 个回应",
+ "Resend removal": "重新发送删除",
+ "Report Content": "举报内容",
+ "Notification settings": "通知设置",
+ "Help": "帮助",
+ "Reload": "重新加载",
+ "Take picture": "拍照",
+ "Remove for everyone": "为所有人删除",
+ "Remove for me": "为我删除",
+ "User Status": "用户状态",
+ "You can use the custom server options to sign into other Matrix servers by specifying a different homeserver URL. This allows you to use %(brand)s with an existing Matrix account on a different homeserver.": "您可以使用自定义服务器选项以使用不同的主服务器链接登录至别的 Matrix 服务器。这允许您通过不同的主服务器上的现存 Matrix 账户使用 %(brand)s。",
+ "Confirm your identity by entering your account password below.": "在下方输入账户密码以确认您的身份。",
+ "Missing captcha public key in homeserver configuration. Please report this to your homeserver administrator.": "在主服务器配置中缺少验证码公钥。请将此报告给您的主服务器管理员。",
+ "Unable to validate homeserver/identity server": "无法验证主服务器/身份服务器",
+ "Enter the location of your Element Matrix Services homeserver. It may use your own domain name or be a subdomain of element.io.": "输入您的 Element Matrix Services 主服务器的地址。它可能使用您自己的域名,也可能是 element.io 的子域名。",
+ "Enter password": "输入密码",
+ "Nice, strong password!": "不错,是个强密码!",
+ "Password is allowed, but unsafe": "密码允许但不安全",
+ "No identity server is configured so you cannot add an email address in order to reset your password in the future.": "没有配置身份服务器因此您不能添加邮件地址以在将来重置您的密码。",
+ "Use an email address to recover your account": "使用邮件地址恢复您的账户",
+ "Enter email address (required on this homeserver)": "输入邮件地址(此主服务器上必须)",
+ "Doesn't look like a valid email address": "看起来不像有效的邮件地址",
+ "Passwords don't match": "密码不匹配",
+ "Other users can invite you to rooms using your contact details": "别的用户可以使用您的联系人信息邀请您加入聊天室",
+ "Enter phone number (required on this homeserver)": "输入电话号码(此主服务器上必须)",
+ "Doesn't look like a valid phone number": "看着不像一个有效的电话号码",
+ "Use lowercase letters, numbers, dashes and underscores only": "仅使用小写字母,数字,横杠和下划线",
+ "Enter username": "输入用户名",
+ "Create your Matrix account on ": "在 上创建您的 Matrix 账户",
+ "Set an email for account recovery. Use email or phone to optionally be discoverable by existing contacts.": "设置邮箱以便恢复账户。您可以选择让现存联系人通过邮箱或电话发现您。",
+ "Set an email for account recovery. Use email to optionally be discoverable by existing contacts.": "设置邮箱以便恢复账户。您可以选择让现存联系人通过邮箱发现您。",
+ "Enter your custom homeserver URL What does this mean?": "设置您自定义的主服务器链接这是什么意思?",
+ "Enter your custom identity server URL What does this mean?": "输入您自定义的身份服务器链接这是什么意思?",
+ "Sign in to your Matrix account on ": "登录到您在 上的 Matrix 账户",
+ "Sign in with SSO": "使用单点登录",
+ "No files visible in this room": "此聊天室中没有可见文件",
+ "Welcome to %(appName)s": "欢迎来到 %(appName)s",
+ "Liberate your communication": "解放您的交流",
+ "Send a Direct Message": "发送私聊",
+ "Explore Public Rooms": "探索公共聊天室",
+ "Create a Group Chat": "创建一个群聊",
+ "Explore rooms": "探索聊天室",
+ "Self-verification request": "自验证请求",
+ "%(creator)s created and configured the room.": "%(creator)s 创建并配置了此聊天室。",
+ "You’re all caught up": "全数阅毕",
+ "You have no visible notifications in this room.": "您在此聊天室内没有可见通知。",
+ "Delete the room address %(alias)s and remove %(name)s from the directory?": "删除聊天室地址 %(alias)s 并将 %(name)s 从目录中移除吗?",
+ "delete the address.": "删除此地址。",
+ "Preview": "预览",
+ "View": "查看",
+ "Find a room…": "寻找聊天室…",
+ "Find a room… (e.g. %(exampleRoom)s)": "寻找聊天室... (例如 %(exampleRoom)s)",
+ "If you can't find the room you're looking for, ask for an invite or Create a new room.": "如果您不能找到您所寻找的聊天室,请索要一个邀请或创建新聊天室。",
+ "Search rooms": "搜索聊天室",
+ "Switch to light mode": "切换到浅色模式",
+ "Switch to dark mode": "切换到深色模式",
+ "Switch theme": "切换主题",
+ "Security & privacy": "安全和隐私",
+ "All settings": "所有设置",
+ "Feedback": "反馈",
+ "User menu": "用户菜单",
+ "Session verified": "会话已验证",
+ "Your Matrix account on ": "您在 上的 Matrix 账户",
+ "No identity server is configured: add one in server settings to reset your password.": "没有配置身份服务器:在服务器设置中添加一个以重设您的密码。",
+ "You have been logged out of all sessions and will no longer receive push notifications. To re-enable notifications, sign in again on each device.": "您已经登出了所有会话,并将不会收到推送通知。要重新启用通知,请在每个设备上重新登录。",
+ "Failed to get autodiscovery configuration from server": "从服务器获取自动发现配置时失败",
+ "Invalid base_url for m.homeserver": "m.homeserver 的 base_url 无效",
+ "Homeserver URL does not appear to be a valid Matrix homeserver": "主服务器链接不像是有效的 Matrix 主服务器",
+ "Invalid base_url for m.identity_server": "m.identity_server 的 base_url 无效",
+ "Identity server URL does not appear to be a valid identity server": "身份服务器链接不像是有效的身份服务器",
+ "This account has been deactivated.": "此账号已被停用。",
+ "Syncing...": "正在同步...",
+ "Signing In...": "正在登录...",
+ "If you've joined lots of rooms, this might take a while": "如果您加入了很多聊天室,可能会消耗一些时间",
+ "Your new account (%(newAccountId)s) is registered, but you're already logged into a different account (%(loggedInUserId)s).": "您的新账户(%(newAccountId)s)已注册,但您已经登录了一个不同的账户(%(loggedInUserId)s)。",
+ "Continue with previous account": "用之前的账户继续",
+ "Log in to your new account.": "登录到您的新账户。",
+ "You can now close this window or log in to your new account.": "您现在可以关闭此窗口或登录到您的新账户。",
+ "Registration Successful": "注册成功",
+ "Use Recovery Key or Passphrase": "使用恢复密钥或密码",
+ "Use Recovery Key": "使用恢复密钥",
+ "This requires the latest %(brand)s on your other devices:": "这需要您在别的设备上有最新版的 %(brand)s:",
+ "%(brand)s Web": "%(brand)s 网页版",
+ "%(brand)s Desktop": "%(brand)s 桌面版",
+ "%(brand)s iOS": "%(brand)s iOS",
+ "%(brand)s X for Android": "%(brand)s X for Android",
+ "or another cross-signing capable Matrix client": "或者别的可以交叉签名的 Matrix 客户端",
+ "Your new session is now verified. It has access to your encrypted messages, and other users will see it as trusted.": "您的新会话现已被验证。它可以访问您的加密消息,别的用户也会视其为受信任的。",
+ "Your new session is now verified. Other users will see it as trusted.": "您的新会话现已被验证。别的用户会视其为受信任的。",
+ "Without completing security on this session, it won’t have access to encrypted messages.": "若不在此会话中完成安全验证,它便不能访问加密消息。",
+ "Failed to re-authenticate due to a homeserver problem": "由于主服务器的问题,重新认证失败",
+ "Failed to re-authenticate": "重新认证失败",
+ "Regain access to your account and recover encryption keys stored in this session. Without them, you won’t be able to read all of your secure messages in any session.": "重新获得访问您账户的权限,并恢复存储在此会话中的加密密钥。没有这些密钥,您将不能在任何会话中阅读您的所有安全消息。",
+ "Enter your password to sign in and regain access to your account.": "输入您的密码以登录并重新获取访问您账户的权限。",
+ "Forgotten your password?": "忘记您的密码了吗?",
+ "Sign in and regain access to your account.": "请登录以重新获取访问您账户的权限。",
+ "You cannot sign in to your account. Please contact your homeserver admin for more information.": "您不能登录进您的账户。请联系您的主服务器管理员以获取更多信息。",
+ "You're signed out": "您已登出",
+ "Clear personal data": "清除个人信息",
+ "Warning: Your personal data (including encryption keys) is still stored in this session. Clear it if you're finished using this session, or want to sign in to another account.": "警告:您的个人信息(包括加密密钥)仍存储于此会话中。如果您不用再使用此会话或想登录进另一个账户,请清除它。",
+ "Command Autocomplete": "命令自动补全",
+ "Community Autocomplete": "社区自动补全",
+ "DuckDuckGo Results": "DuckDuckGo 结果",
+ "Emoji Autocomplete": "表情符号自动补全",
+ "Notification Autocomplete": "通知自动补全",
+ "Room Autocomplete": "聊天室自动补全",
+ "User Autocomplete": "用户自动补全",
+ "Confirm encryption setup": "确认加密设置",
+ "Click the button below to confirm setting up encryption.": "点击下方按钮以确认设置加密。",
+ "Safeguard against losing access to encrypted messages & data by backing up encryption keys on your server.": "通过在您的服务器上备份加密密钥来防止丢失您对加密消息和数据的访问权。",
+ "Generate a Security Key": "生成一个安全密钥",
+ "We’ll generate a Security Key for you to store somewhere safe, like a password manager or a safe.": "我们会生成一个安全密钥以便让您存储在安全的地方,比如密码管理器或保险箱里。",
+ "Enter a Security Phrase": "输入一个安全密码",
+ "Use a secret phrase only you know, and optionally save a Security Key to use for backup.": "使用一个只有您知道的密码,您也可以保存安全密钥以供备份使用。",
+ "Enter your account password to confirm the upgrade:": "输入您的账户密码以确认更新:",
+ "Restore your key backup to upgrade your encryption": "恢复您的密钥备份以更新您的加密方式",
+ "Restore": "恢复",
+ "You'll need to authenticate with the server to confirm the upgrade.": "您需要和服务器进行认证以确认更新。",
+ "Upgrade this session to allow it to verify other sessions, granting them access to encrypted messages and marking them as trusted for other users.": "更新此会话以允许其验证别的会话,以允许它们访问加密消息并将其对别的用户标记为受信任的。",
+ "Enter a security phrase only you know, as it’s used to safeguard your data. To be secure, you shouldn’t re-use your account password.": "输入一个只有您知道的安全密码,它将被用来保护您的数据。为了安全,您不应该复用您的账户密码。",
+ "Enter a recovery passphrase": "输入一个恢复密码",
+ "Great! This recovery passphrase looks strong enough.": "棒!这个恢复密码看着够强。",
+ "Use a different passphrase?": "使用不同的密码?",
+ "Enter your recovery passphrase a second time to confirm it.": "再次输入您的恢复密码以确认。",
+ "Confirm your recovery passphrase": "确认您的恢复密码",
+ "Store your Security Key somewhere safe, like a password manager or a safe, as it’s used to safeguard your encrypted data.": "将您的安全密钥存储在安全的地方,像是密码管理器或保险箱里,它将被用来保护您的加密数据。",
+ "Copy": "复制",
+ "Unable to query secret storage status": "无法查询秘密存储状态",
+ "If you cancel now, you may lose encrypted messages & data if you lose access to your logins.": "如果您现在取消,您可能会丢失加密的消息和数据,如果您丢失了登录信息的话。",
+ "You can also set up Secure Backup & manage your keys in Settings.": "您也可以在设置中设置安全备份并管理您的密钥。",
+ "Set up Secure backup": "设置安全备份",
+ "Upgrade your encryption": "更新您的加密方法",
+ "Set a Security Phrase": "设置一个安全密码",
+ "Confirm Security Phrase": "确认安全密码",
+ "Save your Security Key": "保存您的安全密钥",
+ "Unable to set up secret storage": "无法设置秘密存储",
+ "We'll store an encrypted copy of your keys on our server. Secure your backup with a recovery passphrase.": "我们会在服务器上存储一份您的密钥的加密副本。用恢复密码来保护您的备份。",
+ "Set up with a recovery key": "用恢复密钥设置",
+ "Please enter your recovery passphrase a second time to confirm.": "请再输入您的恢复密码以确认。",
+ "Repeat your recovery passphrase...": "重输您的恢复密码...",
+ "Your recovery key is a safety net - you can use it to restore access to your encrypted messages if you forget your recovery passphrase.": "您的恢复密钥是一张安全网——如果您忘记了恢复密码,则可以使用它来恢复您对加密消息的访问。",
+ "Keep a copy of it somewhere secure, like a password manager or even a safe.": "在安全的地方保存一份副本,像是密码管理器或者保险箱里。",
+ "Your recovery key": "您的恢复密钥",
+ "Your recovery key has been copied to your clipboard, paste it to:": "您的恢复密钥已被复制到您的剪贴板,将其粘贴至:",
+ "Your recovery key is in your Downloads folder.": "您的恢复密钥在您的下载文件夹里。",
+ "Without setting up Secure Message Recovery, you won't be able to restore your encrypted message history if you log out or use another session.": "若不设置安全消息恢复,您如果登出或使用另一个会话,则将不能恢复您的加密消息历史。",
+ "Secure your backup with a recovery passphrase": "用恢复密码保护您的备份",
+ "Make a copy of your recovery key": "制作一份您的恢复密钥的副本",
+ "Create key backup": "创建密钥备份",
+ "This session is encrypting history using the new recovery method.": "此会话正在使用新的恢复方法加密历史。",
+ "This session has detected that your recovery passphrase and key for Secure Messages have been removed.": "此会话检测到您的恢复密码和安全消息的密钥已被移除。",
+ "If you did this accidentally, you can setup Secure Messages on this session which will re-encrypt this session's message history with a new recovery method.": "如果您出于意外这样做了,您可以在此会话上设置安全消息,以使用新的加密方式重新加密此会话的消息历史。",
+ "If disabled, messages from encrypted rooms won't appear in search results.": "如果被禁用,加密聊天室内的消息不会显示在搜索结果中。",
+ "Disable": "禁用",
+ "Not currently indexing messages for any room.": "现在没有为任何聊天室索引消息。",
+ "Currently indexing: %(currentRoom)s": "正在索引:%(currentRoom)s",
+ "%(brand)s is securely caching encrypted messages locally for them to appear in search results:": "%(brand)s 正在安全地在本地缓存加密消息以使其出现在搜索结果中:",
+ "Space used:": "已使用空间:",
+ "Indexed messages:": "已索引的消息:",
+ "Indexed rooms:": "已索引的聊天室:",
+ "%(doneRooms)s out of %(totalRooms)s": "%(totalRooms)s 中之 %(doneRooms)s",
+ "Navigation": "导航",
+ "Calls": "通话",
+ "Room List": "聊天室列表",
+ "Autocomplete": "自动补全",
+ "Alt": "Alt",
+ "Alt Gr": "Alt Gr",
+ "Shift": "Shift",
+ "Super": "Super",
+ "Ctrl": "Ctrl",
+ "New line": "换行",
+ "Jump to start/end of the composer": "跳转到编辑器的开始/结束",
+ "Cancel replying to a message": "取消回复消息",
+ "Scroll up/down in the timeline": "在时间线中向上/下滚动",
+ "Dismiss read marker and jump to bottom": "忽略已读标记并跳转到底部",
+ "Jump to oldest unread message": "跳转到最旧的未读消息",
+ "Upload a file": "上传文件",
+ "Jump to room search": "跳转到聊天室搜索",
+ "Select room from the room list": "从聊天室列表选择聊天室",
+ "Collapse room list section": "折叠聊天室列表段",
+ "Expand room list section": "展开聊天室列表段",
+ "Clear room list filter field": "清除聊天室过滤器字段",
+ "Close dialog or context menu": "关闭对话框或上下文菜单",
+ "Move autocomplete selection up/down": "上移/下移自动补全选项",
+ "Cancel autocomplete": "取消自动补全",
+ "Page Up": "Page Up",
+ "Page Down": "Page Down",
+ "Esc": "Esc",
+ "Enter": "回车",
+ "Space": "空格",
+ "How fast should messages be downloaded.": "消息下载速度。",
+ "IRC display name width": "IRC 显示名称宽度",
+ "When rooms are upgraded": "聊天室升级时间",
+ "Unexpected server error trying to leave the room": "试图离开聊天室时发生意外服务器错误",
+ "Error leaving room": "离开聊天室时出错",
+ "New spinner design": "新的下拉列表设计",
+ "Show message previews for reactions in DMs": "显示私聊消息预览以回复",
+ "Show message previews for reactions in all rooms": "显示所有聊天室的消息预览以回复",
+ "Uploading logs": "正在上传日志",
+ "Downloading logs": "正在下载日志",
+ "This bridge was provisioned by .": "桥接由 准备。",
+ "Workspace: %(networkName)s": "工作区:%(networkName)s",
+ "Channel: %(channelName)s": "频道:%(channelName)s",
+ "well formed": "格式正确",
+ "Master private key:": "主私钥:",
+ "Self signing private key:": "自签名私钥:",
+ "User signing private key:": "用户签名私钥:",
+ "Securely cache encrypted messages locally for them to appear in search results, using ": "在本地安全缓存已加密消息以使其出现在搜索结果中,使用 ",
+ " to store messages from ": " 存储来自 ",
+ "rooms.": "聊天室的消息。",
+ "This session is not backing up your keys, but you do have an existing backup you can restore from and add to going forward.": "此会话未备份您的密钥,但您已有备份,您可以继续并从中恢复和向其添加。",
+ "Invalid theme schema.": "无效主题方案。",
+ "Read Marker lifetime (ms)": "已读标记生存期 (ms)",
+ "Read Marker off-screen lifetime (ms)": "已读标记屏幕外生存期 (ms)",
+ "Unable to revoke sharing for email address": "无法撤消电子邮件地址共享",
+ "Revoke": "撤销",
+ "Unable to revoke sharing for phone number": "无法撤销电话号码共享",
+ "Mod": "管理员",
+ "Explore public rooms": "探索公共聊天室",
+ "Can't see what you’re looking for?": "看不到您要找的吗?",
+ "Explore all public rooms": "探索所有公共聊天室",
+ "%(count)s results|other": "%(count)s 个结果",
+ "You can only join it with a working invite.": "您只能通过有效邀请加入。",
+ "The session you are trying to verify doesn't support scanning a QR code or emoji verification, which is what %(brand)s supports. Try with a different client.": "您尝试验证的会话不支持 %(brand)s 支持的扫描二维码或表情符号验证。尝试使用其他客户端。",
+ "Language Dropdown": "语言下拉菜单",
+ "%(severalUsers)smade no changes %(count)s times|other": "%(severalUsers)s %(count)s 次未做更改",
+ "%(severalUsers)smade no changes %(count)s times|one": "%(severalUsers)s 未做更改",
+ "%(oneUser)smade no changes %(count)s times|other": "%(oneUser)s %(count)s 次未做更改",
+ "%(oneUser)smade no changes %(count)s times|one": "%(oneUser)s 未做更改",
+ "Preparing to download logs": "正在准备下载日志",
+ "Download logs": "下载日志",
+ "We couldn't create your DM. Please check the users you want to invite and try again.": "我们无法创建您的私聊。请检查您想要邀请的用户并重试。",
+ "%(brand)s encountered an error during upload of:": "%(brand)s 在上传此文件时出错:",
+ "Country Dropdown": "国家下拉菜单",
+ "Attach files from chat or just drag and drop them anywhere in a room.": "附加聊天中的文件,或将其拖放到聊天室的任何地方。",
+ "Changing your password will reset any end-to-end encryption keys on all of your sessions, making encrypted chat history unreadable. Set up Key Backup or export your room keys from another session before resetting your password.": "更改密码将重置所有会话上的所有端到端加密密钥,从而使加密的聊天记录不可读。在重置密码之前,请设置密钥备份或从其他会话导出聊天室密钥。",
+ "%(brand)s Android": "%(brand)s Android",
+ "Message downloading sleep time(ms)": "消息下载休眠时间 (ms)",
+ "Toggle Bold": "切换粗体",
+ "Toggle Italics": "切换斜体",
+ "Toggle Quote": "切换引用",
+ "Navigate recent messages to edit": "浏览最近的消息以进行编辑",
+ "Toggle microphone mute": "切换麦克风静音",
+ "Toggle video on/off": "切换视频开/关",
+ "Navigate up/down in the room list": "在聊天室列表中上/下导航",
+ "Previous/next unread room or DM": "上一个/下一个未读聊天室或私聊消息",
+ "Previous/next room or DM": "上一个/下一个聊天室或私聊消息",
+ "Toggle the top left menu": "切换左上方的菜单",
+ "Toggle right panel": "切换右侧面板",
+ "Toggle this dialog": "切换此对话框",
+ "End": "End",
+ "The server is not configured to indicate what the problem is (CORS).": "服务器没有配置为提示错误是什么(CORS)。",
+ "Activate selected button": "激活选择的按钮"
}
diff --git a/src/i18n/strings/zh_Hant.json b/src/i18n/strings/zh_Hant.json
index 4278515ffd..ad845dfb78 100644
--- a/src/i18n/strings/zh_Hant.json
+++ b/src/i18n/strings/zh_Hant.json
@@ -2391,5 +2391,42 @@
"%(brand)s iOS": "%(brand)s iOS",
"%(brand)s X for Android": "Android 的 %(brand)s X",
"Custom Tag": "自訂標籤",
- "* %(senderName)s %(emote)s": "* %(senderName)s %(emote)s"
+ "* %(senderName)s %(emote)s": "* %(senderName)s %(emote)s",
+ "The person who invited you already left the room.": "邀請您的人已離開聊天室。",
+ "The person who invited you already left the room, or their server is offline.": "邀請您的人已離開聊天室,或是他們的伺服器離線了。",
+ "Change notification settings": "變更通知設定",
+ "Your server isn't responding to some requests.": "您的伺服器未回應某些請求。",
+ "You're all caught up.": "都處理好了。",
+ "Server isn't responding": "伺服器沒有回應",
+ "Your server isn't responding to some of your requests. Below are some of the most likely reasons.": "您的伺服器未對您的某些請求回應。下列是可能的原因。",
+ "The server (%(serverName)s) took too long to respond.": "伺服器 (%(serverName)s) 花了太長的時間來回應。",
+ "Your firewall or anti-virus is blocking the request.": "您的防火牆或防毒軟體阻擋了請求。",
+ "A browser extension is preventing the request.": "瀏覽器擴充套件阻擋了請求。",
+ "The server is offline.": "伺服器離線。",
+ "The server has denied your request.": "伺服器拒絕了您的請求。",
+ "Your area is experiencing difficulties connecting to the internet.": "您所在區域可能遇到一些網際網路連線的問題。",
+ "A connection error occurred while trying to contact the server.": "在試圖與伺服器溝通時遇到連線錯誤。",
+ "The server is not configured to indicate what the problem is (CORS).": "伺服器沒有設定好指示問題是什麼 (CORS)。",
+ "Recent changes that have not yet been received": "尚未收到最新變更",
+ "No files visible in this room": "在此聊天室中看不到檔案",
+ "Attach files from chat or just drag and drop them anywhere in a room.": "從聊天中附加檔案,或將其拖放到聊天室的任何地方。",
+ "You’re all caught up": "您都設定好了",
+ "You have no visible notifications in this room.": "您在此聊天室沒有可見的通知。",
+ "%(brand)s Android": "%(brand)s Android",
+ "Master private key:": "主控私鑰:",
+ "Show message previews for reactions in DMs": "在直接訊息中顯示反應的訊息預覽",
+ "Show message previews for reactions in all rooms": "在所有聊天室中顯示反應的訊息預覽",
+ "Explore public rooms": "探索公開聊天室",
+ "Uploading logs": "正在上傳紀錄檔",
+ "Downloading logs": "正在下載紀錄檔",
+ "Can't see what you’re looking for?": "看不到您要找的東西嗎?",
+ "Explore all public rooms": "探索所有公開聊天室",
+ "%(count)s results|other": "%(count)s 個結果",
+ "Preparing to download logs": "正在準備下載紀錄檔",
+ "Download logs": "下載紀錄檔",
+ "Unexpected server error trying to leave the room": "試圖離開聊天室時發生意外的伺服器錯誤",
+ "Error leaving room": "離開聊天室時發生錯誤",
+ "Communities v2 prototypes. Requires compatible homeserver. Highly experimental - use with caution.": "社群 v2 原型。需要相容的家伺服器。高度實驗性,小心使用。",
+ "Explore rooms in %(communityName)s": "在 %(communityName)s 中探索聊天室",
+ "Set up Secure Backup": "設定安全備份"
}
diff --git a/src/indexing/EventIndex.js b/src/indexing/EventIndex.js
index d5abb3f2d2..fa263a2a55 100644
--- a/src/indexing/EventIndex.js
+++ b/src/indexing/EventIndex.js
@@ -145,7 +145,7 @@ export default class EventIndex extends EventEmitter {
const indexManager = PlatformPeg.get().getEventIndexingManager();
if (prevState === "PREPARED" && state === "SYNCING") {
- // If our indexer is empty we're most likely running Riot the
+ // If our indexer is empty we're most likely running Element the
// first time with indexing support or running it with an
// initial sync. Add checkpoints to crawl our encrypted rooms.
const eventIndexWasEmpty = await indexManager.isEventIndexEmpty();
diff --git a/src/languageHandler.tsx b/src/languageHandler.tsx
index 9d28b7d07d..d9feec95b1 100644
--- a/src/languageHandler.tsx
+++ b/src/languageHandler.tsx
@@ -64,7 +64,7 @@ export function _td(s: string): string {
// Wrapper for counterpart's translation function so that it handles nulls and undefineds properly
// Takes the same arguments as counterpart.translate()
function safeCounterpartTranslate(text: string, options?: object) {
- // Horrible hack to avoid https://github.com/vector-im/riot-web/issues/4191
+ // Horrible hack to avoid https://github.com/vector-im/element-web/issues/4191
// The interpolation library that counterpart uses does not support undefined/null
// values and instead will throw an error. This is a problem since everywhere else
// in JS land passing undefined/null will simply stringify instead, and when converting
@@ -295,7 +295,7 @@ export function replaceByRegexes(text: string, mapping: IVariables | Tags): stri
// Allow overriding the text displayed when no translation exists
// Currently only used in unit tests to avoid having to load
-// the translations in riot-web
+// the translations in element-web
export function setMissingEntryGenerator(f: (value: string) => void) {
counterpart.setMissingEntryGenerator(f);
}
@@ -442,7 +442,7 @@ export function pickBestLanguage(langs: string[]): string {
}
function getLangsJson(): Promise
;
} else if (err.httpStatus === 404) {
- const invitingUserId = this._getInvitingUserId(this._state.roomId);
+ const invitingUserId = this.getInvitingUserId(this.state.roomId);
// only provide a better error message for invites
if (invitingUserId) {
// if the inviting user is on the same HS, there can only be one cause: they left.
@@ -292,7 +304,7 @@ class RoomViewStore extends Store {
});
}
- _getInvitingUserId(roomId) {
+ private getInvitingUserId(roomId: string): string {
const cli = MatrixClientPeg.get();
const room = cli.getRoom(roomId);
if (room && room.getMyMembership() === "invite") {
@@ -302,45 +314,45 @@ class RoomViewStore extends Store {
}
}
- _joinRoomError(payload) {
- this._setState({
+ private joinRoomError(payload: ActionPayload) {
+ this.setState({
joining: false,
joinError: payload.err,
});
}
- reset() {
- this._state = Object.assign({}, INITIAL_STATE);
+ public reset() {
+ this.state = Object.assign({}, INITIAL_STATE);
}
// The room ID of the room currently being viewed
- getRoomId() {
- return this._state.roomId;
+ public getRoomId() {
+ return this.state.roomId;
}
// The event to scroll to when the room is first viewed
- getInitialEventId() {
- return this._state.initialEventId;
+ public getInitialEventId() {
+ return this.state.initialEventId;
}
// Whether to highlight the initial event
- isInitialEventHighlighted() {
- return this._state.isInitialEventHighlighted;
+ public isInitialEventHighlighted() {
+ return this.state.isInitialEventHighlighted;
}
// The room alias of the room (or null if not originally specified in view_room)
- getRoomAlias() {
- return this._state.roomAlias;
+ public getRoomAlias() {
+ return this.state.roomAlias;
}
// Whether the current room is loading (true whilst resolving an alias)
- isRoomLoading() {
- return this._state.roomLoading;
+ public isRoomLoading() {
+ return this.state.roomLoading;
}
// Any error that has occurred during loading
- getRoomLoadError() {
- return this._state.roomLoadError;
+ public getRoomLoadError() {
+ return this.state.roomLoadError;
}
// True if we're expecting the user to be joined to the room currently being
@@ -366,27 +378,27 @@ class RoomViewStore extends Store {
// // show join prompt
// }
// }
- isJoining() {
- return this._state.joining;
+ public isJoining() {
+ return this.state.joining;
}
// Any error that has occurred during joining
- getJoinError() {
- return this._state.joinError;
+ public getJoinError() {
+ return this.state.joinError;
}
// The mxEvent if one is about to be forwarded
- getForwardingEvent() {
- return this._state.forwardingEvent;
+ public getForwardingEvent() {
+ return this.state.forwardingEvent;
}
// The mxEvent if one is currently being replied to/quoted
- getQuotingEvent() {
- return this._state.replyingToEvent;
+ public getQuotingEvent() {
+ return this.state.replyingToEvent;
}
- shouldPeek() {
- return this._state.shouldPeek;
+ public shouldPeek() {
+ return this.state.shouldPeek;
}
}
diff --git a/src/stores/SetupEncryptionStore.js b/src/stores/SetupEncryptionStore.js
index 63b8c428eb..ee3b9c9de5 100644
--- a/src/stores/SetupEncryptionStore.js
+++ b/src/stores/SetupEncryptionStore.js
@@ -137,10 +137,10 @@ export class SetupEncryptionStore extends EventEmitter {
}
}
- _onUserTrustStatusChanged = async (userId) => {
+ _onUserTrustStatusChanged = (userId) => {
if (userId !== MatrixClientPeg.get().getUserId()) return;
- const crossSigningReady = await MatrixClientPeg.get().isCrossSigningReady();
- if (crossSigningReady) {
+ const publicKeysTrusted = MatrixClientPeg.get().getCrossSigningId();
+ if (publicKeysTrusted) {
this.phase = PHASE_DONE;
this.emit("update");
}
@@ -150,7 +150,7 @@ export class SetupEncryptionStore extends EventEmitter {
this._setActiveVerificationRequest(request);
}
- onVerificationRequestChange = async () => {
+ onVerificationRequestChange = () => {
if (this.verificationRequest.cancelled) {
this.verificationRequest.off("change", this.onVerificationRequestChange);
this.verificationRequest = null;
@@ -161,8 +161,8 @@ export class SetupEncryptionStore extends EventEmitter {
// At this point, the verification has finished, we just need to wait for
// cross signing to be ready to use, so wait for the user trust status to
// change (or change to DONE if it's already ready).
- const crossSigningReady = await MatrixClientPeg.get().isCrossSigningReady();
- this.phase = crossSigningReady ? PHASE_DONE : PHASE_BUSY;
+ const publicKeysTrusted = MatrixClientPeg.get().getCrossSigningId();
+ this.phase = publicKeysTrusted ? PHASE_DONE : PHASE_BUSY;
this.emit("update");
}
}
diff --git a/src/stores/TagOrderStore.js b/src/stores/TagOrderStore.js
index 2acf531d86..2b72a963b0 100644
--- a/src/stores/TagOrderStore.js
+++ b/src/stores/TagOrderStore.js
@@ -115,9 +115,11 @@ class TagOrderStore extends Store {
break;
}
case 'select_tag': {
+ const allowMultiple = !SettingsStore.getValue("feature_communities_v2_prototypes");
+
let newTags = [];
// Shift-click semantics
- if (payload.shiftKey) {
+ if (payload.shiftKey && allowMultiple) {
// Select range of tags
let start = this._state.orderedTags.indexOf(this._state.anchorTag);
let end = this._state.orderedTags.indexOf(payload.tag);
@@ -135,7 +137,7 @@ class TagOrderStore extends Store {
this._state.orderedTags.slice(start, end + 1).concat(newTags),
)];
} else {
- if (payload.ctrlOrCmdKey) {
+ if (payload.ctrlOrCmdKey && allowMultiple) {
// Toggle individual tag
if (this._state.selectedTags.includes(payload.tag)) {
newTags = this._state.selectedTags.filter((t) => t !== payload.tag);
diff --git a/src/stores/notifications/NotificationColor.ts b/src/stores/notifications/NotificationColor.ts
index aa2384b3df..b12f2b7c00 100644
--- a/src/stores/notifications/NotificationColor.ts
+++ b/src/stores/notifications/NotificationColor.ts
@@ -17,7 +17,7 @@ limitations under the License.
export enum NotificationColor {
// Inverted (None -> Red) because we do integer comparisons on this
None, // nothing special
- // TODO: Remove bold with notifications: https://github.com/vector-im/riot-web/issues/14227
+ // TODO: Remove bold with notifications: https://github.com/vector-im/element-web/issues/14227
Bold, // no badge, show as unread
Grey, // unread notified messages
Red, // unread pings
diff --git a/src/stores/room-list/RoomListStore.ts b/src/stores/room-list/RoomListStore.ts
index c3e7fd5c51..0f3138fe9e 100644
--- a/src/stores/room-list/RoomListStore.ts
+++ b/src/stores/room-list/RoomListStore.ts
@@ -65,7 +65,7 @@ export class RoomListStoreClass extends AsyncStoreWithClient {
private readonly watchedSettings = [
'feature_custom_tags',
- 'advancedRoomListLogging', // TODO: Remove watch: https://github.com/vector-im/riot-web/issues/14602
+ 'advancedRoomListLogging', // TODO: Remove watch: https://github.com/vector-im/element-web/issues/14602
];
constructor() {
@@ -136,7 +136,7 @@ export class RoomListStoreClass extends AsyncStoreWithClient {
}
private async readAndCacheSettingsFromStore() {
- const tagsEnabled = SettingsStore.isFeatureEnabled("feature_custom_tags");
+ const tagsEnabled = SettingsStore.getValue("feature_custom_tags");
await this.updateState({
tagsEnabled,
});
@@ -161,7 +161,7 @@ export class RoomListStoreClass extends AsyncStoreWithClient {
await this.algorithm.setStickyRoom(null);
} else if (activeRoom !== this.algorithm.stickyRoom) {
if (SettingsStore.getValue("advancedRoomListLogging")) {
- // TODO: Remove debug: https://github.com/vector-im/riot-web/issues/14602
+ // TODO: Remove debug: https://github.com/vector-im/element-web/issues/14602
console.log(`Changing sticky room to ${activeRoomId}`);
}
await this.algorithm.setStickyRoom(activeRoom);
@@ -205,7 +205,7 @@ export class RoomListStoreClass extends AsyncStoreWithClient {
if (payload.action === 'setting_updated') {
if (this.watchedSettings.includes(payload.settingName)) {
- // TODO: Remove with https://github.com/vector-im/riot-web/issues/14602
+ // TODO: Remove with https://github.com/vector-im/element-web/issues/14602
if (payload.settingName === "advancedRoomListLogging") {
// Log when the setting changes so we know when it was turned on in the rageshake
const enabled = SettingsStore.getValue("advancedRoomListLogging");
@@ -236,7 +236,7 @@ export class RoomListStoreClass extends AsyncStoreWithClient {
return;
}
if (SettingsStore.getValue("advancedRoomListLogging")) {
- // TODO: Remove debug: https://github.com/vector-im/riot-web/issues/14602
+ // TODO: Remove debug: https://github.com/vector-im/element-web/issues/14602
console.log(`[RoomListDebug] Got own read receipt in ${room.roomId}`);
}
await this.handleRoomUpdate(room, RoomUpdateCause.ReadReceipt);
@@ -246,7 +246,7 @@ export class RoomListStoreClass extends AsyncStoreWithClient {
} else if (payload.action === 'MatrixActions.Room.tags') {
const roomPayload = (payload); // TODO: Type out the dispatcher types
if (SettingsStore.getValue("advancedRoomListLogging")) {
- // TODO: Remove debug: https://github.com/vector-im/riot-web/issues/14602
+ // TODO: Remove debug: https://github.com/vector-im/element-web/issues/14602
console.log(`[RoomListDebug] Got tag change in ${roomPayload.room.roomId}`);
}
await this.handleRoomUpdate(roomPayload.room, RoomUpdateCause.PossibleTagChange);
@@ -261,13 +261,13 @@ export class RoomListStoreClass extends AsyncStoreWithClient {
const room = this.matrixClient.getRoom(roomId);
const tryUpdate = async (updatedRoom: Room) => {
if (SettingsStore.getValue("advancedRoomListLogging")) {
- // TODO: Remove debug: https://github.com/vector-im/riot-web/issues/14602
+ // TODO: Remove debug: https://github.com/vector-im/element-web/issues/14602
console.log(`[RoomListDebug] Live timeline event ${eventPayload.event.getId()}` +
` in ${updatedRoom.roomId}`);
}
if (eventPayload.event.getType() === 'm.room.tombstone' && eventPayload.event.getStateKey() === '') {
if (SettingsStore.getValue("advancedRoomListLogging")) {
- // TODO: Remove debug: https://github.com/vector-im/riot-web/issues/14602
+ // TODO: Remove debug: https://github.com/vector-im/element-web/issues/14602
console.log(`[RoomListDebug] Got tombstone event - trying to remove now-dead room`);
}
const newRoom = this.matrixClient.getRoom(eventPayload.event.getContent()['replacement_room']);
@@ -300,7 +300,7 @@ export class RoomListStoreClass extends AsyncStoreWithClient {
return;
}
if (SettingsStore.getValue("advancedRoomListLogging")) {
- // TODO: Remove debug: https://github.com/vector-im/riot-web/issues/14602
+ // TODO: Remove debug: https://github.com/vector-im/element-web/issues/14602
console.log(`[RoomListDebug] Decrypted timeline event ${eventPayload.event.getId()} in ${roomId}`);
}
await this.handleRoomUpdate(room, RoomUpdateCause.Timeline);
@@ -308,7 +308,7 @@ export class RoomListStoreClass extends AsyncStoreWithClient {
} else if (payload.action === 'MatrixActions.accountData' && payload.event_type === 'm.direct') {
const eventPayload = (payload); // TODO: Type out the dispatcher types
if (SettingsStore.getValue("advancedRoomListLogging")) {
- // TODO: Remove debug: https://github.com/vector-im/riot-web/issues/14602
+ // TODO: Remove debug: https://github.com/vector-im/element-web/issues/14602
console.log(`[RoomListDebug] Received updated DM map`);
}
const dmMap = eventPayload.event.getContent();
@@ -335,7 +335,7 @@ export class RoomListStoreClass extends AsyncStoreWithClient {
const newMembership = getEffectiveMembership(membershipPayload.membership);
if (oldMembership !== EffectiveMembership.Join && newMembership === EffectiveMembership.Join) {
if (SettingsStore.getValue("advancedRoomListLogging")) {
- // TODO: Remove debug: https://github.com/vector-im/riot-web/issues/14602
+ // TODO: Remove debug: https://github.com/vector-im/element-web/issues/14602
console.log(`[RoomListDebug] Handling new room ${membershipPayload.room.roomId}`);
}
@@ -344,7 +344,7 @@ export class RoomListStoreClass extends AsyncStoreWithClient {
const createEvent = membershipPayload.room.currentState.getStateEvents("m.room.create", "");
if (createEvent && createEvent.getContent()['predecessor']) {
if (SettingsStore.getValue("advancedRoomListLogging")) {
- // TODO: Remove debug: https://github.com/vector-im/riot-web/issues/14602
+ // TODO: Remove debug: https://github.com/vector-im/element-web/issues/14602
console.log(`[RoomListDebug] Room has a predecessor`);
}
const prevRoom = this.matrixClient.getRoom(createEvent.getContent()['predecessor']['room_id']);
@@ -352,7 +352,7 @@ export class RoomListStoreClass extends AsyncStoreWithClient {
const isSticky = this.algorithm.stickyRoom === prevRoom;
if (isSticky) {
if (SettingsStore.getValue("advancedRoomListLogging")) {
- // TODO: Remove debug: https://github.com/vector-im/riot-web/issues/14602
+ // TODO: Remove debug: https://github.com/vector-im/element-web/issues/14602
console.log(`[RoomListDebug] Clearing sticky room due to room upgrade`);
}
await this.algorithm.setStickyRoom(null);
@@ -361,7 +361,7 @@ export class RoomListStoreClass extends AsyncStoreWithClient {
// Note: we hit the algorithm instead of our handleRoomUpdate() function to
// avoid redundant updates.
if (SettingsStore.getValue("advancedRoomListLogging")) {
- // TODO: Remove debug: https://github.com/vector-im/riot-web/issues/14602
+ // TODO: Remove debug: https://github.com/vector-im/element-web/issues/14602
console.log(`[RoomListDebug] Removing previous room from room list`);
}
await this.algorithm.handleRoomUpdate(prevRoom, RoomUpdateCause.RoomRemoved);
@@ -369,7 +369,7 @@ export class RoomListStoreClass extends AsyncStoreWithClient {
}
if (SettingsStore.getValue("advancedRoomListLogging")) {
- // TODO: Remove debug: https://github.com/vector-im/riot-web/issues/14602
+ // TODO: Remove debug: https://github.com/vector-im/element-web/issues/14602
console.log(`[RoomListDebug] Adding new room to room list`);
}
await this.handleRoomUpdate(membershipPayload.room, RoomUpdateCause.NewRoom);
@@ -379,7 +379,7 @@ export class RoomListStoreClass extends AsyncStoreWithClient {
if (oldMembership !== EffectiveMembership.Invite && newMembership === EffectiveMembership.Invite) {
if (SettingsStore.getValue("advancedRoomListLogging")) {
- // TODO: Remove debug: https://github.com/vector-im/riot-web/issues/14602
+ // TODO: Remove debug: https://github.com/vector-im/element-web/issues/14602
console.log(`[RoomListDebug] Handling invite to ${membershipPayload.room.roomId}`);
}
await this.handleRoomUpdate(membershipPayload.room, RoomUpdateCause.NewRoom);
@@ -390,7 +390,7 @@ export class RoomListStoreClass extends AsyncStoreWithClient {
// If it's not a join, it's transitioning into a different list (possibly historical)
if (oldMembership !== newMembership) {
if (SettingsStore.getValue("advancedRoomListLogging")) {
- // TODO: Remove debug: https://github.com/vector-im/riot-web/issues/14602
+ // TODO: Remove debug: https://github.com/vector-im/element-web/issues/14602
console.log(`[RoomListDebug] Handling membership change in ${membershipPayload.room.roomId}`);
}
await this.handleRoomUpdate(membershipPayload.room, RoomUpdateCause.PossibleTagChange);
@@ -404,7 +404,7 @@ export class RoomListStoreClass extends AsyncStoreWithClient {
const shouldUpdate = await this.algorithm.handleRoomUpdate(room, cause);
if (shouldUpdate) {
if (SettingsStore.getValue("advancedRoomListLogging")) {
- // TODO: Remove debug: https://github.com/vector-im/riot-web/issues/14602
+ // TODO: Remove debug: https://github.com/vector-im/element-web/issues/14602
console.log(`[DEBUG] Room "${room.name}" (${room.roomId}) triggered by ${cause} requires list update`);
}
this.updateFn.mark();
@@ -418,7 +418,7 @@ export class RoomListStoreClass extends AsyncStoreWithClient {
private async setAndPersistTagSorting(tagId: TagID, sort: SortAlgorithm) {
await this.algorithm.setTagSorting(tagId, sort);
- // TODO: Per-account? https://github.com/vector-im/riot-web/issues/14114
+ // TODO: Per-account? https://github.com/vector-im/element-web/issues/14114
localStorage.setItem(`mx_tagSort_${tagId}`, sort);
}
@@ -428,7 +428,7 @@ export class RoomListStoreClass extends AsyncStoreWithClient {
// noinspection JSMethodCanBeStatic
private getStoredTagSorting(tagId: TagID): SortAlgorithm {
- // TODO: Per-account? https://github.com/vector-im/riot-web/issues/14114
+ // TODO: Per-account? https://github.com/vector-im/element-web/issues/14114
return localStorage.getItem(`mx_tagSort_${tagId}`);
}
@@ -462,7 +462,7 @@ export class RoomListStoreClass extends AsyncStoreWithClient {
private async setAndPersistListOrder(tagId: TagID, order: ListAlgorithm) {
await this.algorithm.setListOrdering(tagId, order);
- // TODO: Per-account? https://github.com/vector-im/riot-web/issues/14114
+ // TODO: Per-account? https://github.com/vector-im/element-web/issues/14114
localStorage.setItem(`mx_listOrder_${tagId}`, order);
}
@@ -472,7 +472,7 @@ export class RoomListStoreClass extends AsyncStoreWithClient {
// noinspection JSMethodCanBeStatic
private getStoredListOrder(tagId: TagID): ListAlgorithm {
- // TODO: Per-account? https://github.com/vector-im/riot-web/issues/14114
+ // TODO: Per-account? https://github.com/vector-im/element-web/issues/14114
return localStorage.getItem(`mx_listOrder_${tagId}`);
}
@@ -521,7 +521,7 @@ export class RoomListStoreClass extends AsyncStoreWithClient {
private onAlgorithmListUpdated = () => {
if (SettingsStore.getValue("advancedRoomListLogging")) {
- // TODO: Remove debug: https://github.com/vector-im/riot-web/issues/14602
+ // TODO: Remove debug: https://github.com/vector-im/element-web/issues/14602
console.log("Underlying algorithm has triggered a list update - marking");
}
this.updateFn.mark();
@@ -574,7 +574,7 @@ export class RoomListStoreClass extends AsyncStoreWithClient {
public addFilter(filter: IFilterCondition): void {
if (SettingsStore.getValue("advancedRoomListLogging")) {
- // TODO: Remove debug: https://github.com/vector-im/riot-web/issues/14602
+ // TODO: Remove debug: https://github.com/vector-im/element-web/issues/14602
console.log("Adding filter condition:", filter);
}
this.filterConditions.push(filter);
@@ -586,7 +586,7 @@ export class RoomListStoreClass extends AsyncStoreWithClient {
public removeFilter(filter: IFilterCondition): void {
if (SettingsStore.getValue("advancedRoomListLogging")) {
- // TODO: Remove debug: https://github.com/vector-im/riot-web/issues/14602
+ // TODO: Remove debug: https://github.com/vector-im/element-web/issues/14602
console.log("Removing filter condition:", filter);
}
const idx = this.filterConditions.indexOf(filter);
diff --git a/src/stores/room-list/algorithms/Algorithm.ts b/src/stores/room-list/algorithms/Algorithm.ts
index f1a7ab1613..439141edb4 100644
--- a/src/stores/room-list/algorithms/Algorithm.ts
+++ b/src/stores/room-list/algorithms/Algorithm.ts
@@ -334,7 +334,7 @@ export class Algorithm extends EventEmitter {
newMap[tagId] = allowedRoomsInThisTag;
if (SettingsStore.getValue("advancedRoomListLogging")) {
- // TODO: Remove debug: https://github.com/vector-im/riot-web/issues/14602
+ // TODO: Remove debug: https://github.com/vector-im/element-web/issues/14602
console.log(`[DEBUG] ${newMap[tagId].length}/${rooms.length} rooms filtered into ${tagId}`);
}
}
@@ -349,7 +349,7 @@ export class Algorithm extends EventEmitter {
if (!this.hasFilters) return; // don't bother doing work if there's nothing to do
if (SettingsStore.getValue("advancedRoomListLogging")) {
- // TODO: Remove debug: https://github.com/vector-im/riot-web/issues/14602
+ // TODO: Remove debug: https://github.com/vector-im/element-web/issues/14602
console.log(`Recalculating filtered rooms for ${tagId}`);
}
delete this.filteredRooms[tagId];
@@ -361,7 +361,7 @@ export class Algorithm extends EventEmitter {
}
if (SettingsStore.getValue("advancedRoomListLogging")) {
- // TODO: Remove debug: https://github.com/vector-im/riot-web/issues/14602
+ // TODO: Remove debug: https://github.com/vector-im/element-web/issues/14602
console.log(`[DEBUG] ${filteredRooms.length}/${rooms.length} rooms filtered into ${tagId}`);
}
}
@@ -403,7 +403,7 @@ export class Algorithm extends EventEmitter {
if (!this._cachedStickyRooms || !updatedTag) {
if (SettingsStore.getValue("advancedRoomListLogging")) {
- // TODO: Remove debug: https://github.com/vector-im/riot-web/issues/14602
+ // TODO: Remove debug: https://github.com/vector-im/element-web/issues/14602
console.log(`Generating clone of cached rooms for sticky room handling`);
}
const stickiedTagMap: ITagMap = {};
@@ -417,7 +417,7 @@ export class Algorithm extends EventEmitter {
// Update the tag indicated by the caller, if possible. This is mostly to ensure
// our cache is up to date.
if (SettingsStore.getValue("advancedRoomListLogging")) {
- // TODO: Remove debug: https://github.com/vector-im/riot-web/issues/14602
+ // TODO: Remove debug: https://github.com/vector-im/element-web/issues/14602
console.log(`Replacing cached sticky rooms for ${updatedTag}`);
}
this._cachedStickyRooms[updatedTag] = this.cachedRooms[updatedTag].map(r => r); // shallow clone
@@ -429,7 +429,7 @@ export class Algorithm extends EventEmitter {
const sticky = this._stickyRoom;
if (!updatedTag || updatedTag === sticky.tag) {
if (SettingsStore.getValue("advancedRoomListLogging")) {
- // TODO: Remove debug: https://github.com/vector-im/riot-web/issues/14602
+ // TODO: Remove debug: https://github.com/vector-im/element-web/issues/14602
console.log(
`Inserting sticky room ${sticky.room.roomId} at position ${sticky.position} in ${sticky.tag}`,
);
@@ -660,7 +660,7 @@ export class Algorithm extends EventEmitter {
*/
public async handleRoomUpdate(room: Room, cause: RoomUpdateCause): Promise {
if (SettingsStore.getValue("advancedRoomListLogging")) {
- // TODO: Remove debug: https://github.com/vector-im/riot-web/issues/14602
+ // TODO: Remove debug: https://github.com/vector-im/element-web/issues/14602
console.log(`Handle room update for ${room.roomId} called with cause ${cause}`);
}
if (!this.algorithms) throw new Error("Not ready: no algorithms to determine tags from");
@@ -720,7 +720,7 @@ export class Algorithm extends EventEmitter {
if (diff.removed.length > 0 || diff.added.length > 0) {
for (const rmTag of diff.removed) {
if (SettingsStore.getValue("advancedRoomListLogging")) {
- // TODO: Remove debug: https://github.com/vector-im/riot-web/issues/14602
+ // TODO: Remove debug: https://github.com/vector-im/element-web/issues/14602
console.log(`Removing ${room.roomId} from ${rmTag}`);
}
const algorithm: OrderingAlgorithm = this.algorithms[rmTag];
@@ -732,7 +732,7 @@ export class Algorithm extends EventEmitter {
}
for (const addTag of diff.added) {
if (SettingsStore.getValue("advancedRoomListLogging")) {
- // TODO: Remove debug: https://github.com/vector-im/riot-web/issues/14602
+ // TODO: Remove debug: https://github.com/vector-im/element-web/issues/14602
console.log(`Adding ${room.roomId} to ${addTag}`);
}
const algorithm: OrderingAlgorithm = this.algorithms[addTag];
@@ -745,14 +745,14 @@ export class Algorithm extends EventEmitter {
this.roomIdsToTags[room.roomId] = newTags;
if (SettingsStore.getValue("advancedRoomListLogging")) {
- // TODO: Remove debug: https://github.com/vector-im/riot-web/issues/14602
+ // TODO: Remove debug: https://github.com/vector-im/element-web/issues/14602
console.log(`Changing update cause for ${room.roomId} to Timeline to sort rooms`);
}
cause = RoomUpdateCause.Timeline;
didTagChange = true;
} else {
if (SettingsStore.getValue("advancedRoomListLogging")) {
- // TODO: Remove debug: https://github.com/vector-im/riot-web/issues/14602
+ // TODO: Remove debug: https://github.com/vector-im/element-web/issues/14602
console.log(`Received no-op update for ${room.roomId} - changing to Timeline update`);
}
cause = RoomUpdateCause.Timeline;
@@ -781,7 +781,7 @@ export class Algorithm extends EventEmitter {
if (cause !== RoomUpdateCause.NewRoom && cause !== RoomUpdateCause.RoomRemoved) {
if (this.stickyRoom === room) {
if (SettingsStore.getValue("advancedRoomListLogging")) {
- // TODO: Remove debug: https://github.com/vector-im/riot-web/issues/14602
+ // TODO: Remove debug: https://github.com/vector-im/element-web/issues/14602
console.warn(`[RoomListDebug] Received ${cause} update for sticky room ${room.roomId} - ignoring`);
}
return false;
@@ -791,14 +791,14 @@ export class Algorithm extends EventEmitter {
if (!this.roomIdsToTags[room.roomId]) {
if (CAUSES_REQUIRING_ROOM.includes(cause)) {
if (SettingsStore.getValue("advancedRoomListLogging")) {
- // TODO: Remove debug: https://github.com/vector-im/riot-web/issues/14602
+ // TODO: Remove debug: https://github.com/vector-im/element-web/issues/14602
console.warn(`Skipping tag update for ${room.roomId} because we don't know about the room`);
}
return false;
}
if (SettingsStore.getValue("advancedRoomListLogging")) {
- // TODO: Remove debug: https://github.com/vector-im/riot-web/issues/14602
+ // TODO: Remove debug: https://github.com/vector-im/element-web/issues/14602
console.log(`[RoomListDebug] Updating tags for room ${room.roomId} (${room.name})`);
}
@@ -812,13 +812,13 @@ export class Algorithm extends EventEmitter {
this.roomIdsToTags[room.roomId] = roomTags;
if (SettingsStore.getValue("advancedRoomListLogging")) {
- // TODO: Remove debug: https://github.com/vector-im/riot-web/issues/14602
+ // TODO: Remove debug: https://github.com/vector-im/element-web/issues/14602
console.log(`[RoomListDebug] Updated tags for ${room.roomId}:`, roomTags);
}
}
if (SettingsStore.getValue("advancedRoomListLogging")) {
- // TODO: Remove debug: https://github.com/vector-im/riot-web/issues/14602
+ // TODO: Remove debug: https://github.com/vector-im/element-web/issues/14602
console.log(`[RoomListDebug] Reached algorithmic handling for ${room.roomId} and cause ${cause}`);
}
@@ -843,7 +843,7 @@ export class Algorithm extends EventEmitter {
}
if (SettingsStore.getValue("advancedRoomListLogging")) {
- // TODO: Remove debug: https://github.com/vector-im/riot-web/issues/14602
+ // TODO: Remove debug: https://github.com/vector-im/element-web/issues/14602
console.log(`[RoomListDebug] Finished handling ${room.roomId} with cause ${cause} (changed=${changed})`);
}
return changed;
diff --git a/src/stores/room-list/algorithms/list-ordering/ImportanceAlgorithm.ts b/src/stores/room-list/algorithms/list-ordering/ImportanceAlgorithm.ts
index e4aa5ff06f..80bdf74afb 100644
--- a/src/stores/room-list/algorithms/list-ordering/ImportanceAlgorithm.ts
+++ b/src/stores/room-list/algorithms/list-ordering/ImportanceAlgorithm.ts
@@ -270,7 +270,7 @@ export class ImportanceAlgorithm extends OrderingAlgorithm {
`!! Room list index corruption: ${lastCat} (i:${indices[lastCat]}) is greater ` +
`than ${thisCat} (i:${indices[thisCat]}) - category indices are likely desynced from reality`);
- // TODO: Regenerate index when this happens: https://github.com/vector-im/riot-web/issues/14234
+ // TODO: Regenerate index when this happens: https://github.com/vector-im/element-web/issues/14234
}
}
}
diff --git a/src/stores/room-list/algorithms/list-ordering/NaturalAlgorithm.ts b/src/stores/room-list/algorithms/list-ordering/NaturalAlgorithm.ts
index 5759f0c32d..cc2a28d892 100644
--- a/src/stores/room-list/algorithms/list-ordering/NaturalAlgorithm.ts
+++ b/src/stores/room-list/algorithms/list-ordering/NaturalAlgorithm.ts
@@ -54,7 +54,7 @@ export class NaturalAlgorithm extends OrderingAlgorithm {
}
}
- // TODO: Optimize this to avoid useless operations: https://github.com/vector-im/riot-web/issues/14457
+ // TODO: Optimize this to avoid useless operations: https://github.com/vector-im/element-web/issues/14457
// For example, we can skip updates to alphabetic (sometimes) and manually ordered tags
this.cachedOrderedRooms = await sortRoomsWithAlgorithm(
this.cachedOrderedRooms,
diff --git a/src/stores/room-list/algorithms/tag-sorting/RecentAlgorithm.ts b/src/stores/room-list/algorithms/tag-sorting/RecentAlgorithm.ts
index 09182f3bfb..7c8c879cf6 100644
--- a/src/stores/room-list/algorithms/tag-sorting/RecentAlgorithm.ts
+++ b/src/stores/room-list/algorithms/tag-sorting/RecentAlgorithm.ts
@@ -33,13 +33,13 @@ export class RecentAlgorithm implements IAlgorithm {
// of the rooms to each other.
// TODO: We could probably improve the sorting algorithm here by finding changes.
- // See https://github.com/vector-im/riot-web/issues/14459
+ // See https://github.com/vector-im/element-web/issues/14459
// For example, if we spent a little bit of time to determine which elements have
// actually changed (probably needs to be done higher up?) then we could do an
// insertion sort or similar on the limited set of changes.
// TODO: Don't assume we're using the same client as the peg
- // See https://github.com/vector-im/riot-web/issues/14458
+ // See https://github.com/vector-im/element-web/issues/14458
let myUserId = '';
if (MatrixClientPeg.get()) {
myUserId = MatrixClientPeg.get().getUserId();
diff --git a/src/stores/room-list/previews/IPreview.ts b/src/stores/room-list/previews/IPreview.ts
index 9beb92bfbf..fe69637543 100644
--- a/src/stores/room-list/previews/IPreview.ts
+++ b/src/stores/room-list/previews/IPreview.ts
@@ -27,5 +27,5 @@ export interface IPreview {
* @param tagId Optional. The tag where the room the event was sent in resides.
* @returns The preview.
*/
- getTextFor(event: MatrixEvent, tagId?: TagID): string;
+ getTextFor(event: MatrixEvent, tagId?: TagID): string | null;
}
diff --git a/src/stores/room-list/previews/ReactionEventPreview.ts b/src/stores/room-list/previews/ReactionEventPreview.ts
index 07fac107ca..95cdc01c66 100644
--- a/src/stores/room-list/previews/ReactionEventPreview.ts
+++ b/src/stores/room-list/previews/ReactionEventPreview.ts
@@ -19,9 +19,16 @@ import { TagID } from "../models";
import { MatrixEvent } from "matrix-js-sdk/src/models/event";
import { getSenderName, isSelf, shouldPrefixMessagesIn } from "./utils";
import { _t } from "../../../languageHandler";
+import SettingsStore from "../../../settings/SettingsStore";
+import DMRoomMap from "../../../utils/DMRoomMap";
export class ReactionEventPreview implements IPreview {
public getTextFor(event: MatrixEvent, tagId?: TagID): string {
+ const showDms = SettingsStore.getValue("feature_roomlist_preview_reactions_dms");
+ const showAll = SettingsStore.getValue("feature_roomlist_preview_reactions_all");
+
+ if (!showAll && (!showDms || DMRoomMap.shared().getUserIdForRoomId(event.getRoomId()))) return null;
+
const relation = event.getRelation();
if (!relation) return null; // invalid reaction (probably redacted)
diff --git a/src/theme.js b/src/theme.js
index c79e466933..a413ae74af 100644
--- a/src/theme.js
+++ b/src/theme.js
@@ -202,7 +202,7 @@ export async function setTheme(theme) {
return new Promise((resolve) => {
const switchTheme = function() {
// we re-enable our theme here just in case we raced with another
- // theme set request as per https://github.com/vector-im/riot-web/issues/5601.
+ // theme set request as per https://github.com/vector-im/element-web/issues/5601.
// We could alternatively lock or similar to stop the race, but
// this is probably good enough for now.
styleElements[stylesheetName].disabled = false;
diff --git a/src/toasts/UpdateToast.tsx b/src/toasts/UpdateToast.tsx
index 595f3a35d6..dfd06cf3a0 100644
--- a/src/toasts/UpdateToast.tsx
+++ b/src/toasts/UpdateToast.tsx
@@ -29,7 +29,7 @@ const TOAST_KEY = "update";
/*
* Check a version string is compatible with the Changelog
- * dialog ([riot-version]-react-[react-sdk-version]-js-[js-sdk-version])
+ * dialog ([element-version]-react-[react-sdk-version]-js-[js-sdk-version])
*/
function checkVersion(ver) {
const parts = ver.split('-');
diff --git a/src/usercontent/index.html b/src/usercontent/index.html
index 90a0fe7c16..9abbdb5289 100644
--- a/src/usercontent/index.html
+++ b/src/usercontent/index.html
@@ -2,9 +2,9 @@
diff --git a/src/utils/AutoDiscoveryUtils.js b/src/utils/AutoDiscoveryUtils.js
index 7452ff31a5..94aa0c3544 100644
--- a/src/utils/AutoDiscoveryUtils.js
+++ b/src/utils/AutoDiscoveryUtils.js
@@ -80,7 +80,7 @@ export default class AutoDiscoveryUtils {
{
a: (sub) => {
return {sub};
@@ -203,7 +203,7 @@ export default class AutoDiscoveryUtils {
// Note: In the cases where we rely on the default IS from the config (namely
// lack of identity server provided by the discovery method), we intentionally do not
// validate it. This has already been validated and this helps some off-the-grid usage
- // of Riot.
+ // of Element.
let preferredIdentityUrl = defaultConfig && defaultConfig['isUrl'];
if (isResult && isResult.state === AutoDiscovery.SUCCESS) {
preferredIdentityUrl = isResult["base_url"];
diff --git a/src/utils/DMRoomMap.js b/src/utils/DMRoomMap.js
index 6ce92a0458..4e219b1611 100644
--- a/src/utils/DMRoomMap.js
+++ b/src/utils/DMRoomMap.js
@@ -16,7 +16,7 @@ limitations under the License.
*/
import {MatrixClientPeg} from '../MatrixClientPeg';
-import _uniq from 'lodash/uniq';
+import {uniq} from "lodash";
import {Room} from "matrix-js-sdk/src/matrix";
/**
@@ -111,7 +111,7 @@ export default class DMRoomMap {
userToRooms[userId] = [roomId];
} else {
roomIds.push(roomId);
- userToRooms[userId] = _uniq(roomIds);
+ userToRooms[userId] = uniq(roomIds);
}
});
return true;
diff --git a/src/utils/DecryptFile.js b/src/utils/DecryptFile.js
index f5a1b0aa62..dcdc2f9fdb 100644
--- a/src/utils/DecryptFile.js
+++ b/src/utils/DecryptFile.js
@@ -28,7 +28,7 @@ import {MatrixClientPeg} from '../MatrixClientPeg';
// called createObjectURL(), and so if the content contains any scripting then it
// will pose a XSS vulnerability when the browser renders it. This is particularly
// bad if the user right-clicks the URI and pastes it into a new window or tab,
-// as the blob will then execute with access to Riot's full JS environment(!)
+// as the blob will then execute with access to Element's full JS environment(!)
//
// See https://github.com/matrix-org/matrix-react-sdk/pull/1820#issuecomment-385210647
// for details.
diff --git a/src/utils/ResizeNotifier.js b/src/utils/ResizeNotifier.js
index f726a43e08..5467716576 100644
--- a/src/utils/ResizeNotifier.js
+++ b/src/utils/ResizeNotifier.js
@@ -53,6 +53,10 @@ export default class ResizeNotifier extends EventEmitter {
this._updateMiddlePanel();
}
+ notifyTimelineHeightChanged() {
+ this._updateMiddlePanel();
+ }
+
// can be called in quick succession
notifyWindowResized() {
// no need to throttle this one,
diff --git a/src/utils/WellKnownUtils.ts b/src/utils/WellKnownUtils.ts
new file mode 100644
index 0000000000..46d9638ecd
--- /dev/null
+++ b/src/utils/WellKnownUtils.ts
@@ -0,0 +1,40 @@
+/*
+Copyright 2020 The Matrix.org Foundation C.I.C.
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+import {MatrixClientPeg} from '../MatrixClientPeg';
+
+const E2EE_WK_KEY = "io.element.e2ee";
+const E2EE_WK_KEY_DEPRECATED = "im.vector.riot.e2ee";
+
+export interface IE2EEWellKnown {
+ default?: boolean;
+}
+
+export function getE2EEWellKnown(): IE2EEWellKnown {
+ const clientWellKnown = MatrixClientPeg.get().getClientWellKnown();
+ if (clientWellKnown && clientWellKnown[E2EE_WK_KEY]) {
+ return clientWellKnown[E2EE_WK_KEY];
+ }
+ if (clientWellKnown && clientWellKnown[E2EE_WK_KEY_DEPRECATED]) {
+ return clientWellKnown[E2EE_WK_KEY_DEPRECATED]
+ }
+ return null;
+}
+
+export function isSecureBackupRequired(): boolean {
+ const wellKnown = getE2EEWellKnown();
+ return wellKnown && wellKnown["secure_backup_required"] === true;
+}
diff --git a/src/utils/WidgetUtils.js b/src/utils/WidgetUtils.js
index f7f4be202b..645953210d 100644
--- a/src/utils/WidgetUtils.js
+++ b/src/utils/WidgetUtils.js
@@ -69,7 +69,7 @@ export default class WidgetUtils {
return false;
}
- // TODO: Enable support for m.widget event type (https://github.com/vector-im/riot-web/issues/13111)
+ // TODO: Enable support for m.widget event type (https://github.com/vector-im/element-web/issues/13111)
return room.currentState.maySendStateEvent('im.vector.modular.widgets', me);
}
@@ -185,7 +185,7 @@ export default class WidgetUtils {
}
const room = MatrixClientPeg.get().getRoom(roomId);
- // TODO: Enable support for m.widget event type (https://github.com/vector-im/riot-web/issues/13111)
+ // TODO: Enable support for m.widget event type (https://github.com/vector-im/element-web/issues/13111)
const startingWidgetEvents = room.currentState.getStateEvents('im.vector.modular.widgets');
if (eventsInIntendedState(startingWidgetEvents)) {
resolve();
@@ -195,7 +195,7 @@ export default class WidgetUtils {
function onRoomStateEvents(ev) {
if (ev.getRoomId() !== roomId) return;
- // TODO: Enable support for m.widget event type (https://github.com/vector-im/riot-web/issues/13111)
+ // TODO: Enable support for m.widget event type (https://github.com/vector-im/element-web/issues/13111)
const currentWidgetEvents = room.currentState.getStateEvents('im.vector.modular.widgets');
if (eventsInIntendedState(currentWidgetEvents)) {
@@ -263,8 +263,8 @@ export default class WidgetUtils {
if (addingWidget) {
content = {
- // TODO: Enable support for m.widget event type (https://github.com/vector-im/riot-web/issues/13111)
- // For now we'll send the legacy event type for compatibility with older apps/riots
+ // TODO: Enable support for m.widget event type (https://github.com/vector-im/element-web/issues/13111)
+ // For now we'll send the legacy event type for compatibility with older apps/elements
type: widgetType.legacy,
url: widgetUrl,
name: widgetName,
@@ -277,7 +277,7 @@ export default class WidgetUtils {
WidgetEchoStore.setRoomWidgetEcho(roomId, widgetId, content);
const client = MatrixClientPeg.get();
- // TODO: Enable support for m.widget event type (https://github.com/vector-im/riot-web/issues/13111)
+ // TODO: Enable support for m.widget event type (https://github.com/vector-im/element-web/issues/13111)
return client.sendStateEvent(roomId, "im.vector.modular.widgets", content, widgetId).then(() => {
return WidgetUtils.waitForRoomWidget(widgetId, roomId, addingWidget);
}).finally(() => {
@@ -291,7 +291,7 @@ export default class WidgetUtils {
* @return {[object]} Array containing current / active room widgets
*/
static getRoomWidgets(room: Room) {
- // TODO: Enable support for m.widget event type (https://github.com/vector-im/riot-web/issues/13111)
+ // TODO: Enable support for m.widget event type (https://github.com/vector-im/element-web/issues/13111)
const appsStateEvents = room.currentState.getStateEvents('im.vector.modular.widgets');
if (!appsStateEvents) {
return [];
@@ -466,7 +466,7 @@ export default class WidgetUtils {
// safe to send.
// We'll end up using a local render URL when we see a Jitsi widget anyways, so this is
// really just for backwards compatibility and to appease the spec.
- baseUrl = "https://riot.im/app/";
+ baseUrl = "https://app.element.io/";
}
const url = new URL("jitsi.html#" + queryString, baseUrl); // this strips hash fragment from baseUrl
return url.href;
diff --git a/src/utils/maps.ts b/src/utils/maps.ts
new file mode 100644
index 0000000000..96832094f0
--- /dev/null
+++ b/src/utils/maps.ts
@@ -0,0 +1,46 @@
+/*
+Copyright 2020 The Matrix.org Foundation C.I.C.
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+import { arrayDiff, arrayMerge, arrayUnion } from "./arrays";
+
+/**
+ * Determines the keys added, changed, and removed between two Maps.
+ * For changes, simple triple equal comparisons are done, not in-depth tree checking.
+ * @param a The first Map. Must be defined.
+ * @param b The second Map. Must be defined.
+ * @returns The difference between the keys of each Map.
+ */
+export function mapDiff(a: Map, b: Map): { changed: K[], added: K[], removed: K[] } {
+ const aKeys = [...a.keys()];
+ const bKeys = [...b.keys()];
+ const keyDiff = arrayDiff(aKeys, bKeys);
+ const possibleChanges = arrayUnion(aKeys, bKeys);
+ const changes = possibleChanges.filter(k => a.get(k) !== b.get(k));
+
+ return {changed: changes, added: keyDiff.added, removed: keyDiff.removed};
+}
+
+/**
+ * Gets all the key changes (added, removed, or value difference) between two Maps.
+ * Triple equals is used to compare values, not in-depth tree checking.
+ * @param a The first Map. Must be defined.
+ * @param b The second Map. Must be defined.
+ * @returns The keys which have been added, removed, or changed between the two Maps.
+ */
+export function mapKeyChanges(a: Map, b: Map): K[] {
+ const diff = mapDiff(a, b);
+ return arrayMerge(diff.removed, diff.added, diff.changed);
+}
diff --git a/src/utils/membership.ts b/src/utils/membership.ts
index 9f1c5b7b41..68ac958490 100644
--- a/src/utils/membership.ts
+++ b/src/utils/membership.ts
@@ -15,6 +15,13 @@ limitations under the License.
*/
import { Room } from "matrix-js-sdk/src/models/room";
+import { MatrixClientPeg } from "../MatrixClientPeg";
+import { _t } from "../languageHandler";
+import Modal from "../Modal";
+import ErrorDialog from "../components/views/dialogs/ErrorDialog";
+import React from "react";
+import dis from "../dispatcher/dispatcher";
+import RoomViewStore from "../stores/RoomViewStore";
/**
* Approximation of a membership status for a given room.
@@ -63,10 +70,71 @@ export function getEffectiveMembership(membership: string): EffectiveMembership
if (membership === 'invite') {
return EffectiveMembership.Invite;
} else if (membership === 'join') {
- // TODO: Include knocks? Update docs as needed in the enum. https://github.com/vector-im/riot-web/issues/14237
+ // TODO: Include knocks? Update docs as needed in the enum. https://github.com/vector-im/element-web/issues/14237
return EffectiveMembership.Join;
} else {
// Probably a leave, kick, or ban
return EffectiveMembership.Leave;
}
}
+
+export async function leaveRoomBehaviour(roomId: string) {
+ let leavingAllVersions = true;
+ const history = await MatrixClientPeg.get().getRoomUpgradeHistory(roomId);
+ if (history && history.length > 0) {
+ const currentRoom = history[history.length - 1];
+ if (currentRoom.roomId !== roomId) {
+ // The user is trying to leave an older version of the room. Let them through
+ // without making them leave the current version of the room.
+ leavingAllVersions = false;
+ }
+ }
+
+ let results: { [roomId: string]: Error & { errcode: string, message: string } } = {};
+ if (!leavingAllVersions) {
+ try {
+ await MatrixClientPeg.get().leave(roomId);
+ } catch (e) {
+ if (e && e.data && e.data.errcode) {
+ const message = e.data.error || _t("Unexpected server error trying to leave the room");
+ results[roomId] = Object.assign(new Error(message), {errcode: e.data.errcode});
+ } else {
+ results[roomId] = e || new Error("Failed to leave room for unknown causes");
+ }
+ }
+ } else {
+ results = await MatrixClientPeg.get().leaveRoomChain(roomId);
+ }
+
+ const errors = Object.entries(results).filter(r => !!r[1]);
+ if (errors.length > 0) {
+ const messages = [];
+ for (const roomErr of errors) {
+ const err = roomErr[1]; // [0] is the roomId
+ let message = _t("Unexpected server error trying to leave the room");
+ if (err.errcode && err.message) {
+ if (err.errcode === 'M_CANNOT_LEAVE_SERVER_NOTICE_ROOM') {
+ Modal.createTrackedDialog('Error Leaving Room', '', ErrorDialog, {
+ title: _t("Can't leave Server Notices room"),
+ description: _t(
+ "This room is used for important messages from the Homeserver, " +
+ "so you cannot leave it.",
+ ),
+ });
+ return;
+ }
+ message = results[roomId].message;
+ }
+ messages.push(message, React.createElement('BR')); // createElement to avoid using a tsx file in utils
+ }
+ Modal.createTrackedDialog('Error Leaving Room', '', ErrorDialog, {
+ title: _t("Error leaving room"),
+ description: messages,
+ });
+ return;
+ }
+
+ if (RoomViewStore.getRoomId() === roomId) {
+ dis.dispatch({action: 'view_next_room'});
+ }
+}
diff --git a/src/utils/objects.ts b/src/utils/objects.ts
index ddd9830832..bc74ab9ee0 100644
--- a/src/utils/objects.ts
+++ b/src/utils/objects.ts
@@ -16,15 +16,17 @@ limitations under the License.
import { arrayDiff, arrayHasDiff, arrayMerge, arrayUnion } from "./arrays";
+type ObjectExcluding = {[k in Exclude]: O[k]};
+
/**
* Gets a new object which represents the provided object, excluding some properties.
* @param a The object to strip properties of. Must be defined.
* @param props The property names to remove.
* @returns The new object without the provided properties.
*/
-export function objectExcluding(a: any, props: string[]): any {
+export function objectExcluding>(a: O, props: P): ObjectExcluding {
// We use a Map to avoid hammering the `delete` keyword, which is slow and painful.
- const tempMap = new Map(Object.entries(a));
+ const tempMap = new Map(Object.entries(a) as [keyof O, any][]);
for (const prop of props) {
tempMap.delete(prop);
}
@@ -33,7 +35,7 @@ export function objectExcluding(a: any, props: string[]): any {
return Array.from(tempMap.entries()).reduce((c, [k, v]) => {
c[k] = v;
return c;
- }, {});
+ }, {} as O);
}
/**
@@ -43,13 +45,13 @@ export function objectExcluding(a: any, props: string[]): any {
* @param props The property names to keep.
* @returns The new object with only the provided properties.
*/
-export function objectWithOnly(a: any, props: string[]): any {
- const existingProps = Object.keys(a);
+export function objectWithOnly>(a: O, props: P): {[k in P[number]]: O[k]} {
+ const existingProps = Object.keys(a) as (keyof O)[];
const diff = arrayDiff(existingProps, props);
if (diff.removed.length === 0) {
return objectShallowClone(a);
} else {
- return objectExcluding(a, diff.removed);
+ return objectExcluding(a, diff.removed) as {[k in P[number]]: O[k]};
}
}
@@ -64,9 +66,9 @@ export function objectWithOnly(a: any, props: string[]): any {
* First argument is the property key with the second being the current value.
* @returns A cloned object.
*/
-export function objectShallowClone(a: any, propertyCloner?: (k: string, v: any) => any): any {
- const newObj = {};
- for (const [k, v] of Object.entries(a)) {
+export function objectShallowClone(a: O, propertyCloner?: (k: keyof O, v: O[keyof O]) => any): O {
+ const newObj = {} as O;
+ for (const [k, v] of Object.entries(a) as [keyof O, O[keyof O]][]) {
newObj[k] = v;
if (propertyCloner) {
newObj[k] = propertyCloner(k, v);
@@ -83,7 +85,7 @@ export function objectShallowClone(a: any, propertyCloner?: (k: string, v: any)
* @param b The second object. Must be defined.
* @returns True if there's a difference between the objects, false otherwise
*/
-export function objectHasDiff(a: any, b: any): boolean {
+export function objectHasDiff(a: O, b: O): boolean {
const aKeys = Object.keys(a);
const bKeys = Object.keys(b);
if (arrayHasDiff(aKeys, bKeys)) return true;
@@ -92,6 +94,8 @@ export function objectHasDiff(a: any, b: any): boolean {
return possibleChanges.some(k => a[k] !== b[k]);
}
+type Diff = { changed: K[], added: K[], removed: K[] };
+
/**
* Determines the keys added, changed, and removed between two objects.
* For changes, simple triple equal comparisons are done, not in-depth
@@ -100,9 +104,9 @@ export function objectHasDiff(a: any, b: any): boolean {
* @param b The second object. Must be defined.
* @returns The difference between the keys of each object.
*/
-export function objectDiff(a: any, b: any): { changed: string[], added: string[], removed: string[] } {
- const aKeys = Object.keys(a);
- const bKeys = Object.keys(b);
+export function objectDiff(a: O, b: O): Diff {
+ const aKeys = Object.keys(a) as (keyof O)[];
+ const bKeys = Object.keys(b) as (keyof O)[];
const keyDiff = arrayDiff(aKeys, bKeys);
const possibleChanges = arrayUnion(aKeys, bKeys);
const changes = possibleChanges.filter(k => a[k] !== b[k]);
@@ -119,7 +123,7 @@ export function objectDiff(a: any, b: any): { changed: string[], added: string[]
* @returns The keys which have been added, removed, or changed between the
* two objects.
*/
-export function objectKeyChanges(a: any, b: any): string[] {
+export function objectKeyChanges(a: O, b: O): (keyof O)[] {
const diff = objectDiff(a, b);
return arrayMerge(diff.removed, diff.added, diff.changed);
}
@@ -131,6 +135,6 @@ export function objectKeyChanges(a: any, b: any): string[] {
* @param obj The object to clone.
* @returns The cloned object
*/
-export function objectClone(obj: any): any {
+export function objectClone(obj: O): O {
return JSON.parse(JSON.stringify(obj));
}
diff --git a/src/utils/pillify.js b/src/utils/pillify.js
index cb140c61a4..432771592a 100644
--- a/src/utils/pillify.js
+++ b/src/utils/pillify.js
@@ -139,7 +139,7 @@ export function pillifyLinks(nodes, mxEvent, pills) {
* It's critical to call this after pillifyLinks, otherwise
* Pills will leak, leaking entire DOM trees via the event
* emitter on BaseAvatar as per
- * https://github.com/vector-im/riot-web/issues/12417
+ * https://github.com/vector-im/element-web/issues/12417
*
* @param {Node[]} pills - array of pill containers whose React
* components should be unmounted.
diff --git a/src/widgets/WidgetApi.ts b/src/widgets/WidgetApi.ts
index 4775c30c95..15603e9437 100644
--- a/src/widgets/WidgetApi.ts
+++ b/src/widgets/WidgetApi.ts
@@ -65,7 +65,7 @@ export interface FromWidgetRequest extends WidgetRequest {
}
/**
- * Handles Riot <--> Widget interactions for embedded/standalone widgets.
+ * Handles Element <--> Widget interactions for embedded/standalone widgets.
*
* Emitted events:
* - terminate(wait): client requested the widget to terminate.
@@ -141,7 +141,7 @@ export class WidgetApi extends EventEmitter {
private replyToRequest(payload: ToWidgetRequest, reply: any) {
if (!window.parent) return;
- const request = objectClone(payload);
+ const request: ToWidgetRequest & {response?: any} = objectClone(payload);
request.response = reply;
window.parent.postMessage(request, this.origin);
diff --git a/test/components/structures/MessagePanel-test.js b/test/components/structures/MessagePanel-test.js
index 3ac70bdac9..235ae94010 100644
--- a/test/components/structures/MessagePanel-test.js
+++ b/test/components/structures/MessagePanel-test.js
@@ -18,9 +18,7 @@ limitations under the License.
import SettingsStore from "../../../src/settings/SettingsStore";
import React from 'react';
-import createReactClass from 'create-react-class';
import ReactDOM from "react-dom";
-import PropTypes from "prop-types";
const TestUtils = require('react-dom/test-utils');
const expect = require('expect');
import { EventEmitter } from "events";
@@ -47,21 +45,19 @@ let client;
const room = new Matrix.Room();
// wrap MessagePanel with a component which provides the MatrixClient in the context.
-const WrappedMessagePanel = createReactClass({
- getInitialState: function() {
- return {
- resizeNotifier: new EventEmitter(),
- };
- },
+class WrappedMessagePanel extends React.Component {
+ state = {
+ resizeNotifier: new EventEmitter(),
+ };
- render: function() {
+ render() {
return ;
- },
-});
+ }
+}
describe('MessagePanel', function() {
const clock = mockclock.clock();
@@ -214,7 +210,7 @@ describe('MessagePanel', function() {
room: roomId,
user: alice,
content: {
- "join_rule": "invite"
+ "join_rule": "invite",
},
ts: ts0 + 2,
}),
diff --git a/test/components/stub-component.js b/test/components/stub-component.js
index a5c3b44409..e242c06707 100644
--- a/test/components/stub-component.js
+++ b/test/components/stub-component.js
@@ -2,19 +2,19 @@
*/
import React from 'react';
-import createReactClass from 'create-react-class';
-export default function(opts) {
- opts = opts || {};
- if (!opts.displayName) {
- opts.displayName = 'StubComponent';
- }
-
- if (!opts.render) {
- opts.render = function() {
- return