diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index d93197fe..a2dccfb2 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -172,12 +172,10 @@ upload_to_fdroid_repo:
- chmod 700 ~/.ssh
- ssh-keyscan -t rsa fdroid.nordgedanken.dev >> ~/.ssh/known_hosts
script:
- - mkdir -p upload
- - cp build/android/* upload/
- cd build/android/
- - export UPDATE_VERSION=$(pcregrep -o1 'version:\\s([0-9]*\\.[0-9]*\\.[0-9]*)\\+[0-9]*' pubspec.yaml) && mv app-release.apk "${UPDATE_VERSION}.apk"
+ - export UPDATE_VERSION=$(pcregrep -o1 'version:\\s([0-9]*\\.[0-9]*\\.[0-9]*)\\+[0-9]*' ../../pubspec.yaml) && mv app-release.apk "${UPDATE_VERSION}.apk"
- rsync -rav -e ssh ./ fluffy@fdroid.nordgedanken.dev:/fdroid/repo
- - ssh fluffy@fdroid.nordgedanken.dev "cd fdroid && mount binfmt_misc -t binfmt_misc /proc/sys/fs/binfmt_misc && fdroid update"
+ - ssh fluffy@fdroid.nordgedanken.dev "cd fdroid && fdroid update"
needs: ["build_android_apk"]
only:
- tags
@@ -216,6 +214,29 @@ build_linux:
- build/linux/release/bundle/
only:
- main
+
+snap:edge:
+ stage: publish
+ image: "cibuilds/snapcraft:core18"
+ only:
+ - main
+ script:
+ ## Manually install the flutter-dev snap, so we can use the flutter extension
+ - 'curl -L $(curl -H "X-Ubuntu-Series: 16" "https://api.snapcraft.io/api/v1/snaps/details/flutter?channel=latest/stable" | jq ".download_url" -r) --output flutter.snap'
+ - sudo mkdir -p /snap/flutter
+ - sudo unsquashfs -d /snap/flutter/current flutter.snap
+ - rm -f flutter.snap
+ - sudo ln -sf /snap/flutter/current/flutter.sh /snap/bin/flutter
+ - sudo ln -sf /snap/flutter/current/env.sh /snap/bin/env.sh
+ - snapcraft
+ - echo $SNAPCRAFT_LOGIN_FILE | base64 --decode --ignore-garbage > snapcraft.login
+ - snapcraft login --with snapcraft.login
+ - snapcraft push --release=edge *.snap
+ - snapcraft logout
+ artifacts:
+ paths:
+ - './*.snap'
+ when: on_success
snap:publish:
stage: publish
@@ -234,3 +255,35 @@ snap:publish:
when: on_success
expire_in: 1 week
needs: []
+
+update-dependencies:
+ stage: coverage
+ needs: []
+ tags:
+ - docker
+ only:
+ - schedules
+ variables:
+ HOST: ${CI_PROJECT_URL}
+ UPDATE_BRANCH: ci-bot/dependency-updates
+ PRIVATE_TOKEN: ${GITLAB_API_TOKEN}
+ before_script:
+ - eval $(ssh-agent -s)
+ - echo "$SSH_PRIVATE_BOT_KEY" | tr -d '\r' | ssh-add - > /dev/null
+
+ - mkdir -p ~/.ssh
+ - chmod 700 ~/.ssh
+
+ - ssh-keyscan "https://gitlab.com" >> ~/.ssh/known_hosts
+ - chmod 644 ~/.ssh/known_hosts
+
+ - git config --global user.email "bot@fluffy.chat"
+ - git config --global user.name "Dependency Update Bot"
+ - sudo apt-get update && sudo apt-get install -y curl
+ script:
+ - flutter pub get
+ - flutter pub pub run dapackages:dapackages.dart ./pubspec.yaml
+ - flutter pub get
+ - git remote set-url --push origin git@gitlab.com:$CI_PROJECT_PATH
+ - 'git diff --exit-code || (git checkout -B ${UPDATE_BRANCH} && git add . && git commit -m "chore: Update dependencies" && git push -f origin ${UPDATE_BRANCH} && ./scripts/open-mr.sh)'
+
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 3d111481..f7fac2e4 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,4 +1,16 @@
-# Version 0.20.0 - 2020-??-??
+# Version 0.21.0 - 2020-10-28
+### Features
+- New user viewer
+- Add code syntax highlighting in messages
+- Updated translations: Thanks to all helpers
+### Changes
+- Stories feature removed
+### Fixes
+- Fixes sentry
+- Fixes Android download
+- Minor fixes
+
+# Version 0.20.0 - 2020-10-23
### Features
- Added translations: Arabic
- Add ability to enable / disable emotes globally
@@ -18,6 +30,7 @@
- Show device name in account information correctly
- Fix tapping on aliases / room pills not always working
- Link clicking in web not always working
+- Return message input field to previous state after editing message - Thanks @inexcode
# Version 0.19.0 - 2020-09-21
### Features
diff --git a/README.md b/README.md
index 092146db..d7342ebc 100644
--- a/README.md
+++ b/README.md
@@ -8,7 +8,7 @@
- Open FluffyChat in the browser - Join the community - Follow me on Mastodon - Translate FluffyChat - Translate the website - FAQ - Website - Download latest APK - Famedly Matrix SDK
+ Open FluffyChat in the browser - Join the community - Follow me on Mastodon - Translate FluffyChat - Translate the website - Website - Download latest APK - Famedly Matrix SDK
@@ -57,11 +57,6 @@ cd fluffychat-flutter
sudo apt install ninja-build
```
-* Outcomment the Google Services plugin at the end of the file `android/app/build.gradle`:
-```
-// apply plugin: "com.google.gms.google-services"
-```
-
* Build with: `flutter build apk`
### iOS / iPadOS
diff --git a/android/app/build.gradle b/android/app/build.gradle
index 36caa499..9b211682 100644
--- a/android/app/build.gradle
+++ b/android/app/build.gradle
@@ -32,7 +32,7 @@ if (keystorePropertiesFile.exists()) {
}
android {
- compileSdkVersion 28
+ compileSdkVersion 30
sourceSets {
main.java.srcDirs += 'src/main/kotlin'
@@ -44,8 +44,8 @@ android {
defaultConfig {
applicationId "chat.fluffy.fluffychat"
- minSdkVersion 18
- targetSdkVersion 28
+ minSdkVersion 21
+ targetSdkVersion 30
versionCode flutterVersionCode.toInteger()
versionName flutterVersionName
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
@@ -87,4 +87,4 @@ dependencies {
implementation "net.zetetic:android-database-sqlcipher:4.4.0" // needed for moor_ffi w/ sqlcipher
}
-apply plugin: "com.google.gms.google-services"
+apply plugin: 'com.google.gms.google-services'
\ No newline at end of file
diff --git a/assets/logo.svg b/assets/logo.svg
index 93d52318..a3a95164 100644
--- a/assets/logo.svg
+++ b/assets/logo.svg
@@ -1,48 +1,43 @@
-
-
-
+
+
+
diff --git a/lib/components/avatar.dart b/lib/components/avatar.dart
index c4b8e16b..0a35c1cd 100644
--- a/lib/components/avatar.dart
+++ b/lib/components/avatar.dart
@@ -45,10 +45,12 @@ class Avatar extends StatelessWidget {
),
);
final noPic = mxContent == null || mxContent.toString().isEmpty;
+ final borderRadius = BorderRadius.circular(size / 2);
return InkWell(
onTap: onTap,
+ borderRadius: borderRadius,
child: ClipRRect(
- borderRadius: BorderRadius.circular(size / 2),
+ borderRadius: borderRadius,
child: Container(
width: size,
height: size,
@@ -68,6 +70,11 @@ class Avatar extends StatelessWidget {
textWidget,
],
),
+ errorWidget: (c, s, d) => Stack(
+ children: [
+ textWidget,
+ ],
+ ),
),
),
),
diff --git a/lib/components/dialogs/send_file_dialog.dart b/lib/components/dialogs/send_file_dialog.dart
index 1ad33ef7..061c0b75 100644
--- a/lib/components/dialogs/send_file_dialog.dart
+++ b/lib/components/dialogs/send_file_dialog.dart
@@ -19,7 +19,7 @@ class SendFileDialog extends StatefulWidget {
class _SendFileDialogState extends State {
bool origImage = false;
-
+ bool _isSending = false;
Future _send() async {
var file = widget.file;
if (file is MatrixImageFile && !origImage) {
@@ -82,10 +82,16 @@ class _SendFileDialogState extends State {
),
FlatButton(
child: Text(L10n.of(context).send),
- onPressed: () async {
- await SimpleDialogs(context).tryRequestWithLoadingDialog(_send());
- await Navigator.of(context).pop();
- },
+ onPressed: _isSending
+ ? null
+ : () async {
+ setState(() {
+ _isSending = true;
+ });
+ await SimpleDialogs(context)
+ .tryRequestWithLoadingDialog(_send());
+ await Navigator.of(context).pop();
+ },
),
],
);
diff --git a/lib/components/html_message.dart b/lib/components/html_message.dart
index df508a41..a67377a0 100644
--- a/lib/components/html_message.dart
+++ b/lib/components/html_message.dart
@@ -33,6 +33,8 @@ class HtmlMessage extends StatelessWidget {
// there is no need to pre-validate the html, as we validate it while rendering
+ final matrix = Matrix.of(context);
+
final themeData = Theme.of(context);
return Html(
data: renderHtml,
@@ -50,12 +52,18 @@ class HtmlMessage extends StatelessWidget {
getMxcUrl: (String mxc, double width, double height) {
final ratio = MediaQuery.of(context).devicePixelRatio;
return Uri.parse(mxc)?.getThumbnail(
- Matrix.of(context).client,
+ matrix.client,
width: (width ?? 800) * ratio,
height: (height ?? 800) * ratio,
method: ThumbnailMethod.scale,
);
},
+ setCodeLanguage: (String key, String value) async {
+ await matrix.store.setItem('code_language.$key', value);
+ },
+ getCodeLanguage: (String key) async {
+ return await matrix.store.getItem('code_language.$key');
+ },
getPillInfo: (String identifier) async {
if (room == null) {
return null;
diff --git a/lib/components/list_items/participant_list_item.dart b/lib/components/list_items/participant_list_item.dart
index 5258f2c4..278fb842 100644
--- a/lib/components/list_items/participant_list_item.dart
+++ b/lib/components/list_items/participant_list_item.dart
@@ -1,66 +1,15 @@
import 'package:famedlysdk/famedlysdk.dart';
-import 'package:fluffychat/components/dialogs/simple_dialogs.dart';
-import 'package:fluffychat/utils/app_route.dart';
-import 'package:fluffychat/views/chat.dart';
import 'package:flutter/material.dart';
import 'package:flutter_gen/gen_l10n/l10n.dart';
import '../avatar.dart';
-import '../matrix.dart';
+import '../user_bottom_sheet.dart';
class ParticipantListItem extends StatelessWidget {
final User user;
const ParticipantListItem(this.user);
- void participantAction(BuildContext context, String action) async {
- switch (action) {
- case 'ban':
- if (await SimpleDialogs(context).askConfirmation()) {
- await SimpleDialogs(context).tryRequestWithLoadingDialog(user.ban());
- }
- break;
- case 'unban':
- if (await SimpleDialogs(context).askConfirmation()) {
- await SimpleDialogs(context)
- .tryRequestWithLoadingDialog(user.unban());
- }
- break;
- case 'kick':
- if (await SimpleDialogs(context).askConfirmation()) {
- await SimpleDialogs(context).tryRequestWithLoadingDialog(user.kick());
- }
- break;
- case 'admin':
- if (await SimpleDialogs(context).askConfirmation()) {
- await SimpleDialogs(context)
- .tryRequestWithLoadingDialog(user.setPower(100));
- }
- break;
- case 'moderator':
- if (await SimpleDialogs(context).askConfirmation()) {
- await SimpleDialogs(context)
- .tryRequestWithLoadingDialog(user.setPower(50));
- }
- break;
- case 'user':
- if (await SimpleDialogs(context).askConfirmation()) {
- await SimpleDialogs(context)
- .tryRequestWithLoadingDialog(user.setPower(0));
- }
- break;
- case 'message':
- final roomId = await user.startDirectChat();
- await Navigator.of(context).pushAndRemoveUntil(
- AppRoute.defaultRoute(
- context,
- ChatView(roomId),
- ),
- (Route r) => r.isFirst);
- break;
- }
- }
-
@override
Widget build(BuildContext context) {
var membershipBatch = {
@@ -74,87 +23,43 @@ class ParticipantListItem extends StatelessWidget {
: user.powerLevel >= 50
? L10n.of(context).moderator
: '';
- var items = >[];
- if (user.id != Matrix.of(context).client.userID) {
- items.add(
- PopupMenuItem(
- child: Text(L10n.of(context).sendAMessage), value: 'message'),
- );
- }
- if (user.canChangePowerLevel &&
- user.room.ownPowerLevel == 100 &&
- user.powerLevel != 100) {
- items.add(
- PopupMenuItem(
- child: Text(L10n.of(context).makeAnAdmin), value: 'admin'),
- );
- }
- if (user.canChangePowerLevel &&
- user.room.ownPowerLevel >= 50 &&
- user.powerLevel != 50) {
- items.add(
- PopupMenuItem(
- child: Text(L10n.of(context).makeAModerator), value: 'moderator'),
- );
- }
- if (user.canChangePowerLevel && user.powerLevel != 0) {
- items.add(
- PopupMenuItem(
- child: Text(L10n.of(context).revokeAllPermissions), value: 'user'),
- );
- }
- if (user.canKick) {
- items.add(
- PopupMenuItem(
- child: Text(L10n.of(context).kickFromChat), value: 'kick'),
- );
- }
- if (user.canBan && user.membership != Membership.ban) {
- items.add(
- PopupMenuItem(child: Text(L10n.of(context).banFromChat), value: 'ban'),
- );
- } else if (user.canBan && user.membership == Membership.ban) {
- items.add(
- PopupMenuItem(
- child: Text(L10n.of(context).removeExile), value: 'unban'),
- );
- }
- return PopupMenuButton(
- onSelected: (action) => participantAction(context, action),
- itemBuilder: (c) => items,
- child: ListTile(
- title: Row(
- children: [
- Text(user.calcDisplayname()),
- permissionBatch.isEmpty
- ? Container()
- : Container(
- padding: EdgeInsets.all(4),
- margin: EdgeInsets.symmetric(horizontal: 8),
- decoration: BoxDecoration(
- color: Theme.of(context).secondaryHeaderColor,
- borderRadius: BorderRadius.circular(8),
- ),
- child: Center(child: Text(permissionBatch)),
- ),
- membershipBatch[user.membership].isEmpty
- ? Container()
- : Container(
- padding: EdgeInsets.all(4),
- margin: EdgeInsets.symmetric(horizontal: 8),
- decoration: BoxDecoration(
- color: Theme.of(context).secondaryHeaderColor,
- borderRadius: BorderRadius.circular(8),
- ),
- child:
- Center(child: Text(membershipBatch[user.membership])),
- ),
- ],
+ return ListTile(
+ onTap: () => showModalBottomSheet(
+ context: context,
+ builder: (context) => UserBottomSheet(
+ user: user,
),
- subtitle: Text(user.id),
- leading: Avatar(user.avatarUrl, user.calcDisplayname()),
),
+ title: Row(
+ children: [
+ Text(user.calcDisplayname()),
+ permissionBatch.isEmpty
+ ? Container()
+ : Container(
+ padding: EdgeInsets.all(4),
+ margin: EdgeInsets.symmetric(horizontal: 8),
+ decoration: BoxDecoration(
+ color: Theme.of(context).secondaryHeaderColor,
+ borderRadius: BorderRadius.circular(8),
+ ),
+ child: Center(child: Text(permissionBatch)),
+ ),
+ membershipBatch[user.membership].isEmpty
+ ? Container()
+ : Container(
+ padding: EdgeInsets.all(4),
+ margin: EdgeInsets.symmetric(horizontal: 8),
+ decoration: BoxDecoration(
+ color: Theme.of(context).secondaryHeaderColor,
+ borderRadius: BorderRadius.circular(8),
+ ),
+ child: Center(child: Text(membershipBatch[user.membership])),
+ ),
+ ],
+ ),
+ subtitle: Text(user.id),
+ leading: Avatar(user.avatarUrl, user.calcDisplayname()),
);
}
}
diff --git a/lib/components/list_items/status_list_item.dart b/lib/components/list_items/status_list_item.dart
deleted file mode 100644
index 1d5f2725..00000000
--- a/lib/components/list_items/status_list_item.dart
+++ /dev/null
@@ -1,83 +0,0 @@
-import 'package:famedlysdk/famedlysdk.dart';
-import 'package:fluffychat/utils/user_status.dart';
-import 'package:fluffychat/views/status_view.dart';
-import 'package:flutter/material.dart';
-import '../avatar.dart';
-import '../matrix.dart';
-
-class StatusListItem extends StatelessWidget {
- final UserStatus status;
-
- const StatusListItem(this.status, {Key key}) : super(key: key);
-
- @override
- Widget build(BuildContext context) {
- final client = Matrix.of(context).client;
- return FutureBuilder(
- future: client.getProfileFromUserId(status.userId),
- builder: (context, snapshot) {
- final profile =
- snapshot.data ?? Profile(status.userId.localpart, null);
- return InkWell(
- borderRadius: BorderRadius.circular(8),
- onTap: () => Navigator.of(context).push(
- MaterialPageRoute(
- builder: (_) => StatusView(
- status: status,
- avatarUrl: profile.avatarUrl,
- displayname: profile.displayname,
- ),
- ),
- ),
- child: Container(
- width: 76,
- child: Column(
- children: [
- SizedBox(height: 10),
- Container(
- child: Stack(
- children: [
- Avatar(profile.avatarUrl, profile.displayname),
- Positioned(
- bottom: 0,
- right: 0,
- child: Container(
- width: 10,
- height: 10,
- decoration: BoxDecoration(
- borderRadius: BorderRadius.circular(20),
- color: Colors.green,
- ),
- ),
- ),
- ],
- ),
- decoration: BoxDecoration(
- border: Border.all(
- width: 1,
- color: Theme.of(context).primaryColor,
- ),
- borderRadius: BorderRadius.circular(80),
- ),
- padding: EdgeInsets.all(2),
- ),
- Padding(
- padding:
- const EdgeInsets.only(left: 6.0, top: 0.0, right: 6.0),
- child: Text(
- profile.displayname.trim().split(' ').first,
- overflow: TextOverflow.clip,
- maxLines: 1,
- style: TextStyle(
- color: Theme.of(context).textTheme.bodyText2.color,
- fontSize: 13,
- ),
- ),
- ),
- ],
- ),
- ),
- );
- });
- }
-}
diff --git a/lib/components/matrix.dart b/lib/components/matrix.dart
index f626e5e8..6e57617d 100644
--- a/lib/components/matrix.dart
+++ b/lib/components/matrix.dart
@@ -7,7 +7,7 @@ import 'package:fluffychat/components/dialogs/simple_dialogs.dart';
import 'package:fluffychat/utils/firebase_controller.dart';
import 'package:fluffychat/utils/matrix_locals.dart';
import 'package:fluffychat/utils/platform_infos.dart';
-import 'package:fluffychat/utils/user_status.dart';
+import 'package:fluffychat/utils/sentry_controller.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter_gen/gen_l10n/l10n.dart';
@@ -18,11 +18,9 @@ import 'package:fluffychat/config/app_config.dart';
import 'package:dbus/dbus.dart';
import 'package:desktop_notifications/desktop_notifications.dart';*/
-import '../main.dart';
import '../utils/app_route.dart';
import '../utils/beautify_string_extension.dart';
import '../utils/famedlysdk_store.dart';
-import '../utils/presence_extension.dart';
import '../views/key_verification.dart';
import '../utils/platform_infos.dart';
import 'avatar.dart';
@@ -81,8 +79,7 @@ class MatrixState extends State {
void clean() async {
if (!kIsWeb) return;
- final storage = await getLocalStorage();
- await storage.deleteItem(widget.clientName);
+ await store.deleteItem(widget.clientName);
}
void _initWithStore() async {
@@ -92,7 +89,6 @@ class MatrixState extends State {
await client.connect();
final firstLoginState = await initLoginState;
if (firstLoginState == LoginState.logged) {
- _cleanUpUserStatus(userStatuses);
if (PlatformInfos.isMobile) {
await FirebaseController.setupFirebase(
this,
@@ -102,7 +98,7 @@ class MatrixState extends State {
}
} catch (e, s) {
client.onLoginStateChanged.sink.addError(e, s);
- captureException(e, s);
+ SentryController.captureException(e, s);
rethrow;
}
}
@@ -124,7 +120,6 @@ class MatrixState extends State {
StreamSubscription onNotification;
StreamSubscription onFocusSub;
StreamSubscription onBlurSub;
- StreamSubscription onPresenceSub;
void onJitsiCall(EventUpdate eventUpdate) {
final event = Event.fromJson(
@@ -247,12 +242,9 @@ class MatrixState extends State {
importantStateEvents: {
'im.ponies.room_emotes', // we want emotes to work properly
});
- onPresenceSub ??= client.onPresence.stream
- .where((p) => p.isUserStatus)
- .listen(_storeUserStatus);
onJitsiCallSub ??= client.onEvent.stream
.where((e) =>
- e.type == 'timeline' &&
+ e.type == EventUpdateType.timeline &&
e.eventType == 'm.room.message' &&
e.content['content']['msgtype'] == Matrix.callNamespace &&
e.content['sender'] != client.userID)
@@ -321,7 +313,7 @@ class MatrixState extends State {
html.Notification.requestPermission();
onNotification ??= client.onEvent.stream
.where((e) =>
- e.type == 'timeline' &&
+ e.type == EventUpdateType.timeline &&
[EventTypes.Message, EventTypes.Sticker, EventTypes.Encrypted]
.contains(e.eventType) &&
e.content['sender'] != client.userID)
@@ -331,64 +323,11 @@ class MatrixState extends State {
super.initState();
}
- List get userStatuses {
- try {
- return (client.accountData[userStatusesType].content['user_statuses']
- as List)
- .map((json) => UserStatus.fromJson(json))
- .toList();
- } catch (_) {}
- return [];
- }
-
- void _storeUserStatus(Presence presence) {
- final tmpUserStatuses = List.from(userStatuses);
- final currentStatusIndex =
- userStatuses.indexWhere((u) => u.userId == presence.senderId);
- final newUserStatus = UserStatus()
- ..receivedAt = DateTime.now().millisecondsSinceEpoch
- ..statusMsg = presence.presence.statusMsg
- ..userId = presence.senderId;
- if (currentStatusIndex == -1) {
- tmpUserStatuses.add(newUserStatus);
- } else if (tmpUserStatuses[currentStatusIndex].statusMsg !=
- presence.presence.statusMsg) {
- if (presence.presence.statusMsg.trim().isEmpty) {
- tmpUserStatuses.removeAt(currentStatusIndex);
- } else {
- tmpUserStatuses[currentStatusIndex] = newUserStatus;
- }
- } else {
- return;
- }
- _cleanUpUserStatus(tmpUserStatuses);
- }
-
- void _cleanUpUserStatus(List tmpUserStatuses) {
- final now = DateTime.now().millisecondsSinceEpoch;
- tmpUserStatuses
- .removeWhere((u) => (now - u.receivedAt) > (1000 * 60 * 60 * 24));
- tmpUserStatuses.sort((a, b) => b.receivedAt.compareTo(a.receivedAt));
- if (tmpUserStatuses.length > 40) {
- tmpUserStatuses.removeRange(40, tmpUserStatuses.length);
- }
- if (tmpUserStatuses != userStatuses) {
- client.setAccountData(
- client.userID,
- userStatusesType,
- {
- 'user_statuses': tmpUserStatuses.map((i) => i.toJson()).toList(),
- },
- );
- }
- }
-
@override
void dispose() {
onRoomKeyRequestSub?.cancel();
onKeyVerificationRequestSub?.cancel();
onJitsiCallSub?.cancel();
- onPresenceSub?.cancel();
onNotification?.cancel();
onFocusSub?.cancel();
onBlurSub?.cancel();
diff --git a/lib/components/theme_switcher.dart b/lib/components/theme_switcher.dart
index a212b821..dafdd4cc 100644
--- a/lib/components/theme_switcher.dart
+++ b/lib/components/theme_switcher.dart
@@ -175,7 +175,7 @@ class ThemeSwitcherWidgetState extends State {
BuildContext context;
Future loadSelection(MatrixState matrix) async {
- String item = await matrix.store.getItem('theme') ?? 'system';
+ var item = await matrix.store.getItem('theme') ?? 'system';
selectedTheme = Themes.values.firstWhere(
(e) => e.toString() == 'Themes.' + item,
orElse: () => Themes.system);
diff --git a/lib/components/user_bottom_sheet.dart b/lib/components/user_bottom_sheet.dart
new file mode 100644
index 00000000..4757f3f4
--- /dev/null
+++ b/lib/components/user_bottom_sheet.dart
@@ -0,0 +1,188 @@
+import 'dart:math';
+
+import 'package:famedlysdk/famedlysdk.dart';
+import 'package:fluffychat/components/adaptive_page_layout.dart';
+import 'package:fluffychat/utils/app_route.dart';
+import 'package:fluffychat/utils/fluffy_share.dart';
+import 'package:fluffychat/views/chat.dart';
+import 'package:flutter/material.dart';
+import 'content_banner.dart';
+import 'package:flutter_gen/gen_l10n/l10n.dart';
+
+import '../utils/presence_extension.dart';
+import 'dialogs/simple_dialogs.dart';
+import 'matrix.dart';
+
+class UserBottomSheet extends StatelessWidget {
+ final User user;
+ final Function onMention;
+
+ const UserBottomSheet({Key key, @required this.user, this.onMention})
+ : super(key: key);
+
+ void participantAction(BuildContext context, String action) async {
+ switch (action) {
+ case 'mention':
+ Navigator.of(context).pop();
+ onMention();
+ break;
+ case 'ban':
+ if (await SimpleDialogs(context).askConfirmation()) {
+ await SimpleDialogs(context).tryRequestWithLoadingDialog(user.ban());
+ }
+ break;
+ case 'unban':
+ if (await SimpleDialogs(context).askConfirmation()) {
+ await SimpleDialogs(context)
+ .tryRequestWithLoadingDialog(user.unban());
+ }
+ break;
+ case 'kick':
+ if (await SimpleDialogs(context).askConfirmation()) {
+ await SimpleDialogs(context).tryRequestWithLoadingDialog(user.kick());
+ }
+ break;
+ case 'admin':
+ if (await SimpleDialogs(context).askConfirmation()) {
+ await SimpleDialogs(context)
+ .tryRequestWithLoadingDialog(user.setPower(100));
+ }
+ break;
+ case 'moderator':
+ if (await SimpleDialogs(context).askConfirmation()) {
+ await SimpleDialogs(context)
+ .tryRequestWithLoadingDialog(user.setPower(50));
+ }
+ break;
+ case 'user':
+ if (await SimpleDialogs(context).askConfirmation()) {
+ await SimpleDialogs(context)
+ .tryRequestWithLoadingDialog(user.setPower(0));
+ }
+ break;
+ case 'message':
+ final roomId = await user.startDirectChat();
+ await Navigator.of(context).pushAndRemoveUntil(
+ AppRoute.defaultRoute(
+ context,
+ ChatView(roomId),
+ ),
+ (Route r) => r.isFirst);
+ break;
+ }
+ }
+
+ @override
+ Widget build(BuildContext context) {
+ final presence = Matrix.of(context).client.presences[user.id];
+ var items = >[];
+
+ if (onMention != null) {
+ items.add(
+ PopupMenuItem(child: Text(L10n.of(context).mention), value: 'mention'),
+ );
+ }
+ if (user.id != Matrix.of(context).client.userID) {
+ items.add(
+ PopupMenuItem(
+ child: Text(L10n.of(context).sendAMessage), value: 'message'),
+ );
+ }
+ if (user.canChangePowerLevel &&
+ user.room.ownPowerLevel == 100 &&
+ user.powerLevel != 100) {
+ items.add(
+ PopupMenuItem(
+ child: Text(L10n.of(context).makeAnAdmin), value: 'admin'),
+ );
+ }
+ if (user.canChangePowerLevel &&
+ user.room.ownPowerLevel >= 50 &&
+ user.powerLevel != 50) {
+ items.add(
+ PopupMenuItem(
+ child: Text(L10n.of(context).makeAModerator), value: 'moderator'),
+ );
+ }
+ if (user.canChangePowerLevel && user.powerLevel != 0) {
+ items.add(
+ PopupMenuItem(
+ child: Text(L10n.of(context).revokeAllPermissions), value: 'user'),
+ );
+ }
+ if (user.canKick) {
+ items.add(
+ PopupMenuItem(
+ child: Text(L10n.of(context).kickFromChat), value: 'kick'),
+ );
+ }
+ if (user.canBan && user.membership != Membership.ban) {
+ items.add(
+ PopupMenuItem(child: Text(L10n.of(context).banFromChat), value: 'ban'),
+ );
+ } else if (user.canBan && user.membership == Membership.ban) {
+ items.add(
+ PopupMenuItem(
+ child: Text(L10n.of(context).removeExile), value: 'unban'),
+ );
+ }
+ return Center(
+ child: Container(
+ width: min(MediaQuery.of(context).size.width,
+ AdaptivePageLayout.defaultMinWidth * 1.5),
+ child: SafeArea(
+ child: Material(
+ elevation: 4,
+ child: Scaffold(
+ extendBodyBehindAppBar: true,
+ appBar: AppBar(
+ elevation: 0,
+ backgroundColor:
+ Theme.of(context).scaffoldBackgroundColor.withOpacity(0.5),
+ leading: IconButton(
+ icon: Icon(Icons.arrow_downward_outlined),
+ onPressed: Navigator.of(context).pop,
+ ),
+ title: Text(user.calcDisplayname()),
+ actions: [
+ if (user.id != Matrix.of(context).client.userID)
+ PopupMenuButton(
+ itemBuilder: (_) => items,
+ onSelected: (action) =>
+ participantAction(context, action),
+ ),
+ ],
+ ),
+ body: Column(
+ children: [
+ Expanded(
+ child: ContentBanner(
+ user.avatarUrl,
+ defaultIcon: Icons.person_outline,
+ ),
+ ),
+ ListTile(
+ title: Text(L10n.of(context).username),
+ subtitle: Text(user.id),
+ trailing: Icon(Icons.share),
+ onTap: () => FluffyShare.share(user.id, context),
+ ),
+ if (presence != null)
+ ListTile(
+ title: Text(presence.getLocalizedStatusMessage(context)),
+ subtitle:
+ Text(presence.getLocalizedLastActiveAgo(context)),
+ trailing: Icon(Icons.circle,
+ color: presence.presence.currentlyActive ?? false
+ ? Colors.green
+ : Colors.grey),
+ ),
+ ],
+ ),
+ ),
+ ),
+ ),
+ ),
+ );
+ }
+}
diff --git a/lib/config/app_config.dart b/lib/config/app_config.dart
index 8c50c09b..a0c98cec 100644
--- a/lib/config/app_config.dart
+++ b/lib/config/app_config.dart
@@ -6,4 +6,6 @@ abstract class AppConfig {
'https://gitlab.com/ChristianPauly/fluffychat-flutter';
static const String supportUrl =
'https://gitlab.com/ChristianPauly/fluffychat-flutter/issues';
+ static const String sentryDsn =
+ 'https://8591d0d863b646feb4f3dda7e5dcab38@o256755.ingest.sentry.io/5243143';
}
diff --git a/lib/l10n/intl_ca.arb b/lib/l10n/intl_ca.arb
new file mode 100644
index 00000000..0967ef42
--- /dev/null
+++ b/lib/l10n/intl_ca.arb
@@ -0,0 +1 @@
+{}
diff --git a/lib/l10n/intl_cs.arb b/lib/l10n/intl_cs.arb
index e08169d5..80bfb588 100644
--- a/lib/l10n/intl_cs.arb
+++ b/lib/l10n/intl_cs.arb
@@ -87,22 +87,22 @@
"type": "text",
"placeholders": {}
},
- "askSSSSCache": "Prosím zadajte vaší prístupovu frázI k \"bezpečému úložišti\" anebo \"klíč na obnovu\" pro uložení klíčů.",
+ "askSSSSCache": "Prosím zadajte vaší přístupovu frázi k „bezpečému úložišti“ anebo „klíč na obnovu“ pro uložení klíčů.",
"@askSSSSCache": {
"type": "text",
"placeholders": {}
},
- "askSSSSSign": "Pro ověření této osoby, zadejte prosím přístupovou frází k “bezpečnému úložišti” anebo “klíč pro obnovu”.",
+ "askSSSSSign": "Pro ověření této osoby, zadejte prosím přístupovou frázi k „bezpečnému úložišti“ anebo „klíč pro obnovu“.",
"@askSSSSSign": {
"type": "text",
"placeholders": {}
},
- "askSSSSVerify": "Zadejte prosím vaší přístupovou frází k “bezpečnému úložišti” anebo “klíč pro obnovu” pro ověření vaší relace.",
+ "askSSSSVerify": "Zadejte prosím vaší přístupovou frází k „bezpečnému úložišti“ anebo „klíč pro obnovu“ pro ověření vaší relace.",
"@askSSSSVerify": {
"type": "text",
"placeholders": {}
},
- "askVerificationRequest": "Přijmout žádost o ověření od (username)?",
+ "askVerificationRequest": "Přijmout žádost o ověření od {username}?",
"@askVerificationRequest": {
"type": "text",
"placeholders": {
@@ -549,7 +549,7 @@
"type": "text",
"placeholders": {}
},
- "enableEncryptionWarning": "Šifrování jiš nebude možné vypnout. Jste si tím jisti?",
+ "enableEncryptionWarning": "Šifrování již nebude možné vypnout. Jste si tím jisti?",
"@enableEncryptionWarning": {
"type": "text",
"placeholders": {}
@@ -948,7 +948,7 @@
"type": "text",
"placeholders": {}
},
- "noGoogleServicesWarning": "Vypadá to, že váš telefon nemá nainstalovány google services. Dobré rozhodnutí pro vaši bezpečnost! Pro příjem notifikací doporučujeme použít miocroG: https://microg.org/",
+ "noGoogleServicesWarning": "Vypadá to, že váš telefon nemá nainstalovány google services. Dobré rozhodnutí pro vaši bezpečnost! Pro příjem notifikací doporučujeme použít microG: https://microg.org/",
"@noGoogleServicesWarning": {
"type": "text",
"placeholders": {}
@@ -1653,7 +1653,7 @@
"type": "text",
"placeholders": {}
},
- "you": "Ty",
+ "you": "Vy",
"@you": {
"type": "text",
"placeholders": {}
@@ -1702,5 +1702,45 @@
"@deactivateAccountWarning": {
"type": "text",
"placeholders": {}
+ },
+ "privacy": "Soukromí",
+ "@privacy": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "unavailable": "Nedostupní",
+ "@unavailable": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "online": "Připojeni",
+ "@online": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "offline": "Odpojeni",
+ "@offline": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "mention": "Zmiň",
+ "@mention": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "enableEmotesGlobally": "Aktivuj balíček emotikon všude",
+ "@enableEmotesGlobally": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "emotePacks": "Balíček emotikon pro místnost",
+ "@emotePacks": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "changeDeviceName": "Změnit název zařízení",
+ "@changeDeviceName": {
+ "type": "text",
+ "placeholders": {}
}
}
diff --git a/lib/l10n/intl_de.arb b/lib/l10n/intl_de.arb
index 93dc0da8..402097e8 100644
--- a/lib/l10n/intl_de.arb
+++ b/lib/l10n/intl_de.arb
@@ -744,7 +744,7 @@
"type": "text",
"placeholders": {}
},
- "isTyping": "schreibt...",
+ "isTyping": "schreibt …",
"@isTyping": {
"type": "text",
"placeholders": {}
@@ -836,12 +836,12 @@
"count": {}
}
},
- "loadingPleaseWait": "Lade... Bitte warten",
+ "loadingPleaseWait": "Ladevorgang … Bitte warten.",
"@loadingPleaseWait": {
"type": "text",
"placeholders": {}
},
- "loadMore": "Lade mehr...",
+ "loadMore": "Mehr laden …",
"@loadMore": {
"type": "text",
"placeholders": {}
@@ -953,7 +953,7 @@
"type": "text",
"placeholders": {}
},
- "noRoomsFound": "Keine Räume gefunden...",
+ "noRoomsFound": "Keine Räume gefunden …",
"@noRoomsFound": {
"type": "text",
"placeholders": {}
@@ -985,7 +985,7 @@
"type": "text",
"placeholders": {}
},
- "oopsSomethingWentWrong": "Hoppla! Da ist etwas schief gelaufen ...",
+ "oopsSomethingWentWrong": "Hoppla! Etwas ist schief gelaufen …",
"@oopsSomethingWentWrong": {
"type": "text",
"placeholders": {}
@@ -1485,7 +1485,7 @@
"type": "text",
"placeholders": {}
},
- "userAndOthersAreTyping": "{username} und {count} andere schreiben...",
+ "userAndOthersAreTyping": "{username} und {count} andere schreiben …",
"@userAndOthersAreTyping": {
"type": "text",
"placeholders": {
@@ -1493,7 +1493,7 @@
"count": {}
}
},
- "userAndUserAreTyping": "{username} und {username2} schreiben...",
+ "userAndUserAreTyping": "{username} und {username2} schreiben …",
"@userAndUserAreTyping": {
"type": "text",
"placeholders": {
@@ -1501,7 +1501,7 @@
"username2": {}
}
},
- "userIsTyping": "{username} schreibt ...",
+ "userIsTyping": "{username} schreibt …",
"@userIsTyping": {
"type": "text",
"placeholders": {
@@ -1598,7 +1598,7 @@
"type": "text",
"placeholders": {}
},
- "waitingPartnerNumbers": "Warte darauf, dass der Partner die Zahlen annimmt...",
+ "waitingPartnerNumbers": "Warten, dass der Partner die Zahlen annimmt …",
"@waitingPartnerNumbers": {
"type": "text",
"placeholders": {}
@@ -1618,7 +1618,7 @@
"type": "text",
"placeholders": {}
},
- "welcomeText": "Herzlich willkommen beim knuffigsten Instant Messenger im Matrix-Netwerk.",
+ "welcomeText": "Herzlich willkommen beim knuffigsten Instant Messenger im Matrix-Netzwerk.",
"@welcomeText": {
"type": "text",
"placeholders": {}
@@ -1628,7 +1628,7 @@
"type": "text",
"placeholders": {}
},
- "writeAMessage": "Schreibe eine Nachricht ...",
+ "writeAMessage": "Schreibe eine Nachricht …",
"@writeAMessage": {
"type": "text",
"placeholders": {}
@@ -1722,5 +1722,25 @@
"@changeDeviceName": {
"type": "text",
"placeholders": {}
+ },
+ "unavailable": "Nicht Verfügbar",
+ "@unavailable": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "offline": "Offline",
+ "@offline": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "online": "Online",
+ "@online": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "mention": "Erwähnen",
+ "@mention": {
+ "type": "text",
+ "placeholders": {}
}
}
diff --git a/lib/l10n/intl_en.arb b/lib/l10n/intl_en.arb
index 35ceddd6..94237671 100644
--- a/lib/l10n/intl_en.arb
+++ b/lib/l10n/intl_en.arb
@@ -194,7 +194,7 @@
"username": {}
}
},
- "changedTheDisplaynameTo": "{username} changed the displayname to: {displayname}",
+ "changedTheDisplaynameTo": "{username} changed the displayname to: '{displayname}'",
"@changedTheDisplaynameTo": {
"type": "text",
"placeholders": {
@@ -759,7 +759,7 @@
"type": "text",
"placeholders": {}
},
- "isTyping": "is typing...",
+ "isTyping": "is typing…",
"@isTyping": {
"type": "text",
"placeholders": {}
@@ -851,12 +851,12 @@
"type": "text",
"placeholders": {}
},
- "loadingPleaseWait": "Loading... Please wait",
+ "loadingPleaseWait": "Loading… Please wait.",
"@loadingPleaseWait": {
"type": "text",
"placeholders": {}
},
- "loadMore": "Load more...",
+ "loadMore": "Load more…",
"@loadMore": {
"type": "text",
"placeholders": {}
@@ -895,6 +895,11 @@
"type": "text",
"placeholders": {}
},
+ "mention": "Mention",
+ "@mention": {
+ "type": "text",
+ "placeholders": {}
+ },
"messageWillBeRemovedWarning": "Message will be removed for all participants",
"@messageWillBeRemovedWarning": {
"type": "text",
@@ -965,7 +970,7 @@
"type": "text",
"placeholders": {}
},
- "noRoomsFound": "No rooms found...",
+ "noRoomsFound": "No rooms found…",
"@noRoomsFound": {
"type": "text",
"placeholders": {}
@@ -992,12 +997,27 @@
"type": "text",
"placeholders": {}
},
+ "online": "Online",
+ "@online": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "offline": "Offline",
+ "@offline": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "unavailable": "Unavailable",
+ "@unavailable": {
+ "type": "text",
+ "placeholders": {}
+ },
"onlineKeyBackupEnabled": "Online Key Backup is enabled",
"@onlineKeyBackupEnabled": {
"type": "text",
"placeholders": {}
},
- "oopsSomethingWentWrong": "Oops something went wrong...",
+ "oopsSomethingWentWrong": "Oops, something went wrong…",
"@oopsSomethingWentWrong": {
"type": "text",
"placeholders": {}
@@ -1542,7 +1562,7 @@
"unreadChats": {}
}
},
- "userAndOthersAreTyping": "{username} and {count} others are typing...",
+ "userAndOthersAreTyping": "{username} and {count} others are typing…",
"@userAndOthersAreTyping": {
"type": "text",
"placeholders": {
@@ -1550,7 +1570,7 @@
"count": {}
}
},
- "userAndUserAreTyping": "{username} and {username2} are typing...",
+ "userAndUserAreTyping": "{username} and {username2} are typing…",
"@userAndUserAreTyping": {
"type": "text",
"placeholders": {
@@ -1563,7 +1583,7 @@
"type": "text",
"placeholders": {}
},
- "userIsTyping": "{username} is typing...",
+ "userIsTyping": "{username} is typing…",
"@userIsTyping": {
"type": "text",
"placeholders": {
@@ -1638,17 +1658,17 @@
"type": "text",
"placeholders": {}
},
- "waitingPartnerAcceptRequest": "Waiting for partner to accept the request...",
+ "waitingPartnerAcceptRequest": "Waiting for partner to accept the request…",
"@waitingPartnerAcceptRequest": {
"type": "text",
"placeholders": {}
},
- "waitingPartnerEmoji": "Waiting for partner to accept the emoji...",
+ "waitingPartnerEmoji": "Waiting for partner to accept the emoji…",
"@waitingPartnerEmoji": {
"type": "text",
"placeholders": {}
},
- "waitingPartnerNumbers": "Waiting for partner to accept the numbers...",
+ "waitingPartnerNumbers": "Waiting for partner to accept the numbers…",
"@waitingPartnerNumbers": {
"type": "text",
"placeholders": {}
@@ -1673,7 +1693,7 @@
"type": "text",
"placeholders": {}
},
- "welcomeText": "Welcome to the cutest instant messenger in the matrix network.",
+ "welcomeText": "Welcome to the cutest instant messenger in the Matrix network.",
"@welcomeText": {
"type": "text",
"placeholders": {}
@@ -1683,7 +1703,7 @@
"type": "text",
"placeholders": {}
},
- "writeAMessage": "Write a message...",
+ "writeAMessage": "Write a message…",
"@writeAMessage": {
"type": "text",
"placeholders": {}
@@ -1723,4 +1743,4 @@
"type": "text",
"placeholders": {}
}
-}
\ No newline at end of file
+}
diff --git a/lib/l10n/intl_eo.arb b/lib/l10n/intl_eo.arb
new file mode 100644
index 00000000..ef24c3fa
--- /dev/null
+++ b/lib/l10n/intl_eo.arb
@@ -0,0 +1,1744 @@
+{
+ "participatingUserDevices": "Partoprenantaj aparatoj de uzanto",
+ "@participatingUserDevices": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "optionalGroupName": "(Malnepra) Nomo de grupo",
+ "@optionalGroupName": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "openCamera": "Malfermi fotilon",
+ "@openCamera": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "unavailable": "Nedisponeble",
+ "@unavailable": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "offline": "Eksterrete",
+ "@offline": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "online": "Enrete",
+ "@online": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "numberSelected": "{number} elektitaj",
+ "@numberSelected": {
+ "type": "text",
+ "placeholders": {
+ "number": {}
+ }
+ },
+ "noPermission": "Neniu permeso",
+ "@noPermission": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "noEmotesFound": "Neniuj mienetoj troviĝis. 😕",
+ "@noEmotesFound": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "noCrossSignBootstrap": "FluffyChat ankoraŭ ne subtenas ŝaltadon de delegaj subskriboj. Bonvolu ŝalti ilin per Riot (Element).",
+ "@noCrossSignBootstrap": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "needPantalaimonWarning": "Bonvolu scii, ke vi ankoraŭ bezonas la programon Pantalaimon por uzi tutvojan ĉifradon.",
+ "@needPantalaimonWarning": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "messageWillBeRemovedWarning": "Mesaĝo foriĝos por ĉiuj partoprenantoj",
+ "@messageWillBeRemovedWarning": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "mention": "Mencii",
+ "@mention": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "makeAnAdmin": "Igi administranto",
+ "@makeAnAdmin": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "makeAModerator": "Igi reguligisto",
+ "@makeAModerator": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "loadCountMoreParticipants": "Enlegi {count} pliajn partoprenantojn",
+ "@loadCountMoreParticipants": {
+ "type": "text",
+ "placeholders": {
+ "count": {}
+ }
+ },
+ "loadMore": "Enlegi pli…",
+ "@loadMore": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "lastSeenIp": "Lastafoje vidita IP-adreso",
+ "@lastSeenIp": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "lastActiveAgo": "Lastafoje aktiva: {localizedTimeShort}",
+ "@lastActiveAgo": {
+ "type": "text",
+ "placeholders": {
+ "localizedTimeShort": {}
+ }
+ },
+ "invitedUsersOnly": "Nur invititoj",
+ "@invitedUsersOnly": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "ignoreListDescription": "Vi povas malatenti uzantojn, kiuj vin ĝenas. Vi ne povos ricevi mesaĝojn nek invitojn al ĉambroj de la uzantoj sur via listo de malatentatoj.",
+ "@ignoreListDescription": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "ignoreUsername": "Malatenti uzantonomon",
+ "@ignoreUsername": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "ignoredUsers": "Malatentitaj uzantoj",
+ "@ignoredUsers": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "enableEmotesGlobally": "Ŝalti mienetaron ĉie",
+ "@enableEmotesGlobally": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "emotePacks": "Mienetaroj por la ĉambro",
+ "@emotePacks": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "emoteInvalid": "Nevalida mallongigo de mieneto!",
+ "@emoteInvalid": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "emoteExists": "Mieneto jam ekzistas!",
+ "@emoteExists": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "emoteWarnNeedToPick": "Vi devas elekti mallongigon de mieneto kaj bildon!",
+ "@emoteWarnNeedToPick": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "emoteShortcode": "Mallongigo de mieneto",
+ "@emoteShortcode": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "emoteSettings": "Agordoj pri mienetoj",
+ "@emoteSettings": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "guestsAreForbidden": "Gastoj estas malpermesitaj",
+ "@guestsAreForbidden": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "discardPicture": "Forĵeti bildon",
+ "@discardPicture": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "authentication": "Aŭtentikigo",
+ "@authentication": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "alias": "kromnomo",
+ "@alias": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "yourOwnUsername": "Via propra uzantonomo",
+ "@yourOwnUsername": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "youHaveBeenBannedFromThisChat": "Vi estas forbarita de ĉi tiu babilo",
+ "@youHaveBeenBannedFromThisChat": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "youCannotInviteYourself": "Vi ne povas inviti vin mem",
+ "@youCannotInviteYourself": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "youAreNoLongerParticipatingInThisChat": "Vi ne plu partoprenas ĉi tiun babilon",
+ "@youAreNoLongerParticipatingInThisChat": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "youAreInvitedToThisChat": "Vi estas invitita al ĉi tiu babilo",
+ "@youAreInvitedToThisChat": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "you": "Vi",
+ "@you": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "yes": "Jes",
+ "@yes": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "writeAMessage": "Skribi mesaĝon…",
+ "@writeAMessage": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "whoIsAllowedToJoinThisGroup": "Kiu rajtas aliĝi al ĉi tiu grupo",
+ "@whoIsAllowedToJoinThisGroup": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "wednesday": "Merkredo",
+ "@wednesday": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "warningEncryptionInBeta": "Tutvoja ĉifrado estas ankoraŭ beta-versia! Uzu je via propra risko!",
+ "@warningEncryptionInBeta": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "wallpaper": "Fonbildo",
+ "@wallpaper": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "warning": "Averto!",
+ "@warning": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "voiceMessage": "Voĉmesaĝo",
+ "@voiceMessage": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "videoCall": "Vidvoko",
+ "@videoCall": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "verifyUser": "Kontroli uzanton",
+ "@verifyUser": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "verifyTitle": "Kontrolante alian konton",
+ "@verifyTitle": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "verifySuccess": "Vi sukcese kontrolis!",
+ "@verifySuccess": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "verifyStart": "Komenci kontrolon",
+ "@verifyStart": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "verifiedSession": "Sukcese kontrolis salutaĵon!",
+ "@verifiedSession": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "verifyManual": "Kontroli permane",
+ "@verifyManual": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "verify": "Kontroli",
+ "@verify": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "userSentUnknownEvent": "{username} sendis eventon de speco {type}",
+ "@userSentUnknownEvent": {
+ "type": "text",
+ "placeholders": {
+ "username": {},
+ "type": {}
+ }
+ },
+ "userIsTyping": "{username} tajpas…",
+ "@userIsTyping": {
+ "type": "text",
+ "placeholders": {
+ "username": {}
+ }
+ },
+ "username": "Uzantonomo",
+ "@username": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "userAndUserAreTyping": "{username} kaj {username2} tajpas…",
+ "@userAndUserAreTyping": {
+ "type": "text",
+ "placeholders": {
+ "username": {},
+ "username2": {}
+ }
+ },
+ "unknownEvent": "Nekonata evento «{type}»",
+ "@unknownEvent": {
+ "type": "text",
+ "placeholders": {
+ "type": {}
+ }
+ },
+ "unknownSessionVerify": "Nekonata salutaĵo; bonvolu kontroli",
+ "@unknownSessionVerify": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "unknownEncryptionAlgorithm": "Nekonata ĉifra algoritmo",
+ "@unknownEncryptionAlgorithm": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "unknownDevice": "Nekonata aparato",
+ "@unknownDevice": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "unmuteChat": "Malsilentigi babilon",
+ "@unmuteChat": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "unblockDevice": "Malbloki aparaton",
+ "@unblockDevice": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "unbannedUser": "{username} malforbaris uzanton {targetName}",
+ "@unbannedUser": {
+ "type": "text",
+ "placeholders": {
+ "username": {},
+ "targetName": {}
+ }
+ },
+ "tuesday": "Mardo",
+ "@tuesday": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "tryToSendAgain": "Reprovi sendi",
+ "@tryToSendAgain": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "title": "FluffyChat",
+ "@title": {
+ "description": "Title for the application",
+ "type": "text",
+ "placeholders": {}
+ },
+ "thursday": "Ĵaŭdo",
+ "@thursday": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "theyMatch": "Ili akordas",
+ "@theyMatch": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "theyDontMatch": "Ili ne akordas",
+ "@theyDontMatch": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "tapToShowMenu": "Tuŝetu por montri menuon",
+ "@tapToShowMenu": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "donate": "Donaci",
+ "@donate": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "sunday": "Dimanĉo",
+ "@sunday": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "submit": "Sendi",
+ "@submit": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "startYourFirstChat": "Komencu vian unuan babilon :-)",
+ "@startYourFirstChat": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "statusExampleMessage": "Kiel vi fartas?",
+ "@statusExampleMessage": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "startedACall": "{senderName} komencis vokon",
+ "@startedACall": {
+ "type": "text",
+ "placeholders": {
+ "senderName": {}
+ }
+ },
+ "signUp": "Registriĝi",
+ "@signUp": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "setInvitationLink": "Agordi invitan ligilon",
+ "@setInvitationLink": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "setGroupDescription": "Agordi priskribon de grupo",
+ "@setGroupDescription": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "setAProfilePicture": "Agordi profilbildon",
+ "@setAProfilePicture": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "sessionVerified": "Salutaĵo estas kontrolita",
+ "@sessionVerified": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "sentAVideo": "{username} sendis filmon",
+ "@sentAVideo": {
+ "type": "text",
+ "placeholders": {
+ "username": {}
+ }
+ },
+ "sentASticker": "{username} sendis glumarkon",
+ "@sentASticker": {
+ "type": "text",
+ "placeholders": {
+ "username": {}
+ }
+ },
+ "sentAPicture": "{username} sendis bildon",
+ "@sentAPicture": {
+ "type": "text",
+ "placeholders": {
+ "username": {}
+ }
+ },
+ "sentAFile": "{username} sendis dosieron",
+ "@sentAFile": {
+ "type": "text",
+ "placeholders": {
+ "username": {}
+ }
+ },
+ "sendVideo": "Sendi filmon",
+ "@sendVideo": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "sendOriginal": "Sendi originalon",
+ "@sendOriginal": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "sendImage": "Sendi bildon",
+ "@sendImage": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "sendFile": "Sendi dosieron",
+ "@sendFile": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "sendAMessage": "Sendi mesaĝon",
+ "@sendAMessage": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "send": "Sendi",
+ "@send": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "no": "Ne",
+ "@no": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "changesHaveBeenSaved": "Ŝanĝoj konserviĝis",
+ "@changesHaveBeenSaved": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "sentryInfo": "Informoj pri via privateco: https://sentry.io/security/",
+ "@sentryInfo": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "lastSeenLongTimeAgo": "Vidita antaŭ longe",
+ "@lastSeenLongTimeAgo": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "searchForAChat": "Serĉi babilon",
+ "@searchForAChat": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "saturday": "Sabato",
+ "@saturday": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "roomHasBeenUpgraded": "Ĉambro gradaltiĝis",
+ "@roomHasBeenUpgraded": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "requestToReadOlderMessages": "Peti legi pli malnovajn mesaĝojn",
+ "@requestToReadOlderMessages": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "requestPermission": "Peti permeson",
+ "@requestPermission": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "reply": "Respondi",
+ "@reply": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "removeMessage": "Forigi mesaĝon",
+ "@removeMessage": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "remove": "Forigi",
+ "@remove": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "revokeAllPermissions": "Nuligi ĉiujn permesojn",
+ "@revokeAllPermissions": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "removeDevice": "Forigi aparaton",
+ "@removeDevice": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "removedBy": "Forigita de {username}",
+ "@removedBy": {
+ "type": "text",
+ "placeholders": {
+ "username": {}
+ }
+ },
+ "redactedAnEvent": "{username} redaktis eventon",
+ "@redactedAnEvent": {
+ "type": "text",
+ "placeholders": {
+ "username": {}
+ }
+ },
+ "rejoin": "Ree aliĝi",
+ "@rejoin": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "publicRooms": "Publikaj ĉambroj",
+ "@publicRooms": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "privacy": "Privateco",
+ "@privacy": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "pleaseEnterYourUsername": "Bonvolu enigi vian uzantonomon",
+ "@pleaseEnterYourUsername": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "pleaseEnterYourPassword": "Bonvolu enigi vian pasvorton",
+ "@pleaseEnterYourPassword": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "pleaseEnterAMatrixIdentifier": "Bonvolu enigi identigilon de Matrix",
+ "@pleaseEnterAMatrixIdentifier": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "pleaseChooseAUsername": "Bonvolu elekti uzantonomon",
+ "@pleaseChooseAUsername": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "passwordHasBeenChanged": "Pasvorto ŝanĝiĝis",
+ "@passwordHasBeenChanged": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "password": "Pasvorto",
+ "@password": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "passphraseOrKey": "pasfrazo aŭ rehava ŝlosilo",
+ "@passphraseOrKey": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "openAppToReadMessages": "Malfermu la aplikaĵon por legi mesaĝojn",
+ "@openAppToReadMessages": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "oopsSomethingWentWrong": "Oj! Io misokazis…",
+ "@oopsSomethingWentWrong": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "ok": "bone",
+ "@ok": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "noRoomsFound": "Neniuj ĉambroj troviĝis…",
+ "@noRoomsFound": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "noGoogleServicesWarning": "Ŝajnas, ke via telefono ne havas servojn de Google. Tio estas bona decido por via privateco! Por ricevadi pasivajn sciigojn en FluffyChat, ni rekomendas, ke vi uzu la programaron microG: https://microg.org/",
+ "@noGoogleServicesWarning": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "newVerificationRequest": "Nova kontrolpeto!",
+ "@newVerificationRequest": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "newPrivateChat": "Nova privata babilo",
+ "@newPrivateChat": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "newMessageInFluffyChat": "Nova mesaĝo en FluffyChat",
+ "@newMessageInFluffyChat": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "muteChat": "Silentigi babilon",
+ "@muteChat": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "monday": "Lundo",
+ "@monday": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "moderator": "Reguligisto",
+ "@moderator": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "makeSureTheIdentifierIsValid": "Certigu, ke la identigilo estas valida",
+ "@makeSureTheIdentifierIsValid": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "logInTo": "Saluti servilon {homeserver}",
+ "@logInTo": {
+ "type": "text",
+ "placeholders": {
+ "homeserver": {}
+ }
+ },
+ "login": "Saluti",
+ "@login": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "loadingPleaseWait": "Enlegante… bonvolu atendi",
+ "@loadingPleaseWait": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "license": "Permesilo",
+ "@license": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "userLeftTheChat": "{username} foriris de la babilo",
+ "@userLeftTheChat": {
+ "type": "text",
+ "placeholders": {
+ "username": {}
+ }
+ },
+ "logout": "Adiaŭi",
+ "@logout": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "leftTheChat": "Foriris de la ĉambro",
+ "@leftTheChat": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "leave": "Foriri",
+ "@leave": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "kickFromChat": "Forpeli de babilo",
+ "@kickFromChat": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "kickedAndBanned": "{username} forpelis kaj forbaris uzanton {targetName}",
+ "@kickedAndBanned": {
+ "type": "text",
+ "placeholders": {
+ "username": {},
+ "targetName": {}
+ }
+ },
+ "kicked": "{username} forpelis uzanton {targetName}",
+ "@kicked": {
+ "type": "text",
+ "placeholders": {
+ "username": {},
+ "targetName": {}
+ }
+ },
+ "keysMissing": "Ŝlosiloj mankas",
+ "@keysMissing": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "keysCached": "Ŝlosiloj estas kaŝmemoritaj",
+ "@keysCached": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "joinRoom": "Aliĝi al ĉambro",
+ "@joinRoom": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "joinedTheChat": "{username} aliĝis al la babilo",
+ "@joinedTheChat": {
+ "type": "text",
+ "placeholders": {
+ "username": {}
+ }
+ },
+ "isTyping": "tajpas…",
+ "@isTyping": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "invitedUser": "{username} invitis uzanton {targetName}",
+ "@invitedUser": {
+ "type": "text",
+ "placeholders": {
+ "username": {},
+ "targetName": {}
+ }
+ },
+ "inviteText": "{username} invitis vin al FluffyChat. \n1. Instalu la aplikaĵon FluffyChat: https://fluffychat.im \n2. Registriĝu aŭ salutu \n3. Malfermu la invitan ligilon: {link}",
+ "@inviteText": {
+ "type": "text",
+ "placeholders": {
+ "username": {},
+ "link": {}
+ }
+ },
+ "inviteContactToGroup": "Inviti kontakton al {groupName}",
+ "@inviteContactToGroup": {
+ "type": "text",
+ "placeholders": {
+ "groupName": {}
+ }
+ },
+ "inviteContact": "Inviti kontakton",
+ "@inviteContact": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "incorrectPassphraseOrKey": "Neĝusta pasfrazo aŭ rehava ŝlosilo",
+ "@incorrectPassphraseOrKey": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "identity": "Identeco",
+ "@identity": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "id": "Identigilo",
+ "@id": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "homeserverIsNotCompatible": "Hejmservilo ne estas interkonforma",
+ "@homeserverIsNotCompatible": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "help": "Helpo",
+ "@help": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "hasWithdrawnTheInvitationFor": "{username} nuligis la inviton por {targetName}",
+ "@hasWithdrawnTheInvitationFor": {
+ "type": "text",
+ "placeholders": {
+ "username": {},
+ "targetName": {}
+ }
+ },
+ "guestsCanJoin": "Gastoj povas aliĝi",
+ "@guestsCanJoin": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "groupWith": "Grupo kun {displayname}",
+ "@groupWith": {
+ "type": "text",
+ "placeholders": {
+ "displayname": {}
+ }
+ },
+ "groupIsPublic": "Grupo estas publika",
+ "@groupIsPublic": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "groupDescriptionHasBeenChanged": "Priskribo de grupo ŝanĝiĝis",
+ "@groupDescriptionHasBeenChanged": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "groupDescription": "Priskribo de grupo",
+ "@groupDescription": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "group": "Grupo",
+ "@group": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "fromTheInvitation": "Ekde la invito",
+ "@fromTheInvitation": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "fromJoining": "Ekde aliĝo",
+ "@fromJoining": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "friday": "Vendredo",
+ "@friday": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "forward": "Plusendi",
+ "@forward": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "fluffychat": "FluffyChat",
+ "@fluffychat": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "fileSize": "Grandeco de dosiero",
+ "@fileSize": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "fileName": "Dosiernomo",
+ "@fileName": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "enterYourHomeserver": "Enigu vian hejmservilon",
+ "@enterYourHomeserver": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "enterAUsername": "Enigu uzantonomon",
+ "@enterAUsername": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "enterAGroupName": "Enigu nomon de grupo",
+ "@enterAGroupName": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "endedTheCall": "{senderName} finis la vokon",
+ "@endedTheCall": {
+ "type": "text",
+ "placeholders": {
+ "senderName": {}
+ }
+ },
+ "encryptionNotEnabled": "Ĉifrado ne estas ŝaltita",
+ "@encryptionNotEnabled": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "encryptionAlgorithm": "Ĉifra algoritmo",
+ "@encryptionAlgorithm": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "encryption": "Ĉifrado",
+ "@encryption": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "enableEncryptionWarning": "Vi ne povos malŝalti la ĉifradon. Ĉu vi certas?",
+ "@enableEncryptionWarning": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "emptyChat": "Malplena babilo",
+ "@emptyChat": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "editDisplayname": "Redakti prezentan nomon",
+ "@editDisplayname": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "downloadFile": "Elŝuti dosieron",
+ "@downloadFile": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "displaynameHasBeenChanged": "Prezenta nomo ŝanĝiĝis",
+ "@displaynameHasBeenChanged": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "devices": "Aparatoj",
+ "@devices": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "device": "Aparato",
+ "@device": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "deny": "Malakcepti",
+ "@deny": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "deleteMessage": "Forigi mesaĝon",
+ "@deleteMessage": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "deleteAccount": "Forigi konton",
+ "@deleteAccount": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "deactivateAccountWarning": "Ĉi tio malaktivigos vian konton de uzanto. Ne eblas tion malfari! Ĉu certe vi certas?",
+ "@deactivateAccountWarning": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "delete": "Forigi",
+ "@delete": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "dateAndTimeOfDay": "{date}, {timeOfDay}",
+ "@dateAndTimeOfDay": {
+ "type": "text",
+ "placeholders": {
+ "date": {},
+ "timeOfDay": {}
+ }
+ },
+ "crossSigningEnabled": "Delegaj subskriboj estas ŝaltitaj",
+ "@crossSigningEnabled": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "crossSigningDisabled": "Delegaj subskriboj estas malŝaltitaj",
+ "@crossSigningDisabled": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "createdTheChat": "{username} kreis la babilon",
+ "@createdTheChat": {
+ "type": "text",
+ "placeholders": {
+ "username": {}
+ }
+ },
+ "createAccountNow": "Krei konton nun",
+ "@createAccountNow": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "create": "Krei",
+ "@create": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "countParticipants": "{count} partoprenantoj",
+ "@countParticipants": {
+ "type": "text",
+ "placeholders": {
+ "count": {}
+ }
+ },
+ "couldNotSetDisplayname": "Ne povis agordi prezentan nomon",
+ "@couldNotSetDisplayname": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "couldNotSetAvatar": "Ne povis agordi profilbildon",
+ "@couldNotSetAvatar": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "couldNotDecryptMessage": "Ne povis malĉifri mesaĝon: {error}",
+ "@couldNotDecryptMessage": {
+ "type": "text",
+ "placeholders": {
+ "error": {}
+ }
+ },
+ "copy": "Kopii",
+ "@copy": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "copiedToClipboard": "Kopiite al tondujo",
+ "@copiedToClipboard": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "contentViewer": "Vidilo de enhavo",
+ "@contentViewer": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "contactHasBeenInvitedToTheGroup": "Kontakto invitiĝis al la grupo",
+ "@contactHasBeenInvitedToTheGroup": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "connectionAttemptFailed": "Malsukcesis provo konektiĝi",
+ "@connectionAttemptFailed": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "connect": "Konektiĝi",
+ "@connect": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "confirm": "Konfirmi",
+ "@confirm": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "compareNumbersMatch": "Komparu kaj certigu, ke la jenaj numeroj samas en ambaŭ aparatoj:",
+ "@compareNumbersMatch": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "compareEmojiMatch": "Komparu kaj certigu, ke la jenaj bildosignoj samas en ambaŭ aparatoj:",
+ "@compareEmojiMatch": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "close": "Fermi",
+ "@close": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "chooseAUsername": "Elektu uzantonomon",
+ "@chooseAUsername": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "chooseAStrongPassword": "Elektu fortan pasvorton",
+ "@chooseAStrongPassword": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "chatDetails": "Detaloj pri babilo",
+ "@chatDetails": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "chat": "Babilo",
+ "@chat": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "channelCorruptedDecryptError": "La ĉifrado estas difektita",
+ "@channelCorruptedDecryptError": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "changeTheServer": "Ŝanĝi la servilon",
+ "@changeTheServer": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "changeWallpaper": "Ŝanĝi fonbildon",
+ "@changeWallpaper": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "changeTheNameOfTheGroup": "Ŝanĝi nomon de la grupo",
+ "@changeTheNameOfTheGroup": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "changelog": "Protokolo de ŝanĝoj",
+ "@changelog": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "changedTheRoomInvitationLink": "{username} ŝanĝis la invitan ligilon",
+ "@changedTheRoomInvitationLink": {
+ "type": "text",
+ "placeholders": {
+ "username": {}
+ }
+ },
+ "changedTheRoomAliases": "{username} ŝanĝis la kromnomojn de la ĉambro",
+ "@changedTheRoomAliases": {
+ "type": "text",
+ "placeholders": {
+ "username": {}
+ }
+ },
+ "changedTheProfileAvatar": "{username} ŝanĝis sian profilbildon",
+ "@changedTheProfileAvatar": {
+ "type": "text",
+ "placeholders": {
+ "username": {}
+ }
+ },
+ "changedTheJoinRulesTo": "{username} ŝanĝis regulojn pri aliĝado al: {joinRules}",
+ "@changedTheJoinRulesTo": {
+ "type": "text",
+ "placeholders": {
+ "username": {},
+ "joinRules": {}
+ }
+ },
+ "changedTheJoinRules": "{username} ŝanĝis regulojn pri aliĝado",
+ "@changedTheJoinRules": {
+ "type": "text",
+ "placeholders": {
+ "username": {}
+ }
+ },
+ "changedTheHistoryVisibilityTo": "{username} ŝanĝis videblecon de la historio al: {rules}",
+ "@changedTheHistoryVisibilityTo": {
+ "type": "text",
+ "placeholders": {
+ "username": {},
+ "rules": {}
+ }
+ },
+ "changedTheHistoryVisibility": "{username} ŝanĝis videblecon de la historio",
+ "@changedTheHistoryVisibility": {
+ "type": "text",
+ "placeholders": {
+ "username": {}
+ }
+ },
+ "changedTheGuestAccessRulesTo": "{username} ŝanĝis regulojn pri aliro de gastoj al: {rules}",
+ "@changedTheGuestAccessRulesTo": {
+ "type": "text",
+ "placeholders": {
+ "username": {},
+ "rules": {}
+ }
+ },
+ "changedTheGuestAccessRules": "{username} ŝanĝis regulojn pri aliro de gastoj",
+ "@changedTheGuestAccessRules": {
+ "type": "text",
+ "placeholders": {
+ "username": {}
+ }
+ },
+ "changeTheHomeserver": "Ŝanĝi hejmservilon",
+ "@changeTheHomeserver": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "changedTheDisplaynameTo": "{username} ŝanĝis la prezentan nomon al: {username}",
+ "@changedTheDisplaynameTo": {
+ "type": "text",
+ "placeholders": {
+ "username": {},
+ "displayname": {}
+ }
+ },
+ "changedTheChatPermissions": "{username} ŝanĝis permesojn pri la babilo",
+ "@changedTheChatPermissions": {
+ "type": "text",
+ "placeholders": {
+ "username": {}
+ }
+ },
+ "changedTheChatDescriptionTo": "{username} ŝanĝis priskribon de la babilo al: «{description}»",
+ "@changedTheChatDescriptionTo": {
+ "type": "text",
+ "placeholders": {
+ "username": {},
+ "description": {}
+ }
+ },
+ "changedTheChatNameTo": "{username} ŝanĝis nomon de la babilo al: «{chatname}»",
+ "@changedTheChatNameTo": {
+ "type": "text",
+ "placeholders": {
+ "username": {},
+ "chatname": {}
+ }
+ },
+ "changedTheChatAvatar": "{username} ŝanĝis bildon de la babilo",
+ "@changedTheChatAvatar": {
+ "type": "text",
+ "placeholders": {
+ "username": {}
+ }
+ },
+ "changeDeviceName": "Ŝanĝi nomon de aparato",
+ "@changeDeviceName": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "cancel": "Nuligi",
+ "@cancel": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "cachedKeys": "Sukcese kaŝmemoris ŝlosilojn!",
+ "@cachedKeys": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "byDefaultYouWillBeConnectedTo": "Implice vi konektiĝos al {homeserver}",
+ "@byDefaultYouWillBeConnectedTo": {
+ "type": "text",
+ "placeholders": {
+ "homeserver": {}
+ }
+ },
+ "blockDevice": "Bloki aparaton",
+ "@blockDevice": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "bannedUser": "{username} forbaris uzanton {targetName}",
+ "@bannedUser": {
+ "type": "text",
+ "placeholders": {
+ "username": {},
+ "targetName": {}
+ }
+ },
+ "banned": "Forbarita",
+ "@banned": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "banFromChat": "Forbari de babilo",
+ "@banFromChat": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "askSSSSVerify": "Bonvolu enigi pasfrazon de via sekura deponejo aŭ vian rehavan ŝlosilon por kontroli vian salutaĵon.",
+ "@askSSSSVerify": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "askSSSSCache": "Bonvolu enigi pasfrazon de via sekura deponejo aŭ rehavan ŝlosilon por kaŝmemori la ŝlosilojn.",
+ "@askSSSSCache": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "areGuestsAllowedToJoin": "Ĉu gastoj rajtas aliĝi",
+ "@areGuestsAllowedToJoin": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "anyoneCanJoin": "Ĉiu ajn povas aliĝi",
+ "@anyoneCanJoin": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "avatarHasBeenChanged": "Profilbildo ŝanĝiĝis",
+ "@avatarHasBeenChanged": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "askVerificationRequest": "Ĉu akcepti ĉi tiun kontrolpeton de {username}?",
+ "@askVerificationRequest": {
+ "type": "text",
+ "placeholders": {
+ "username": {}
+ }
+ },
+ "areYouSure": "Ĉu vi certas?",
+ "@areYouSure": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "answeredTheCall": "{senderName} respondis la vokon",
+ "@answeredTheCall": {
+ "type": "text",
+ "placeholders": {
+ "senderName": {}
+ }
+ },
+ "alreadyHaveAnAccount": "Ĉu vi jam havas konton?",
+ "@alreadyHaveAnAccount": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "admin": "Administranto",
+ "@admin": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "addGroupDescription": "Aldoni priskribon de grupo",
+ "@addGroupDescription": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "activatedEndToEndEncryption": "{username} aktivigis tutvojan ĉifradon",
+ "@activatedEndToEndEncryption": {
+ "type": "text",
+ "placeholders": {
+ "username": {}
+ }
+ },
+ "accountInformation": "Informoj pri konto",
+ "@accountInformation": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "account": "Konto",
+ "@account": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "acceptedTheInvitation": "{username} akceptis la inviton",
+ "@acceptedTheInvitation": {
+ "type": "text",
+ "placeholders": {
+ "username": {}
+ }
+ },
+ "accept": "Akcepti",
+ "@accept": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "about": "Prio",
+ "@about": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "thisRoomHasBeenArchived": "Ĉi tiu ĉambro arĥiviĝis.",
+ "@thisRoomHasBeenArchived": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "archivedRoom": "Arĥivita ĉambro",
+ "@archivedRoom": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "sharedTheLocation": "{username} konigis sian lokon",
+ "@sharedTheLocation": {
+ "type": "text",
+ "placeholders": {
+ "username": {}
+ }
+ },
+ "isDeviceKeyCorrect": "Ĉu la jena identigilo de aparato estas ĝusta?",
+ "@isDeviceKeyCorrect": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "currentlyActive": "Nun aktiva",
+ "@currentlyActive": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "askSSSSSign": "Por ke vi povu kontroli (subskribi) la alian personon, bonvolu enigi pasfrazon de via sekreta deponejo aŭ vian rehavan ŝlosilon.",
+ "@askSSSSSign": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "share": "Konigi",
+ "@share": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "none": "Neniu",
+ "@none": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "editJitsiInstance": "Redakti provizanton de Jitsi",
+ "@editJitsiInstance": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "invited": "Invitita",
+ "@invited": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "renderRichContent": "Bildigi riĉforman enhavon de mesaĝoj",
+ "@renderRichContent": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "onlineKeyBackupEnabled": "Enreta savkopiado de ŝlosiloj estas ŝaltita",
+ "@onlineKeyBackupEnabled": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "onlineKeyBackupDisabled": "Enreta savkopiado de ŝlosiloj estas malŝaltita",
+ "@onlineKeyBackupDisabled": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "notSupportedInWeb": "Nesubtenata de la TTT-versio",
+ "@notSupportedInWeb": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "noMegolmBootstrap": "FluffyChat ankoraŭ ne subtenas ŝaltadon de Enreta savkopiado de ŝlosiloj. Bonvolu ŝalti ĝin per Riot (Element).",
+ "@noMegolmBootstrap": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "dateWithoutYear": "{day}a de la {month}a",
+ "@dateWithoutYear": {
+ "type": "text",
+ "placeholders": {
+ "month": {},
+ "day": {}
+ }
+ },
+ "dateWithYear": "{day}a de la {month}a de {year}",
+ "@dateWithYear": {
+ "type": "text",
+ "placeholders": {
+ "year": {},
+ "month": {},
+ "day": {}
+ }
+ },
+ "waitingPartnerEmoji": "Atendante akcepton de la bildosignoj de la kunulo…",
+ "@waitingPartnerEmoji": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "waitingPartnerNumbers": "Atendante akcepton de la numeroj de la kunulo…",
+ "@waitingPartnerNumbers": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "waitingPartnerAcceptRequest": "Atendante konfirmon de peto de la kunulo…",
+ "@waitingPartnerAcceptRequest": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "visibilityOfTheChatHistory": "Videbleco de historio de la babilo",
+ "@visibilityOfTheChatHistory": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "visibleForEveryone": "Videbla al ĉiuj",
+ "@visibleForEveryone": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "visibleForAllParticipants": "Videbla al ĉiuj partoprenantoj",
+ "@visibleForAllParticipants": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "userAndOthersAreTyping": "{username} kaj {count} aliaj tajpas…",
+ "@userAndOthersAreTyping": {
+ "type": "text",
+ "placeholders": {
+ "username": {},
+ "count": {}
+ }
+ },
+ "unreadMessagesInChats": "{unreadEvents} nelegitaj mesaĝoj en {unreadChats} babiloj",
+ "@unreadMessagesInChats": {
+ "type": "text",
+ "placeholders": {
+ "unreadEvents": {},
+ "unreadChats": {}
+ }
+ },
+ "unreadMessages": "{unreadEvents} nelegitaj mesaĝoj",
+ "@unreadMessages": {
+ "type": "text",
+ "placeholders": {
+ "unreadEvents": {}
+ }
+ },
+ "unreadChats": "{unreadCount} nelegitaj babiloj",
+ "@unreadChats": {
+ "type": "text",
+ "placeholders": {
+ "unreadCount": {}
+ }
+ },
+ "unpin": "Malfiksi",
+ "@unpin": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "timeOfDay": "{hours24}:{minutes}",
+ "@timeOfDay": {
+ "type": "text",
+ "placeholders": {
+ "hours12": {},
+ "hours24": {},
+ "minutes": {},
+ "suffix": {}
+ }
+ },
+ "sourceCode": "Fontkodo",
+ "@sourceCode": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "useAmoledTheme": "Ĉu uzi kolorojn adaptitajn por AMOLED?",
+ "@useAmoledTheme": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "darkTheme": "Malhela",
+ "@darkTheme": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "lightTheme": "Hela",
+ "@lightTheme": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "systemTheme": "Sistema",
+ "@systemTheme": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "changeTheme": "Ŝanĝu la haŭton",
+ "@changeTheme": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "skip": "Preterpasi",
+ "@skip": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "sentCallInformations": "{senderName} sendis informojn pri voko",
+ "@sentCallInformations": {
+ "type": "text",
+ "placeholders": {
+ "senderName": {}
+ }
+ },
+ "sentAnAudio": "{username} sendis sondosieron",
+ "@sentAnAudio": {
+ "type": "text",
+ "placeholders": {
+ "username": {}
+ }
+ },
+ "sendAudio": "Sendi sondosieron",
+ "@sendAudio": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "seenByUserAndCountOthers": "Vidita de {username} kaj {count} aliaj",
+ "@seenByUserAndCountOthers": {
+ "type": "text",
+ "placeholders": {
+ "username": {},
+ "count": {}
+ }
+ },
+ "seenByUserAndUser": "Vidita de {username} kaj {username2}",
+ "@seenByUserAndUser": {
+ "type": "text",
+ "placeholders": {
+ "username": {},
+ "username2": {}
+ }
+ },
+ "seenByUser": "Vidita de {username}",
+ "@seenByUser": {
+ "type": "text",
+ "placeholders": {
+ "username": {}
+ }
+ },
+ "sendBugReports": "Permesi raportadon de eraroj per sentry.io",
+ "@sendBugReports": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "removeExile": "Malforbari",
+ "@removeExile": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "removeAllOtherDevices": "Forigi ĉiujn aliajn aparatojn",
+ "@removeAllOtherDevices": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "rejectedTheInvitation": "{username} rifuzis la inviton",
+ "@rejectedTheInvitation": {
+ "type": "text",
+ "placeholders": {
+ "username": {}
+ }
+ },
+ "recording": "Registrante",
+ "@recording": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "reject": "Rifuzi",
+ "@reject": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "play": "Ludi {fileName}",
+ "@play": {
+ "type": "text",
+ "placeholders": {
+ "fileName": {}
+ }
+ },
+ "pin": "Fiksi",
+ "@pin": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "pickImage": "Elekti bildon",
+ "@pickImage": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "archive": "Arĥivo",
+ "@archive": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "settings": "Agordoj",
+ "@settings": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "end2endEncryptionSettings": "Agordoj pri tutvoja ĉifrado",
+ "@end2endEncryptionSettings": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "createNewGroup": "Krei novan grupon",
+ "@createNewGroup": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "setStatus": "Agordi staton",
+ "@setStatus": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "welcomeText": "Bonvenu al la plej ĉarma tujmesaĝilo en la reto de Matrix.",
+ "@welcomeText": {
+ "type": "text",
+ "placeholders": {}
+ }
+}
diff --git a/lib/l10n/intl_et.arb b/lib/l10n/intl_et.arb
index 53f0b4c2..f05cab50 100644
--- a/lib/l10n/intl_et.arb
+++ b/lib/l10n/intl_et.arb
@@ -1722,5 +1722,25 @@
"@changeDeviceName": {
"type": "text",
"placeholders": {}
+ },
+ "mention": "Märgi ära",
+ "@mention": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "offline": "Väljas",
+ "@offline": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "unavailable": "Eemal",
+ "@unavailable": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "online": "Saadaval",
+ "@online": {
+ "type": "text",
+ "placeholders": {}
}
}
diff --git a/lib/l10n/intl_fr.arb b/lib/l10n/intl_fr.arb
index caf51426..0b51d554 100644
--- a/lib/l10n/intl_fr.arb
+++ b/lib/l10n/intl_fr.arb
@@ -1722,5 +1722,25 @@
"@changeDeviceName": {
"type": "text",
"placeholders": {}
+ },
+ "unavailable": "Indisponible",
+ "@unavailable": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "offline": "Hors ligne",
+ "@offline": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "online": "En ligne",
+ "@online": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "mention": "Mention",
+ "@mention": {
+ "type": "text",
+ "placeholders": {}
}
}
diff --git a/lib/l10n/intl_gl.arb b/lib/l10n/intl_gl.arb
index 313197db..832a11e1 100644
--- a/lib/l10n/intl_gl.arb
+++ b/lib/l10n/intl_gl.arb
@@ -769,7 +769,7 @@
"type": "text",
"placeholders": {}
},
- "isTyping": "está escribindo...",
+ "isTyping": "está escribindo…",
"@isTyping": {
"type": "text",
"placeholders": {}
@@ -861,12 +861,12 @@
"count": {}
}
},
- "loadingPleaseWait": "Cargando... Agarda",
+ "loadingPleaseWait": "Cargando... Agarda.",
"@loadingPleaseWait": {
"type": "text",
"placeholders": {}
},
- "loadMore": "Cargar máis...",
+ "loadMore": "Cargar máis…",
"@loadMore": {
"type": "text",
"placeholders": {}
@@ -978,7 +978,7 @@
"type": "text",
"placeholders": {}
},
- "noRoomsFound": "Non se atoparon salas...",
+ "noRoomsFound": "Non se atoparon salas…",
"@noRoomsFound": {
"type": "text",
"placeholders": {}
@@ -1010,7 +1010,7 @@
"type": "text",
"placeholders": {}
},
- "oopsSomethingWentWrong": "Ooooi, algo fallou...",
+ "oopsSomethingWentWrong": "Ooooi, algo fallou…",
"@oopsSomethingWentWrong": {
"type": "text",
"placeholders": {}
@@ -1515,7 +1515,7 @@
"type": "text",
"placeholders": {}
},
- "userAndOthersAreTyping": "{username} e {count} máis están escribindo...",
+ "userAndOthersAreTyping": "{username} e {count} máis están escribindo…",
"@userAndOthersAreTyping": {
"type": "text",
"placeholders": {
@@ -1523,7 +1523,7 @@
"count": {}
}
},
- "userAndUserAreTyping": "{username} e {username2} están escribindo...",
+ "userAndUserAreTyping": "{username} e {username2} están escribindo…",
"@userAndUserAreTyping": {
"type": "text",
"placeholders": {
@@ -1531,7 +1531,7 @@
"username2": {}
}
},
- "userIsTyping": "{username} está escribindo...",
+ "userIsTyping": "{username} está escribindo…",
"@userIsTyping": {
"type": "text",
"placeholders": {
@@ -1628,7 +1628,7 @@
"type": "text",
"placeholders": {}
},
- "waitingPartnerNumbers": "Agardando a que a outra parte acepte os números...",
+ "waitingPartnerNumbers": "Agardando a que a outra parte acepte os números…",
"@waitingPartnerNumbers": {
"type": "text",
"placeholders": {}
@@ -1653,7 +1653,7 @@
"type": "text",
"placeholders": {}
},
- "welcomeText": "Benvida á mensaxería instantánea más cuquiña da rede matrix.",
+ "welcomeText": "Benvida á mensaxería instantánea más cuquiña da rede Matrix.",
"@welcomeText": {
"type": "text",
"placeholders": {}
@@ -1663,7 +1663,7 @@
"type": "text",
"placeholders": {}
},
- "writeAMessage": "Escribe unha mensaxe...",
+ "writeAMessage": "Escribe unha mensaxe…",
"@writeAMessage": {
"type": "text",
"placeholders": {}
@@ -1722,5 +1722,25 @@
"@changeDeviceName": {
"type": "text",
"placeholders": {}
+ },
+ "unavailable": "Non dispoñible",
+ "@unavailable": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "offline": "Desconectada",
+ "@offline": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "online": "En liña",
+ "@online": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "mention": "Mención",
+ "@mention": {
+ "type": "text",
+ "placeholders": {}
}
}
diff --git a/lib/l10n/intl_hr.arb b/lib/l10n/intl_hr.arb
index d8d098c3..17ff57da 100644
--- a/lib/l10n/intl_hr.arb
+++ b/lib/l10n/intl_hr.arb
@@ -861,12 +861,12 @@
"count": {}
}
},
- "loadingPleaseWait": "Učitava se … Pričekaj",
+ "loadingPleaseWait": "Učitava se … Pričekaj.",
"@loadingPleaseWait": {
"type": "text",
"placeholders": {}
},
- "loadMore": "Učitaj više …",
+ "loadMore": "Učitaj još …",
"@loadMore": {
"type": "text",
"placeholders": {}
@@ -923,7 +923,7 @@
"type": "text",
"placeholders": {}
},
- "needPantalaimonWarning": "Za sada trebaš Pantalaimon za obostrano šifriranje.",
+ "needPantalaimonWarning": "Za trenutačno korištenje obostranog šifriranja trebaš Pantalaimon.",
"@needPantalaimonWarning": {
"type": "text",
"placeholders": {}
@@ -948,7 +948,7 @@
"type": "text",
"placeholders": {}
},
- "noCrossSignBootstrap": "Fluffychat trenutačno ne podržava unakrsno potpisivanje. Aktiviraj je u Riot.",
+ "noCrossSignBootstrap": "Fluffychat trenutačno ne podržava mogućnost unakrsnog potpisivanja. Aktiviraj je u Riotu.",
"@noCrossSignBootstrap": {
"type": "text",
"placeholders": {}
@@ -963,7 +963,7 @@
"type": "text",
"placeholders": {}
},
- "noMegolmBootstrap": "Fluffychat trenutačno ne podržava aktiviranje online sigurnosnu kopiju ključeva. Aktiviraj je u Riot.",
+ "noMegolmBootstrap": "Fluffychat trenutačno ne podržava mogućnost aktiviranja internetskog ključa sigurnosnih kopija. Aktiviraj je u Riotu.",
"@noMegolmBootstrap": {
"type": "text",
"placeholders": {}
@@ -1000,12 +1000,12 @@
"type": "text",
"placeholders": {}
},
- "onlineKeyBackupDisabled": "Online sigurnosna kopija ključeva je deaktivirana",
+ "onlineKeyBackupDisabled": "Internetski ključ sigurnosnih kopija je deaktiviran",
"@onlineKeyBackupDisabled": {
"type": "text",
"placeholders": {}
},
- "onlineKeyBackupEnabled": "Online sigurnosna kopija ključeva je aktivirana",
+ "onlineKeyBackupEnabled": "Internetski ključ sigurnosnih kopija je aktiviran",
"@onlineKeyBackupEnabled": {
"type": "text",
"placeholders": {}
@@ -1628,7 +1628,7 @@
"type": "text",
"placeholders": {}
},
- "waitingPartnerNumbers": "Čekanje na partnera, da prihvati brojeve …",
+ "waitingPartnerNumbers": "Čeka se, da partner prihvati brojeve …",
"@waitingPartnerNumbers": {
"type": "text",
"placeholders": {}
@@ -1653,7 +1653,7 @@
"type": "text",
"placeholders": {}
},
- "welcomeText": "Lijep pozdrav u najslađi program za čavrljanje u mreži matrix.",
+ "welcomeText": "Lijep pozdrav u najslađem programu za čavrljanje u mreži Matrix.",
"@welcomeText": {
"type": "text",
"placeholders": {}
@@ -1722,5 +1722,25 @@
"@changeDeviceName": {
"type": "text",
"placeholders": {}
+ },
+ "offline": "Nepovezano s internetom",
+ "@offline": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "online": "Povezano s internetom",
+ "@online": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "unavailable": "Nedostupno",
+ "@unavailable": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "mention": "Spominjanje",
+ "@mention": {
+ "type": "text",
+ "placeholders": {}
}
}
diff --git a/lib/l10n/intl_it.arb b/lib/l10n/intl_it.arb
index 089134ff..3ef6ff31 100644
--- a/lib/l10n/intl_it.arb
+++ b/lib/l10n/intl_it.arb
@@ -224,7 +224,7 @@
"day": {}
}
},
- "dateWithoutYear": "{month}-{day}",
+ "dateWithoutYear": "{day}/{month}",
"@dateWithoutYear": {
"type": "text",
"placeholders": {
@@ -445,19 +445,19 @@
"rules": {}
}
},
- "changedTheChatAvatar": "{username} ha cambiato avatar",
+ "changedTheChatAvatar": "{username} ha cambiato l'avatar della chat",
"@changedTheChatAvatar": {
"type": "text",
"placeholders": {
"username": {}
}
},
- "askSSSSSign": "Per entrare con l'altro utente, per favore inserisci la tua passphrase o recovery key.",
+ "askSSSSSign": "Per far accedere l'altra persona, per favore inserisci la tua frase segreta o chiave di recupero.",
"@askSSSSSign": {
"type": "text",
"placeholders": {}
},
- "askSSSSCache": "Per favore inserisci la tua passphrase o recovery key per la cache delle chiavi.",
+ "askSSSSCache": "Per favore inserisci la tua frase segrata o chiave di recuparo per mettere in cache le chiavi.",
"@askSSSSCache": {
"type": "text",
"placeholders": {}
@@ -578,5 +578,165 @@
"@deny": {
"type": "text",
"placeholders": {}
+ },
+ "crossSigningDisabled": "La firma incrociata è disabilitata",
+ "@crossSigningDisabled": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "inviteText": "{username} ti ha invitato/a a FluffyChat.\n1. Installa FluffyChat: https://fluffychat.im\n2. Iscriviti o accedi\n3. Apri il collegamento di invito: {link}",
+ "@inviteText": {
+ "type": "text",
+ "placeholders": {
+ "username": {},
+ "link": {}
+ }
+ },
+ "invited": "Invitato/a",
+ "@invited": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "inviteContactToGroup": "Invita un contatto a {groupName}",
+ "@inviteContactToGroup": {
+ "type": "text",
+ "placeholders": {
+ "groupName": {}
+ }
+ },
+ "inviteContact": "Invita contatto",
+ "@inviteContact": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "incorrectPassphraseOrKey": "Frase segrata o chiave di ripristino errate",
+ "@incorrectPassphraseOrKey": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "ignoreListDescription": "Puoi ignorare gli utenti che ti stanno disturbando. Non sarai in grado di ricevere messaggi o inviti a stanze virtuali dagli utenti nel tuo elenco personale da ignorare.",
+ "@ignoreListDescription": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "ignoreUsername": "Ignora il nome utente",
+ "@ignoreUsername": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "ignoredUsers": "Utenti ignorati",
+ "@ignoredUsers": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "identity": "Identità",
+ "@identity": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "id": "ID",
+ "@id": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "homeserverIsNotCompatible": "Il server principale non è compatibile",
+ "@homeserverIsNotCompatible": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "help": "Aiuto",
+ "@help": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "hasWithdrawnTheInvitationFor": "{username} ha ritirato l'invito per {targetName}",
+ "@hasWithdrawnTheInvitationFor": {
+ "type": "text",
+ "placeholders": {
+ "username": {},
+ "targetName": {}
+ }
+ },
+ "guestsCanJoin": "Gli ospiti possono partecipare",
+ "@guestsCanJoin": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "guestsAreForbidden": "Gli ospiti sono vietati",
+ "@guestsAreForbidden": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "groupWith": "Gruppo con {displayname}",
+ "@groupWith": {
+ "type": "text",
+ "placeholders": {
+ "displayname": {}
+ }
+ },
+ "groupIsPublic": "Il gruppo è pubblico",
+ "@groupIsPublic": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "groupDescriptionHasBeenChanged": "La descrizione del gruppo è stata modificata",
+ "@groupDescriptionHasBeenChanged": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "groupDescription": "Descrizione del gruppo",
+ "@groupDescription": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "group": "Gruppo",
+ "@group": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "fromTheInvitation": "Dall'invito",
+ "@fromTheInvitation": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "fromJoining": "Dall'adesione",
+ "@fromJoining": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "friday": "venerdì",
+ "@friday": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "forward": "Inoltra",
+ "@forward": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "fluffychat": "FluffyChat",
+ "@fluffychat": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "fileSize": "Dimensione del file",
+ "@fileSize": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "fileName": "Nome del file",
+ "@fileName": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "enterYourHomeserver": "Inserisci il tuo server principale",
+ "@enterYourHomeserver": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "crossSigningEnabled": "La firma incrociata è abilitata",
+ "@crossSigningEnabled": {
+ "type": "text",
+ "placeholders": {}
}
}
diff --git a/lib/l10n/intl_nb.arb b/lib/l10n/intl_nb.arb
new file mode 100644
index 00000000..6f7feb08
--- /dev/null
+++ b/lib/l10n/intl_nb.arb
@@ -0,0 +1,1105 @@
+{
+ "yourOwnUsername": "Ditt eget brukernavn",
+ "@yourOwnUsername": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "youHaveBeenBannedFromThisChat": "Du har blitt bannlyst fra denne sludringen",
+ "@youHaveBeenBannedFromThisChat": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "youAreInvitedToThisChat": "Du er invitert til denne sludringen",
+ "@youAreInvitedToThisChat": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "you": "Deg",
+ "@you": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "unpin": "Løsne",
+ "@unpin": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "unknownEncryptionAlgorithm": "Ukjent krypteringsalgoritme",
+ "@unknownEncryptionAlgorithm": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "unknownDevice": "Ukjent enhet",
+ "@unknownDevice": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "unmuteChat": "Opphev forstumming av sludring",
+ "@unmuteChat": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "tuesday": "Tirsdag",
+ "@tuesday": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "tryToSendAgain": "Prøv å sende igjen",
+ "@tryToSendAgain": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "title": "FluffyChat",
+ "@title": {
+ "description": "Title for the application",
+ "type": "text",
+ "placeholders": {}
+ },
+ "thursday": "Torsdag",
+ "@thursday": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "tapToShowMenu": "Trykk for å vise meny",
+ "@tapToShowMenu": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "donate": "Doner",
+ "@donate": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "sunday": "Søndag",
+ "@sunday": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "submit": "Send inn",
+ "@submit": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "sourceCode": "Kildekode",
+ "@sourceCode": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "darkTheme": "Mørk",
+ "@darkTheme": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "lightTheme": "Lys",
+ "@lightTheme": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "statusExampleMessage": "Hvordan har du det i dag?",
+ "@statusExampleMessage": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "systemTheme": "System",
+ "@systemTheme": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "changeTheme": "Endre din stil",
+ "@changeTheme": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "skip": "Hopp over",
+ "@skip": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "signUp": "Registrer deg",
+ "@signUp": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "settings": "Innstilinger",
+ "@settings": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "setStatus": "Angi status",
+ "@setStatus": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "setGroupDescription": "Sett gruppebeskrivelse",
+ "@setGroupDescription": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "setAProfilePicture": "Sett et profilbilde",
+ "@setAProfilePicture": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "sentAVideo": "{username} sendte en video",
+ "@sentAVideo": {
+ "type": "text",
+ "placeholders": {
+ "username": {}
+ }
+ },
+ "sentAPicture": "{username} sendte et bilde",
+ "@sentAPicture": {
+ "type": "text",
+ "placeholders": {
+ "username": {}
+ }
+ },
+ "sentAnAudio": "{username} sendte lyd",
+ "@sentAnAudio": {
+ "type": "text",
+ "placeholders": {
+ "username": {}
+ }
+ },
+ "sentAFile": "{username} sendte en fil",
+ "@sentAFile": {
+ "type": "text",
+ "placeholders": {
+ "username": {}
+ }
+ },
+ "sendVideo": "Send video",
+ "@sendVideo": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "sendOriginal": "Send original",
+ "@sendOriginal": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "sendImage": "Send bilde",
+ "@sendImage": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "sendFile": "Send fil",
+ "@sendFile": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "sendAudio": "Send lyd",
+ "@sendAudio": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "sendAMessage": "Send en melding",
+ "@sendAMessage": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "send": "Send",
+ "@send": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "seenByUserAndUser": "Sett av {username} og {username2}",
+ "@seenByUserAndUser": {
+ "type": "text",
+ "placeholders": {
+ "username": {},
+ "username2": {}
+ }
+ },
+ "seenByUser": "Sett av {username}",
+ "@seenByUser": {
+ "type": "text",
+ "placeholders": {
+ "username": {}
+ }
+ },
+ "no": "Nei",
+ "@no": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "lastSeenLongTimeAgo": "Sett for lenge siden",
+ "@lastSeenLongTimeAgo": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "searchForAChat": "Søk etter en sludring",
+ "@searchForAChat": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "share": "Del",
+ "@share": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "saturday": "Lørdag",
+ "@saturday": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "requestPermission": "Forespør tilgang",
+ "@requestPermission": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "reply": "Svar",
+ "@reply": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "removeMessage": "Fjern melding",
+ "@removeMessage": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "revokeAllPermissions": "Trekk tilbake alle tilganger",
+ "@revokeAllPermissions": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "remove": "Fjern",
+ "@remove": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "removeDevice": "Fjern enhet",
+ "@removeDevice": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "removedBy": "Fjernet av {username}",
+ "@removedBy": {
+ "type": "text",
+ "placeholders": {
+ "username": {}
+ }
+ },
+ "removeAllOtherDevices": "Fjern alle andre enheter",
+ "@removeAllOtherDevices": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "publicRooms": "Offentlige rom",
+ "@publicRooms": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "privacy": "Personvern",
+ "@privacy": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "pleaseEnterYourUsername": "Skriv inn brukernavnet ditt",
+ "@pleaseEnterYourUsername": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "pleaseEnterYourPassword": "Skriv inn passordet ditt",
+ "@pleaseEnterYourPassword": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "pleaseChooseAUsername": "Velg et brukernavn",
+ "@pleaseChooseAUsername": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "play": "Spill av {fileName}",
+ "@play": {
+ "type": "text",
+ "placeholders": {
+ "fileName": {}
+ }
+ },
+ "pin": "Fest",
+ "@pin": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "pickImage": "Velg bilde",
+ "@pickImage": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "passwordHasBeenChanged": "Passord endret",
+ "@passwordHasBeenChanged": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "password": "Passord",
+ "@password": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "optionalGroupName": "Gruppenavn (valgfritt)",
+ "@optionalGroupName": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "openCamera": "Åpne kamera",
+ "@openCamera": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "unavailable": "Utilgjengelig",
+ "@unavailable": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "offline": "Frakoblet",
+ "@offline": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "online": "Pålogget",
+ "@online": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "ok": "OK",
+ "@ok": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "login": "Logg inn",
+ "@login": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "license": "Lisens",
+ "@license": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "userLeftTheChat": "{username} har forlatt sludringen",
+ "@userLeftTheChat": {
+ "type": "text",
+ "placeholders": {
+ "username": {}
+ }
+ },
+ "logout": "Logg ut",
+ "@logout": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "leftTheChat": "Forlat sludringen",
+ "@leftTheChat": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "leave": "Forlat",
+ "@leave": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "joinRoom": "Ta del i rom",
+ "@joinRoom": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "joinedTheChat": "{username} tok del i sludringen",
+ "@joinedTheChat": {
+ "type": "text",
+ "placeholders": {
+ "username": {}
+ }
+ },
+ "editJitsiInstance": "Skriv inn Jitsi-instans",
+ "@editJitsiInstance": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "invitedUsersOnly": "Kun inviterte brukere",
+ "@invitedUsersOnly": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "invited": "Invitert",
+ "@invited": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "inviteContact": "Inviter kontakt",
+ "@inviteContact": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "ignoreUsername": "Ignorer brukernavn",
+ "@ignoreUsername": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "ignoredUsers": "Ignorerte brukere",
+ "@ignoredUsers": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "identity": "Identitet",
+ "@identity": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "id": "ID",
+ "@id": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "help": "Hjelp",
+ "@help": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "guestsAreForbidden": "Gjester forbudt",
+ "@guestsAreForbidden": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "guestsCanJoin": "Gjester kan ta del",
+ "@guestsCanJoin": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "groupIsPublic": "Gruppen er offentlig",
+ "@groupIsPublic": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "groupDescription": "Gruppebeskrivelse",
+ "@groupDescription": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "group": "Gruppe",
+ "@group": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "fromTheInvitation": "Fra invitasjonen",
+ "@fromTheInvitation": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "friday": "Fredag",
+ "@friday": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "forward": "Videre",
+ "@forward": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "fluffychat": "FluffyChat",
+ "@fluffychat": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "fileSize": "Filstørrelse",
+ "@fileSize": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "fileName": "Filnavn",
+ "@fileName": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "enterYourHomeserver": "Skriv inn din hjemmetjener",
+ "@enterYourHomeserver": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "enterAUsername": "Skriv inn et brukernavn",
+ "@enterAUsername": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "enterAGroupName": "Skriv inn et gruppenavn",
+ "@enterAGroupName": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "end2endEncryptionSettings": "Ende-til-ende -krypteringsinnstillinger",
+ "@end2endEncryptionSettings": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "encryptionAlgorithm": "Krypteringsalgoritme",
+ "@encryptionAlgorithm": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "encryption": "Kryptering",
+ "@encryption": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "editDisplayname": "Rediger visningsnavn",
+ "@editDisplayname": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "downloadFile": "Last ned fil",
+ "@downloadFile": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "devices": "Enheter",
+ "@devices": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "device": "Enhet",
+ "@device": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "deny": "Nekt",
+ "@deny": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "deleteMessage": "Slett melding",
+ "@deleteMessage": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "deleteAccount": "Slett konto",
+ "@deleteAccount": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "delete": "Slett",
+ "@delete": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "createAccountNow": "Opprett konto nå",
+ "@createAccountNow": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "create": "Opprett",
+ "@create": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "countParticipants": "{count} deltagere",
+ "@countParticipants": {
+ "type": "text",
+ "placeholders": {
+ "count": {}
+ }
+ },
+ "couldNotSetDisplayname": "Kunne ikke sette visningsnavn",
+ "@couldNotSetDisplayname": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "couldNotDecryptMessage": "Kunne ikke dekryptere melding: {error}",
+ "@couldNotDecryptMessage": {
+ "type": "text",
+ "placeholders": {
+ "error": {}
+ }
+ },
+ "copy": "Kopier",
+ "@copy": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "copiedToClipboard": "Kopiert til utklippstavle",
+ "@copiedToClipboard": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "contentViewer": "Innholdsviser",
+ "@contentViewer": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "connect": "Koble til",
+ "@connect": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "confirm": "Bekreft",
+ "@confirm": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "close": "Lukk",
+ "@close": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "chooseAUsername": "Velg et brukernavn",
+ "@chooseAUsername": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "chooseAStrongPassword": "Velg et sterkt passord",
+ "@chooseAStrongPassword": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "changeTheServer": "Endre tjeneren",
+ "@changeTheServer": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "changeWallpaper": "Endre bakgrunnsbilde",
+ "@changeWallpaper": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "changeTheNameOfTheGroup": "Endre gruppens navn",
+ "@changeTheNameOfTheGroup": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "changelog": "Endringslogg",
+ "@changelog": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "changedTheGuestAccessRules": "{username} endret gjestetilgangsreglene",
+ "@changedTheGuestAccessRules": {
+ "type": "text",
+ "placeholders": {
+ "username": {}
+ }
+ },
+ "changeTheHomeserver": "Endre hjemmetjener",
+ "@changeTheHomeserver": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "areYouSure": "Er du sikker?",
+ "@areYouSure": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "areGuestsAllowedToJoin": "Skal gjester tillates å ta del",
+ "@areGuestsAllowedToJoin": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "archivedRoom": "Arkivert rom",
+ "@archivedRoom": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "anyoneCanJoin": "Hvem som helst kan delta",
+ "@anyoneCanJoin": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "answeredTheCall": "{senderName} besvarte anropet",
+ "@answeredTheCall": {
+ "type": "text",
+ "placeholders": {
+ "senderName": {}
+ }
+ },
+ "alreadyHaveAnAccount": "Har du allerede en konto?",
+ "@alreadyHaveAnAccount": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "alias": "alias",
+ "@alias": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "admin": "Administrator",
+ "@admin": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "addGroupDescription": "Legg til gruppebeskrivelse",
+ "@addGroupDescription": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "activatedEndToEndEncryption": "{username} skrudde på ende-til-ende -kryptering",
+ "@activatedEndToEndEncryption": {
+ "type": "text",
+ "placeholders": {
+ "username": {}
+ }
+ },
+ "accountInformation": "Kontoinfo",
+ "@accountInformation": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "account": "Konto",
+ "@account": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "acceptedTheInvitation": "{username} godtok invitasjonen",
+ "@acceptedTheInvitation": {
+ "type": "text",
+ "placeholders": {
+ "username": {}
+ }
+ },
+ "accept": "Godta",
+ "@accept": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "about": "Om",
+ "@about": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "youCannotInviteYourself": "Du kan ikke invitere deg selv",
+ "@youCannotInviteYourself": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "youAreNoLongerParticipatingInThisChat": "Du deltar ikke lenger i denne sludringen",
+ "@youAreNoLongerParticipatingInThisChat": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "wednesday": "Onsdag",
+ "@wednesday": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "wallpaper": "Bakgrunnsbilde",
+ "@wallpaper": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "warning": "Advarsel!",
+ "@warning": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "visibleForEveryone": "Synlig for alle",
+ "@visibleForEveryone": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "visibleForAllParticipants": "Synlig for alle deltagere",
+ "@visibleForAllParticipants": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "videoCall": "Videosamtale",
+ "@videoCall": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "verifyUser": "Bekreft bruker",
+ "@verifyUser": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "verifyStart": "Start bekreftelse",
+ "@verifyStart": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "verifyManual": "Bekreft manuelt",
+ "@verifyManual": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "verify": "Bekreft",
+ "@verify": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "userSentUnknownEvent": "{username} sendte en {type}-hendelse",
+ "@userSentUnknownEvent": {
+ "type": "text",
+ "placeholders": {
+ "username": {},
+ "type": {}
+ }
+ },
+ "userIsTyping": "{username} skriver…",
+ "@userIsTyping": {
+ "type": "text",
+ "placeholders": {
+ "username": {}
+ }
+ },
+ "username": "Brukernavn",
+ "@username": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "userAndUserAreTyping": "{username} og {username2} skriver…",
+ "@userAndUserAreTyping": {
+ "type": "text",
+ "placeholders": {
+ "username": {},
+ "username2": {}
+ }
+ },
+ "userAndOthersAreTyping": "{username} og {count} andre skriver…",
+ "@userAndOthersAreTyping": {
+ "type": "text",
+ "placeholders": {
+ "username": {},
+ "count": {}
+ }
+ },
+ "unreadMessagesInChats": "{unreadEvents} uleste meldinger i {unreadChats} sludringer",
+ "@unreadMessagesInChats": {
+ "type": "text",
+ "placeholders": {
+ "unreadEvents": {},
+ "unreadChats": {}
+ }
+ },
+ "unreadMessages": "{unreadEvents} uleste meldinger",
+ "@unreadMessages": {
+ "type": "text",
+ "placeholders": {
+ "unreadEvents": {}
+ }
+ },
+ "unreadChats": "{unreadCount} uleste sludringer",
+ "@unreadChats": {
+ "type": "text",
+ "placeholders": {
+ "unreadCount": {}
+ }
+ },
+ "newVerificationRequest": "Ny bekreftelsesforespørsel.",
+ "@newVerificationRequest": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "newPrivateChat": "Ny privat sludring",
+ "@newPrivateChat": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "newMessageInFluffyChat": "Ny melding i FluffyChat",
+ "@newMessageInFluffyChat": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "muteChat": "Forstum sludring",
+ "@muteChat": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "monday": "Mandag",
+ "@monday": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "logInTo": "Logg inn på {homeserver}",
+ "@logInTo": {
+ "type": "text",
+ "placeholders": {
+ "homeserver": {}
+ }
+ },
+ "loadCountMoreParticipants": "Last inn {count} deltagere til",
+ "@loadCountMoreParticipants": {
+ "type": "text",
+ "placeholders": {
+ "count": {}
+ }
+ },
+ "loadMore": "Last inn mer…",
+ "@loadMore": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "loadingPleaseWait": "Laster inn… Vent.",
+ "@loadingPleaseWait": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "changedTheRoomInvitationLink": "{username} endret invitasjonslenken",
+ "@changedTheRoomInvitationLink": {
+ "type": "text",
+ "placeholders": {
+ "username": {}
+ }
+ },
+ "changedTheRoomAliases": "{username} endret rom-aliasene",
+ "@changedTheRoomAliases": {
+ "type": "text",
+ "placeholders": {
+ "username": {}
+ }
+ },
+ "changedTheJoinRulesTo": "{username} endret tilgangsreglene til: {joinRules}",
+ "@changedTheJoinRulesTo": {
+ "type": "text",
+ "placeholders": {
+ "username": {},
+ "joinRules": {}
+ }
+ },
+ "changedTheJoinRules": "{username} endret tilgangsreglene",
+ "@changedTheJoinRules": {
+ "type": "text",
+ "placeholders": {
+ "username": {}
+ }
+ },
+ "changedTheGuestAccessRulesTo": "{username} endret gjestetilgangsregler til: {rules}",
+ "@changedTheGuestAccessRulesTo": {
+ "type": "text",
+ "placeholders": {
+ "username": {},
+ "rules": {}
+ }
+ },
+ "encryptionNotEnabled": "Kryptering er ikke påskrudd",
+ "@encryptionNotEnabled": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "discardPicture": "Forkast bilde",
+ "@discardPicture": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "dateWithYear": "{day} {month} {year}",
+ "@dateWithYear": {
+ "type": "text",
+ "placeholders": {
+ "year": {},
+ "month": {},
+ "day": {}
+ }
+ },
+ "dateWithoutYear": "{day} {month}",
+ "@dateWithoutYear": {
+ "type": "text",
+ "placeholders": {
+ "month": {},
+ "day": {}
+ }
+ },
+ "dateAndTimeOfDay": "{timeOfDay}, {date}",
+ "@dateAndTimeOfDay": {
+ "type": "text",
+ "placeholders": {
+ "date": {},
+ "timeOfDay": {}
+ }
+ },
+ "createNewGroup": "Opprett ny gruppe",
+ "@createNewGroup": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "couldNotSetAvatar": "Kunne ikke sette avatar",
+ "@couldNotSetAvatar": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "changedTheProfileAvatar": "{username} endret avataren sin",
+ "@changedTheProfileAvatar": {
+ "type": "text",
+ "placeholders": {
+ "username": {}
+ }
+ },
+ "changedTheHistoryVisibilityTo": "{username} endret historikksynlighet til: {rules}",
+ "@changedTheHistoryVisibilityTo": {
+ "type": "text",
+ "placeholders": {
+ "username": {},
+ "rules": {}
+ }
+ },
+ "changedTheHistoryVisibility": "{username} endret historikksynlighet",
+ "@changedTheHistoryVisibility": {
+ "type": "text",
+ "placeholders": {
+ "username": {}
+ }
+ },
+ "changedTheDisplaynameTo": "{username} endret visningsnavn til: {displayname}",
+ "@changedTheDisplaynameTo": {
+ "type": "text",
+ "placeholders": {
+ "username": {},
+ "displayname": {}
+ }
+ },
+ "changedTheChatPermissions": "{username} endret sludretilgangene",
+ "@changedTheChatPermissions": {
+ "type": "text",
+ "placeholders": {
+ "username": {}
+ }
+ },
+ "changedTheChatDescriptionTo": "{username} endret sludrebeskrivelse til: «{description}»",
+ "@changedTheChatDescriptionTo": {
+ "type": "text",
+ "placeholders": {
+ "username": {},
+ "description": {}
+ }
+ },
+ "changedTheChatNameTo": "{username} endret sludringsnavn til: «{chatname}»",
+ "@changedTheChatNameTo": {
+ "type": "text",
+ "placeholders": {
+ "username": {},
+ "chatname": {}
+ }
+ },
+ "changedTheChatAvatar": "{username} endret sludreavatar",
+ "@changedTheChatAvatar": {
+ "type": "text",
+ "placeholders": {
+ "username": {}
+ }
+ },
+ "changeDeviceName": "Endre enhetsnavn",
+ "@changeDeviceName": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "cancel": "Avbryt",
+ "@cancel": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "byDefaultYouWillBeConnectedTo": "Som forvalg vil du bli tilkoblet via {homeserver}",
+ "@byDefaultYouWillBeConnectedTo": {
+ "type": "text",
+ "placeholders": {
+ "homeserver": {}
+ }
+ },
+ "blockDevice": "Blokker enhet",
+ "@blockDevice": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "bannedUser": "{username} bannlyste {targetName}",
+ "@bannedUser": {
+ "type": "text",
+ "placeholders": {
+ "username": {},
+ "targetName": {}
+ }
+ }
+}
diff --git a/lib/l10n/intl_ru.arb b/lib/l10n/intl_ru.arb
index d8960c14..a8881c39 100644
--- a/lib/l10n/intl_ru.arb
+++ b/lib/l10n/intl_ru.arb
@@ -759,7 +759,7 @@
"type": "text",
"placeholders": {}
},
- "isTyping": "Печатает...",
+ "isTyping": "Печатает…",
"@isTyping": {
"type": "text",
"placeholders": {}
@@ -851,12 +851,12 @@
"count": {}
}
},
- "loadingPleaseWait": "Пожалуйста, подождите...",
+ "loadingPleaseWait": "Пожалуйста, подождите…",
"@loadingPleaseWait": {
"type": "text",
"placeholders": {}
},
- "loadMore": "Загрузить больше...",
+ "loadMore": "Загрузить больше…",
"@loadMore": {
"type": "text",
"placeholders": {}
@@ -968,7 +968,7 @@
"type": "text",
"placeholders": {}
},
- "noRoomsFound": "Комнаты не найдены...",
+ "noRoomsFound": "Комнаты не найдены…",
"@noRoomsFound": {
"type": "text",
"placeholders": {}
@@ -1000,7 +1000,7 @@
"type": "text",
"placeholders": {}
},
- "oopsSomethingWentWrong": "Упс! Что-то пошло не так...",
+ "oopsSomethingWentWrong": "Упс! Что-то пошло не так…",
"@oopsSomethingWentWrong": {
"type": "text",
"placeholders": {}
@@ -1500,7 +1500,7 @@
"type": "text",
"placeholders": {}
},
- "userAndOthersAreTyping": "{username} и {count} других участников печатают...",
+ "userAndOthersAreTyping": "{username} и {count} других участников печатают…",
"@userAndOthersAreTyping": {
"type": "text",
"placeholders": {
@@ -1508,7 +1508,7 @@
"count": {}
}
},
- "userAndUserAreTyping": "{username} и {username2} печатают...",
+ "userAndUserAreTyping": "{username} и {username2} печатают…",
"@userAndUserAreTyping": {
"type": "text",
"placeholders": {
@@ -1516,7 +1516,7 @@
"username2": {}
}
},
- "userIsTyping": "{username} печатает...",
+ "userIsTyping": "{username} печатает…",
"@userIsTyping": {
"type": "text",
"placeholders": {
@@ -1613,7 +1613,7 @@
"type": "text",
"placeholders": {}
},
- "waitingPartnerNumbers": "В ожидании партнёра, чтобы принять числа...",
+ "waitingPartnerNumbers": "В ожидании партнёра, чтобы принять числа…",
"@waitingPartnerNumbers": {
"type": "text",
"placeholders": {}
@@ -1643,7 +1643,7 @@
"type": "text",
"placeholders": {}
},
- "writeAMessage": "Напишите сообщение...",
+ "writeAMessage": "Напишите сообщение…",
"@writeAMessage": {
"type": "text",
"placeholders": {}
@@ -1698,7 +1698,7 @@
"type": "text",
"placeholders": {}
},
- "deactivateAccountWarning": "Это деактивирует вашу учётную запись пользователя. Это не может быть отменено! Вы уверены?",
+ "deactivateAccountWarning": "Это деактивирует вашу учётную запись пользователя. Данное действие не может быть отменено! Вы уверены?",
"@deactivateAccountWarning": {
"type": "text",
"placeholders": {}
@@ -1708,12 +1708,12 @@
"type": "text",
"placeholders": {}
},
- "enableEmotesGlobally": "Включить набор эмоджи глобально",
+ "enableEmotesGlobally": "Включить набор эмодзи глобально",
"@enableEmotesGlobally": {
"type": "text",
"placeholders": {}
},
- "emotePacks": "Наборы эмоджи для комнаты",
+ "emotePacks": "Наборы эмодзи для комнаты",
"@emotePacks": {
"type": "text",
"placeholders": {}
@@ -1722,5 +1722,25 @@
"@changeDeviceName": {
"type": "text",
"placeholders": {}
+ },
+ "mention": "Упомянуть",
+ "@mention": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "offline": "Не в сети",
+ "@offline": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "online": "В сети",
+ "@online": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "unavailable": "Недоступен",
+ "@unavailable": {
+ "type": "text",
+ "placeholders": {}
}
}
diff --git a/lib/l10n/intl_tr.arb b/lib/l10n/intl_tr.arb
index c767ae9a..59163039 100644
--- a/lib/l10n/intl_tr.arb
+++ b/lib/l10n/intl_tr.arb
@@ -137,7 +137,7 @@
"targetName": {}
}
},
- "blockDevice": "Cihazı Engelle",
+ "blockDevice": "Aygıtı Engelle",
"@blockDevice": {
"type": "text",
"placeholders": {}
@@ -323,12 +323,12 @@
"type": "text",
"placeholders": {}
},
- "compareEmojiMatch": "Karşılaştırın ve aşağıdaki emojilerin diğer cihazdakilerle eşleştiğinden emin olun:",
+ "compareEmojiMatch": "Karşılaştırın ve aşağıdaki emojilerin diğer aygıttaki emojilerle eşleştiğinden emin olun:",
"@compareEmojiMatch": {
"type": "text",
"placeholders": {}
},
- "compareNumbersMatch": "Karşılaştırın ve aşağıdaki numaraların diğer cihazdakilerle eşleştiğinden emin olun:",
+ "compareNumbersMatch": "Karşılaştırın ve aşağıdaki numaraların diğer aygıttaki numaralarla eşleştiğinden emin olun:",
"@compareNumbersMatch": {
"type": "text",
"placeholders": {}
@@ -474,12 +474,12 @@
"type": "text",
"placeholders": {}
},
- "device": "Cihaz",
+ "device": "Aygıt",
"@device": {
"type": "text",
"placeholders": {}
},
- "devices": "Cihazlar",
+ "devices": "Aygıtlar",
"@devices": {
"type": "text",
"placeholders": {}
@@ -727,7 +727,7 @@
"link": {}
}
},
- "isDeviceKeyCorrect": "Aşağıdaki cihaz anahtarı doğru mu?",
+ "isDeviceKeyCorrect": "Aşağıdaki aygıt anahtarı doğru mu?",
"@isDeviceKeyCorrect": {
"type": "text",
"placeholders": {}
@@ -983,7 +983,7 @@
"type": "text",
"placeholders": {}
},
- "participatingUserDevices": "Katılan kullanıcı cihazları",
+ "participatingUserDevices": "Katılan kullanıcı aygıtları",
"@participatingUserDevices": {
"type": "text",
"placeholders": {}
@@ -1069,7 +1069,7 @@
"type": "text",
"placeholders": {}
},
- "removeAllOtherDevices": "Diğer tüm cihazları kaldır",
+ "removeAllOtherDevices": "Diğer tüm aygıtları kaldır",
"@removeAllOtherDevices": {
"type": "text",
"placeholders": {}
@@ -1081,7 +1081,7 @@
"username": {}
}
},
- "removeDevice": "Cihazı kaldır",
+ "removeDevice": "Aygıtı kaldır",
"@removeDevice": {
"type": "text",
"placeholders": {}
@@ -1355,12 +1355,12 @@
"targetName": {}
}
},
- "unblockDevice": "Cihazın Engellemesini Kaldır",
+ "unblockDevice": "Aygıtın Engellemesini Kaldır",
"@unblockDevice": {
"type": "text",
"placeholders": {}
},
- "unknownDevice": "Bilinmeyen cihaz",
+ "unknownDevice": "Bilinmeyen aygıt",
"@unknownDevice": {
"type": "text",
"placeholders": {}
@@ -1718,9 +1718,29 @@
"type": "text",
"placeholders": {}
},
- "changeDeviceName": "Cihaz adını değiştir",
+ "changeDeviceName": "Aygıt adını değiştir",
"@changeDeviceName": {
"type": "text",
"placeholders": {}
+ },
+ "mention": "Bahset",
+ "@mention": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "unavailable": "Yok",
+ "@unavailable": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "offline": "Çevrim dışı",
+ "@offline": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "online": "Çevrim içi",
+ "@online": {
+ "type": "text",
+ "placeholders": {}
}
}
diff --git a/lib/l10n/intl_vi.arb b/lib/l10n/intl_vi.arb
new file mode 100644
index 00000000..a8a59ba1
--- /dev/null
+++ b/lib/l10n/intl_vi.arb
@@ -0,0 +1,98 @@
+{
+ "blockDevice": "Thiết bị bị chặn",
+ "@blockDevice": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "askSSSSCache": "Vui lòng nhập cụm mật khẩu hoặc khóa khôi phục để lưu khóa vào bộ nhớ cache.",
+ "@askSSSSCache": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "areYouSure": "Bạn chắc chứ?",
+ "@areYouSure": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "areGuestsAllowedToJoin": "Khách vãng lai có được tham gia không",
+ "@areGuestsAllowedToJoin": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "archivedRoom": "Phòng hội thảo đã lưu trữ",
+ "@archivedRoom": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "archive": "Lưu trữ",
+ "@archive": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "anyoneCanJoin": "Mọi người đều có thể gia nhập",
+ "@anyoneCanJoin": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "answeredTheCall": "{senderName} đã trả lời cuộc gọi",
+ "@answeredTheCall": {
+ "type": "text",
+ "placeholders": {
+ "senderName": {}
+ }
+ },
+ "alreadyHaveAnAccount": "Bạn đã có tài khoản?",
+ "@alreadyHaveAnAccount": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "alias": "bí danh",
+ "@alias": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "admin": "Quản trị viên",
+ "@admin": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "addGroupDescription": "Thêm mô tả cho nhóm",
+ "@addGroupDescription": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "activatedEndToEndEncryption": "{username} đã kích hoạt mã hóa đầu cuối 2 chiều",
+ "@activatedEndToEndEncryption": {
+ "type": "text",
+ "placeholders": {
+ "username": {}
+ }
+ },
+ "accountInformation": "Thông tin tài khoản",
+ "@accountInformation": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "account": "Tài khoản",
+ "@account": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "acceptedTheInvitation": "{username} đã đồng ý lời mời",
+ "@acceptedTheInvitation": {
+ "type": "text",
+ "placeholders": {
+ "username": {}
+ }
+ },
+ "accept": "Đồng ý",
+ "@accept": {
+ "type": "text",
+ "placeholders": {}
+ },
+ "about": "Giới thiệu",
+ "@about": {
+ "type": "text",
+ "placeholders": {}
+ }
+}
diff --git a/lib/main.dart b/lib/main.dart
index a08f0015..bba5897c 100644
--- a/lib/main.dart
+++ b/lib/main.dart
@@ -3,39 +3,26 @@ import 'dart:io';
import 'package:bot_toast/bot_toast.dart';
import 'package:famedlysdk/famedlysdk.dart';
+import 'package:fluffychat/utils/sentry_controller.dart';
import 'package:fluffychat/views/homeserver_picker.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_gen/gen_l10n/l10n.dart';
-import 'package:sentry/sentry.dart';
import 'package:universal_html/prefer_universal/html.dart' as html;
import 'components/matrix.dart';
import 'components/theme_switcher.dart';
-import 'utils/famedlysdk_store.dart';
import 'views/chat_list.dart';
-final sentry = SentryClient(dsn: '8591d0d863b646feb4f3dda7e5dcab38');
-
-void captureException(error, stackTrace) async {
- debugPrint(error.toString());
- debugPrint(stackTrace.toString());
- final storage = await getLocalStorage();
- if (storage.getItem('sentry') == true) {
- await sentry.captureException(
- exception: error,
- stackTrace: stackTrace,
- );
- }
-}
-
void main() {
SystemChrome.setSystemUIOverlayStyle(
SystemUiOverlayStyle(statusBarColor: Colors.transparent));
+ FlutterError.onError = (FlutterErrorDetails details) =>
+ Zone.current.handleUncaughtError(details.exception, details.stack);
runZonedGuarded(
() => runApp(App()),
- captureException,
+ SentryController.captureException,
);
}
diff --git a/lib/utils/famedlysdk_store.dart b/lib/utils/famedlysdk_store.dart
index 25acf110..34232e59 100644
--- a/lib/utils/famedlysdk_store.dart
+++ b/lib/utils/famedlysdk_store.dart
@@ -1,27 +1,13 @@
-import 'dart:convert';
-
import 'package:famedlysdk/famedlysdk.dart';
import 'package:fluffychat/utils/platform_infos.dart';
-import 'package:flutter/material.dart';
-import 'package:flutter/foundation.dart';
import 'package:flutter_secure_storage/flutter_secure_storage.dart';
import 'package:localstorage/localstorage.dart';
import 'package:path_provider/path_provider.dart';
import 'dart:async';
import 'dart:core';
import './database/shared.dart';
-import 'package:olm/olm.dart' as olm; // needed for migration
import 'package:random_string/random_string.dart';
-Future getLocalStorage() async {
- final directory = PlatformInfos.isBetaDesktop
- ? await getApplicationSupportDirectory()
- : (PlatformInfos.isWeb ? null : await getApplicationDocumentsDirectory());
- final localStorage = LocalStorage('LocalStorage', directory?.path);
- await localStorage.ready;
- return localStorage;
-}
-
Future getDatabase(Client client) async {
while (_generateDatabaseLock) {
await Future.delayed(Duration(milliseconds: 50));
@@ -31,9 +17,9 @@ Future getDatabase(Client client) async {
if (_db != null) return _db;
final store = Store();
var password = await store.getItem('database-password');
- var needMigration = false;
+ var newPassword = false;
if (password == null || password.isEmpty) {
- needMigration = true;
+ newPassword = true;
password = randomString(255);
}
_db = await constructDb(
@@ -41,11 +27,7 @@ Future getDatabase(Client client) async {
filename: 'moor.sqlite',
password: password,
);
- // Check if database is open:
- debugPrint((await _db.customSelect('SELECT 1').get()).toString());
- if (needMigration) {
- debugPrint('[Moor] Start migration');
- await migrate(client.clientName, _db, store);
+ if (newPassword) {
await store.setItem('database-password', password);
}
return _db;
@@ -57,239 +39,54 @@ Future getDatabase(Client client) async {
Database _db;
bool _generateDatabaseLock = false;
-Future migrate(String clientName, Database db, Store store) async {
- debugPrint('[Store] attempting old migration to moor...');
- final oldKeys = await store.getAllItems();
- if (oldKeys == null || oldKeys.isEmpty) {
- debugPrint('[Store] empty store!');
- return; // we are done!
- }
- final credentialsStr = oldKeys[clientName];
- if (credentialsStr == null || credentialsStr.isEmpty) {
- debugPrint('[Store] no credentials found!');
- return; // no credentials
- }
- final Map credentials = json.decode(credentialsStr);
- if (!credentials.containsKey('homeserver') ||
- !credentials.containsKey('token') ||
- !credentials.containsKey('userID')) {
- debugPrint('[Store] invalid credentials!');
- return; // invalid old store, we are done, too!
- }
- var clientId = 0;
- final oldClient = await db.getClient(clientName);
- if (oldClient == null) {
- clientId = await db.insertClient(
- clientName,
- credentials['homeserver'],
- credentials['token'],
- credentials['userID'],
- credentials['deviceID'],
- credentials['deviceName'],
- null,
- credentials['olmAccount'],
- );
- } else {
- clientId = oldClient.clientId;
- await db.updateClient(
- credentials['homeserver'],
- credentials['token'],
- credentials['userID'],
- credentials['deviceID'],
- credentials['deviceName'],
- null,
- credentials['olmAccount'],
- clientId,
- );
- }
- await db.clearCache(clientId);
- debugPrint('[Store] Inserted/updated client, clientId = ${clientId}');
- await db.transaction(() async {
- // alright, we stored / updated the client and have the account ID, time to import everything else!
- // user_device_keys and user_device_keys_key
- debugPrint('[Store] Migrating user device keys...');
- final deviceKeysListString = oldKeys['${clientName}.user_device_keys'];
- if (deviceKeysListString != null && deviceKeysListString.isNotEmpty) {
- Map rawUserDeviceKeys =
- json.decode(deviceKeysListString);
- for (final entry in rawUserDeviceKeys.entries) {
- final map = entry.value;
- await db.storeUserDeviceKeysInfo(
- clientId, map['user_id'], map['outdated']);
- for (final rawKey in map['device_keys'].entries) {
- final jsonVaue = rawKey.value;
- await db.storeUserDeviceKey(
- clientId,
- jsonVaue['user_id'],
- jsonVaue['device_id'],
- json.encode(jsonVaue),
- jsonVaue['verified'],
- jsonVaue['blocked']);
- }
- }
- }
- for (final entry in oldKeys.entries) {
- final key = entry.key;
- final value = entry.value;
- if (value == null || value.isEmpty) {
- continue;
- }
- // olm_sessions
- final olmSessionsMatch =
- RegExp(r'^\/clients\/([^\/]+)\/olm-sessions$').firstMatch(key);
- if (olmSessionsMatch != null) {
- if (olmSessionsMatch[1] != credentials['deviceID']) {
- continue;
- }
- debugPrint('[Store] migrating olm sessions...');
- final identityKey = json.decode(value);
- for (final olmKey in identityKey.entries) {
- final identKey = olmKey.key;
- final sessions = olmKey.value;
- for (final pickle in sessions) {
- var sess = olm.Session();
- sess.unpickle(credentials['userID'], pickle);
- await db.storeOlmSession(
- clientId, identKey, sess.session_id(), pickle, null);
- sess?.free();
- }
- }
- }
- // outbound_group_sessions
- final outboundGroupSessionsMatch = RegExp(
- r'^\/clients\/([^\/]+)\/rooms\/([^\/]+)\/outbound_group_session$')
- .firstMatch(key);
- if (outboundGroupSessionsMatch != null) {
- if (outboundGroupSessionsMatch[1] != credentials['deviceID']) {
- continue;
- }
- final pickle = value;
- final roomId = outboundGroupSessionsMatch[2];
- debugPrint(
- '[Store] Migrating outbound group sessions for room ${roomId}...');
- final devicesString = oldKeys[
- '/clients/${outboundGroupSessionsMatch[1]}/rooms/${roomId}/outbound_group_session_devices'];
- var devices = [];
- if (devicesString != null) {
- devices = List.from(json.decode(devicesString));
- }
- await db.storeOutboundGroupSession(
- clientId,
- roomId,
- pickle,
- json.encode(devices),
- DateTime.now().millisecondsSinceEpoch,
- 0,
- );
- }
- // session_keys
- final sessionKeysMatch =
- RegExp(r'^\/clients\/([^\/]+)\/rooms\/([^\/]+)\/session_keys$')
- .firstMatch(key);
- if (sessionKeysMatch != null) {
- if (sessionKeysMatch[1] != credentials['deviceID']) {
- continue;
- }
- final roomId = sessionKeysMatch[2];
- debugPrint('[Store] Migrating session keys for room ${roomId}...');
- final map = json.decode(value);
- for (final entry in map.entries) {
- await db.storeInboundGroupSession(
- clientId,
- roomId,
- entry.key,
- entry.value['inboundGroupSession'],
- json.encode(entry.value['content']),
- json.encode(entry.value['indexes']),
- null,
- null);
- }
- }
- }
- });
-}
-
-// see https://github.com/mogol/flutter_secure_storage/issues/161#issuecomment-704578453
-class AsyncMutex {
- Completer _completer;
-
- Future lock() async {
- while (_completer != null) {
- await _completer.future;
- }
-
- _completer = Completer();
- }
-
- void unlock() {
- assert(_completer != null);
- final completer = _completer;
- _completer = null;
- completer.complete();
- }
-}
-
class Store {
- final LocalStorage storage;
+ LocalStorage storage;
final FlutterSecureStorage secureStorage;
- static final _mutex = AsyncMutex();
Store()
- : storage = LocalStorage('LocalStorage'),
- secureStorage = PlatformInfos.isMobile ? FlutterSecureStorage() : null;
+ : secureStorage = PlatformInfos.isMobile ? FlutterSecureStorage() : null;
- Future getItem(String key) async {
- if (!PlatformInfos.isMobile) {
+ Future _setupLocalStorage() async {
+ if (storage == null) {
+ final directory = PlatformInfos.isBetaDesktop
+ ? await getApplicationSupportDirectory()
+ : (PlatformInfos.isWeb
+ ? null
+ : await getApplicationDocumentsDirectory());
+ storage = LocalStorage('LocalStorage', directory?.path);
await storage.ready;
+ }
+ }
+
+ Future getItem(String key) async {
+ if (!PlatformInfos.isMobile) {
+ await _setupLocalStorage();
try {
- return await storage.getItem(key);
+ return await storage.getItem(key)?.toString();
} catch (_) {
return null;
}
}
try {
- await _mutex.lock();
return await secureStorage.read(key: key);
} catch (_) {
return null;
- } finally {
- _mutex.unlock();
}
}
Future setItem(String key, String value) async {
if (!PlatformInfos.isMobile) {
- await storage.ready;
+ await _setupLocalStorage();
return await storage.setItem(key, value);
}
- if (value == null) {
- return await secureStorage.delete(key: key);
- } else {
- try {
- await _mutex.lock();
- return await secureStorage.write(key: key, value: value);
- } finally {
- _mutex.unlock();
- }
- }
+ return await secureStorage.write(key: key, value: value);
}
- Future