Merge branch 'main' of https://git.extera.xyz/OfficialDakari/ExteraNext
This commit is contained in:
commit
165d222726
|
|
@ -6,6 +6,11 @@
|
|||
"longPressToRecordVoiceMessage": "Long press to record voice message.",
|
||||
"pause": "Pause",
|
||||
"resume": "Resume",
|
||||
"newSubSpace": "New sub space",
|
||||
"moveToDifferentSpace": "Move to different space",
|
||||
"moveUp": "Move up",
|
||||
"moveDown": "Move down",
|
||||
"removeFromSpaceDescription": "The chat will be removed from the space but still appear in your chat list.",
|
||||
"endPoll": "End poll",
|
||||
"anonymousPoll": "Anonymous",
|
||||
"publicPoll": "Public",
|
||||
|
|
@ -16,6 +21,7 @@
|
|||
"vote": "Vote",
|
||||
"changeVote": "Re-vote",
|
||||
"choicesSelected": "{selected} of {max} selected",
|
||||
"discuss": "Discuss",
|
||||
"@choicesSelected": {
|
||||
"type": "String",
|
||||
"placeholders": {
|
||||
|
|
@ -893,6 +899,9 @@
|
|||
},
|
||||
"chatPermissions": "Chat permissions",
|
||||
"@chatPermissions": {},
|
||||
"chatThreads": "Threads",
|
||||
"@chatThreads": {},
|
||||
"chatThreadsDescription": "See all threads in this room",
|
||||
"editDisplayname": "Edit displayname",
|
||||
"@editDisplayname": {
|
||||
"type": "String",
|
||||
|
|
@ -3145,6 +3154,24 @@
|
|||
},
|
||||
"restricted": "Restricted",
|
||||
"@restricted": {},
|
||||
"spaceMemberOf": "Space member of {spaces}",
|
||||
"@spaceMemberOf": {
|
||||
"type": "String",
|
||||
"placeholders": {
|
||||
"spaces": {
|
||||
"type": "String"
|
||||
}
|
||||
}
|
||||
},
|
||||
"spaceMemberOfCanKnock": "Space member of {spaces} can knock",
|
||||
"@spaceMemberOfCanKnock": {
|
||||
"type": "String",
|
||||
"placeholders": {
|
||||
"spaces": {
|
||||
"type": "String"
|
||||
}
|
||||
}
|
||||
},
|
||||
"knockRestricted": "Knock restricted",
|
||||
"@knockRestricted": {},
|
||||
"goToSpace": "Go to space: {space}",
|
||||
|
|
|
|||
|
|
@ -6,6 +6,11 @@
|
|||
"noMessagesYet": "Нет сообщений",
|
||||
"longPressToRecordVoiceMessage": "Зажмите, чтобы записать голосовое сообщение.",
|
||||
"pause": "Пауза",
|
||||
"newSubSpace": "Новое подпространство",
|
||||
"moveToDifferentSpace": "Перенести в другое пространство",
|
||||
"moveUp": "Вверх",
|
||||
"moveDown": "Вниз",
|
||||
"removeFromSpaceDescription": "Эта комната будет удалена из пространства, но останется в Вашем списке чатов.",
|
||||
"resume": "Продолжить",
|
||||
"anonymousPoll": "Анонимный",
|
||||
"publicPoll": "Открытый",
|
||||
|
|
@ -16,6 +21,7 @@
|
|||
"vote": "Голосовать",
|
||||
"changeVote": "Изменить ответ",
|
||||
"choicesSelected": "Выбрано {selected} из {max}",
|
||||
"discuss": "Обсудить",
|
||||
"@choicesSelected": {
|
||||
"type": "String",
|
||||
"placeholders": {
|
||||
|
|
@ -41,7 +47,7 @@
|
|||
"type": "String",
|
||||
"placeholders": {}
|
||||
},
|
||||
"cleanExifDescription": "Удалять метаданные EXIF (модель камеры, геолокация, время) из изображений еред отправкой.",
|
||||
"cleanExifDescription": "Удалять метаданные EXIF (модель камеры, геолокация, время) из изображений перед отправкой.",
|
||||
"@cleanExifDescription": {
|
||||
"type": "String",
|
||||
"placeholders": {}
|
||||
|
|
@ -892,6 +898,9 @@
|
|||
},
|
||||
"chatPermissions": "Права в чате",
|
||||
"@chatPermissions": {},
|
||||
"chatThreads": "Обсуждения",
|
||||
"@chatThreads": {},
|
||||
"chatThreadsDescription": "Список всех обсуждений в этой комнате",
|
||||
"editDisplayname": "Отображаемое имя",
|
||||
"@editDisplayname": {
|
||||
"type": "String",
|
||||
|
|
@ -936,7 +945,7 @@
|
|||
"@globalChatId": {},
|
||||
"accessAndVisibility": "Доступность и видимость",
|
||||
"@accessAndVisibility": {},
|
||||
"accessAndVisibilityDescription": "Кто может зайти и как найти этот чат.",
|
||||
"accessAndVisibilityDescription": "Кто может зайти и как найти этот чат",
|
||||
"@accessAndVisibilityDescription": {},
|
||||
"calls": "Звонки",
|
||||
"@calls": {},
|
||||
|
|
@ -3145,6 +3154,25 @@
|
|||
"space": {}
|
||||
},
|
||||
"markAsUnread": "Отметить как непрочитанное",
|
||||
|
||||
"spaceMemberOf": "Участники пространства {spaces}",
|
||||
"@spaceMemberOf": {
|
||||
"type": "String",
|
||||
"placeholders": {
|
||||
"spaces": {
|
||||
"type": "String"
|
||||
}
|
||||
}
|
||||
},
|
||||
"spaceMemberOfCanKnock": "Участники пространства {spaces} (по запросу)",
|
||||
"@spaceMemberOfCanKnock": {
|
||||
"type": "String",
|
||||
"placeholders": {
|
||||
"spaces": {
|
||||
"type": "String"
|
||||
}
|
||||
}
|
||||
},
|
||||
"userLevel": "{level} - Пользователь",
|
||||
"@userLevel": {
|
||||
"type": "String",
|
||||
|
|
|
|||
|
|
@ -5,5 +5,4 @@ output-class: L10n
|
|||
preferred-supported-locales: ["en"]
|
||||
use-deferred-loading: true
|
||||
nullable-getter: false
|
||||
synthetic-package: false
|
||||
output-dir: lib/generated/l10n
|
||||
|
|
@ -15,6 +15,8 @@ abstract class AppConfig {
|
|||
static bool enableGradient = true;
|
||||
static bool cleanExif = true;
|
||||
|
||||
|
||||
static String? httpProxy;
|
||||
static String get defaultHomeserver => _defaultHomeserver;
|
||||
static double fontSizeFactor = 1;
|
||||
static const Color chatColor = primaryColor;
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
import 'dart:async';
|
||||
|
||||
import 'package:extera_next/pages/chat_thread/thread.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
import 'package:go_router/go_router.dart';
|
||||
|
|
@ -148,6 +149,27 @@ abstract class AppRoutes {
|
|||
),
|
||||
),
|
||||
redirect: loggedOutRedirect,
|
||||
routes: [
|
||||
GoRoute(
|
||||
path: 'threads',
|
||||
redirect: loggedOutRedirect,
|
||||
routes: [
|
||||
GoRoute(
|
||||
path: ':threadroot',
|
||||
pageBuilder: (context, state) => defaultPageBuilder(
|
||||
context,
|
||||
state,
|
||||
ThreadPage(
|
||||
roomId: state.pathParameters['roomid']!,
|
||||
threadRootEventId:
|
||||
state.pathParameters['threadroot']!,
|
||||
eventId: state.uri.queryParameters['event'],
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
redirect: loggedOutRedirect,
|
||||
|
|
@ -347,11 +369,31 @@ abstract class AppRoutes {
|
|||
roomId: state.pathParameters['roomid']!,
|
||||
shareItems: shareItems,
|
||||
eventId: state.uri.queryParameters['event'],
|
||||
showThreadRoots: state.uri.queryParameters['threads'] == 'true',
|
||||
),
|
||||
);
|
||||
},
|
||||
redirect: loggedOutRedirect,
|
||||
routes: [
|
||||
GoRoute(
|
||||
path: 'threads',
|
||||
redirect: loggedOutRedirect,
|
||||
routes: [
|
||||
GoRoute(
|
||||
path: ':threadroot',
|
||||
pageBuilder: (context, state) => defaultPageBuilder(
|
||||
context,
|
||||
state,
|
||||
ThreadPage(
|
||||
roomId: state.pathParameters['roomid']!,
|
||||
threadRootEventId:
|
||||
state.pathParameters['threadroot']!,
|
||||
eventId: state.uri.queryParameters['event'],
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
GoRoute(
|
||||
path: 'search',
|
||||
pageBuilder: (context, state) => defaultPageBuilder(
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
import 'package:shared_preferences/shared_preferences.dart';
|
||||
|
||||
abstract class SettingKeys {
|
||||
static const String httpProxy = 'xyz.extera.next.httpProxy';
|
||||
static const String cleanExif = 'xyz.extera.next.cleanExif';
|
||||
static const String displayNavigationRail = 'chat.fluffy.displayNavigationRail';
|
||||
static const String hideAvatarsInInvites = 'xyz.extera.next.hideAvatarsInInvites';
|
||||
|
|
|
|||
|
|
@ -223,6 +223,36 @@ abstract class L10n {
|
|||
/// **'Resume'**
|
||||
String get resume;
|
||||
|
||||
/// No description provided for @newSubSpace.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'New sub space'**
|
||||
String get newSubSpace;
|
||||
|
||||
/// No description provided for @moveToDifferentSpace.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Move to different space'**
|
||||
String get moveToDifferentSpace;
|
||||
|
||||
/// No description provided for @moveUp.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Move up'**
|
||||
String get moveUp;
|
||||
|
||||
/// No description provided for @moveDown.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Move down'**
|
||||
String get moveDown;
|
||||
|
||||
/// No description provided for @removeFromSpaceDescription.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'The chat will be removed from the space but still appear in your chat list.'**
|
||||
String get removeFromSpaceDescription;
|
||||
|
||||
/// No description provided for @endPoll.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
|
|
@ -283,6 +313,12 @@ abstract class L10n {
|
|||
/// **'{selected} of {max} selected'**
|
||||
String choicesSelected(int selected, int max);
|
||||
|
||||
/// No description provided for @discuss.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Discuss'**
|
||||
String get discuss;
|
||||
|
||||
/// No description provided for @pollType.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
|
|
@ -1311,6 +1347,18 @@ abstract class L10n {
|
|||
/// **'Chat permissions'**
|
||||
String get chatPermissions;
|
||||
|
||||
/// No description provided for @chatThreads.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Threads'**
|
||||
String get chatThreads;
|
||||
|
||||
/// No description provided for @chatThreadsDescription.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'See all threads in this room'**
|
||||
String get chatThreadsDescription;
|
||||
|
||||
/// No description provided for @editDisplayname.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
|
|
@ -4353,6 +4401,18 @@ abstract class L10n {
|
|||
/// **'Restricted'**
|
||||
String get restricted;
|
||||
|
||||
/// No description provided for @spaceMemberOf.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Space member of {spaces}'**
|
||||
String spaceMemberOf(String spaces);
|
||||
|
||||
/// No description provided for @spaceMemberOfCanKnock.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
/// **'Space member of {spaces} can knock'**
|
||||
String spaceMemberOfCanKnock(String spaces);
|
||||
|
||||
/// No description provided for @knockRestricted.
|
||||
///
|
||||
/// In en, this message translates to:
|
||||
|
|
|
|||
|
|
@ -24,6 +24,22 @@ class L10nAr extends L10n {
|
|||
@override
|
||||
String get resume => 'Resume';
|
||||
|
||||
@override
|
||||
String get newSubSpace => 'New sub space';
|
||||
|
||||
@override
|
||||
String get moveToDifferentSpace => 'Move to different space';
|
||||
|
||||
@override
|
||||
String get moveUp => 'Move up';
|
||||
|
||||
@override
|
||||
String get moveDown => 'Move down';
|
||||
|
||||
@override
|
||||
String get removeFromSpaceDescription =>
|
||||
'The chat will be removed from the space but still appear in your chat list.';
|
||||
|
||||
@override
|
||||
String get endPoll => 'End poll';
|
||||
|
||||
|
|
@ -56,6 +72,9 @@ class L10nAr extends L10n {
|
|||
return '$selected of $max selected';
|
||||
}
|
||||
|
||||
@override
|
||||
String get discuss => 'Discuss';
|
||||
|
||||
@override
|
||||
String get pollType => 'Poll type';
|
||||
|
||||
|
|
@ -656,6 +675,12 @@ class L10nAr extends L10n {
|
|||
@override
|
||||
String get chatPermissions => 'صلاحيات المحادثة';
|
||||
|
||||
@override
|
||||
String get chatThreads => 'Threads';
|
||||
|
||||
@override
|
||||
String get chatThreadsDescription => 'See all threads in this room';
|
||||
|
||||
@override
|
||||
String get editDisplayname => 'حرر الاسم العلني';
|
||||
|
||||
|
|
@ -2406,6 +2431,16 @@ class L10nAr extends L10n {
|
|||
@override
|
||||
String get restricted => 'مقيد';
|
||||
|
||||
@override
|
||||
String spaceMemberOf(String spaces) {
|
||||
return 'Space member of $spaces';
|
||||
}
|
||||
|
||||
@override
|
||||
String spaceMemberOfCanKnock(String spaces) {
|
||||
return 'Space member of $spaces can knock';
|
||||
}
|
||||
|
||||
@override
|
||||
String get knockRestricted => 'قيود النقر';
|
||||
|
||||
|
|
|
|||
|
|
@ -24,6 +24,22 @@ class L10nBe extends L10n {
|
|||
@override
|
||||
String get resume => 'Resume';
|
||||
|
||||
@override
|
||||
String get newSubSpace => 'New sub space';
|
||||
|
||||
@override
|
||||
String get moveToDifferentSpace => 'Move to different space';
|
||||
|
||||
@override
|
||||
String get moveUp => 'Move up';
|
||||
|
||||
@override
|
||||
String get moveDown => 'Move down';
|
||||
|
||||
@override
|
||||
String get removeFromSpaceDescription =>
|
||||
'The chat will be removed from the space but still appear in your chat list.';
|
||||
|
||||
@override
|
||||
String get endPoll => 'End poll';
|
||||
|
||||
|
|
@ -56,6 +72,9 @@ class L10nBe extends L10n {
|
|||
return '$selected of $max selected';
|
||||
}
|
||||
|
||||
@override
|
||||
String get discuss => 'Discuss';
|
||||
|
||||
@override
|
||||
String get pollType => 'Poll type';
|
||||
|
||||
|
|
@ -660,6 +679,12 @@ class L10nBe extends L10n {
|
|||
@override
|
||||
String get chatPermissions => 'Chat permissions';
|
||||
|
||||
@override
|
||||
String get chatThreads => 'Threads';
|
||||
|
||||
@override
|
||||
String get chatThreadsDescription => 'See all threads in this room';
|
||||
|
||||
@override
|
||||
String get editDisplayname => 'Edit displayname';
|
||||
|
||||
|
|
@ -2421,6 +2446,16 @@ class L10nBe extends L10n {
|
|||
@override
|
||||
String get restricted => 'Restricted';
|
||||
|
||||
@override
|
||||
String spaceMemberOf(String spaces) {
|
||||
return 'Space member of $spaces';
|
||||
}
|
||||
|
||||
@override
|
||||
String spaceMemberOfCanKnock(String spaces) {
|
||||
return 'Space member of $spaces can knock';
|
||||
}
|
||||
|
||||
@override
|
||||
String get knockRestricted => 'Knock restricted';
|
||||
|
||||
|
|
|
|||
|
|
@ -24,6 +24,22 @@ class L10nBn extends L10n {
|
|||
@override
|
||||
String get resume => 'Resume';
|
||||
|
||||
@override
|
||||
String get newSubSpace => 'New sub space';
|
||||
|
||||
@override
|
||||
String get moveToDifferentSpace => 'Move to different space';
|
||||
|
||||
@override
|
||||
String get moveUp => 'Move up';
|
||||
|
||||
@override
|
||||
String get moveDown => 'Move down';
|
||||
|
||||
@override
|
||||
String get removeFromSpaceDescription =>
|
||||
'The chat will be removed from the space but still appear in your chat list.';
|
||||
|
||||
@override
|
||||
String get endPoll => 'End poll';
|
||||
|
||||
|
|
@ -56,6 +72,9 @@ class L10nBn extends L10n {
|
|||
return '$selected of $max selected';
|
||||
}
|
||||
|
||||
@override
|
||||
String get discuss => 'Discuss';
|
||||
|
||||
@override
|
||||
String get pollType => 'Poll type';
|
||||
|
||||
|
|
@ -660,6 +679,12 @@ class L10nBn extends L10n {
|
|||
@override
|
||||
String get chatPermissions => 'Chat permissions';
|
||||
|
||||
@override
|
||||
String get chatThreads => 'Threads';
|
||||
|
||||
@override
|
||||
String get chatThreadsDescription => 'See all threads in this room';
|
||||
|
||||
@override
|
||||
String get editDisplayname => 'Edit displayname';
|
||||
|
||||
|
|
@ -2421,6 +2446,16 @@ class L10nBn extends L10n {
|
|||
@override
|
||||
String get restricted => 'Restricted';
|
||||
|
||||
@override
|
||||
String spaceMemberOf(String spaces) {
|
||||
return 'Space member of $spaces';
|
||||
}
|
||||
|
||||
@override
|
||||
String spaceMemberOfCanKnock(String spaces) {
|
||||
return 'Space member of $spaces can knock';
|
||||
}
|
||||
|
||||
@override
|
||||
String get knockRestricted => 'Knock restricted';
|
||||
|
||||
|
|
|
|||
|
|
@ -24,6 +24,22 @@ class L10nBo extends L10n {
|
|||
@override
|
||||
String get resume => 'Resume';
|
||||
|
||||
@override
|
||||
String get newSubSpace => 'New sub space';
|
||||
|
||||
@override
|
||||
String get moveToDifferentSpace => 'Move to different space';
|
||||
|
||||
@override
|
||||
String get moveUp => 'Move up';
|
||||
|
||||
@override
|
||||
String get moveDown => 'Move down';
|
||||
|
||||
@override
|
||||
String get removeFromSpaceDescription =>
|
||||
'The chat will be removed from the space but still appear in your chat list.';
|
||||
|
||||
@override
|
||||
String get endPoll => 'End poll';
|
||||
|
||||
|
|
@ -56,6 +72,9 @@ class L10nBo extends L10n {
|
|||
return '$selected of $max selected';
|
||||
}
|
||||
|
||||
@override
|
||||
String get discuss => 'Discuss';
|
||||
|
||||
@override
|
||||
String get pollType => 'Poll type';
|
||||
|
||||
|
|
@ -660,6 +679,12 @@ class L10nBo extends L10n {
|
|||
@override
|
||||
String get chatPermissions => 'Chat permissions';
|
||||
|
||||
@override
|
||||
String get chatThreads => 'Threads';
|
||||
|
||||
@override
|
||||
String get chatThreadsDescription => 'See all threads in this room';
|
||||
|
||||
@override
|
||||
String get editDisplayname => 'Edit displayname';
|
||||
|
||||
|
|
@ -2421,6 +2446,16 @@ class L10nBo extends L10n {
|
|||
@override
|
||||
String get restricted => 'Restricted';
|
||||
|
||||
@override
|
||||
String spaceMemberOf(String spaces) {
|
||||
return 'Space member of $spaces';
|
||||
}
|
||||
|
||||
@override
|
||||
String spaceMemberOfCanKnock(String spaces) {
|
||||
return 'Space member of $spaces can knock';
|
||||
}
|
||||
|
||||
@override
|
||||
String get knockRestricted => 'Knock restricted';
|
||||
|
||||
|
|
|
|||
|
|
@ -24,6 +24,22 @@ class L10nCa extends L10n {
|
|||
@override
|
||||
String get resume => 'Resume';
|
||||
|
||||
@override
|
||||
String get newSubSpace => 'New sub space';
|
||||
|
||||
@override
|
||||
String get moveToDifferentSpace => 'Move to different space';
|
||||
|
||||
@override
|
||||
String get moveUp => 'Move up';
|
||||
|
||||
@override
|
||||
String get moveDown => 'Move down';
|
||||
|
||||
@override
|
||||
String get removeFromSpaceDescription =>
|
||||
'The chat will be removed from the space but still appear in your chat list.';
|
||||
|
||||
@override
|
||||
String get endPoll => 'End poll';
|
||||
|
||||
|
|
@ -56,6 +72,9 @@ class L10nCa extends L10n {
|
|||
return '$selected of $max selected';
|
||||
}
|
||||
|
||||
@override
|
||||
String get discuss => 'Discuss';
|
||||
|
||||
@override
|
||||
String get pollType => 'Poll type';
|
||||
|
||||
|
|
@ -665,6 +684,12 @@ class L10nCa extends L10n {
|
|||
@override
|
||||
String get chatPermissions => 'Permisos del xat';
|
||||
|
||||
@override
|
||||
String get chatThreads => 'Threads';
|
||||
|
||||
@override
|
||||
String get chatThreadsDescription => 'See all threads in this room';
|
||||
|
||||
@override
|
||||
String get editDisplayname => 'Edita l\'àlies';
|
||||
|
||||
|
|
@ -2445,6 +2470,16 @@ class L10nCa extends L10n {
|
|||
@override
|
||||
String get restricted => 'Restringit';
|
||||
|
||||
@override
|
||||
String spaceMemberOf(String spaces) {
|
||||
return 'Space member of $spaces';
|
||||
}
|
||||
|
||||
@override
|
||||
String spaceMemberOfCanKnock(String spaces) {
|
||||
return 'Space member of $spaces can knock';
|
||||
}
|
||||
|
||||
@override
|
||||
String get knockRestricted => 'No es pot picar a la porta';
|
||||
|
||||
|
|
|
|||
|
|
@ -24,6 +24,22 @@ class L10nCs extends L10n {
|
|||
@override
|
||||
String get resume => 'Resume';
|
||||
|
||||
@override
|
||||
String get newSubSpace => 'New sub space';
|
||||
|
||||
@override
|
||||
String get moveToDifferentSpace => 'Move to different space';
|
||||
|
||||
@override
|
||||
String get moveUp => 'Move up';
|
||||
|
||||
@override
|
||||
String get moveDown => 'Move down';
|
||||
|
||||
@override
|
||||
String get removeFromSpaceDescription =>
|
||||
'The chat will be removed from the space but still appear in your chat list.';
|
||||
|
||||
@override
|
||||
String get endPoll => 'End poll';
|
||||
|
||||
|
|
@ -56,6 +72,9 @@ class L10nCs extends L10n {
|
|||
return '$selected of $max selected';
|
||||
}
|
||||
|
||||
@override
|
||||
String get discuss => 'Discuss';
|
||||
|
||||
@override
|
||||
String get pollType => 'Poll type';
|
||||
|
||||
|
|
@ -664,6 +683,12 @@ class L10nCs extends L10n {
|
|||
@override
|
||||
String get chatPermissions => 'Oprávnění konverzace';
|
||||
|
||||
@override
|
||||
String get chatThreads => 'Threads';
|
||||
|
||||
@override
|
||||
String get chatThreadsDescription => 'See all threads in this room';
|
||||
|
||||
@override
|
||||
String get editDisplayname => 'Změnit přezdívku';
|
||||
|
||||
|
|
@ -2425,6 +2450,16 @@ class L10nCs extends L10n {
|
|||
@override
|
||||
String get restricted => 'Restricted';
|
||||
|
||||
@override
|
||||
String spaceMemberOf(String spaces) {
|
||||
return 'Space member of $spaces';
|
||||
}
|
||||
|
||||
@override
|
||||
String spaceMemberOfCanKnock(String spaces) {
|
||||
return 'Space member of $spaces can knock';
|
||||
}
|
||||
|
||||
@override
|
||||
String get knockRestricted => 'Knock restricted';
|
||||
|
||||
|
|
|
|||
|
|
@ -24,6 +24,22 @@ class L10nDe extends L10n {
|
|||
@override
|
||||
String get resume => 'Resume';
|
||||
|
||||
@override
|
||||
String get newSubSpace => 'New sub space';
|
||||
|
||||
@override
|
||||
String get moveToDifferentSpace => 'Move to different space';
|
||||
|
||||
@override
|
||||
String get moveUp => 'Move up';
|
||||
|
||||
@override
|
||||
String get moveDown => 'Move down';
|
||||
|
||||
@override
|
||||
String get removeFromSpaceDescription =>
|
||||
'The chat will be removed from the space but still appear in your chat list.';
|
||||
|
||||
@override
|
||||
String get endPoll => 'End poll';
|
||||
|
||||
|
|
@ -56,6 +72,9 @@ class L10nDe extends L10n {
|
|||
return '$selected of $max selected';
|
||||
}
|
||||
|
||||
@override
|
||||
String get discuss => 'Discuss';
|
||||
|
||||
@override
|
||||
String get pollType => 'Poll type';
|
||||
|
||||
|
|
@ -666,6 +685,12 @@ class L10nDe extends L10n {
|
|||
@override
|
||||
String get chatPermissions => 'Chatberechtigungen';
|
||||
|
||||
@override
|
||||
String get chatThreads => 'Threads';
|
||||
|
||||
@override
|
||||
String get chatThreadsDescription => 'See all threads in this room';
|
||||
|
||||
@override
|
||||
String get editDisplayname => 'Anzeigename ändern';
|
||||
|
||||
|
|
@ -2440,6 +2465,16 @@ class L10nDe extends L10n {
|
|||
@override
|
||||
String get restricted => 'Beschränkt';
|
||||
|
||||
@override
|
||||
String spaceMemberOf(String spaces) {
|
||||
return 'Space member of $spaces';
|
||||
}
|
||||
|
||||
@override
|
||||
String spaceMemberOfCanKnock(String spaces) {
|
||||
return 'Space member of $spaces can knock';
|
||||
}
|
||||
|
||||
@override
|
||||
String get knockRestricted => 'Anklopfen beschränkt';
|
||||
|
||||
|
|
|
|||
|
|
@ -24,6 +24,22 @@ class L10nEl extends L10n {
|
|||
@override
|
||||
String get resume => 'Resume';
|
||||
|
||||
@override
|
||||
String get newSubSpace => 'New sub space';
|
||||
|
||||
@override
|
||||
String get moveToDifferentSpace => 'Move to different space';
|
||||
|
||||
@override
|
||||
String get moveUp => 'Move up';
|
||||
|
||||
@override
|
||||
String get moveDown => 'Move down';
|
||||
|
||||
@override
|
||||
String get removeFromSpaceDescription =>
|
||||
'The chat will be removed from the space but still appear in your chat list.';
|
||||
|
||||
@override
|
||||
String get endPoll => 'End poll';
|
||||
|
||||
|
|
@ -56,6 +72,9 @@ class L10nEl extends L10n {
|
|||
return '$selected of $max selected';
|
||||
}
|
||||
|
||||
@override
|
||||
String get discuss => 'Discuss';
|
||||
|
||||
@override
|
||||
String get pollType => 'Poll type';
|
||||
|
||||
|
|
@ -661,6 +680,12 @@ class L10nEl extends L10n {
|
|||
@override
|
||||
String get chatPermissions => 'Chat permissions';
|
||||
|
||||
@override
|
||||
String get chatThreads => 'Threads';
|
||||
|
||||
@override
|
||||
String get chatThreadsDescription => 'See all threads in this room';
|
||||
|
||||
@override
|
||||
String get editDisplayname => 'Edit displayname';
|
||||
|
||||
|
|
@ -2422,6 +2447,16 @@ class L10nEl extends L10n {
|
|||
@override
|
||||
String get restricted => 'Restricted';
|
||||
|
||||
@override
|
||||
String spaceMemberOf(String spaces) {
|
||||
return 'Space member of $spaces';
|
||||
}
|
||||
|
||||
@override
|
||||
String spaceMemberOfCanKnock(String spaces) {
|
||||
return 'Space member of $spaces can knock';
|
||||
}
|
||||
|
||||
@override
|
||||
String get knockRestricted => 'Knock restricted';
|
||||
|
||||
|
|
|
|||
|
|
@ -24,6 +24,22 @@ class L10nEn extends L10n {
|
|||
@override
|
||||
String get resume => 'Resume';
|
||||
|
||||
@override
|
||||
String get newSubSpace => 'New sub space';
|
||||
|
||||
@override
|
||||
String get moveToDifferentSpace => 'Move to different space';
|
||||
|
||||
@override
|
||||
String get moveUp => 'Move up';
|
||||
|
||||
@override
|
||||
String get moveDown => 'Move down';
|
||||
|
||||
@override
|
||||
String get removeFromSpaceDescription =>
|
||||
'The chat will be removed from the space but still appear in your chat list.';
|
||||
|
||||
@override
|
||||
String get endPoll => 'End poll';
|
||||
|
||||
|
|
@ -56,6 +72,9 @@ class L10nEn extends L10n {
|
|||
return '$selected of $max selected';
|
||||
}
|
||||
|
||||
@override
|
||||
String get discuss => 'Discuss';
|
||||
|
||||
@override
|
||||
String get pollType => 'Poll type';
|
||||
|
||||
|
|
@ -660,6 +679,12 @@ class L10nEn extends L10n {
|
|||
@override
|
||||
String get chatPermissions => 'Chat permissions';
|
||||
|
||||
@override
|
||||
String get chatThreads => 'Threads';
|
||||
|
||||
@override
|
||||
String get chatThreadsDescription => 'See all threads in this room';
|
||||
|
||||
@override
|
||||
String get editDisplayname => 'Edit displayname';
|
||||
|
||||
|
|
@ -2421,6 +2446,16 @@ class L10nEn extends L10n {
|
|||
@override
|
||||
String get restricted => 'Restricted';
|
||||
|
||||
@override
|
||||
String spaceMemberOf(String spaces) {
|
||||
return 'Space member of $spaces';
|
||||
}
|
||||
|
||||
@override
|
||||
String spaceMemberOfCanKnock(String spaces) {
|
||||
return 'Space member of $spaces can knock';
|
||||
}
|
||||
|
||||
@override
|
||||
String get knockRestricted => 'Knock restricted';
|
||||
|
||||
|
|
|
|||
|
|
@ -24,6 +24,22 @@ class L10nEo extends L10n {
|
|||
@override
|
||||
String get resume => 'Resume';
|
||||
|
||||
@override
|
||||
String get newSubSpace => 'New sub space';
|
||||
|
||||
@override
|
||||
String get moveToDifferentSpace => 'Move to different space';
|
||||
|
||||
@override
|
||||
String get moveUp => 'Move up';
|
||||
|
||||
@override
|
||||
String get moveDown => 'Move down';
|
||||
|
||||
@override
|
||||
String get removeFromSpaceDescription =>
|
||||
'The chat will be removed from the space but still appear in your chat list.';
|
||||
|
||||
@override
|
||||
String get endPoll => 'End poll';
|
||||
|
||||
|
|
@ -56,6 +72,9 @@ class L10nEo extends L10n {
|
|||
return '$selected of $max selected';
|
||||
}
|
||||
|
||||
@override
|
||||
String get discuss => 'Discuss';
|
||||
|
||||
@override
|
||||
String get pollType => 'Poll type';
|
||||
|
||||
|
|
@ -663,6 +682,12 @@ class L10nEo extends L10n {
|
|||
@override
|
||||
String get chatPermissions => 'Chat permissions';
|
||||
|
||||
@override
|
||||
String get chatThreads => 'Threads';
|
||||
|
||||
@override
|
||||
String get chatThreadsDescription => 'See all threads in this room';
|
||||
|
||||
@override
|
||||
String get editDisplayname => 'Redakti prezentan nomon';
|
||||
|
||||
|
|
@ -2428,6 +2453,16 @@ class L10nEo extends L10n {
|
|||
@override
|
||||
String get restricted => 'Restricted';
|
||||
|
||||
@override
|
||||
String spaceMemberOf(String spaces) {
|
||||
return 'Space member of $spaces';
|
||||
}
|
||||
|
||||
@override
|
||||
String spaceMemberOfCanKnock(String spaces) {
|
||||
return 'Space member of $spaces can knock';
|
||||
}
|
||||
|
||||
@override
|
||||
String get knockRestricted => 'Knock restricted';
|
||||
|
||||
|
|
|
|||
|
|
@ -24,6 +24,22 @@ class L10nEs extends L10n {
|
|||
@override
|
||||
String get resume => 'Resume';
|
||||
|
||||
@override
|
||||
String get newSubSpace => 'New sub space';
|
||||
|
||||
@override
|
||||
String get moveToDifferentSpace => 'Move to different space';
|
||||
|
||||
@override
|
||||
String get moveUp => 'Move up';
|
||||
|
||||
@override
|
||||
String get moveDown => 'Move down';
|
||||
|
||||
@override
|
||||
String get removeFromSpaceDescription =>
|
||||
'The chat will be removed from the space but still appear in your chat list.';
|
||||
|
||||
@override
|
||||
String get endPoll => 'End poll';
|
||||
|
||||
|
|
@ -56,6 +72,9 @@ class L10nEs extends L10n {
|
|||
return '$selected of $max selected';
|
||||
}
|
||||
|
||||
@override
|
||||
String get discuss => 'Discuss';
|
||||
|
||||
@override
|
||||
String get pollType => 'Poll type';
|
||||
|
||||
|
|
@ -664,6 +683,12 @@ class L10nEs extends L10n {
|
|||
@override
|
||||
String get chatPermissions => 'Permisos del chat';
|
||||
|
||||
@override
|
||||
String get chatThreads => 'Threads';
|
||||
|
||||
@override
|
||||
String get chatThreadsDescription => 'See all threads in this room';
|
||||
|
||||
@override
|
||||
String get editDisplayname => 'Editar nombre visible';
|
||||
|
||||
|
|
@ -2444,6 +2469,16 @@ class L10nEs extends L10n {
|
|||
@override
|
||||
String get restricted => 'Restringido';
|
||||
|
||||
@override
|
||||
String spaceMemberOf(String spaces) {
|
||||
return 'Space member of $spaces';
|
||||
}
|
||||
|
||||
@override
|
||||
String spaceMemberOfCanKnock(String spaces) {
|
||||
return 'Space member of $spaces can knock';
|
||||
}
|
||||
|
||||
@override
|
||||
String get knockRestricted => 'Aviso restringido';
|
||||
|
||||
|
|
|
|||
|
|
@ -24,6 +24,22 @@ class L10nEt extends L10n {
|
|||
@override
|
||||
String get resume => 'Resume';
|
||||
|
||||
@override
|
||||
String get newSubSpace => 'New sub space';
|
||||
|
||||
@override
|
||||
String get moveToDifferentSpace => 'Move to different space';
|
||||
|
||||
@override
|
||||
String get moveUp => 'Move up';
|
||||
|
||||
@override
|
||||
String get moveDown => 'Move down';
|
||||
|
||||
@override
|
||||
String get removeFromSpaceDescription =>
|
||||
'The chat will be removed from the space but still appear in your chat list.';
|
||||
|
||||
@override
|
||||
String get endPoll => 'End poll';
|
||||
|
||||
|
|
@ -56,6 +72,9 @@ class L10nEt extends L10n {
|
|||
return '$selected of $max selected';
|
||||
}
|
||||
|
||||
@override
|
||||
String get discuss => 'Discuss';
|
||||
|
||||
@override
|
||||
String get pollType => 'Poll type';
|
||||
|
||||
|
|
@ -662,6 +681,12 @@ class L10nEt extends L10n {
|
|||
@override
|
||||
String get chatPermissions => 'Vestluse õigused';
|
||||
|
||||
@override
|
||||
String get chatThreads => 'Threads';
|
||||
|
||||
@override
|
||||
String get chatThreadsDescription => 'See all threads in this room';
|
||||
|
||||
@override
|
||||
String get editDisplayname => 'Muuda kuvatavat nime';
|
||||
|
||||
|
|
@ -2439,6 +2464,16 @@ class L10nEt extends L10n {
|
|||
@override
|
||||
String get restricted => 'Piiratud';
|
||||
|
||||
@override
|
||||
String spaceMemberOf(String spaces) {
|
||||
return 'Space member of $spaces';
|
||||
}
|
||||
|
||||
@override
|
||||
String spaceMemberOfCanKnock(String spaces) {
|
||||
return 'Space member of $spaces can knock';
|
||||
}
|
||||
|
||||
@override
|
||||
String get knockRestricted => 'Koputa piiratud ligipääsuga jututoa uksele';
|
||||
|
||||
|
|
|
|||
|
|
@ -24,6 +24,22 @@ class L10nEu extends L10n {
|
|||
@override
|
||||
String get resume => 'Resume';
|
||||
|
||||
@override
|
||||
String get newSubSpace => 'New sub space';
|
||||
|
||||
@override
|
||||
String get moveToDifferentSpace => 'Move to different space';
|
||||
|
||||
@override
|
||||
String get moveUp => 'Move up';
|
||||
|
||||
@override
|
||||
String get moveDown => 'Move down';
|
||||
|
||||
@override
|
||||
String get removeFromSpaceDescription =>
|
||||
'The chat will be removed from the space but still appear in your chat list.';
|
||||
|
||||
@override
|
||||
String get endPoll => 'End poll';
|
||||
|
||||
|
|
@ -56,6 +72,9 @@ class L10nEu extends L10n {
|
|||
return '$selected of $max selected';
|
||||
}
|
||||
|
||||
@override
|
||||
String get discuss => 'Discuss';
|
||||
|
||||
@override
|
||||
String get pollType => 'Poll type';
|
||||
|
||||
|
|
@ -663,6 +682,12 @@ class L10nEu extends L10n {
|
|||
@override
|
||||
String get chatPermissions => 'Txataren baimenak';
|
||||
|
||||
@override
|
||||
String get chatThreads => 'Threads';
|
||||
|
||||
@override
|
||||
String get chatThreadsDescription => 'See all threads in this room';
|
||||
|
||||
@override
|
||||
String get editDisplayname => 'Editatu ezizena';
|
||||
|
||||
|
|
@ -2431,6 +2456,16 @@ class L10nEu extends L10n {
|
|||
@override
|
||||
String get restricted => 'Mugatuta';
|
||||
|
||||
@override
|
||||
String spaceMemberOf(String spaces) {
|
||||
return 'Space member of $spaces';
|
||||
}
|
||||
|
||||
@override
|
||||
String spaceMemberOfCanKnock(String spaces) {
|
||||
return 'Space member of $spaces can knock';
|
||||
}
|
||||
|
||||
@override
|
||||
String get knockRestricted => 'Eskatu baimena sarrera mugatua duen txatean';
|
||||
|
||||
|
|
|
|||
|
|
@ -24,6 +24,22 @@ class L10nFa extends L10n {
|
|||
@override
|
||||
String get resume => 'Resume';
|
||||
|
||||
@override
|
||||
String get newSubSpace => 'New sub space';
|
||||
|
||||
@override
|
||||
String get moveToDifferentSpace => 'Move to different space';
|
||||
|
||||
@override
|
||||
String get moveUp => 'Move up';
|
||||
|
||||
@override
|
||||
String get moveDown => 'Move down';
|
||||
|
||||
@override
|
||||
String get removeFromSpaceDescription =>
|
||||
'The chat will be removed from the space but still appear in your chat list.';
|
||||
|
||||
@override
|
||||
String get endPoll => 'End poll';
|
||||
|
||||
|
|
@ -56,6 +72,9 @@ class L10nFa extends L10n {
|
|||
return '$selected of $max selected';
|
||||
}
|
||||
|
||||
@override
|
||||
String get discuss => 'Discuss';
|
||||
|
||||
@override
|
||||
String get pollType => 'Poll type';
|
||||
|
||||
|
|
@ -658,6 +677,12 @@ class L10nFa extends L10n {
|
|||
@override
|
||||
String get chatPermissions => 'Chat permissions';
|
||||
|
||||
@override
|
||||
String get chatThreads => 'Threads';
|
||||
|
||||
@override
|
||||
String get chatThreadsDescription => 'See all threads in this room';
|
||||
|
||||
@override
|
||||
String get editDisplayname => 'ویرایش نام نمایشی';
|
||||
|
||||
|
|
@ -2424,6 +2449,16 @@ class L10nFa extends L10n {
|
|||
@override
|
||||
String get restricted => 'Restricted';
|
||||
|
||||
@override
|
||||
String spaceMemberOf(String spaces) {
|
||||
return 'Space member of $spaces';
|
||||
}
|
||||
|
||||
@override
|
||||
String spaceMemberOfCanKnock(String spaces) {
|
||||
return 'Space member of $spaces can knock';
|
||||
}
|
||||
|
||||
@override
|
||||
String get knockRestricted => 'Knock restricted';
|
||||
|
||||
|
|
|
|||
|
|
@ -24,6 +24,22 @@ class L10nFi extends L10n {
|
|||
@override
|
||||
String get resume => 'Resume';
|
||||
|
||||
@override
|
||||
String get newSubSpace => 'New sub space';
|
||||
|
||||
@override
|
||||
String get moveToDifferentSpace => 'Move to different space';
|
||||
|
||||
@override
|
||||
String get moveUp => 'Move up';
|
||||
|
||||
@override
|
||||
String get moveDown => 'Move down';
|
||||
|
||||
@override
|
||||
String get removeFromSpaceDescription =>
|
||||
'The chat will be removed from the space but still appear in your chat list.';
|
||||
|
||||
@override
|
||||
String get endPoll => 'End poll';
|
||||
|
||||
|
|
@ -56,6 +72,9 @@ class L10nFi extends L10n {
|
|||
return '$selected of $max selected';
|
||||
}
|
||||
|
||||
@override
|
||||
String get discuss => 'Discuss';
|
||||
|
||||
@override
|
||||
String get pollType => 'Poll type';
|
||||
|
||||
|
|
@ -665,6 +684,12 @@ class L10nFi extends L10n {
|
|||
@override
|
||||
String get chatPermissions => 'Keskustelun oikeudet';
|
||||
|
||||
@override
|
||||
String get chatThreads => 'Threads';
|
||||
|
||||
@override
|
||||
String get chatThreadsDescription => 'See all threads in this room';
|
||||
|
||||
@override
|
||||
String get editDisplayname => 'Muokkaa näyttönimeä';
|
||||
|
||||
|
|
@ -2430,6 +2455,16 @@ class L10nFi extends L10n {
|
|||
@override
|
||||
String get restricted => 'Restricted';
|
||||
|
||||
@override
|
||||
String spaceMemberOf(String spaces) {
|
||||
return 'Space member of $spaces';
|
||||
}
|
||||
|
||||
@override
|
||||
String spaceMemberOfCanKnock(String spaces) {
|
||||
return 'Space member of $spaces can knock';
|
||||
}
|
||||
|
||||
@override
|
||||
String get knockRestricted => 'Knock restricted';
|
||||
|
||||
|
|
|
|||
|
|
@ -24,6 +24,22 @@ class L10nFil extends L10n {
|
|||
@override
|
||||
String get resume => 'Resume';
|
||||
|
||||
@override
|
||||
String get newSubSpace => 'New sub space';
|
||||
|
||||
@override
|
||||
String get moveToDifferentSpace => 'Move to different space';
|
||||
|
||||
@override
|
||||
String get moveUp => 'Move up';
|
||||
|
||||
@override
|
||||
String get moveDown => 'Move down';
|
||||
|
||||
@override
|
||||
String get removeFromSpaceDescription =>
|
||||
'The chat will be removed from the space but still appear in your chat list.';
|
||||
|
||||
@override
|
||||
String get endPoll => 'End poll';
|
||||
|
||||
|
|
@ -56,6 +72,9 @@ class L10nFil extends L10n {
|
|||
return '$selected of $max selected';
|
||||
}
|
||||
|
||||
@override
|
||||
String get discuss => 'Discuss';
|
||||
|
||||
@override
|
||||
String get pollType => 'Poll type';
|
||||
|
||||
|
|
@ -666,6 +685,12 @@ class L10nFil extends L10n {
|
|||
@override
|
||||
String get chatPermissions => 'Mga pahintulot ng chat';
|
||||
|
||||
@override
|
||||
String get chatThreads => 'Threads';
|
||||
|
||||
@override
|
||||
String get chatThreadsDescription => 'See all threads in this room';
|
||||
|
||||
@override
|
||||
String get editDisplayname => 'I-edit ang display name';
|
||||
|
||||
|
|
@ -2427,6 +2452,16 @@ class L10nFil extends L10n {
|
|||
@override
|
||||
String get restricted => 'Restricted';
|
||||
|
||||
@override
|
||||
String spaceMemberOf(String spaces) {
|
||||
return 'Space member of $spaces';
|
||||
}
|
||||
|
||||
@override
|
||||
String spaceMemberOfCanKnock(String spaces) {
|
||||
return 'Space member of $spaces can knock';
|
||||
}
|
||||
|
||||
@override
|
||||
String get knockRestricted => 'Knock restricted';
|
||||
|
||||
|
|
|
|||
|
|
@ -24,6 +24,22 @@ class L10nFr extends L10n {
|
|||
@override
|
||||
String get resume => 'Resume';
|
||||
|
||||
@override
|
||||
String get newSubSpace => 'New sub space';
|
||||
|
||||
@override
|
||||
String get moveToDifferentSpace => 'Move to different space';
|
||||
|
||||
@override
|
||||
String get moveUp => 'Move up';
|
||||
|
||||
@override
|
||||
String get moveDown => 'Move down';
|
||||
|
||||
@override
|
||||
String get removeFromSpaceDescription =>
|
||||
'The chat will be removed from the space but still appear in your chat list.';
|
||||
|
||||
@override
|
||||
String get endPoll => 'End poll';
|
||||
|
||||
|
|
@ -56,6 +72,9 @@ class L10nFr extends L10n {
|
|||
return '$selected of $max selected';
|
||||
}
|
||||
|
||||
@override
|
||||
String get discuss => 'Discuss';
|
||||
|
||||
@override
|
||||
String get pollType => 'Poll type';
|
||||
|
||||
|
|
@ -669,6 +688,12 @@ class L10nFr extends L10n {
|
|||
@override
|
||||
String get chatPermissions => 'Permissions du salon';
|
||||
|
||||
@override
|
||||
String get chatThreads => 'Threads';
|
||||
|
||||
@override
|
||||
String get chatThreadsDescription => 'See all threads in this room';
|
||||
|
||||
@override
|
||||
String get editDisplayname => 'Changer de nom d\'affichage';
|
||||
|
||||
|
|
@ -2465,6 +2490,16 @@ class L10nFr extends L10n {
|
|||
@override
|
||||
String get restricted => 'Limité';
|
||||
|
||||
@override
|
||||
String spaceMemberOf(String spaces) {
|
||||
return 'Space member of $spaces';
|
||||
}
|
||||
|
||||
@override
|
||||
String spaceMemberOfCanKnock(String spaces) {
|
||||
return 'Space member of $spaces can knock';
|
||||
}
|
||||
|
||||
@override
|
||||
String get knockRestricted => 'Frapper à la porte limité';
|
||||
|
||||
|
|
|
|||
|
|
@ -24,6 +24,22 @@ class L10nGa extends L10n {
|
|||
@override
|
||||
String get resume => 'Resume';
|
||||
|
||||
@override
|
||||
String get newSubSpace => 'New sub space';
|
||||
|
||||
@override
|
||||
String get moveToDifferentSpace => 'Move to different space';
|
||||
|
||||
@override
|
||||
String get moveUp => 'Move up';
|
||||
|
||||
@override
|
||||
String get moveDown => 'Move down';
|
||||
|
||||
@override
|
||||
String get removeFromSpaceDescription =>
|
||||
'The chat will be removed from the space but still appear in your chat list.';
|
||||
|
||||
@override
|
||||
String get endPoll => 'End poll';
|
||||
|
||||
|
|
@ -56,6 +72,9 @@ class L10nGa extends L10n {
|
|||
return '$selected of $max selected';
|
||||
}
|
||||
|
||||
@override
|
||||
String get discuss => 'Discuss';
|
||||
|
||||
@override
|
||||
String get pollType => 'Poll type';
|
||||
|
||||
|
|
@ -668,6 +687,12 @@ class L10nGa extends L10n {
|
|||
@override
|
||||
String get chatPermissions => 'Ceadanna comhrá';
|
||||
|
||||
@override
|
||||
String get chatThreads => 'Threads';
|
||||
|
||||
@override
|
||||
String get chatThreadsDescription => 'See all threads in this room';
|
||||
|
||||
@override
|
||||
String get editDisplayname => 'Cuir ainm taispeána in eagar';
|
||||
|
||||
|
|
@ -2450,6 +2475,16 @@ class L10nGa extends L10n {
|
|||
@override
|
||||
String get restricted => 'Srianta';
|
||||
|
||||
@override
|
||||
String spaceMemberOf(String spaces) {
|
||||
return 'Space member of $spaces';
|
||||
}
|
||||
|
||||
@override
|
||||
String spaceMemberOfCanKnock(String spaces) {
|
||||
return 'Space member of $spaces can knock';
|
||||
}
|
||||
|
||||
@override
|
||||
String get knockRestricted => 'Cnoc Mhuire srianta';
|
||||
|
||||
|
|
|
|||
|
|
@ -24,6 +24,22 @@ class L10nGl extends L10n {
|
|||
@override
|
||||
String get resume => 'Resume';
|
||||
|
||||
@override
|
||||
String get newSubSpace => 'New sub space';
|
||||
|
||||
@override
|
||||
String get moveToDifferentSpace => 'Move to different space';
|
||||
|
||||
@override
|
||||
String get moveUp => 'Move up';
|
||||
|
||||
@override
|
||||
String get moveDown => 'Move down';
|
||||
|
||||
@override
|
||||
String get removeFromSpaceDescription =>
|
||||
'The chat will be removed from the space but still appear in your chat list.';
|
||||
|
||||
@override
|
||||
String get endPoll => 'End poll';
|
||||
|
||||
|
|
@ -56,6 +72,9 @@ class L10nGl extends L10n {
|
|||
return '$selected of $max selected';
|
||||
}
|
||||
|
||||
@override
|
||||
String get discuss => 'Discuss';
|
||||
|
||||
@override
|
||||
String get pollType => 'Poll type';
|
||||
|
||||
|
|
@ -663,6 +682,12 @@ class L10nGl extends L10n {
|
|||
@override
|
||||
String get chatPermissions => 'Permisos da conversa';
|
||||
|
||||
@override
|
||||
String get chatThreads => 'Threads';
|
||||
|
||||
@override
|
||||
String get chatThreadsDescription => 'See all threads in this room';
|
||||
|
||||
@override
|
||||
String get editDisplayname => 'Editar nome público';
|
||||
|
||||
|
|
@ -2433,6 +2458,16 @@ class L10nGl extends L10n {
|
|||
@override
|
||||
String get restricted => 'Non accesible';
|
||||
|
||||
@override
|
||||
String spaceMemberOf(String spaces) {
|
||||
return 'Space member of $spaces';
|
||||
}
|
||||
|
||||
@override
|
||||
String spaceMemberOfCanKnock(String spaces) {
|
||||
return 'Space member of $spaces can knock';
|
||||
}
|
||||
|
||||
@override
|
||||
String get knockRestricted => 'Peta á porta';
|
||||
|
||||
|
|
|
|||
|
|
@ -24,6 +24,22 @@ class L10nHe extends L10n {
|
|||
@override
|
||||
String get resume => 'Resume';
|
||||
|
||||
@override
|
||||
String get newSubSpace => 'New sub space';
|
||||
|
||||
@override
|
||||
String get moveToDifferentSpace => 'Move to different space';
|
||||
|
||||
@override
|
||||
String get moveUp => 'Move up';
|
||||
|
||||
@override
|
||||
String get moveDown => 'Move down';
|
||||
|
||||
@override
|
||||
String get removeFromSpaceDescription =>
|
||||
'The chat will be removed from the space but still appear in your chat list.';
|
||||
|
||||
@override
|
||||
String get endPoll => 'End poll';
|
||||
|
||||
|
|
@ -56,6 +72,9 @@ class L10nHe extends L10n {
|
|||
return '$selected of $max selected';
|
||||
}
|
||||
|
||||
@override
|
||||
String get discuss => 'Discuss';
|
||||
|
||||
@override
|
||||
String get pollType => 'Poll type';
|
||||
|
||||
|
|
@ -658,6 +677,12 @@ class L10nHe extends L10n {
|
|||
@override
|
||||
String get chatPermissions => 'Chat permissions';
|
||||
|
||||
@override
|
||||
String get chatThreads => 'Threads';
|
||||
|
||||
@override
|
||||
String get chatThreadsDescription => 'See all threads in this room';
|
||||
|
||||
@override
|
||||
String get editDisplayname => 'ערוך את שם התצוגה';
|
||||
|
||||
|
|
@ -2416,6 +2441,16 @@ class L10nHe extends L10n {
|
|||
@override
|
||||
String get restricted => 'Restricted';
|
||||
|
||||
@override
|
||||
String spaceMemberOf(String spaces) {
|
||||
return 'Space member of $spaces';
|
||||
}
|
||||
|
||||
@override
|
||||
String spaceMemberOfCanKnock(String spaces) {
|
||||
return 'Space member of $spaces can knock';
|
||||
}
|
||||
|
||||
@override
|
||||
String get knockRestricted => 'Knock restricted';
|
||||
|
||||
|
|
|
|||
|
|
@ -24,6 +24,22 @@ class L10nHi extends L10n {
|
|||
@override
|
||||
String get resume => 'Resume';
|
||||
|
||||
@override
|
||||
String get newSubSpace => 'New sub space';
|
||||
|
||||
@override
|
||||
String get moveToDifferentSpace => 'Move to different space';
|
||||
|
||||
@override
|
||||
String get moveUp => 'Move up';
|
||||
|
||||
@override
|
||||
String get moveDown => 'Move down';
|
||||
|
||||
@override
|
||||
String get removeFromSpaceDescription =>
|
||||
'The chat will be removed from the space but still appear in your chat list.';
|
||||
|
||||
@override
|
||||
String get endPoll => 'End poll';
|
||||
|
||||
|
|
@ -56,6 +72,9 @@ class L10nHi extends L10n {
|
|||
return '$selected of $max selected';
|
||||
}
|
||||
|
||||
@override
|
||||
String get discuss => 'Discuss';
|
||||
|
||||
@override
|
||||
String get pollType => 'Poll type';
|
||||
|
||||
|
|
@ -660,6 +679,12 @@ class L10nHi extends L10n {
|
|||
@override
|
||||
String get chatPermissions => 'Chat permissions';
|
||||
|
||||
@override
|
||||
String get chatThreads => 'Threads';
|
||||
|
||||
@override
|
||||
String get chatThreadsDescription => 'See all threads in this room';
|
||||
|
||||
@override
|
||||
String get editDisplayname => 'Edit displayname';
|
||||
|
||||
|
|
@ -2421,6 +2446,16 @@ class L10nHi extends L10n {
|
|||
@override
|
||||
String get restricted => 'Restricted';
|
||||
|
||||
@override
|
||||
String spaceMemberOf(String spaces) {
|
||||
return 'Space member of $spaces';
|
||||
}
|
||||
|
||||
@override
|
||||
String spaceMemberOfCanKnock(String spaces) {
|
||||
return 'Space member of $spaces can knock';
|
||||
}
|
||||
|
||||
@override
|
||||
String get knockRestricted => 'Knock restricted';
|
||||
|
||||
|
|
|
|||
|
|
@ -24,6 +24,22 @@ class L10nHr extends L10n {
|
|||
@override
|
||||
String get resume => 'Resume';
|
||||
|
||||
@override
|
||||
String get newSubSpace => 'New sub space';
|
||||
|
||||
@override
|
||||
String get moveToDifferentSpace => 'Move to different space';
|
||||
|
||||
@override
|
||||
String get moveUp => 'Move up';
|
||||
|
||||
@override
|
||||
String get moveDown => 'Move down';
|
||||
|
||||
@override
|
||||
String get removeFromSpaceDescription =>
|
||||
'The chat will be removed from the space but still appear in your chat list.';
|
||||
|
||||
@override
|
||||
String get endPoll => 'End poll';
|
||||
|
||||
|
|
@ -56,6 +72,9 @@ class L10nHr extends L10n {
|
|||
return '$selected of $max selected';
|
||||
}
|
||||
|
||||
@override
|
||||
String get discuss => 'Discuss';
|
||||
|
||||
@override
|
||||
String get pollType => 'Poll type';
|
||||
|
||||
|
|
@ -661,6 +680,12 @@ class L10nHr extends L10n {
|
|||
@override
|
||||
String get chatPermissions => 'Dozvole za razgovor';
|
||||
|
||||
@override
|
||||
String get chatThreads => 'Threads';
|
||||
|
||||
@override
|
||||
String get chatThreadsDescription => 'See all threads in this room';
|
||||
|
||||
@override
|
||||
String get editDisplayname => 'Uredi prikazano ime';
|
||||
|
||||
|
|
@ -2430,6 +2455,16 @@ class L10nHr extends L10n {
|
|||
@override
|
||||
String get restricted => 'Ograničeni';
|
||||
|
||||
@override
|
||||
String spaceMemberOf(String spaces) {
|
||||
return 'Space member of $spaces';
|
||||
}
|
||||
|
||||
@override
|
||||
String spaceMemberOfCanKnock(String spaces) {
|
||||
return 'Space member of $spaces can knock';
|
||||
}
|
||||
|
||||
@override
|
||||
String get knockRestricted => 'Pokucaj na ograničene sobe';
|
||||
|
||||
|
|
|
|||
|
|
@ -24,6 +24,22 @@ class L10nHu extends L10n {
|
|||
@override
|
||||
String get resume => 'Resume';
|
||||
|
||||
@override
|
||||
String get newSubSpace => 'New sub space';
|
||||
|
||||
@override
|
||||
String get moveToDifferentSpace => 'Move to different space';
|
||||
|
||||
@override
|
||||
String get moveUp => 'Move up';
|
||||
|
||||
@override
|
||||
String get moveDown => 'Move down';
|
||||
|
||||
@override
|
||||
String get removeFromSpaceDescription =>
|
||||
'The chat will be removed from the space but still appear in your chat list.';
|
||||
|
||||
@override
|
||||
String get endPoll => 'End poll';
|
||||
|
||||
|
|
@ -56,6 +72,9 @@ class L10nHu extends L10n {
|
|||
return '$selected of $max selected';
|
||||
}
|
||||
|
||||
@override
|
||||
String get discuss => 'Discuss';
|
||||
|
||||
@override
|
||||
String get pollType => 'Poll type';
|
||||
|
||||
|
|
@ -663,6 +682,12 @@ class L10nHu extends L10n {
|
|||
@override
|
||||
String get chatPermissions => 'Csevegés engedélyek';
|
||||
|
||||
@override
|
||||
String get chatThreads => 'Threads';
|
||||
|
||||
@override
|
||||
String get chatThreadsDescription => 'See all threads in this room';
|
||||
|
||||
@override
|
||||
String get editDisplayname => 'Megjelenítési név szerkesztése';
|
||||
|
||||
|
|
@ -2431,6 +2456,16 @@ class L10nHu extends L10n {
|
|||
@override
|
||||
String get restricted => 'Korlátozott';
|
||||
|
||||
@override
|
||||
String spaceMemberOf(String spaces) {
|
||||
return 'Space member of $spaces';
|
||||
}
|
||||
|
||||
@override
|
||||
String spaceMemberOfCanKnock(String spaces) {
|
||||
return 'Space member of $spaces can knock';
|
||||
}
|
||||
|
||||
@override
|
||||
String get knockRestricted => 'Kopogás korlátozva';
|
||||
|
||||
|
|
|
|||
|
|
@ -24,6 +24,22 @@ class L10nIa extends L10n {
|
|||
@override
|
||||
String get resume => 'Resume';
|
||||
|
||||
@override
|
||||
String get newSubSpace => 'New sub space';
|
||||
|
||||
@override
|
||||
String get moveToDifferentSpace => 'Move to different space';
|
||||
|
||||
@override
|
||||
String get moveUp => 'Move up';
|
||||
|
||||
@override
|
||||
String get moveDown => 'Move down';
|
||||
|
||||
@override
|
||||
String get removeFromSpaceDescription =>
|
||||
'The chat will be removed from the space but still appear in your chat list.';
|
||||
|
||||
@override
|
||||
String get endPoll => 'End poll';
|
||||
|
||||
|
|
@ -56,6 +72,9 @@ class L10nIa extends L10n {
|
|||
return '$selected of $max selected';
|
||||
}
|
||||
|
||||
@override
|
||||
String get discuss => 'Discuss';
|
||||
|
||||
@override
|
||||
String get pollType => 'Poll type';
|
||||
|
||||
|
|
@ -660,6 +679,12 @@ class L10nIa extends L10n {
|
|||
@override
|
||||
String get chatPermissions => 'Chat permissions';
|
||||
|
||||
@override
|
||||
String get chatThreads => 'Threads';
|
||||
|
||||
@override
|
||||
String get chatThreadsDescription => 'See all threads in this room';
|
||||
|
||||
@override
|
||||
String get editDisplayname => 'Edit displayname';
|
||||
|
||||
|
|
@ -2421,6 +2446,16 @@ class L10nIa extends L10n {
|
|||
@override
|
||||
String get restricted => 'Restricted';
|
||||
|
||||
@override
|
||||
String spaceMemberOf(String spaces) {
|
||||
return 'Space member of $spaces';
|
||||
}
|
||||
|
||||
@override
|
||||
String spaceMemberOfCanKnock(String spaces) {
|
||||
return 'Space member of $spaces can knock';
|
||||
}
|
||||
|
||||
@override
|
||||
String get knockRestricted => 'Knock restricted';
|
||||
|
||||
|
|
|
|||
|
|
@ -24,6 +24,22 @@ class L10nId extends L10n {
|
|||
@override
|
||||
String get resume => 'Resume';
|
||||
|
||||
@override
|
||||
String get newSubSpace => 'New sub space';
|
||||
|
||||
@override
|
||||
String get moveToDifferentSpace => 'Move to different space';
|
||||
|
||||
@override
|
||||
String get moveUp => 'Move up';
|
||||
|
||||
@override
|
||||
String get moveDown => 'Move down';
|
||||
|
||||
@override
|
||||
String get removeFromSpaceDescription =>
|
||||
'The chat will be removed from the space but still appear in your chat list.';
|
||||
|
||||
@override
|
||||
String get endPoll => 'End poll';
|
||||
|
||||
|
|
@ -56,6 +72,9 @@ class L10nId extends L10n {
|
|||
return '$selected of $max selected';
|
||||
}
|
||||
|
||||
@override
|
||||
String get discuss => 'Discuss';
|
||||
|
||||
@override
|
||||
String get pollType => 'Poll type';
|
||||
|
||||
|
|
@ -667,6 +686,12 @@ class L10nId extends L10n {
|
|||
@override
|
||||
String get chatPermissions => 'Perizinan obrolan';
|
||||
|
||||
@override
|
||||
String get chatThreads => 'Threads';
|
||||
|
||||
@override
|
||||
String get chatThreadsDescription => 'See all threads in this room';
|
||||
|
||||
@override
|
||||
String get editDisplayname => 'Edit nama tampilan';
|
||||
|
||||
|
|
@ -2438,6 +2463,16 @@ class L10nId extends L10n {
|
|||
@override
|
||||
String get restricted => 'Dibatasi';
|
||||
|
||||
@override
|
||||
String spaceMemberOf(String spaces) {
|
||||
return 'Space member of $spaces';
|
||||
}
|
||||
|
||||
@override
|
||||
String spaceMemberOfCanKnock(String spaces) {
|
||||
return 'Space member of $spaces can knock';
|
||||
}
|
||||
|
||||
@override
|
||||
String get knockRestricted => 'Ketukan dibatasi';
|
||||
|
||||
|
|
|
|||
|
|
@ -24,6 +24,22 @@ class L10nIe extends L10n {
|
|||
@override
|
||||
String get resume => 'Resume';
|
||||
|
||||
@override
|
||||
String get newSubSpace => 'New sub space';
|
||||
|
||||
@override
|
||||
String get moveToDifferentSpace => 'Move to different space';
|
||||
|
||||
@override
|
||||
String get moveUp => 'Move up';
|
||||
|
||||
@override
|
||||
String get moveDown => 'Move down';
|
||||
|
||||
@override
|
||||
String get removeFromSpaceDescription =>
|
||||
'The chat will be removed from the space but still appear in your chat list.';
|
||||
|
||||
@override
|
||||
String get endPoll => 'End poll';
|
||||
|
||||
|
|
@ -56,6 +72,9 @@ class L10nIe extends L10n {
|
|||
return '$selected of $max selected';
|
||||
}
|
||||
|
||||
@override
|
||||
String get discuss => 'Discuss';
|
||||
|
||||
@override
|
||||
String get pollType => 'Poll type';
|
||||
|
||||
|
|
@ -659,6 +678,12 @@ class L10nIe extends L10n {
|
|||
@override
|
||||
String get chatPermissions => 'Chat permissions';
|
||||
|
||||
@override
|
||||
String get chatThreads => 'Threads';
|
||||
|
||||
@override
|
||||
String get chatThreadsDescription => 'See all threads in this room';
|
||||
|
||||
@override
|
||||
String get editDisplayname => 'Redacter li visibil nómine';
|
||||
|
||||
|
|
@ -2420,6 +2445,16 @@ class L10nIe extends L10n {
|
|||
@override
|
||||
String get restricted => 'Restricted';
|
||||
|
||||
@override
|
||||
String spaceMemberOf(String spaces) {
|
||||
return 'Space member of $spaces';
|
||||
}
|
||||
|
||||
@override
|
||||
String spaceMemberOfCanKnock(String spaces) {
|
||||
return 'Space member of $spaces can knock';
|
||||
}
|
||||
|
||||
@override
|
||||
String get knockRestricted => 'Knock restricted';
|
||||
|
||||
|
|
|
|||
|
|
@ -24,6 +24,22 @@ class L10nIt extends L10n {
|
|||
@override
|
||||
String get resume => 'Resume';
|
||||
|
||||
@override
|
||||
String get newSubSpace => 'New sub space';
|
||||
|
||||
@override
|
||||
String get moveToDifferentSpace => 'Move to different space';
|
||||
|
||||
@override
|
||||
String get moveUp => 'Move up';
|
||||
|
||||
@override
|
||||
String get moveDown => 'Move down';
|
||||
|
||||
@override
|
||||
String get removeFromSpaceDescription =>
|
||||
'The chat will be removed from the space but still appear in your chat list.';
|
||||
|
||||
@override
|
||||
String get endPoll => 'End poll';
|
||||
|
||||
|
|
@ -56,6 +72,9 @@ class L10nIt extends L10n {
|
|||
return '$selected of $max selected';
|
||||
}
|
||||
|
||||
@override
|
||||
String get discuss => 'Discuss';
|
||||
|
||||
@override
|
||||
String get pollType => 'Poll type';
|
||||
|
||||
|
|
@ -664,6 +683,12 @@ class L10nIt extends L10n {
|
|||
@override
|
||||
String get chatPermissions => 'Permessi della chat';
|
||||
|
||||
@override
|
||||
String get chatThreads => 'Threads';
|
||||
|
||||
@override
|
||||
String get chatThreadsDescription => 'See all threads in this room';
|
||||
|
||||
@override
|
||||
String get editDisplayname => 'Modifica il nominativo';
|
||||
|
||||
|
|
@ -2445,6 +2470,16 @@ class L10nIt extends L10n {
|
|||
@override
|
||||
String get restricted => 'Limitato';
|
||||
|
||||
@override
|
||||
String spaceMemberOf(String spaces) {
|
||||
return 'Space member of $spaces';
|
||||
}
|
||||
|
||||
@override
|
||||
String spaceMemberOfCanKnock(String spaces) {
|
||||
return 'Space member of $spaces can knock';
|
||||
}
|
||||
|
||||
@override
|
||||
String get knockRestricted => 'Limitato al bussare';
|
||||
|
||||
|
|
|
|||
|
|
@ -24,6 +24,22 @@ class L10nJa extends L10n {
|
|||
@override
|
||||
String get resume => 'Resume';
|
||||
|
||||
@override
|
||||
String get newSubSpace => 'New sub space';
|
||||
|
||||
@override
|
||||
String get moveToDifferentSpace => 'Move to different space';
|
||||
|
||||
@override
|
||||
String get moveUp => 'Move up';
|
||||
|
||||
@override
|
||||
String get moveDown => 'Move down';
|
||||
|
||||
@override
|
||||
String get removeFromSpaceDescription =>
|
||||
'The chat will be removed from the space but still appear in your chat list.';
|
||||
|
||||
@override
|
||||
String get endPoll => 'End poll';
|
||||
|
||||
|
|
@ -56,6 +72,9 @@ class L10nJa extends L10n {
|
|||
return '$selected of $max selected';
|
||||
}
|
||||
|
||||
@override
|
||||
String get discuss => 'Discuss';
|
||||
|
||||
@override
|
||||
String get pollType => 'Poll type';
|
||||
|
||||
|
|
@ -651,6 +670,12 @@ class L10nJa extends L10n {
|
|||
@override
|
||||
String get chatPermissions => 'Chat permissions';
|
||||
|
||||
@override
|
||||
String get chatThreads => 'Threads';
|
||||
|
||||
@override
|
||||
String get chatThreadsDescription => 'See all threads in this room';
|
||||
|
||||
@override
|
||||
String get editDisplayname => '表示名を編集';
|
||||
|
||||
|
|
@ -2390,6 +2415,16 @@ class L10nJa extends L10n {
|
|||
@override
|
||||
String get restricted => 'Restricted';
|
||||
|
||||
@override
|
||||
String spaceMemberOf(String spaces) {
|
||||
return 'Space member of $spaces';
|
||||
}
|
||||
|
||||
@override
|
||||
String spaceMemberOfCanKnock(String spaces) {
|
||||
return 'Space member of $spaces can knock';
|
||||
}
|
||||
|
||||
@override
|
||||
String get knockRestricted => 'Knock restricted';
|
||||
|
||||
|
|
|
|||
|
|
@ -24,6 +24,22 @@ class L10nKa extends L10n {
|
|||
@override
|
||||
String get resume => 'Resume';
|
||||
|
||||
@override
|
||||
String get newSubSpace => 'New sub space';
|
||||
|
||||
@override
|
||||
String get moveToDifferentSpace => 'Move to different space';
|
||||
|
||||
@override
|
||||
String get moveUp => 'Move up';
|
||||
|
||||
@override
|
||||
String get moveDown => 'Move down';
|
||||
|
||||
@override
|
||||
String get removeFromSpaceDescription =>
|
||||
'The chat will be removed from the space but still appear in your chat list.';
|
||||
|
||||
@override
|
||||
String get endPoll => 'End poll';
|
||||
|
||||
|
|
@ -56,6 +72,9 @@ class L10nKa extends L10n {
|
|||
return '$selected of $max selected';
|
||||
}
|
||||
|
||||
@override
|
||||
String get discuss => 'Discuss';
|
||||
|
||||
@override
|
||||
String get pollType => 'Poll type';
|
||||
|
||||
|
|
@ -662,6 +681,12 @@ class L10nKa extends L10n {
|
|||
@override
|
||||
String get chatPermissions => 'ჩატის უფლებები';
|
||||
|
||||
@override
|
||||
String get chatThreads => 'Threads';
|
||||
|
||||
@override
|
||||
String get chatThreadsDescription => 'See all threads in this room';
|
||||
|
||||
@override
|
||||
String get editDisplayname => 'ნაჩვენები სახელის შეცვლა';
|
||||
|
||||
|
|
@ -2423,6 +2448,16 @@ class L10nKa extends L10n {
|
|||
@override
|
||||
String get restricted => 'Restricted';
|
||||
|
||||
@override
|
||||
String spaceMemberOf(String spaces) {
|
||||
return 'Space member of $spaces';
|
||||
}
|
||||
|
||||
@override
|
||||
String spaceMemberOfCanKnock(String spaces) {
|
||||
return 'Space member of $spaces can knock';
|
||||
}
|
||||
|
||||
@override
|
||||
String get knockRestricted => 'Knock restricted';
|
||||
|
||||
|
|
|
|||
|
|
@ -24,6 +24,22 @@ class L10nKo extends L10n {
|
|||
@override
|
||||
String get resume => 'Resume';
|
||||
|
||||
@override
|
||||
String get newSubSpace => 'New sub space';
|
||||
|
||||
@override
|
||||
String get moveToDifferentSpace => 'Move to different space';
|
||||
|
||||
@override
|
||||
String get moveUp => 'Move up';
|
||||
|
||||
@override
|
||||
String get moveDown => 'Move down';
|
||||
|
||||
@override
|
||||
String get removeFromSpaceDescription =>
|
||||
'The chat will be removed from the space but still appear in your chat list.';
|
||||
|
||||
@override
|
||||
String get endPoll => 'End poll';
|
||||
|
||||
|
|
@ -56,6 +72,9 @@ class L10nKo extends L10n {
|
|||
return '$selected of $max selected';
|
||||
}
|
||||
|
||||
@override
|
||||
String get discuss => 'Discuss';
|
||||
|
||||
@override
|
||||
String get pollType => 'Poll type';
|
||||
|
||||
|
|
@ -649,6 +668,12 @@ class L10nKo extends L10n {
|
|||
@override
|
||||
String get chatPermissions => '채팅 권한';
|
||||
|
||||
@override
|
||||
String get chatThreads => 'Threads';
|
||||
|
||||
@override
|
||||
String get chatThreadsDescription => 'See all threads in this room';
|
||||
|
||||
@override
|
||||
String get editDisplayname => '표시 이름 수정';
|
||||
|
||||
|
|
@ -2372,6 +2397,16 @@ class L10nKo extends L10n {
|
|||
@override
|
||||
String get restricted => '스페이스 멤버로 제한';
|
||||
|
||||
@override
|
||||
String spaceMemberOf(String spaces) {
|
||||
return 'Space member of $spaces';
|
||||
}
|
||||
|
||||
@override
|
||||
String spaceMemberOfCanKnock(String spaces) {
|
||||
return 'Space member of $spaces can knock';
|
||||
}
|
||||
|
||||
@override
|
||||
String get knockRestricted => '스페이스 멤버만 참가 요청 가능';
|
||||
|
||||
|
|
|
|||
|
|
@ -24,6 +24,22 @@ class L10nLt extends L10n {
|
|||
@override
|
||||
String get resume => 'Resume';
|
||||
|
||||
@override
|
||||
String get newSubSpace => 'New sub space';
|
||||
|
||||
@override
|
||||
String get moveToDifferentSpace => 'Move to different space';
|
||||
|
||||
@override
|
||||
String get moveUp => 'Move up';
|
||||
|
||||
@override
|
||||
String get moveDown => 'Move down';
|
||||
|
||||
@override
|
||||
String get removeFromSpaceDescription =>
|
||||
'The chat will be removed from the space but still appear in your chat list.';
|
||||
|
||||
@override
|
||||
String get endPoll => 'End poll';
|
||||
|
||||
|
|
@ -56,6 +72,9 @@ class L10nLt extends L10n {
|
|||
return '$selected of $max selected';
|
||||
}
|
||||
|
||||
@override
|
||||
String get discuss => 'Discuss';
|
||||
|
||||
@override
|
||||
String get pollType => 'Poll type';
|
||||
|
||||
|
|
@ -662,6 +681,12 @@ class L10nLt extends L10n {
|
|||
@override
|
||||
String get chatPermissions => 'Chat permissions';
|
||||
|
||||
@override
|
||||
String get chatThreads => 'Threads';
|
||||
|
||||
@override
|
||||
String get chatThreadsDescription => 'See all threads in this room';
|
||||
|
||||
@override
|
||||
String get editDisplayname => 'Redaguoti rodomą vardą';
|
||||
|
||||
|
|
@ -2427,6 +2452,16 @@ class L10nLt extends L10n {
|
|||
@override
|
||||
String get restricted => 'Restricted';
|
||||
|
||||
@override
|
||||
String spaceMemberOf(String spaces) {
|
||||
return 'Space member of $spaces';
|
||||
}
|
||||
|
||||
@override
|
||||
String spaceMemberOfCanKnock(String spaces) {
|
||||
return 'Space member of $spaces can knock';
|
||||
}
|
||||
|
||||
@override
|
||||
String get knockRestricted => 'Knock restricted';
|
||||
|
||||
|
|
|
|||
|
|
@ -24,6 +24,22 @@ class L10nLv extends L10n {
|
|||
@override
|
||||
String get resume => 'Resume';
|
||||
|
||||
@override
|
||||
String get newSubSpace => 'New sub space';
|
||||
|
||||
@override
|
||||
String get moveToDifferentSpace => 'Move to different space';
|
||||
|
||||
@override
|
||||
String get moveUp => 'Move up';
|
||||
|
||||
@override
|
||||
String get moveDown => 'Move down';
|
||||
|
||||
@override
|
||||
String get removeFromSpaceDescription =>
|
||||
'The chat will be removed from the space but still appear in your chat list.';
|
||||
|
||||
@override
|
||||
String get endPoll => 'End poll';
|
||||
|
||||
|
|
@ -56,6 +72,9 @@ class L10nLv extends L10n {
|
|||
return '$selected of $max selected';
|
||||
}
|
||||
|
||||
@override
|
||||
String get discuss => 'Discuss';
|
||||
|
||||
@override
|
||||
String get pollType => 'Poll type';
|
||||
|
||||
|
|
@ -666,6 +685,12 @@ class L10nLv extends L10n {
|
|||
@override
|
||||
String get chatPermissions => 'Tērzēšanas atļaujas';
|
||||
|
||||
@override
|
||||
String get chatThreads => 'Threads';
|
||||
|
||||
@override
|
||||
String get chatThreadsDescription => 'See all threads in this room';
|
||||
|
||||
@override
|
||||
String get editDisplayname => 'Labot attēlojamo vārdu';
|
||||
|
||||
|
|
@ -2438,6 +2463,16 @@ class L10nLv extends L10n {
|
|||
@override
|
||||
String get restricted => 'Ierobežots';
|
||||
|
||||
@override
|
||||
String spaceMemberOf(String spaces) {
|
||||
return 'Space member of $spaces';
|
||||
}
|
||||
|
||||
@override
|
||||
String spaceMemberOfCanKnock(String spaces) {
|
||||
return 'Space member of $spaces can knock';
|
||||
}
|
||||
|
||||
@override
|
||||
String get knockRestricted => 'Pieklauvēt ierobežotajiem';
|
||||
|
||||
|
|
|
|||
|
|
@ -24,6 +24,22 @@ class L10nNb extends L10n {
|
|||
@override
|
||||
String get resume => 'Resume';
|
||||
|
||||
@override
|
||||
String get newSubSpace => 'New sub space';
|
||||
|
||||
@override
|
||||
String get moveToDifferentSpace => 'Move to different space';
|
||||
|
||||
@override
|
||||
String get moveUp => 'Move up';
|
||||
|
||||
@override
|
||||
String get moveDown => 'Move down';
|
||||
|
||||
@override
|
||||
String get removeFromSpaceDescription =>
|
||||
'The chat will be removed from the space but still appear in your chat list.';
|
||||
|
||||
@override
|
||||
String get endPoll => 'End poll';
|
||||
|
||||
|
|
@ -56,6 +72,9 @@ class L10nNb extends L10n {
|
|||
return '$selected of $max selected';
|
||||
}
|
||||
|
||||
@override
|
||||
String get discuss => 'Discuss';
|
||||
|
||||
@override
|
||||
String get pollType => 'Poll type';
|
||||
|
||||
|
|
@ -660,6 +679,12 @@ class L10nNb extends L10n {
|
|||
@override
|
||||
String get chatPermissions => 'Chat permissions';
|
||||
|
||||
@override
|
||||
String get chatThreads => 'Threads';
|
||||
|
||||
@override
|
||||
String get chatThreadsDescription => 'See all threads in this room';
|
||||
|
||||
@override
|
||||
String get editDisplayname => 'Rediger visningsnavn';
|
||||
|
||||
|
|
@ -2424,6 +2449,16 @@ class L10nNb extends L10n {
|
|||
@override
|
||||
String get restricted => 'Restricted';
|
||||
|
||||
@override
|
||||
String spaceMemberOf(String spaces) {
|
||||
return 'Space member of $spaces';
|
||||
}
|
||||
|
||||
@override
|
||||
String spaceMemberOfCanKnock(String spaces) {
|
||||
return 'Space member of $spaces can knock';
|
||||
}
|
||||
|
||||
@override
|
||||
String get knockRestricted => 'Knock restricted';
|
||||
|
||||
|
|
|
|||
|
|
@ -24,6 +24,22 @@ class L10nNl extends L10n {
|
|||
@override
|
||||
String get resume => 'Resume';
|
||||
|
||||
@override
|
||||
String get newSubSpace => 'New sub space';
|
||||
|
||||
@override
|
||||
String get moveToDifferentSpace => 'Move to different space';
|
||||
|
||||
@override
|
||||
String get moveUp => 'Move up';
|
||||
|
||||
@override
|
||||
String get moveDown => 'Move down';
|
||||
|
||||
@override
|
||||
String get removeFromSpaceDescription =>
|
||||
'The chat will be removed from the space but still appear in your chat list.';
|
||||
|
||||
@override
|
||||
String get endPoll => 'End poll';
|
||||
|
||||
|
|
@ -56,6 +72,9 @@ class L10nNl extends L10n {
|
|||
return '$selected of $max selected';
|
||||
}
|
||||
|
||||
@override
|
||||
String get discuss => 'Discuss';
|
||||
|
||||
@override
|
||||
String get pollType => 'Poll type';
|
||||
|
||||
|
|
@ -662,6 +681,12 @@ class L10nNl extends L10n {
|
|||
@override
|
||||
String get chatPermissions => 'Chat toestemmingen';
|
||||
|
||||
@override
|
||||
String get chatThreads => 'Threads';
|
||||
|
||||
@override
|
||||
String get chatThreadsDescription => 'See all threads in this room';
|
||||
|
||||
@override
|
||||
String get editDisplayname => 'Naam wijzigen';
|
||||
|
||||
|
|
@ -2427,6 +2452,16 @@ class L10nNl extends L10n {
|
|||
@override
|
||||
String get restricted => 'Beperkt';
|
||||
|
||||
@override
|
||||
String spaceMemberOf(String spaces) {
|
||||
return 'Space member of $spaces';
|
||||
}
|
||||
|
||||
@override
|
||||
String spaceMemberOfCanKnock(String spaces) {
|
||||
return 'Space member of $spaces can knock';
|
||||
}
|
||||
|
||||
@override
|
||||
String get knockRestricted => 'Kloppen is beperkt';
|
||||
|
||||
|
|
|
|||
|
|
@ -24,6 +24,22 @@ class L10nPl extends L10n {
|
|||
@override
|
||||
String get resume => 'Resume';
|
||||
|
||||
@override
|
||||
String get newSubSpace => 'New sub space';
|
||||
|
||||
@override
|
||||
String get moveToDifferentSpace => 'Move to different space';
|
||||
|
||||
@override
|
||||
String get moveUp => 'Move up';
|
||||
|
||||
@override
|
||||
String get moveDown => 'Move down';
|
||||
|
||||
@override
|
||||
String get removeFromSpaceDescription =>
|
||||
'The chat will be removed from the space but still appear in your chat list.';
|
||||
|
||||
@override
|
||||
String get endPoll => 'End poll';
|
||||
|
||||
|
|
@ -56,6 +72,9 @@ class L10nPl extends L10n {
|
|||
return '$selected of $max selected';
|
||||
}
|
||||
|
||||
@override
|
||||
String get discuss => 'Discuss';
|
||||
|
||||
@override
|
||||
String get pollType => 'Poll type';
|
||||
|
||||
|
|
@ -663,6 +682,12 @@ class L10nPl extends L10n {
|
|||
@override
|
||||
String get chatPermissions => 'Uprawnienia w czacie';
|
||||
|
||||
@override
|
||||
String get chatThreads => 'Threads';
|
||||
|
||||
@override
|
||||
String get chatThreadsDescription => 'See all threads in this room';
|
||||
|
||||
@override
|
||||
String get editDisplayname => 'Edytuj nazwę wyświetlaną';
|
||||
|
||||
|
|
@ -2437,6 +2462,16 @@ class L10nPl extends L10n {
|
|||
@override
|
||||
String get restricted => 'Ograniczone';
|
||||
|
||||
@override
|
||||
String spaceMemberOf(String spaces) {
|
||||
return 'Space member of $spaces';
|
||||
}
|
||||
|
||||
@override
|
||||
String spaceMemberOfCanKnock(String spaces) {
|
||||
return 'Space member of $spaces can knock';
|
||||
}
|
||||
|
||||
@override
|
||||
String get knockRestricted => 'Pukanie jest ograniczone';
|
||||
|
||||
|
|
|
|||
|
|
@ -24,6 +24,22 @@ class L10nPt extends L10n {
|
|||
@override
|
||||
String get resume => 'Resume';
|
||||
|
||||
@override
|
||||
String get newSubSpace => 'New sub space';
|
||||
|
||||
@override
|
||||
String get moveToDifferentSpace => 'Move to different space';
|
||||
|
||||
@override
|
||||
String get moveUp => 'Move up';
|
||||
|
||||
@override
|
||||
String get moveDown => 'Move down';
|
||||
|
||||
@override
|
||||
String get removeFromSpaceDescription =>
|
||||
'The chat will be removed from the space but still appear in your chat list.';
|
||||
|
||||
@override
|
||||
String get endPoll => 'End poll';
|
||||
|
||||
|
|
@ -56,6 +72,9 @@ class L10nPt extends L10n {
|
|||
return '$selected of $max selected';
|
||||
}
|
||||
|
||||
@override
|
||||
String get discuss => 'Discuss';
|
||||
|
||||
@override
|
||||
String get pollType => 'Poll type';
|
||||
|
||||
|
|
@ -660,6 +679,12 @@ class L10nPt extends L10n {
|
|||
@override
|
||||
String get chatPermissions => 'Chat permissions';
|
||||
|
||||
@override
|
||||
String get chatThreads => 'Threads';
|
||||
|
||||
@override
|
||||
String get chatThreadsDescription => 'See all threads in this room';
|
||||
|
||||
@override
|
||||
String get editDisplayname => 'Edit displayname';
|
||||
|
||||
|
|
@ -2421,6 +2446,16 @@ class L10nPt extends L10n {
|
|||
@override
|
||||
String get restricted => 'Restricted';
|
||||
|
||||
@override
|
||||
String spaceMemberOf(String spaces) {
|
||||
return 'Space member of $spaces';
|
||||
}
|
||||
|
||||
@override
|
||||
String spaceMemberOfCanKnock(String spaces) {
|
||||
return 'Space member of $spaces can knock';
|
||||
}
|
||||
|
||||
@override
|
||||
String get knockRestricted => 'Knock restricted';
|
||||
|
||||
|
|
|
|||
|
|
@ -24,6 +24,22 @@ class L10nRo extends L10n {
|
|||
@override
|
||||
String get resume => 'Resume';
|
||||
|
||||
@override
|
||||
String get newSubSpace => 'New sub space';
|
||||
|
||||
@override
|
||||
String get moveToDifferentSpace => 'Move to different space';
|
||||
|
||||
@override
|
||||
String get moveUp => 'Move up';
|
||||
|
||||
@override
|
||||
String get moveDown => 'Move down';
|
||||
|
||||
@override
|
||||
String get removeFromSpaceDescription =>
|
||||
'The chat will be removed from the space but still appear in your chat list.';
|
||||
|
||||
@override
|
||||
String get endPoll => 'End poll';
|
||||
|
||||
|
|
@ -56,6 +72,9 @@ class L10nRo extends L10n {
|
|||
return '$selected of $max selected';
|
||||
}
|
||||
|
||||
@override
|
||||
String get discuss => 'Discuss';
|
||||
|
||||
@override
|
||||
String get pollType => 'Poll type';
|
||||
|
||||
|
|
@ -665,6 +684,12 @@ class L10nRo extends L10n {
|
|||
@override
|
||||
String get chatPermissions => 'Chat permissions';
|
||||
|
||||
@override
|
||||
String get chatThreads => 'Threads';
|
||||
|
||||
@override
|
||||
String get chatThreadsDescription => 'See all threads in this room';
|
||||
|
||||
@override
|
||||
String get editDisplayname => 'Schimbați displayname';
|
||||
|
||||
|
|
@ -2438,6 +2463,16 @@ class L10nRo extends L10n {
|
|||
@override
|
||||
String get restricted => 'Restricted';
|
||||
|
||||
@override
|
||||
String spaceMemberOf(String spaces) {
|
||||
return 'Space member of $spaces';
|
||||
}
|
||||
|
||||
@override
|
||||
String spaceMemberOfCanKnock(String spaces) {
|
||||
return 'Space member of $spaces can knock';
|
||||
}
|
||||
|
||||
@override
|
||||
String get knockRestricted => 'Knock restricted';
|
||||
|
||||
|
|
|
|||
|
|
@ -24,6 +24,22 @@ class L10nRu extends L10n {
|
|||
@override
|
||||
String get resume => 'Продолжить';
|
||||
|
||||
@override
|
||||
String get newSubSpace => 'Новое подпространство';
|
||||
|
||||
@override
|
||||
String get moveToDifferentSpace => 'Перенести в другое пространство';
|
||||
|
||||
@override
|
||||
String get moveUp => 'Вверх';
|
||||
|
||||
@override
|
||||
String get moveDown => 'Вниз';
|
||||
|
||||
@override
|
||||
String get removeFromSpaceDescription =>
|
||||
'Эта комната будет удалена из пространства, но останется в Вашем списке чатов.';
|
||||
|
||||
@override
|
||||
String get endPoll => 'Завершить опрос';
|
||||
|
||||
|
|
@ -56,6 +72,9 @@ class L10nRu extends L10n {
|
|||
return 'Выбрано $selected из $max';
|
||||
}
|
||||
|
||||
@override
|
||||
String get discuss => 'Обсудить';
|
||||
|
||||
@override
|
||||
String get pollType => 'Тип опроса';
|
||||
|
||||
|
|
@ -88,7 +107,7 @@ class L10nRu extends L10n {
|
|||
|
||||
@override
|
||||
String get cleanExifDescription =>
|
||||
'Удалять метаданные EXIF (модель камеры, геолокация, время) из изображений еред отправкой.';
|
||||
'Удалять метаданные EXIF (модель камеры, геолокация, время) из изображений перед отправкой.';
|
||||
|
||||
@override
|
||||
String get repeatPassword => 'Повторите пароль';
|
||||
|
|
@ -662,6 +681,12 @@ class L10nRu extends L10n {
|
|||
@override
|
||||
String get chatPermissions => 'Права в чате';
|
||||
|
||||
@override
|
||||
String get chatThreads => 'Обсуждения';
|
||||
|
||||
@override
|
||||
String get chatThreadsDescription => 'Список всех обсуждений в этой комнате';
|
||||
|
||||
@override
|
||||
String get editDisplayname => 'Отображаемое имя';
|
||||
|
||||
|
|
@ -695,7 +720,7 @@ class L10nRu extends L10n {
|
|||
|
||||
@override
|
||||
String get accessAndVisibilityDescription =>
|
||||
'Кто может зайти и как найти этот чат.';
|
||||
'Кто может зайти и как найти этот чат';
|
||||
|
||||
@override
|
||||
String get calls => 'Звонки';
|
||||
|
|
@ -2426,6 +2451,16 @@ class L10nRu extends L10n {
|
|||
@override
|
||||
String get restricted => 'Ограничено';
|
||||
|
||||
@override
|
||||
String spaceMemberOf(String spaces) {
|
||||
return 'Участники пространства $spaces';
|
||||
}
|
||||
|
||||
@override
|
||||
String spaceMemberOfCanKnock(String spaces) {
|
||||
return 'Участники пространства $spaces (по запросу)';
|
||||
}
|
||||
|
||||
@override
|
||||
String get knockRestricted => 'Ограничено + по запросу';
|
||||
|
||||
|
|
|
|||
|
|
@ -24,6 +24,22 @@ class L10nSk extends L10n {
|
|||
@override
|
||||
String get resume => 'Resume';
|
||||
|
||||
@override
|
||||
String get newSubSpace => 'New sub space';
|
||||
|
||||
@override
|
||||
String get moveToDifferentSpace => 'Move to different space';
|
||||
|
||||
@override
|
||||
String get moveUp => 'Move up';
|
||||
|
||||
@override
|
||||
String get moveDown => 'Move down';
|
||||
|
||||
@override
|
||||
String get removeFromSpaceDescription =>
|
||||
'The chat will be removed from the space but still appear in your chat list.';
|
||||
|
||||
@override
|
||||
String get endPoll => 'End poll';
|
||||
|
||||
|
|
@ -56,6 +72,9 @@ class L10nSk extends L10n {
|
|||
return '$selected of $max selected';
|
||||
}
|
||||
|
||||
@override
|
||||
String get discuss => 'Discuss';
|
||||
|
||||
@override
|
||||
String get pollType => 'Poll type';
|
||||
|
||||
|
|
@ -662,6 +681,12 @@ class L10nSk extends L10n {
|
|||
@override
|
||||
String get chatPermissions => 'Chat permissions';
|
||||
|
||||
@override
|
||||
String get chatThreads => 'Threads';
|
||||
|
||||
@override
|
||||
String get chatThreadsDescription => 'See all threads in this room';
|
||||
|
||||
@override
|
||||
String get editDisplayname => 'Zmeniť prezývku';
|
||||
|
||||
|
|
@ -2422,6 +2447,16 @@ class L10nSk extends L10n {
|
|||
@override
|
||||
String get restricted => 'Restricted';
|
||||
|
||||
@override
|
||||
String spaceMemberOf(String spaces) {
|
||||
return 'Space member of $spaces';
|
||||
}
|
||||
|
||||
@override
|
||||
String spaceMemberOfCanKnock(String spaces) {
|
||||
return 'Space member of $spaces can knock';
|
||||
}
|
||||
|
||||
@override
|
||||
String get knockRestricted => 'Knock restricted';
|
||||
|
||||
|
|
|
|||
|
|
@ -24,6 +24,22 @@ class L10nSl extends L10n {
|
|||
@override
|
||||
String get resume => 'Resume';
|
||||
|
||||
@override
|
||||
String get newSubSpace => 'New sub space';
|
||||
|
||||
@override
|
||||
String get moveToDifferentSpace => 'Move to different space';
|
||||
|
||||
@override
|
||||
String get moveUp => 'Move up';
|
||||
|
||||
@override
|
||||
String get moveDown => 'Move down';
|
||||
|
||||
@override
|
||||
String get removeFromSpaceDescription =>
|
||||
'The chat will be removed from the space but still appear in your chat list.';
|
||||
|
||||
@override
|
||||
String get endPoll => 'End poll';
|
||||
|
||||
|
|
@ -56,6 +72,9 @@ class L10nSl extends L10n {
|
|||
return '$selected of $max selected';
|
||||
}
|
||||
|
||||
@override
|
||||
String get discuss => 'Discuss';
|
||||
|
||||
@override
|
||||
String get pollType => 'Poll type';
|
||||
|
||||
|
|
@ -664,6 +683,12 @@ class L10nSl extends L10n {
|
|||
@override
|
||||
String get chatPermissions => 'Chat permissions';
|
||||
|
||||
@override
|
||||
String get chatThreads => 'Threads';
|
||||
|
||||
@override
|
||||
String get chatThreadsDescription => 'See all threads in this room';
|
||||
|
||||
@override
|
||||
String get editDisplayname => 'Edit displayname';
|
||||
|
||||
|
|
@ -2425,6 +2450,16 @@ class L10nSl extends L10n {
|
|||
@override
|
||||
String get restricted => 'Restricted';
|
||||
|
||||
@override
|
||||
String spaceMemberOf(String spaces) {
|
||||
return 'Space member of $spaces';
|
||||
}
|
||||
|
||||
@override
|
||||
String spaceMemberOfCanKnock(String spaces) {
|
||||
return 'Space member of $spaces can knock';
|
||||
}
|
||||
|
||||
@override
|
||||
String get knockRestricted => 'Knock restricted';
|
||||
|
||||
|
|
|
|||
|
|
@ -24,6 +24,22 @@ class L10nSr extends L10n {
|
|||
@override
|
||||
String get resume => 'Resume';
|
||||
|
||||
@override
|
||||
String get newSubSpace => 'New sub space';
|
||||
|
||||
@override
|
||||
String get moveToDifferentSpace => 'Move to different space';
|
||||
|
||||
@override
|
||||
String get moveUp => 'Move up';
|
||||
|
||||
@override
|
||||
String get moveDown => 'Move down';
|
||||
|
||||
@override
|
||||
String get removeFromSpaceDescription =>
|
||||
'The chat will be removed from the space but still appear in your chat list.';
|
||||
|
||||
@override
|
||||
String get endPoll => 'End poll';
|
||||
|
||||
|
|
@ -56,6 +72,9 @@ class L10nSr extends L10n {
|
|||
return '$selected of $max selected';
|
||||
}
|
||||
|
||||
@override
|
||||
String get discuss => 'Discuss';
|
||||
|
||||
@override
|
||||
String get pollType => 'Poll type';
|
||||
|
||||
|
|
@ -660,6 +679,12 @@ class L10nSr extends L10n {
|
|||
@override
|
||||
String get chatPermissions => 'Chat permissions';
|
||||
|
||||
@override
|
||||
String get chatThreads => 'Threads';
|
||||
|
||||
@override
|
||||
String get chatThreadsDescription => 'See all threads in this room';
|
||||
|
||||
@override
|
||||
String get editDisplayname => 'Уреди име за приказ';
|
||||
|
||||
|
|
@ -2417,6 +2442,16 @@ class L10nSr extends L10n {
|
|||
@override
|
||||
String get restricted => 'Restricted';
|
||||
|
||||
@override
|
||||
String spaceMemberOf(String spaces) {
|
||||
return 'Space member of $spaces';
|
||||
}
|
||||
|
||||
@override
|
||||
String spaceMemberOfCanKnock(String spaces) {
|
||||
return 'Space member of $spaces can knock';
|
||||
}
|
||||
|
||||
@override
|
||||
String get knockRestricted => 'Knock restricted';
|
||||
|
||||
|
|
|
|||
|
|
@ -24,6 +24,22 @@ class L10nSv extends L10n {
|
|||
@override
|
||||
String get resume => 'Resume';
|
||||
|
||||
@override
|
||||
String get newSubSpace => 'New sub space';
|
||||
|
||||
@override
|
||||
String get moveToDifferentSpace => 'Move to different space';
|
||||
|
||||
@override
|
||||
String get moveUp => 'Move up';
|
||||
|
||||
@override
|
||||
String get moveDown => 'Move down';
|
||||
|
||||
@override
|
||||
String get removeFromSpaceDescription =>
|
||||
'The chat will be removed from the space but still appear in your chat list.';
|
||||
|
||||
@override
|
||||
String get endPoll => 'End poll';
|
||||
|
||||
|
|
@ -56,6 +72,9 @@ class L10nSv extends L10n {
|
|||
return '$selected of $max selected';
|
||||
}
|
||||
|
||||
@override
|
||||
String get discuss => 'Discuss';
|
||||
|
||||
@override
|
||||
String get pollType => 'Poll type';
|
||||
|
||||
|
|
@ -661,6 +680,12 @@ class L10nSv extends L10n {
|
|||
@override
|
||||
String get chatPermissions => 'Chatt-behörigheter';
|
||||
|
||||
@override
|
||||
String get chatThreads => 'Threads';
|
||||
|
||||
@override
|
||||
String get chatThreadsDescription => 'See all threads in this room';
|
||||
|
||||
@override
|
||||
String get editDisplayname => 'Ändra visningsnamn';
|
||||
|
||||
|
|
@ -2431,6 +2456,16 @@ class L10nSv extends L10n {
|
|||
@override
|
||||
String get restricted => 'Restricted';
|
||||
|
||||
@override
|
||||
String spaceMemberOf(String spaces) {
|
||||
return 'Space member of $spaces';
|
||||
}
|
||||
|
||||
@override
|
||||
String spaceMemberOfCanKnock(String spaces) {
|
||||
return 'Space member of $spaces can knock';
|
||||
}
|
||||
|
||||
@override
|
||||
String get knockRestricted => 'Knock restricted';
|
||||
|
||||
|
|
|
|||
|
|
@ -24,6 +24,22 @@ class L10nTa extends L10n {
|
|||
@override
|
||||
String get resume => 'Resume';
|
||||
|
||||
@override
|
||||
String get newSubSpace => 'New sub space';
|
||||
|
||||
@override
|
||||
String get moveToDifferentSpace => 'Move to different space';
|
||||
|
||||
@override
|
||||
String get moveUp => 'Move up';
|
||||
|
||||
@override
|
||||
String get moveDown => 'Move down';
|
||||
|
||||
@override
|
||||
String get removeFromSpaceDescription =>
|
||||
'The chat will be removed from the space but still appear in your chat list.';
|
||||
|
||||
@override
|
||||
String get endPoll => 'End poll';
|
||||
|
||||
|
|
@ -56,6 +72,9 @@ class L10nTa extends L10n {
|
|||
return '$selected of $max selected';
|
||||
}
|
||||
|
||||
@override
|
||||
String get discuss => 'Discuss';
|
||||
|
||||
@override
|
||||
String get pollType => 'Poll type';
|
||||
|
||||
|
|
@ -670,6 +689,12 @@ class L10nTa extends L10n {
|
|||
@override
|
||||
String get chatPermissions => 'அரட்டை அனுமதிகள்';
|
||||
|
||||
@override
|
||||
String get chatThreads => 'Threads';
|
||||
|
||||
@override
|
||||
String get chatThreadsDescription => 'See all threads in this room';
|
||||
|
||||
@override
|
||||
String get editDisplayname => 'காட்சி பெயர் திருத்து';
|
||||
|
||||
|
|
@ -2452,6 +2477,16 @@ class L10nTa extends L10n {
|
|||
@override
|
||||
String get restricted => 'தடைசெய்யப்பட்டது';
|
||||
|
||||
@override
|
||||
String spaceMemberOf(String spaces) {
|
||||
return 'Space member of $spaces';
|
||||
}
|
||||
|
||||
@override
|
||||
String spaceMemberOfCanKnock(String spaces) {
|
||||
return 'Space member of $spaces can knock';
|
||||
}
|
||||
|
||||
@override
|
||||
String get knockRestricted => 'நாக் தடை';
|
||||
|
||||
|
|
|
|||
|
|
@ -24,6 +24,22 @@ class L10nTe extends L10n {
|
|||
@override
|
||||
String get resume => 'Resume';
|
||||
|
||||
@override
|
||||
String get newSubSpace => 'New sub space';
|
||||
|
||||
@override
|
||||
String get moveToDifferentSpace => 'Move to different space';
|
||||
|
||||
@override
|
||||
String get moveUp => 'Move up';
|
||||
|
||||
@override
|
||||
String get moveDown => 'Move down';
|
||||
|
||||
@override
|
||||
String get removeFromSpaceDescription =>
|
||||
'The chat will be removed from the space but still appear in your chat list.';
|
||||
|
||||
@override
|
||||
String get endPoll => 'End poll';
|
||||
|
||||
|
|
@ -56,6 +72,9 @@ class L10nTe extends L10n {
|
|||
return '$selected of $max selected';
|
||||
}
|
||||
|
||||
@override
|
||||
String get discuss => 'Discuss';
|
||||
|
||||
@override
|
||||
String get pollType => 'Poll type';
|
||||
|
||||
|
|
@ -660,6 +679,12 @@ class L10nTe extends L10n {
|
|||
@override
|
||||
String get chatPermissions => 'Chat permissions';
|
||||
|
||||
@override
|
||||
String get chatThreads => 'Threads';
|
||||
|
||||
@override
|
||||
String get chatThreadsDescription => 'See all threads in this room';
|
||||
|
||||
@override
|
||||
String get editDisplayname => 'Edit displayname';
|
||||
|
||||
|
|
@ -2421,6 +2446,16 @@ class L10nTe extends L10n {
|
|||
@override
|
||||
String get restricted => 'Restricted';
|
||||
|
||||
@override
|
||||
String spaceMemberOf(String spaces) {
|
||||
return 'Space member of $spaces';
|
||||
}
|
||||
|
||||
@override
|
||||
String spaceMemberOfCanKnock(String spaces) {
|
||||
return 'Space member of $spaces can knock';
|
||||
}
|
||||
|
||||
@override
|
||||
String get knockRestricted => 'Knock restricted';
|
||||
|
||||
|
|
|
|||
|
|
@ -24,6 +24,22 @@ class L10nTh extends L10n {
|
|||
@override
|
||||
String get resume => 'Resume';
|
||||
|
||||
@override
|
||||
String get newSubSpace => 'New sub space';
|
||||
|
||||
@override
|
||||
String get moveToDifferentSpace => 'Move to different space';
|
||||
|
||||
@override
|
||||
String get moveUp => 'Move up';
|
||||
|
||||
@override
|
||||
String get moveDown => 'Move down';
|
||||
|
||||
@override
|
||||
String get removeFromSpaceDescription =>
|
||||
'The chat will be removed from the space but still appear in your chat list.';
|
||||
|
||||
@override
|
||||
String get endPoll => 'End poll';
|
||||
|
||||
|
|
@ -56,6 +72,9 @@ class L10nTh extends L10n {
|
|||
return '$selected of $max selected';
|
||||
}
|
||||
|
||||
@override
|
||||
String get discuss => 'Discuss';
|
||||
|
||||
@override
|
||||
String get pollType => 'Poll type';
|
||||
|
||||
|
|
@ -662,6 +681,12 @@ class L10nTh extends L10n {
|
|||
@override
|
||||
String get chatPermissions => 'Chat permissions';
|
||||
|
||||
@override
|
||||
String get chatThreads => 'Threads';
|
||||
|
||||
@override
|
||||
String get chatThreadsDescription => 'See all threads in this room';
|
||||
|
||||
@override
|
||||
String get editDisplayname => 'Edit displayname';
|
||||
|
||||
|
|
@ -2423,6 +2448,16 @@ class L10nTh extends L10n {
|
|||
@override
|
||||
String get restricted => 'Restricted';
|
||||
|
||||
@override
|
||||
String spaceMemberOf(String spaces) {
|
||||
return 'Space member of $spaces';
|
||||
}
|
||||
|
||||
@override
|
||||
String spaceMemberOfCanKnock(String spaces) {
|
||||
return 'Space member of $spaces can knock';
|
||||
}
|
||||
|
||||
@override
|
||||
String get knockRestricted => 'Knock restricted';
|
||||
|
||||
|
|
|
|||
|
|
@ -24,6 +24,22 @@ class L10nTr extends L10n {
|
|||
@override
|
||||
String get resume => 'Resume';
|
||||
|
||||
@override
|
||||
String get newSubSpace => 'New sub space';
|
||||
|
||||
@override
|
||||
String get moveToDifferentSpace => 'Move to different space';
|
||||
|
||||
@override
|
||||
String get moveUp => 'Move up';
|
||||
|
||||
@override
|
||||
String get moveDown => 'Move down';
|
||||
|
||||
@override
|
||||
String get removeFromSpaceDescription =>
|
||||
'The chat will be removed from the space but still appear in your chat list.';
|
||||
|
||||
@override
|
||||
String get endPoll => 'End poll';
|
||||
|
||||
|
|
@ -56,6 +72,9 @@ class L10nTr extends L10n {
|
|||
return '$selected of $max selected';
|
||||
}
|
||||
|
||||
@override
|
||||
String get discuss => 'Discuss';
|
||||
|
||||
@override
|
||||
String get pollType => 'Poll type';
|
||||
|
||||
|
|
@ -662,6 +681,12 @@ class L10nTr extends L10n {
|
|||
@override
|
||||
String get chatPermissions => 'Sohbet izinleri';
|
||||
|
||||
@override
|
||||
String get chatThreads => 'Threads';
|
||||
|
||||
@override
|
||||
String get chatThreadsDescription => 'See all threads in this room';
|
||||
|
||||
@override
|
||||
String get editDisplayname => 'Görünen adı düzenle';
|
||||
|
||||
|
|
@ -2431,6 +2456,16 @@ class L10nTr extends L10n {
|
|||
@override
|
||||
String get restricted => 'Kısıtlı';
|
||||
|
||||
@override
|
||||
String spaceMemberOf(String spaces) {
|
||||
return 'Space member of $spaces';
|
||||
}
|
||||
|
||||
@override
|
||||
String spaceMemberOfCanKnock(String spaces) {
|
||||
return 'Space member of $spaces can knock';
|
||||
}
|
||||
|
||||
@override
|
||||
String get knockRestricted => 'Tıklatma kısıtlı';
|
||||
|
||||
|
|
|
|||
|
|
@ -24,6 +24,22 @@ class L10nUk extends L10n {
|
|||
@override
|
||||
String get resume => 'Resume';
|
||||
|
||||
@override
|
||||
String get newSubSpace => 'New sub space';
|
||||
|
||||
@override
|
||||
String get moveToDifferentSpace => 'Move to different space';
|
||||
|
||||
@override
|
||||
String get moveUp => 'Move up';
|
||||
|
||||
@override
|
||||
String get moveDown => 'Move down';
|
||||
|
||||
@override
|
||||
String get removeFromSpaceDescription =>
|
||||
'The chat will be removed from the space but still appear in your chat list.';
|
||||
|
||||
@override
|
||||
String get endPoll => 'End poll';
|
||||
|
||||
|
|
@ -56,6 +72,9 @@ class L10nUk extends L10n {
|
|||
return '$selected of $max selected';
|
||||
}
|
||||
|
||||
@override
|
||||
String get discuss => 'Discuss';
|
||||
|
||||
@override
|
||||
String get pollType => 'Poll type';
|
||||
|
||||
|
|
@ -664,6 +683,12 @@ class L10nUk extends L10n {
|
|||
@override
|
||||
String get chatPermissions => 'Дозволи бесіди';
|
||||
|
||||
@override
|
||||
String get chatThreads => 'Threads';
|
||||
|
||||
@override
|
||||
String get chatThreadsDescription => 'See all threads in this room';
|
||||
|
||||
@override
|
||||
String get editDisplayname => 'Змінити показуване ім\'я';
|
||||
|
||||
|
|
@ -2434,6 +2459,16 @@ class L10nUk extends L10n {
|
|||
@override
|
||||
String get restricted => 'Обмежено';
|
||||
|
||||
@override
|
||||
String spaceMemberOf(String spaces) {
|
||||
return 'Space member of $spaces';
|
||||
}
|
||||
|
||||
@override
|
||||
String spaceMemberOfCanKnock(String spaces) {
|
||||
return 'Space member of $spaces can knock';
|
||||
}
|
||||
|
||||
@override
|
||||
String get knockRestricted => 'Стук обмежено';
|
||||
|
||||
|
|
|
|||
|
|
@ -24,6 +24,22 @@ class L10nVi extends L10n {
|
|||
@override
|
||||
String get resume => 'Resume';
|
||||
|
||||
@override
|
||||
String get newSubSpace => 'New sub space';
|
||||
|
||||
@override
|
||||
String get moveToDifferentSpace => 'Move to different space';
|
||||
|
||||
@override
|
||||
String get moveUp => 'Move up';
|
||||
|
||||
@override
|
||||
String get moveDown => 'Move down';
|
||||
|
||||
@override
|
||||
String get removeFromSpaceDescription =>
|
||||
'The chat will be removed from the space but still appear in your chat list.';
|
||||
|
||||
@override
|
||||
String get endPoll => 'End poll';
|
||||
|
||||
|
|
@ -56,6 +72,9 @@ class L10nVi extends L10n {
|
|||
return '$selected of $max selected';
|
||||
}
|
||||
|
||||
@override
|
||||
String get discuss => 'Discuss';
|
||||
|
||||
@override
|
||||
String get pollType => 'Poll type';
|
||||
|
||||
|
|
@ -660,6 +679,12 @@ class L10nVi extends L10n {
|
|||
@override
|
||||
String get chatPermissions => 'Chat permissions';
|
||||
|
||||
@override
|
||||
String get chatThreads => 'Threads';
|
||||
|
||||
@override
|
||||
String get chatThreadsDescription => 'See all threads in this room';
|
||||
|
||||
@override
|
||||
String get editDisplayname => 'Sửa tên hiển thị';
|
||||
|
||||
|
|
@ -2420,6 +2445,16 @@ class L10nVi extends L10n {
|
|||
@override
|
||||
String get restricted => 'Bị hạn chế';
|
||||
|
||||
@override
|
||||
String spaceMemberOf(String spaces) {
|
||||
return 'Space member of $spaces';
|
||||
}
|
||||
|
||||
@override
|
||||
String spaceMemberOfCanKnock(String spaces) {
|
||||
return 'Space member of $spaces can knock';
|
||||
}
|
||||
|
||||
@override
|
||||
String get knockRestricted => 'Knock restricted';
|
||||
|
||||
|
|
|
|||
|
|
@ -24,6 +24,22 @@ class L10nZh extends L10n {
|
|||
@override
|
||||
String get resume => 'Resume';
|
||||
|
||||
@override
|
||||
String get newSubSpace => 'New sub space';
|
||||
|
||||
@override
|
||||
String get moveToDifferentSpace => 'Move to different space';
|
||||
|
||||
@override
|
||||
String get moveUp => 'Move up';
|
||||
|
||||
@override
|
||||
String get moveDown => 'Move down';
|
||||
|
||||
@override
|
||||
String get removeFromSpaceDescription =>
|
||||
'The chat will be removed from the space but still appear in your chat list.';
|
||||
|
||||
@override
|
||||
String get endPoll => 'End poll';
|
||||
|
||||
|
|
@ -56,6 +72,9 @@ class L10nZh extends L10n {
|
|||
return '$selected of $max selected';
|
||||
}
|
||||
|
||||
@override
|
||||
String get discuss => 'Discuss';
|
||||
|
||||
@override
|
||||
String get pollType => 'Poll type';
|
||||
|
||||
|
|
@ -644,6 +663,12 @@ class L10nZh extends L10n {
|
|||
@override
|
||||
String get chatPermissions => '聊天权限';
|
||||
|
||||
@override
|
||||
String get chatThreads => 'Threads';
|
||||
|
||||
@override
|
||||
String get chatThreadsDescription => 'See all threads in this room';
|
||||
|
||||
@override
|
||||
String get editDisplayname => '编辑昵称';
|
||||
|
||||
|
|
@ -2346,6 +2371,16 @@ class L10nZh extends L10n {
|
|||
@override
|
||||
String get restricted => '受限';
|
||||
|
||||
@override
|
||||
String spaceMemberOf(String spaces) {
|
||||
return 'Space member of $spaces';
|
||||
}
|
||||
|
||||
@override
|
||||
String spaceMemberOfCanKnock(String spaces) {
|
||||
return 'Space member of $spaces can knock';
|
||||
}
|
||||
|
||||
@override
|
||||
String get knockRestricted => '“请求加入”请求受限';
|
||||
|
||||
|
|
|
|||
|
|
@ -51,12 +51,14 @@ class ChatPage extends StatelessWidget {
|
|||
final String roomId;
|
||||
final List<ShareItem>? shareItems;
|
||||
final String? eventId;
|
||||
final bool? showThreadRoots;
|
||||
|
||||
const ChatPage({
|
||||
super.key,
|
||||
required this.roomId,
|
||||
this.eventId,
|
||||
this.shareItems,
|
||||
this.showThreadRoots,
|
||||
});
|
||||
|
||||
@override
|
||||
|
|
@ -79,20 +81,25 @@ class ChatPage extends StatelessWidget {
|
|||
room: room,
|
||||
shareItems: shareItems,
|
||||
eventId: eventId,
|
||||
showThreadRoots: showThreadRoots,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class ChatPageWithRoom extends StatefulWidget {
|
||||
final Room room;
|
||||
final Thread? thread;
|
||||
final List<ShareItem>? shareItems;
|
||||
final String? eventId;
|
||||
final bool? showThreadRoots;
|
||||
|
||||
const ChatPageWithRoom({
|
||||
super.key,
|
||||
required this.room,
|
||||
this.thread,
|
||||
this.shareItems,
|
||||
this.eventId,
|
||||
this.showThreadRoots,
|
||||
});
|
||||
|
||||
@override
|
||||
|
|
@ -102,6 +109,10 @@ class ChatPageWithRoom extends StatefulWidget {
|
|||
class ChatController extends State<ChatPageWithRoom>
|
||||
with WidgetsBindingObserver {
|
||||
Room get room => sendingClient.getRoomById(roomId) ?? widget.room;
|
||||
bool get showThreadRoots => (widget.showThreadRoots ?? false);
|
||||
Thread? get thread =>
|
||||
sendingClient.getRoomById(roomId)?.threads[threadRootEventId] ??
|
||||
widget.room.threads[threadRootEventId];
|
||||
|
||||
late Client sendingClient;
|
||||
|
||||
|
|
@ -110,6 +121,7 @@ class ChatController extends State<ChatPageWithRoom>
|
|||
late final String readMarkerEventId;
|
||||
|
||||
String get roomId => widget.room.id;
|
||||
String? get threadRootEventId => widget.thread?.rootEvent.eventId;
|
||||
|
||||
final AutoScrollController scrollController = AutoScrollController();
|
||||
|
||||
|
|
@ -134,6 +146,7 @@ class ChatController extends State<ChatPageWithRoom>
|
|||
builder: (c) => SendFileDialog(
|
||||
files: details.files,
|
||||
room: room,
|
||||
thread: thread,
|
||||
replyEvent: replyEvent,
|
||||
outerContext: context,
|
||||
),
|
||||
|
|
@ -274,6 +287,7 @@ class ChatController extends State<ChatPageWithRoom>
|
|||
builder: (c) => SendFileDialog(
|
||||
files: files,
|
||||
room: room,
|
||||
thread: thread,
|
||||
outerContext: context,
|
||||
replyEvent: replyEvent,
|
||||
),
|
||||
|
|
@ -317,11 +331,14 @@ class ChatController extends State<ChatPageWithRoom>
|
|||
if (kIsWeb) {
|
||||
onFocusSub = html.window.onFocus.listen((_) => setReadMarker());
|
||||
}
|
||||
|
||||
_getThreads();
|
||||
}
|
||||
|
||||
void _tryLoadTimeline() async {
|
||||
final initialEventId = widget.eventId;
|
||||
loadTimelineFuture = _getTimeline();
|
||||
Logs().v("Trying to load timeline...");
|
||||
try {
|
||||
await loadTimelineFuture;
|
||||
if (initialEventId != null) scrollToEventId(initialEventId);
|
||||
|
|
@ -369,13 +386,32 @@ class ChatController extends State<ChatPageWithRoom>
|
|||
scrollUpBannerEventId = eventId;
|
||||
});
|
||||
|
||||
void updateView() {
|
||||
Future<void> updateView() async {
|
||||
if (!mounted) return;
|
||||
setReadMarker();
|
||||
await updateThreads();
|
||||
setState(() {});
|
||||
}
|
||||
|
||||
Future<void> updateThreads() async {
|
||||
if (timeline?.events == null) return;
|
||||
final lastEvent = timeline?.events[timeline!.events.length - 1];
|
||||
|
||||
if (lastEvent == null) return;
|
||||
if (lastEvent.relationshipType == RelationshipTypes.thread &&
|
||||
lastEvent.relationshipEventId != null) {
|
||||
final thread = await room.client.database
|
||||
.getThread(room.id, lastEvent.relationshipEventId!, room.client);
|
||||
if (thread != null) {
|
||||
setState(() {
|
||||
threads?[lastEvent.eventId] = thread;
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Future<void>? loadTimelineFuture;
|
||||
Map<String, Thread>? threads = {};
|
||||
|
||||
int? animateInEventIndex;
|
||||
|
||||
|
|
@ -384,15 +420,7 @@ class ChatController extends State<ChatPageWithRoom>
|
|||
animateInEventIndex = i;
|
||||
}
|
||||
|
||||
Future<void> _getTimeline({
|
||||
String? eventContextId,
|
||||
}) async {
|
||||
await Matrix.of(context).client.roomsLoading;
|
||||
await Matrix.of(context).client.accountDataLoading;
|
||||
if (eventContextId != null &&
|
||||
(!eventContextId.isValidMatrixId || eventContextId.sigil != '\$')) {
|
||||
eventContextId = null;
|
||||
}
|
||||
Future<void> _loadRoomTimeline({String? eventContextId}) async {
|
||||
try {
|
||||
timeline?.cancelSubscriptions();
|
||||
timeline = await room.getTimeline(
|
||||
|
|
@ -412,12 +440,72 @@ class ChatController extends State<ChatPageWithRoom>
|
|||
_showScrollUpMaterialBanner(eventContextId!);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> _loadThreadTimeline({String? eventContextId}) async {
|
||||
if (thread == null) {
|
||||
throw Exception(
|
||||
"_loadThreadTimeline should not be called, thread == null",
|
||||
);
|
||||
}
|
||||
try {
|
||||
timeline?.cancelSubscriptions();
|
||||
timeline = await thread!.getTimeline(
|
||||
onUpdate: updateView,
|
||||
eventContextId: eventContextId,
|
||||
onInsert: onInsert,
|
||||
);
|
||||
Logs().v("Thread timeline loaded");
|
||||
} catch (e, s) {
|
||||
Logs().w(
|
||||
'Unable to load timeline on event ID $eventContextId (in thread)',
|
||||
e,
|
||||
s,
|
||||
);
|
||||
if (!mounted) return;
|
||||
timeline = await thread!.getTimeline(
|
||||
onUpdate: updateView,
|
||||
onInsert: onInsert,
|
||||
);
|
||||
if (!mounted) return;
|
||||
if (e is TimeoutException || e is IOException) {
|
||||
_showScrollUpMaterialBanner(eventContextId!);
|
||||
}
|
||||
}
|
||||
if (timeline is ThreadTimeline) {
|
||||
(timeline as ThreadTimeline).getThreadEvents();
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> _getTimeline({
|
||||
String? eventContextId,
|
||||
}) async {
|
||||
await Matrix.of(context).client.roomsLoading;
|
||||
await Matrix.of(context).client.accountDataLoading;
|
||||
if (eventContextId != null &&
|
||||
(!eventContextId.isValidMatrixId || eventContextId.sigil != '\$')) {
|
||||
eventContextId = null;
|
||||
}
|
||||
if (thread == null) {
|
||||
await _loadRoomTimeline(eventContextId: eventContextId);
|
||||
} else {
|
||||
await _loadThreadTimeline(eventContextId: eventContextId);
|
||||
}
|
||||
timeline!.requestKeys(onlineKeyBackupOnly: false);
|
||||
if (room.markedUnread) room.markUnread(false);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
Future<void> _getThreads() async {
|
||||
try {
|
||||
threads = await room.getThreads();
|
||||
Logs().w('Thread amount: ${threads?.length}');
|
||||
} catch (e, s) {
|
||||
Logs().w('Unable to load threads in $roomId', e, s);
|
||||
}
|
||||
}
|
||||
|
||||
String? scrollToEventIdMarker;
|
||||
|
||||
@override
|
||||
|
|
@ -459,10 +547,14 @@ class ChatController extends State<ChatPageWithRoom>
|
|||
.then((_) {
|
||||
_setReadMarkerFuture = null;
|
||||
});
|
||||
|
||||
if (timeline is RoomTimeline) {
|
||||
if (eventId == null || eventId == timeline.room.lastEvent?.eventId) {
|
||||
Matrix.of(context).backgroundPush?.cancelNotification(roomId);
|
||||
}
|
||||
}
|
||||
// TODO same for Threads
|
||||
}
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
|
|
@ -533,6 +625,9 @@ class ChatController extends State<ChatPageWithRoom>
|
|||
inReplyTo: replyEvent,
|
||||
editEventId: editEvent?.eventId,
|
||||
parseCommands: parseCommands,
|
||||
threadRootEventId: thread?.rootEvent.eventId,
|
||||
threadLastEventId:
|
||||
thread?.lastEvent?.eventId ?? thread?.rootEvent.eventId,
|
||||
);
|
||||
sendController.value = TextEditingValue(
|
||||
text: pendingText,
|
||||
|
|
@ -551,7 +646,12 @@ class ChatController extends State<ChatPageWithRoom>
|
|||
void sendPollAction() async {
|
||||
await showAdaptiveDialog(
|
||||
context: context,
|
||||
builder: (c) => SendPollDialog(room: room, outerContext: context));
|
||||
builder: (c) => SendPollDialog(
|
||||
room: room,
|
||||
thread: thread,
|
||||
outerContext: context,
|
||||
),
|
||||
);
|
||||
replyEvent = null;
|
||||
}
|
||||
|
||||
|
|
@ -570,6 +670,7 @@ class ChatController extends State<ChatPageWithRoom>
|
|||
builder: (c) => SendFileDialog(
|
||||
files: files,
|
||||
room: room,
|
||||
thread: thread,
|
||||
outerContext: context,
|
||||
replyEvent: replyEvent,
|
||||
),
|
||||
|
|
@ -584,6 +685,7 @@ class ChatController extends State<ChatPageWithRoom>
|
|||
builder: (c) => SendFileDialog(
|
||||
files: [XFile.fromData(image)],
|
||||
room: room,
|
||||
thread: thread,
|
||||
outerContext: context,
|
||||
),
|
||||
);
|
||||
|
|
@ -600,6 +702,7 @@ class ChatController extends State<ChatPageWithRoom>
|
|||
builder: (c) => SendFileDialog(
|
||||
files: [file],
|
||||
room: room,
|
||||
thread: thread,
|
||||
outerContext: context,
|
||||
),
|
||||
);
|
||||
|
|
@ -619,6 +722,7 @@ class ChatController extends State<ChatPageWithRoom>
|
|||
builder: (c) => SendFileDialog(
|
||||
files: [file],
|
||||
room: room,
|
||||
thread: thread,
|
||||
outerContext: context,
|
||||
),
|
||||
);
|
||||
|
|
@ -645,7 +749,8 @@ class ChatController extends State<ChatPageWithRoom>
|
|||
name: fileName ?? audioFile.path,
|
||||
);
|
||||
|
||||
await room.sendFileEvent(
|
||||
await room
|
||||
.sendFileEvent(
|
||||
file,
|
||||
inReplyTo: replyEvent,
|
||||
extraContent: {
|
||||
|
|
@ -659,7 +764,10 @@ class ChatController extends State<ChatPageWithRoom>
|
|||
'waveform': waveform,
|
||||
},
|
||||
},
|
||||
).catchError((e) {
|
||||
threadLastEventId: thread?.lastEvent?.eventId,
|
||||
threadRootEventId: thread?.rootEvent.eventId,
|
||||
)
|
||||
.catchError((e) {
|
||||
scaffoldMessenger.showSnackBar(
|
||||
SnackBar(
|
||||
content: Text(
|
||||
|
|
@ -698,7 +806,10 @@ class ChatController extends State<ChatPageWithRoom>
|
|||
void sendLocationAction() async {
|
||||
await showAdaptiveDialog(
|
||||
context: context,
|
||||
builder: (c) => SendLocationDialog(room: room),
|
||||
builder: (c) => SendLocationDialog(
|
||||
room: room,
|
||||
thread: thread,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
|
|
@ -744,7 +855,8 @@ class ChatController extends State<ChatPageWithRoom>
|
|||
|
||||
final reports = await mx.client.getEventReports();
|
||||
final report = reports.firstWhere(
|
||||
(rep) => rep['room_id'] == roomId && rep['event_id'] == event.eventId);
|
||||
(rep) => rep['room_id'] == roomId && rep['event_id'] == event.eventId,
|
||||
);
|
||||
final recoveredEvent = await mx.client.getReportedEvent(report['id']);
|
||||
|
||||
if (recoveredEvent == null) {
|
||||
|
|
@ -754,7 +866,8 @@ class ChatController extends State<ChatPageWithRoom>
|
|||
return;
|
||||
}
|
||||
|
||||
Navigator.of(context).push(new MaterialPageRoute(
|
||||
Navigator.of(context).push(
|
||||
MaterialPageRoute(
|
||||
builder: (BuildContext ctx) {
|
||||
return RecoveredEventDialog(
|
||||
event: recoveredEvent,
|
||||
|
|
@ -762,7 +875,8 @@ class ChatController extends State<ChatPageWithRoom>
|
|||
);
|
||||
},
|
||||
fullscreenDialog: true,
|
||||
));
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
void translateEventAction() async {
|
||||
|
|
@ -774,10 +888,12 @@ class ChatController extends State<ChatPageWithRoom>
|
|||
}
|
||||
final event = selectedEvents.single;
|
||||
var text = event.isRichMessage ? event.formattedText : event.text;
|
||||
var content = {...event.content};
|
||||
final content = {...event.content};
|
||||
try {
|
||||
text = await Translator.translate(
|
||||
text, PlatformDispatcher.instance.locale.languageCode);
|
||||
text,
|
||||
PlatformDispatcher.instance.locale.languageCode,
|
||||
);
|
||||
} catch (e) {
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
SnackBar(content: Text(L10n.of(context).errorTranslatingMessage)),
|
||||
|
|
@ -790,19 +906,24 @@ class ChatController extends State<ChatPageWithRoom>
|
|||
content['body'] = text;
|
||||
}
|
||||
content['xyz.extera.translated'] = true;
|
||||
Navigator.of(context).push(new MaterialPageRoute(
|
||||
Navigator.of(context).push(
|
||||
MaterialPageRoute(
|
||||
builder: (BuildContext ctx) {
|
||||
return TranslatedEventDialog(
|
||||
event: new Event(
|
||||
event: Event(
|
||||
content: content,
|
||||
type: 'm.room.message',
|
||||
eventId: event.eventId,
|
||||
senderId: event.senderId,
|
||||
originServerTs: event.originServerTs,
|
||||
room: room),
|
||||
timeline: timeline!);
|
||||
room: room,
|
||||
),
|
||||
timeline: timeline!,
|
||||
);
|
||||
},
|
||||
fullscreenDialog: true));
|
||||
fullscreenDialog: true,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
void reportEventAction() async {
|
||||
|
|
@ -871,20 +992,43 @@ class ChatController extends State<ChatPageWithRoom>
|
|||
}
|
||||
}
|
||||
|
||||
void discussAction() async {
|
||||
final event = selectedEvents.first;
|
||||
if (!room.threads.containsKey(event.eventId)) {
|
||||
room.threads[event.eventId] = Thread(
|
||||
room: room,
|
||||
rootEvent: event,
|
||||
client: room.client,
|
||||
currentUserParticipated: false,
|
||||
count: 0,
|
||||
highlightCount: 0,
|
||||
notificationCount: 0,
|
||||
);
|
||||
}
|
||||
|
||||
context.go('/rooms/$roomId/threads/${event.eventId}');
|
||||
selectedEvents.clear();
|
||||
}
|
||||
|
||||
void endPollAction() async {
|
||||
final event = selectedEvents.first;
|
||||
if (event == null) return;
|
||||
final client = currentRoomBundle.firstWhere(
|
||||
(cl) => selectedEvents.first.senderId == cl!.userID,
|
||||
orElse: () => null,
|
||||
);
|
||||
if (client == null) return;
|
||||
if (event.senderId != client!.userID) return;
|
||||
await room.sendEvent({
|
||||
if (event.senderId != client.userID) return;
|
||||
await room.sendEvent(
|
||||
{
|
||||
'org.matrix.msc1767.text': 'Ended poll',
|
||||
'm.relates_to': {'rel_type': 'm.reference', 'event_id': event.eventId},
|
||||
'body': 'Ended poll'
|
||||
}, type: 'org.matrix.msc3381.poll.end');
|
||||
'm.relates_to': {
|
||||
'rel_type': 'm.reference',
|
||||
'event_id': event.eventId,
|
||||
},
|
||||
'body': 'Ended poll',
|
||||
},
|
||||
type: 'org.matrix.msc3381.poll.end',
|
||||
);
|
||||
}
|
||||
|
||||
void redactEventsAction() async {
|
||||
|
|
|
|||
|
|
@ -31,21 +31,39 @@ class ChatAppBarTitle extends StatelessWidget {
|
|||
hoverColor: Colors.transparent,
|
||||
splashColor: Colors.transparent,
|
||||
highlightColor: Colors.transparent,
|
||||
onTap: controller.isArchived
|
||||
? null
|
||||
: () => FluffyThemes.isThreeColumnMode(context)
|
||||
? controller.toggleDisplayChatDetailsColumn()
|
||||
: context.go('/rooms/${room.id}/details'),
|
||||
onTap: () {
|
||||
if (controller.thread != null) {
|
||||
if (context.canPop()) {
|
||||
context.pop();
|
||||
} else {
|
||||
context.go('/rooms/${room.id}');
|
||||
}
|
||||
return;
|
||||
}
|
||||
if (!controller.isArchived) {
|
||||
if (FluffyThemes.isThreeColumnMode(context)) {
|
||||
controller.toggleDisplayChatDetailsColumn();
|
||||
} else {
|
||||
context.go('/rooms/${room.id}/details');
|
||||
}
|
||||
}
|
||||
},
|
||||
child: Row(
|
||||
children: [
|
||||
Hero(
|
||||
tag: 'content_banner',
|
||||
child: Avatar(
|
||||
child: controller.thread == null
|
||||
? Avatar(
|
||||
mxContent: room.avatar,
|
||||
name: room.getLocalizedDisplayname(
|
||||
MatrixLocals(L10n.of(context)),
|
||||
),
|
||||
size: 32,
|
||||
)
|
||||
: Icon(
|
||||
Icons.chat_bubble_outline,
|
||||
color: Colors.grey[200],
|
||||
size: 20,
|
||||
),
|
||||
),
|
||||
const SizedBox(width: 12),
|
||||
|
|
@ -54,7 +72,10 @@ class ChatAppBarTitle extends StatelessWidget {
|
|||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
room.getLocalizedDisplayname(MatrixLocals(L10n.of(context))),
|
||||
controller.thread == null
|
||||
? room.getLocalizedDisplayname(
|
||||
MatrixLocals(L10n.of(context)))
|
||||
: '${controller.thread!.rootEvent.senderFromMemoryOrFallback.displayName ?? controller.thread!.rootEvent.senderId}: ${controller.thread!.rootEvent.text}',
|
||||
maxLines: 1,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
style: const TextStyle(
|
||||
|
|
|
|||
|
|
@ -15,10 +15,12 @@ import 'package:extera_next/utils/platform_infos.dart';
|
|||
|
||||
class ChatEventList extends StatelessWidget {
|
||||
final ChatController controller;
|
||||
final bool showThreadRoots;
|
||||
|
||||
const ChatEventList({
|
||||
super.key,
|
||||
required this.controller,
|
||||
this.showThreadRoots = false,
|
||||
});
|
||||
|
||||
@override
|
||||
|
|
@ -37,8 +39,18 @@ class ChatEventList extends StatelessWidget {
|
|||
|
||||
final horizontalPadding = FluffyThemes.isColumnMode(context) ? 8.0 : 0.0;
|
||||
|
||||
final events = timeline.events.filterByVisibleInGui();
|
||||
var events = timeline.events;
|
||||
|
||||
if (showThreadRoots) {
|
||||
events = events.filterThreadRoots();
|
||||
} else {
|
||||
events = events.filterByThreaded(controller.thread != null);
|
||||
}
|
||||
|
||||
events = events.filterByVisibleInGui();
|
||||
|
||||
final animateInEventIndex = controller.animateInEventIndex;
|
||||
final threads = controller.room.threads;
|
||||
|
||||
// create a map of eventId --> index to greatly improve performance of
|
||||
// ListView's findChildIndexCallback
|
||||
|
|
@ -121,6 +133,10 @@ class ChatEventList extends StatelessWidget {
|
|||
timeline.events.length > animateInEventIndex &&
|
||||
event == timeline.events[animateInEventIndex];
|
||||
|
||||
final thread = threads.containsKey(event.eventId)
|
||||
? threads[event.eventId]
|
||||
: null;
|
||||
|
||||
return AutoScrollTag(
|
||||
key: ValueKey(event.eventId),
|
||||
index: i,
|
||||
|
|
@ -128,6 +144,7 @@ class ChatEventList extends StatelessWidget {
|
|||
child: Message(
|
||||
event,
|
||||
animateIn: animateIn,
|
||||
thread: thread,
|
||||
resetAnimateIn: () {
|
||||
controller.animateInEventIndex = null;
|
||||
},
|
||||
|
|
|
|||
|
|
@ -48,7 +48,15 @@ class ChatView extends StatelessWidget {
|
|||
tooltip: L10n.of(context).copy,
|
||||
onPressed: controller.copyEventsAction,
|
||||
),
|
||||
if (controller.selectedEvents.length == 1 && controller.selectedEvents.single.content['xyz.extera.translated'] == null)
|
||||
if (controller.selectedEvents.length == 1)
|
||||
IconButton(
|
||||
onPressed: controller.discussAction,
|
||||
icon: const Icon(Icons.chat_bubble_outline),
|
||||
tooltip: L10n.of(context).discuss,
|
||||
),
|
||||
if (controller.selectedEvents.length == 1 &&
|
||||
controller.selectedEvents.single.content['xyz.extera.translated'] ==
|
||||
null)
|
||||
IconButton(
|
||||
icon: const Icon(Icons.translate_outlined),
|
||||
tooltip: L10n.of(context).translateMessage,
|
||||
|
|
@ -118,8 +126,10 @@ class ChatView extends StatelessWidget {
|
|||
Text(L10n.of(context).recoverMessage),
|
||||
]),
|
||||
),
|
||||
if (controller.selectedEvents.single.type == 'org.matrix.msc3381.poll.start' && controller.selectedEvents.single.senderId == Matrix.of(context).client.userID)
|
||||
|
||||
if (controller.selectedEvents.single.type ==
|
||||
'org.matrix.msc3381.poll.start' &&
|
||||
controller.selectedEvents.single.senderId ==
|
||||
Matrix.of(context).client.userID)
|
||||
PopupMenuItem(
|
||||
value: _EventContextAction.endPoll,
|
||||
child: Row(
|
||||
|
|
@ -318,7 +328,10 @@ class ChatView extends StatelessWidget {
|
|||
Expanded(
|
||||
child: GestureDetector(
|
||||
onTap: controller.clearSingleSelectedEvent,
|
||||
child: ChatEventList(controller: controller),
|
||||
child: ChatEventList(
|
||||
controller: controller,
|
||||
showThreadRoots: controller.showThreadRoots,
|
||||
),
|
||||
),
|
||||
),
|
||||
if (controller.showScrollDownButton)
|
||||
|
|
@ -337,7 +350,8 @@ class ChatView extends StatelessWidget {
|
|||
),
|
||||
)
|
||||
else if (controller.room.canSendDefaultMessages &&
|
||||
controller.room.membership == Membership.join)
|
||||
controller.room.membership == Membership.join &&
|
||||
!controller.showThreadRoots)
|
||||
Container(
|
||||
margin: EdgeInsets.all(bottomSheetPadding),
|
||||
constraints: const BoxConstraints(
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@ import 'package:flutter/material.dart';
|
|||
import 'package:flutter/services.dart';
|
||||
|
||||
import 'package:extera_next/generated/l10n/l10n.dart';
|
||||
import 'package:go_router/go_router.dart';
|
||||
import 'package:matrix/matrix.dart';
|
||||
import 'package:swipe_to_action/swipe_to_action.dart';
|
||||
|
||||
|
|
@ -45,6 +46,7 @@ class Message extends StatelessWidget {
|
|||
final List<Color> colors;
|
||||
final bool gradient;
|
||||
final bool singleSelected;
|
||||
final Thread? thread;
|
||||
|
||||
const Message(
|
||||
this.event, {
|
||||
|
|
@ -54,6 +56,7 @@ class Message extends StatelessWidget {
|
|||
this.longPressSelect = false,
|
||||
this.gradient = false,
|
||||
this.singleSelected = false,
|
||||
this.thread,
|
||||
required this.onSelect,
|
||||
required this.onInfoTab,
|
||||
required this.scrollToEventId,
|
||||
|
|
@ -688,6 +691,59 @@ class Message extends StatelessWidget {
|
|||
: const SizedBox.shrink(),
|
||||
),
|
||||
),
|
||||
thread != null
|
||||
? Align(
|
||||
alignment: ownMessage
|
||||
? Alignment.bottomRight
|
||||
: Alignment.bottomLeft,
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(8.0),
|
||||
child: InkWell(
|
||||
child: Row(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
Icon(
|
||||
(thread?.hasNewMessages ?? false) ? Icons.mark_chat_unread_outlined : Icons.chat_bubble_outline,
|
||||
color: Colors.grey[200],
|
||||
size: 20,
|
||||
),
|
||||
const SizedBox(width: 16),
|
||||
thread!.lastEvent != null
|
||||
? FutureBuilder<User?>(
|
||||
future: thread!.lastEvent!
|
||||
.fetchSenderUser(),
|
||||
builder:
|
||||
(context, snapshot) {
|
||||
final user = snapshot
|
||||
.data ??
|
||||
event
|
||||
.senderFromMemoryOrFallback;
|
||||
|
||||
return Avatar(
|
||||
mxContent:
|
||||
user.avatarUrl,
|
||||
name: user
|
||||
.calcDisplayname(),
|
||||
size: 24,
|
||||
);
|
||||
},
|
||||
)
|
||||
: const SizedBox.shrink(),
|
||||
const SizedBox(width: 6),
|
||||
thread!.lastEvent != null
|
||||
? Text(
|
||||
thread!.lastEvent!.text,
|
||||
)
|
||||
: const Text('Thread'),
|
||||
],
|
||||
),
|
||||
onTap: () => context.go(
|
||||
'/rooms/${event.roomId}/threads/${event.eventId}',
|
||||
),
|
||||
),
|
||||
),
|
||||
)
|
||||
: const SizedBox.shrink(),
|
||||
],
|
||||
),
|
||||
),
|
||||
|
|
|
|||
|
|
@ -58,8 +58,12 @@ class PollWidgetState extends State<PollWidget> {
|
|||
|
||||
final rel = await Matrix.of(context)
|
||||
.client
|
||||
.getRelatingEventsWithRelTypeAndEventType(room.id, widget.event.eventId,
|
||||
"m.reference", "org.matrix.msc3381.poll.response");
|
||||
.getRelatingEventsWithRelTypeAndEventType(
|
||||
room.id,
|
||||
widget.event.eventId,
|
||||
"m.reference",
|
||||
"org.matrix.msc3381.poll.response",
|
||||
);
|
||||
|
||||
// Get all poll response events for this poll
|
||||
final responses = rel.chunk;
|
||||
|
|
@ -90,8 +94,12 @@ class PollWidgetState extends State<PollWidget> {
|
|||
|
||||
final rel = await Matrix.of(context)
|
||||
.client
|
||||
.getRelatingEventsWithRelTypeAndEventType(room.id, pollEventId,
|
||||
"m.reference", "org.matrix.msc3381.poll.response");
|
||||
.getRelatingEventsWithRelTypeAndEventType(
|
||||
room.id,
|
||||
pollEventId,
|
||||
"m.reference",
|
||||
"org.matrix.msc3381.poll.response",
|
||||
);
|
||||
|
||||
// Get all poll response events for this poll
|
||||
final responses = rel.chunk;
|
||||
|
|
@ -124,7 +132,8 @@ class PollWidgetState extends State<PollWidget> {
|
|||
final room = widget.event.room;
|
||||
|
||||
// Send poll response event
|
||||
await room.sendEvent({
|
||||
await room.sendEvent(
|
||||
{
|
||||
'm.relates_to': {
|
||||
'rel_type': 'm.reference',
|
||||
'event_id': widget.event.eventId,
|
||||
|
|
@ -132,7 +141,9 @@ class PollWidgetState extends State<PollWidget> {
|
|||
'org.matrix.msc3381.poll.response': {
|
||||
'answers': answers,
|
||||
},
|
||||
}, type: 'org.matrix.msc3381.poll.response');
|
||||
},
|
||||
type: 'org.matrix.msc3381.poll.response',
|
||||
);
|
||||
|
||||
setState(() {
|
||||
selectedAnswers = answers;
|
||||
|
|
@ -369,9 +380,11 @@ class PollWidgetState extends State<PollWidget> {
|
|||
height: 16,
|
||||
child: CircularProgressIndicator(strokeWidth: 2),
|
||||
)
|
||||
: Text(hasVoted
|
||||
: Text(
|
||||
hasVoted
|
||||
? L10n.of(context).changeVote
|
||||
: L10n.of(context).vote),
|
||||
: L10n.of(context).vote,
|
||||
),
|
||||
),
|
||||
|
||||
const Spacer(),
|
||||
|
|
|
|||
|
|
@ -1,28 +1,17 @@
|
|||
import 'dart:io';
|
||||
|
||||
import 'package:extera_next/pages/chat/events/html_message.dart';
|
||||
import 'package:extera_next/pages/image_viewer/image_viewer.dart';
|
||||
import 'package:extera_next/widgets/mxc_image.dart';
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
import 'package:chewie/chewie.dart';
|
||||
import 'package:extera_next/generated/l10n/l10n.dart';
|
||||
import 'package:flutter_linkify/flutter_linkify.dart';
|
||||
import 'package:matrix/matrix.dart';
|
||||
import 'package:path_provider/path_provider.dart';
|
||||
import 'package:universal_html/html.dart' as html;
|
||||
import 'package:video_player/video_player.dart';
|
||||
|
||||
import 'package:extera_next/config/app_config.dart';
|
||||
import 'package:extera_next/pages/chat/events/image_bubble.dart';
|
||||
import 'package:extera_next/utils/file_description.dart';
|
||||
import 'package:extera_next/utils/localized_exception_extension.dart';
|
||||
import 'package:extera_next/utils/matrix_sdk_extensions/event_extension.dart';
|
||||
import 'package:extera_next/utils/platform_infos.dart';
|
||||
import 'package:extera_next/utils/url_launcher.dart';
|
||||
import 'package:extera_next/widgets/blur_hash.dart';
|
||||
import '../../../utils/error_reporter.dart';
|
||||
|
||||
class EventVideoPlayer extends StatelessWidget {
|
||||
final Event event;
|
||||
|
|
@ -128,8 +117,6 @@ class EventVideoPlayer extends StatelessWidget {
|
|||
),
|
||||
),
|
||||
if (fileDescription != null &&
|
||||
textColor != null &&
|
||||
linkColor != null &&
|
||||
!event.isRichFileDescription)
|
||||
SizedBox(
|
||||
width: width,
|
||||
|
|
@ -159,8 +146,6 @@ class EventVideoPlayer extends StatelessWidget {
|
|||
),
|
||||
),
|
||||
if (fileDescription != null &&
|
||||
textColor != null &&
|
||||
linkColor != null &&
|
||||
event.isRichFileDescription)
|
||||
SizedBox(
|
||||
width: width,
|
||||
|
|
|
|||
|
|
@ -23,12 +23,14 @@ import 'package:html_unescape/html_unescape.dart';
|
|||
|
||||
class SendFileDialog extends StatefulWidget {
|
||||
final Room room;
|
||||
final Thread? thread;
|
||||
final List<XFile> files;
|
||||
final BuildContext outerContext;
|
||||
final Event? replyEvent;
|
||||
|
||||
const SendFileDialog({
|
||||
required this.room,
|
||||
required this.thread,
|
||||
required this.files,
|
||||
required this.outerContext,
|
||||
this.replyEvent,
|
||||
|
|
@ -151,6 +153,8 @@ class SendFileDialogState extends State<SendFileDialog> {
|
|||
thumbnail: thumbnail,
|
||||
shrinkImageMaxDimension: compress ? 1600 : null,
|
||||
extraContent: extraContent,
|
||||
threadLastEventId: widget.thread?.lastEvent?.eventId ?? widget.thread?.rootEvent.eventId,
|
||||
threadRootEventId: widget.thread?.rootEvent.eventId
|
||||
);
|
||||
} on MatrixException catch (e) {
|
||||
final retryAfterMs = e.retryAfterMs;
|
||||
|
|
|
|||
|
|
@ -13,9 +13,11 @@ import 'package:extera_next/widgets/future_loading_dialog.dart';
|
|||
|
||||
class SendLocationDialog extends StatefulWidget {
|
||||
final Room room;
|
||||
final Thread? thread;
|
||||
|
||||
const SendLocationDialog({
|
||||
required this.room,
|
||||
required this.thread,
|
||||
super.key,
|
||||
});
|
||||
|
||||
|
|
@ -85,7 +87,13 @@ class SendLocationDialogState extends State<SendLocationDialog> {
|
|||
'geo:${position!.latitude},${position!.longitude};u=${position!.accuracy}';
|
||||
await showFutureLoadingDialog(
|
||||
context: context,
|
||||
future: () => widget.room.sendLocation(body, uri),
|
||||
future: () {
|
||||
if (widget.thread != null) {
|
||||
return widget.thread!.sendLocation(body, uri);
|
||||
} else {
|
||||
return widget.room.sendLocation(body, uri);
|
||||
}
|
||||
},
|
||||
);
|
||||
Navigator.of(context, rootNavigator: false).pop();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,4 @@
|
|||
import 'package:uuid/uuid.dart';
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:extera_next/generated/l10n/l10n.dart';
|
||||
import 'package:matrix/matrix.dart';
|
||||
|
|
@ -8,9 +7,11 @@ class SendPollDialog extends StatefulWidget {
|
|||
final Room room;
|
||||
final BuildContext outerContext;
|
||||
final Event? replyEvent;
|
||||
final Thread? thread;
|
||||
|
||||
const SendPollDialog({
|
||||
required this.room,
|
||||
required this.thread,
|
||||
required this.outerContext,
|
||||
this.replyEvent,
|
||||
super.key,
|
||||
|
|
@ -74,11 +75,13 @@ class SendPollDialogState extends State<SendPollDialog> {
|
|||
'm.text': question,
|
||||
},
|
||||
'answers': answers
|
||||
.map((answer) => {
|
||||
.map(
|
||||
(answer) => {
|
||||
'id': const Uuid().v4(),
|
||||
'org.matrix.msc1767.text': answer,
|
||||
'm.text': answer,
|
||||
})
|
||||
},
|
||||
)
|
||||
.toList(),
|
||||
'max_selections': _maxSelections,
|
||||
'kind': _kind,
|
||||
|
|
@ -86,7 +89,13 @@ class SendPollDialogState extends State<SendPollDialog> {
|
|||
};
|
||||
|
||||
try {
|
||||
await widget.room.sendEvent(pollContent, type: 'org.matrix.msc3381.poll.start');
|
||||
await widget.room.sendEvent(
|
||||
pollContent,
|
||||
type: 'org.matrix.msc3381.poll.start',
|
||||
threadLastEventId: widget.thread?.lastEvent?.eventId ??
|
||||
widget.thread?.rootEvent.eventId,
|
||||
threadRootEventId: widget.thread?.rootEvent.eventId,
|
||||
);
|
||||
// ignore: use_build_context_synchronously
|
||||
Navigator.of(context).pop();
|
||||
} catch (e) {
|
||||
|
|
@ -154,7 +163,7 @@ class SendPollDialogState extends State<SendPollDialog> {
|
|||
),
|
||||
const SizedBox(height: 16),
|
||||
DropdownButtonFormField<int>(
|
||||
value: _maxSelections,
|
||||
initialValue: _maxSelections,
|
||||
decoration: InputDecoration(
|
||||
labelText: L10n.of(context).maxSelections,
|
||||
border: const OutlineInputBorder(),
|
||||
|
|
@ -170,7 +179,7 @@ class SendPollDialogState extends State<SendPollDialog> {
|
|||
),
|
||||
const SizedBox(height: 16),
|
||||
DropdownButtonFormField<String>(
|
||||
value: _kind,
|
||||
initialValue: _kind,
|
||||
decoration: InputDecoration(
|
||||
labelText: L10n.of(context).pollType,
|
||||
border: const OutlineInputBorder(),
|
||||
|
|
|
|||
|
|
@ -16,14 +16,13 @@ class TranslatedEventDialog extends StatefulWidget {
|
|||
});
|
||||
|
||||
@override
|
||||
TranslatedEventDialogState createState() =>
|
||||
TranslatedEventDialogState(event, timeline);
|
||||
TranslatedEventDialogState createState() => TranslatedEventDialogState();
|
||||
}
|
||||
|
||||
class TranslatedEventDialogState extends State<TranslatedEventDialog> {
|
||||
final Event event;
|
||||
final Timeline timeline;
|
||||
TranslatedEventDialogState(this.event, this.timeline);
|
||||
Event get event => widget.event;
|
||||
Timeline get timeline => widget.timeline;
|
||||
TranslatedEventDialogState();
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final theme = Theme.of(context);
|
||||
|
|
@ -48,20 +47,16 @@ class TranslatedEventDialogState extends State<TranslatedEventDialog> {
|
|||
longPressSelect: false,
|
||||
selected: false,
|
||||
wallpaperMode: false,
|
||||
gradient: false
|
||||
gradient: false,
|
||||
);
|
||||
|
||||
return Scaffold(
|
||||
appBar: AppBar(
|
||||
title: Text(L10n.of(context).translatedMessage)
|
||||
),
|
||||
body: Container(
|
||||
child: Column(
|
||||
appBar: AppBar(title: Text(L10n.of(context).translatedMessage)),
|
||||
body: Column(
|
||||
children: [
|
||||
message,
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -26,6 +26,16 @@ class ChatAccessSettingsController extends State<ChatAccessSettings> {
|
|||
bool historyVisibilityLoading = false;
|
||||
bool guestAccessLoading = false;
|
||||
Room get room => Matrix.of(context).client.getRoomById(widget.roomId)!;
|
||||
Set<Room> get knownSpaceParents => {
|
||||
...room.client.rooms.where(
|
||||
(space) =>
|
||||
space.isSpace &&
|
||||
space.spaceChildren.any((child) => child.roomId == room.id),
|
||||
),
|
||||
...room.spaceParents
|
||||
.map((parent) => room.client.getRoomById(parent.roomId ?? ''))
|
||||
.whereType<Room>(),
|
||||
};
|
||||
|
||||
String get roomVersion =>
|
||||
room
|
||||
|
|
@ -46,9 +56,12 @@ class ChatAccessSettingsController extends State<ChatAccessSettings> {
|
|||
joinRules.remove(JoinRules.knock);
|
||||
}
|
||||
|
||||
// Not yet supported in FluffyChat:
|
||||
if (knownSpaceParents.isEmpty) {
|
||||
joinRules.remove(JoinRules.restricted);
|
||||
if (roomVersionInt != null && roomVersionInt <= 6) {
|
||||
joinRules.remove(JoinRules.knockRestricted);
|
||||
}
|
||||
}
|
||||
|
||||
// If an unsupported join rule is the current join rule, display it:
|
||||
final currentJoinRule = room.joinRules;
|
||||
|
|
@ -64,7 +77,13 @@ class ChatAccessSettingsController extends State<ChatAccessSettings> {
|
|||
});
|
||||
|
||||
try {
|
||||
await room.setJoinRules(newJoinRules);
|
||||
await room.setJoinRules(
|
||||
newJoinRules,
|
||||
allowConditionRoomId: {JoinRules.restricted, JoinRules.knockRestricted}
|
||||
.contains(newJoinRules)
|
||||
? knownSpaceParents.first.id
|
||||
: null,
|
||||
);
|
||||
} catch (e, s) {
|
||||
Logs().w('Unable to change join rules', e, s);
|
||||
if (mounted) {
|
||||
|
|
|
|||
|
|
@ -45,18 +45,26 @@ class ChatAccessSettingsPageView extends StatelessWidget {
|
|||
),
|
||||
),
|
||||
),
|
||||
for (final historyVisibility in HistoryVisibility.values)
|
||||
RadioListTile<HistoryVisibility>.adaptive(
|
||||
title: Text(
|
||||
historyVisibility
|
||||
.getLocalizedString(MatrixLocals(L10n.of(context))),
|
||||
),
|
||||
value: historyVisibility,
|
||||
RadioGroup<HistoryVisibility>(
|
||||
groupValue: room.historyVisibility,
|
||||
onChanged: controller.historyVisibilityLoading ||
|
||||
!room.canChangeHistoryVisibility
|
||||
? null
|
||||
? (_) {}
|
||||
: controller.setHistoryVisibility,
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
for (final historyVisibility in HistoryVisibility.values)
|
||||
RadioListTile<HistoryVisibility>.adaptive(
|
||||
title: Text(
|
||||
historyVisibility.getLocalizedString(
|
||||
MatrixLocals(L10n.of(context)),
|
||||
),
|
||||
),
|
||||
value: historyVisibility,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
Divider(color: theme.dividerColor),
|
||||
ListTile(
|
||||
|
|
@ -68,18 +76,27 @@ class ChatAccessSettingsPageView extends StatelessWidget {
|
|||
),
|
||||
),
|
||||
),
|
||||
RadioGroup(
|
||||
groupValue: room.joinRules,
|
||||
onChanged: controller.setJoinRule,
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
for (final joinRule in controller.availableJoinRules)
|
||||
if (joinRule != JoinRules.private)
|
||||
RadioListTile<JoinRules>.adaptive(
|
||||
enabled: !controller.joinRulesLoading &&
|
||||
room.canChangeJoinRules,
|
||||
title: Text(
|
||||
joinRule.localizedString(L10n.of(context)),
|
||||
joinRule.localizedString(
|
||||
L10n.of(context),
|
||||
controller.knownSpaceParents,
|
||||
),
|
||||
),
|
||||
value: joinRule,
|
||||
groupValue: room.joinRules,
|
||||
onChanged: controller.joinRulesLoading ||
|
||||
!room.canChangeJoinRules
|
||||
? null
|
||||
: controller.setJoinRule,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
Divider(color: theme.dividerColor),
|
||||
if ({JoinRules.public, JoinRules.knock}
|
||||
|
|
@ -93,19 +110,25 @@ class ChatAccessSettingsPageView extends StatelessWidget {
|
|||
),
|
||||
),
|
||||
),
|
||||
RadioGroup(
|
||||
groupValue: room.guestAccess,
|
||||
onChanged: controller.setGuestAccess,
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
for (final guestAccess in GuestAccess.values)
|
||||
RadioListTile<GuestAccess>.adaptive(
|
||||
enabled: !controller.guestAccessLoading &&
|
||||
room.canChangeGuestAccess,
|
||||
title: Text(
|
||||
guestAccess.getLocalizedString(
|
||||
MatrixLocals(L10n.of(context)),
|
||||
),
|
||||
),
|
||||
value: guestAccess,
|
||||
groupValue: room.guestAccess,
|
||||
onChanged: controller.guestAccessLoading ||
|
||||
!room.canChangeGuestAccess
|
||||
? null
|
||||
: controller.setGuestAccess,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
Divider(color: theme.dividerColor),
|
||||
ListTile(
|
||||
|
|
@ -260,7 +283,7 @@ class _AliasListTile extends StatelessWidget {
|
|||
}
|
||||
|
||||
extension JoinRulesDisplayString on JoinRules {
|
||||
String localizedString(L10n l10n) {
|
||||
String localizedString(L10n l10n, Set<Room> spaceParents) {
|
||||
switch (this) {
|
||||
case JoinRules.public:
|
||||
return l10n.anyoneCanJoin;
|
||||
|
|
@ -271,9 +294,17 @@ extension JoinRulesDisplayString on JoinRules {
|
|||
case JoinRules.private:
|
||||
return l10n.noOneCanJoin;
|
||||
case JoinRules.restricted:
|
||||
return l10n.restricted;
|
||||
return l10n.spaceMemberOf(
|
||||
spaceParents
|
||||
.map((space) => space.getLocalizedDisplayname(MatrixLocals(l10n)))
|
||||
.join(', '),
|
||||
);
|
||||
case JoinRules.knockRestricted:
|
||||
return l10n.knockRestricted;
|
||||
return l10n.spaceMemberOfCanKnock(
|
||||
spaceParents
|
||||
.map((space) => space.getLocalizedDisplayname(MatrixLocals(l10n)))
|
||||
.join(', '),
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -259,6 +259,21 @@ class ChatDetailsView extends StatelessWidget {
|
|||
const SizedBox(height: 16),
|
||||
],
|
||||
Divider(color: theme.dividerColor),
|
||||
ListTile(
|
||||
leading: CircleAvatar(
|
||||
backgroundColor: theme.scaffoldBackgroundColor,
|
||||
foregroundColor: iconColor,
|
||||
child: const Icon(
|
||||
Icons.chat_bubble_outline,
|
||||
),
|
||||
),
|
||||
title: Text(L10n.of(context).chatThreads),
|
||||
subtitle:
|
||||
Text(L10n.of(context).chatThreadsDescription),
|
||||
onTap: () =>
|
||||
context.push('/rooms/${room.id}?threads=true'),
|
||||
trailing: const Icon(Icons.chevron_right_outlined),
|
||||
),
|
||||
ListTile(
|
||||
leading: CircleAvatar(
|
||||
backgroundColor: theme.scaffoldBackgroundColor,
|
||||
|
|
|
|||
|
|
@ -1,9 +1,10 @@
|
|||
import 'package:flutter/material.dart';
|
||||
|
||||
import 'package:extera_next/generated/l10n/l10n.dart';
|
||||
import 'package:matrix/matrix.dart';
|
||||
|
||||
import 'package:extera_next/config/app_config.dart';
|
||||
import 'package:extera_next/generated/l10n/l10n.dart';
|
||||
import 'package:extera_next/pages/chat_list/unread_bubble.dart';
|
||||
import 'package:extera_next/utils/matrix_sdk_extensions/matrix_locals.dart';
|
||||
import 'package:extera_next/utils/room_status_extension.dart';
|
||||
import 'package:extera_next/widgets/adaptive_dialogs/show_ok_cancel_alert_dialog.dart';
|
||||
|
|
@ -35,32 +36,6 @@ class ChatListItem extends StatelessWidget {
|
|||
super.key,
|
||||
});
|
||||
|
||||
Future<bool> archiveAction(BuildContext context) async {
|
||||
{
|
||||
if ([Membership.leave, Membership.ban].contains(room.membership)) {
|
||||
final forgetResult = await showFutureLoadingDialog(
|
||||
context: context,
|
||||
future: () => room.forget(),
|
||||
);
|
||||
return forgetResult.isValue;
|
||||
}
|
||||
final confirmed = await showOkCancelAlertDialog(
|
||||
context: context,
|
||||
title: L10n.of(context).areYouSure,
|
||||
okLabel: L10n.of(context).leave,
|
||||
cancelLabel: L10n.of(context).cancel,
|
||||
message: L10n.of(context).archiveRoomDescription,
|
||||
isDestructive: true,
|
||||
);
|
||||
if (confirmed != OkCancelResult.ok) return false;
|
||||
final leaveResult = await showFutureLoadingDialog(
|
||||
context: context,
|
||||
future: () => room.leave(),
|
||||
);
|
||||
return leaveResult.isValue;
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final theme = Theme.of(context);
|
||||
|
|
@ -69,14 +44,9 @@ class ChatListItem extends StatelessWidget {
|
|||
final typingText = room.getLocalizedTypingText(context);
|
||||
final lastEvent = room.lastEvent;
|
||||
final ownMessage = lastEvent?.senderId == room.client.userID;
|
||||
final unread = room.isUnread || room.membership == Membership.invite;
|
||||
final unread = room.isUnread;
|
||||
final directChatMatrixId = room.directChatMatrixID;
|
||||
final isDirectChat = directChatMatrixId != null;
|
||||
final unreadBubbleSize = unread || room.hasNewMessages
|
||||
? room.notificationCount > 0
|
||||
? 20.0
|
||||
: 14.0
|
||||
: 0.0;
|
||||
final hasNotifications = room.notificationCount > 0;
|
||||
final backgroundColor =
|
||||
activeChat ? theme.colorScheme.secondaryContainer : null;
|
||||
|
|
@ -93,8 +63,6 @@ class ChatListItem extends StatelessWidget {
|
|||
: room.getState(EventTypes.RoomMember, lastEvent.senderId) == null;
|
||||
final space = this.space;
|
||||
|
||||
final inviterMxId = room.getState(EventTypes.RoomMember, room.client.userID!)?.senderId;
|
||||
|
||||
return Padding(
|
||||
padding: const EdgeInsets.symmetric(
|
||||
horizontal: 8,
|
||||
|
|
@ -116,9 +84,7 @@ class ChatListItem extends StatelessWidget {
|
|||
duration: FluffyThemes.animationDuration,
|
||||
curve: FluffyThemes.animationCurve,
|
||||
scale: hovered ? 1.1 : 1.0,
|
||||
child:
|
||||
(!AppConfig.hideAvatarsInInvites || room.membership != Membership.invite)
|
||||
? SizedBox(
|
||||
child: SizedBox(
|
||||
width: Avatar.defaultSize,
|
||||
height: Avatar.defaultSize,
|
||||
child: Stack(
|
||||
|
|
@ -195,7 +161,7 @@ class ChatListItem extends StatelessWidget {
|
|||
),
|
||||
],
|
||||
),
|
||||
) : null,
|
||||
),
|
||||
),
|
||||
),
|
||||
title: Row(
|
||||
|
|
@ -232,13 +198,12 @@ class ChatListItem extends StatelessWidget {
|
|||
color: theme.colorScheme.primary,
|
||||
),
|
||||
),
|
||||
if (!room.isSpace &&
|
||||
lastEvent != null &&
|
||||
room.membership != Membership.invite)
|
||||
if (!room.isSpace && room.membership != Membership.invite)
|
||||
Padding(
|
||||
padding: const EdgeInsets.only(left: 4.0),
|
||||
child: Text(
|
||||
lastEvent.originServerTs.localizedTimeShort(context),
|
||||
room.latestEventReceivedTime
|
||||
.localizedTimeShort(context),
|
||||
style: TextStyle(
|
||||
fontSize: 12,
|
||||
color: theme.colorScheme.outline,
|
||||
|
|
@ -253,7 +218,7 @@ class ChatListItem extends StatelessWidget {
|
|||
children: <Widget>[
|
||||
if (typingText.isEmpty &&
|
||||
ownMessage &&
|
||||
room.lastEvent!.status.isSending) ...[
|
||||
room.lastEvent?.status.isSending == true) ...[
|
||||
const SizedBox(
|
||||
width: 16,
|
||||
height: 16,
|
||||
|
|
@ -321,7 +286,7 @@ class ChatListItem extends StatelessWidget {
|
|||
),
|
||||
builder: (context, snapshot) => Text(
|
||||
room.membership == Membership.invite
|
||||
? "${room
|
||||
? room
|
||||
.getState(
|
||||
EventTypes.RoomMember,
|
||||
room.client.userID!,
|
||||
|
|
@ -331,9 +296,9 @@ class ChatListItem extends StatelessWidget {
|
|||
(isDirectChat
|
||||
? L10n.of(context).newChatRequest
|
||||
: L10n.of(context)
|
||||
.inviteGroupChat)}${inviterMxId != null ? " ($inviterMxId)" : ""}"
|
||||
.inviteGroupChat)
|
||||
: snapshot.data ??
|
||||
L10n.of(context).emptyChat,
|
||||
L10n.of(context).noMessagesYet,
|
||||
softWrap: false,
|
||||
maxLines: room.notificationCount >= 1 ? 2 : 1,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
|
|
@ -349,48 +314,33 @@ class ChatListItem extends StatelessWidget {
|
|||
),
|
||||
),
|
||||
const SizedBox(width: 8),
|
||||
AnimatedContainer(
|
||||
duration: FluffyThemes.animationDuration,
|
||||
curve: FluffyThemes.animationCurve,
|
||||
alignment: Alignment.center,
|
||||
padding: const EdgeInsets.symmetric(horizontal: 7),
|
||||
height: unreadBubbleSize,
|
||||
width: !hasNotifications && !unread && !room.hasNewMessages
|
||||
? 0
|
||||
: (unreadBubbleSize - 9) *
|
||||
room.notificationCount.toString().length +
|
||||
9,
|
||||
decoration: BoxDecoration(
|
||||
color: room.highlightCount > 0 ||
|
||||
room.membership == Membership.invite
|
||||
? theme.colorScheme.error
|
||||
: hasNotifications || room.markedUnread
|
||||
? theme.colorScheme.primary
|
||||
: theme.colorScheme.primaryContainer,
|
||||
borderRadius: BorderRadius.circular(7),
|
||||
),
|
||||
child: hasNotifications
|
||||
? Text(
|
||||
room.notificationCount.toString(),
|
||||
style: TextStyle(
|
||||
color: room.highlightCount > 0 ||
|
||||
room.membership == Membership.invite
|
||||
? theme.colorScheme.onError
|
||||
: hasNotifications
|
||||
? theme.colorScheme.onPrimary
|
||||
: theme.colorScheme.onPrimaryContainer,
|
||||
fontSize: 13,
|
||||
fontWeight: FontWeight.w500,
|
||||
),
|
||||
textAlign: TextAlign.center,
|
||||
)
|
||||
: const SizedBox.shrink(),
|
||||
),
|
||||
UnreadBubble(room: room),
|
||||
],
|
||||
),
|
||||
onTap: onTap,
|
||||
trailing: onForget == null
|
||||
? null
|
||||
? room.membership == Membership.invite
|
||||
? IconButton(
|
||||
tooltip: L10n.of(context).decline,
|
||||
icon: const Icon(Icons.delete_forever_outlined),
|
||||
color: theme.colorScheme.error,
|
||||
onPressed: () async {
|
||||
final consent = await showOkCancelAlertDialog(
|
||||
context: context,
|
||||
title: L10n.of(context).decline,
|
||||
message: L10n.of(context).areYouSure,
|
||||
okLabel: L10n.of(context).yes,
|
||||
isDestructive: true,
|
||||
);
|
||||
if (consent != OkCancelResult.ok) return;
|
||||
if (!context.mounted) return;
|
||||
await showFutureLoadingDialog(
|
||||
context: context,
|
||||
future: room.leave,
|
||||
);
|
||||
},
|
||||
)
|
||||
: null
|
||||
: IconButton(
|
||||
icon: const Icon(Icons.delete_outlined),
|
||||
onPressed: onForget,
|
||||
|
|
|
|||
|
|
@ -1,27 +1,40 @@
|
|||
import 'dart:convert';
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
import 'package:collection/collection.dart';
|
||||
import 'package:extera_next/generated/l10n/l10n.dart';
|
||||
import 'package:go_router/go_router.dart';
|
||||
import 'package:matrix/matrix.dart' as sdk;
|
||||
import 'package:matrix/matrix.dart';
|
||||
|
||||
import 'package:extera_next/config/app_config.dart';
|
||||
import 'package:extera_next/config/themes.dart';
|
||||
import 'package:extera_next/pages/chat_list/chat_list_item.dart';
|
||||
import 'package:extera_next/pages/chat_list/search_title.dart';
|
||||
import 'package:extera_next/generated/l10n/l10n.dart';
|
||||
import 'package:extera_next/pages/chat_list/unread_bubble.dart';
|
||||
import 'package:extera_next/utils/localized_exception_extension.dart';
|
||||
import 'package:extera_next/utils/matrix_sdk_extensions/matrix_locals.dart';
|
||||
import 'package:extera_next/utils/stream_extension.dart';
|
||||
import 'package:extera_next/utils/string_color.dart';
|
||||
import 'package:extera_next/widgets/adaptive_dialogs/public_room_dialog.dart';
|
||||
import 'package:extera_next/widgets/adaptive_dialogs/show_modal_action_popup.dart';
|
||||
import 'package:extera_next/widgets/adaptive_dialogs/show_ok_cancel_alert_dialog.dart';
|
||||
import 'package:extera_next/widgets/adaptive_dialogs/show_text_input_dialog.dart';
|
||||
import 'package:extera_next/widgets/avatar.dart';
|
||||
import 'package:extera_next/widgets/future_loading_dialog.dart';
|
||||
import 'package:extera_next/widgets/hover_builder.dart';
|
||||
import 'package:extera_next/widgets/matrix.dart';
|
||||
|
||||
enum AddRoomType { chat, subspace }
|
||||
|
||||
enum SpaceChildAction { edit, moveToSpace, removeFromSpace }
|
||||
|
||||
enum SpaceActions {
|
||||
settings,
|
||||
invite,
|
||||
members,
|
||||
leave,
|
||||
}
|
||||
|
||||
class SpaceView extends StatefulWidget {
|
||||
final String spaceId;
|
||||
final void Function() onBack;
|
||||
|
|
@ -45,7 +58,7 @@ class SpaceView extends StatefulWidget {
|
|||
}
|
||||
|
||||
class _SpaceViewState extends State<SpaceView> {
|
||||
final List<SpaceRoomsChunk> _discoveredChildren = [];
|
||||
final List<SpaceRoomsChunk$2> _discoveredChildren = [];
|
||||
final TextEditingController _filterController = TextEditingController();
|
||||
String? _nextBatch;
|
||||
bool _noMoreRooms = false;
|
||||
|
|
@ -58,9 +71,28 @@ class _SpaceViewState extends State<SpaceView> {
|
|||
}
|
||||
|
||||
void _loadHierarchy() async {
|
||||
final room = Matrix.of(context).client.getRoomById(widget.spaceId);
|
||||
final matrix = Matrix.of(context);
|
||||
final room = matrix.client.getRoomById(widget.spaceId);
|
||||
if (room == null) return;
|
||||
|
||||
final cacheKey = 'spaces_history_cache${room.id}';
|
||||
if (_discoveredChildren.isEmpty) {
|
||||
final cachedChildren = matrix.store.getStringList(cacheKey);
|
||||
if (cachedChildren != null) {
|
||||
try {
|
||||
_discoveredChildren.addAll(
|
||||
cachedChildren.map(
|
||||
(jsonString) =>
|
||||
SpaceRoomsChunk$2.fromJson(jsonDecode(jsonString)),
|
||||
),
|
||||
);
|
||||
} catch (e, s) {
|
||||
Logs().e('Unable to json decode spaces hierarchy cache!', e, s);
|
||||
matrix.store.remove(cacheKey);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
setState(() {
|
||||
_isLoading = true;
|
||||
});
|
||||
|
|
@ -74,16 +106,25 @@ class _SpaceViewState extends State<SpaceView> {
|
|||
);
|
||||
if (!mounted) return;
|
||||
setState(() {
|
||||
if (_nextBatch == null) _discoveredChildren.clear();
|
||||
_nextBatch = hierarchy.nextBatch;
|
||||
if (hierarchy.nextBatch == null) {
|
||||
_noMoreRooms = true;
|
||||
}
|
||||
_discoveredChildren.addAll(
|
||||
hierarchy.rooms
|
||||
.where((c) => room.client.getRoomById(c.roomId) == null),
|
||||
hierarchy.rooms.where((room) => room.roomId != widget.spaceId),
|
||||
);
|
||||
_isLoading = false;
|
||||
});
|
||||
|
||||
if (_nextBatch == null) {
|
||||
matrix.store.setStringList(
|
||||
cacheKey,
|
||||
_discoveredChildren
|
||||
.map((child) => jsonEncode(child.toJson()))
|
||||
.toList(),
|
||||
);
|
||||
}
|
||||
} catch (e, s) {
|
||||
Logs().w('Unable to load hierarchy', e, s);
|
||||
if (!mounted) return;
|
||||
|
|
@ -95,7 +136,7 @@ class _SpaceViewState extends State<SpaceView> {
|
|||
}
|
||||
}
|
||||
|
||||
void _joinChildRoom(SpaceRoomsChunk item) async {
|
||||
void _joinChildRoom(SpaceRoomsChunk$2 item) async {
|
||||
final client = Matrix.of(context).client;
|
||||
final space = client.getRoomById(widget.spaceId);
|
||||
|
||||
|
|
@ -111,9 +152,7 @@ class _SpaceViewState extends State<SpaceView> {
|
|||
),
|
||||
);
|
||||
if (mounted && joined == true) {
|
||||
setState(() {
|
||||
_discoveredChildren.remove(item);
|
||||
});
|
||||
setState(() {});
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -129,6 +168,10 @@ class _SpaceViewState extends State<SpaceView> {
|
|||
await space?.postLoad();
|
||||
context.push('/rooms/${widget.spaceId}/invite');
|
||||
break;
|
||||
case SpaceActions.members:
|
||||
await space?.postLoad();
|
||||
context.push('/rooms/${widget.spaceId}/details/members');
|
||||
break;
|
||||
case SpaceActions.leave:
|
||||
final confirmed = await showOkCancelAlertDialog(
|
||||
context: context,
|
||||
|
|
@ -151,27 +194,11 @@ class _SpaceViewState extends State<SpaceView> {
|
|||
}
|
||||
}
|
||||
|
||||
void _addChatOrSubspace() async {
|
||||
final roomType = await showModalActionPopup(
|
||||
context: context,
|
||||
title: L10n.of(context).addChatOrSubSpace,
|
||||
actions: [
|
||||
AdaptiveModalAction(
|
||||
value: AddRoomType.subspace,
|
||||
label: L10n.of(context).createNewSpace,
|
||||
),
|
||||
AdaptiveModalAction(
|
||||
value: AddRoomType.chat,
|
||||
label: L10n.of(context).createGroup,
|
||||
),
|
||||
],
|
||||
);
|
||||
if (roomType == null) return;
|
||||
|
||||
void _addChatOrSubspace(AddRoomType roomType) async {
|
||||
final names = await showTextInputDialog(
|
||||
context: context,
|
||||
title: roomType == AddRoomType.subspace
|
||||
? L10n.of(context).createNewSpace
|
||||
? L10n.of(context).newSubSpace
|
||||
: L10n.of(context).createGroup,
|
||||
hintText: roomType == AddRoomType.subspace
|
||||
? L10n.of(context).spaceName
|
||||
|
|
@ -196,29 +223,169 @@ class _SpaceViewState extends State<SpaceView> {
|
|||
late final String roomId;
|
||||
final activeSpace = client.getRoomById(widget.spaceId)!;
|
||||
await activeSpace.postLoad();
|
||||
final isPublicSpace = activeSpace.joinRules == JoinRules.public;
|
||||
|
||||
if (roomType == AddRoomType.subspace) {
|
||||
roomId = await client.createSpace(
|
||||
name: names,
|
||||
visibility: activeSpace.joinRules == JoinRules.public
|
||||
? sdk.Visibility.public
|
||||
: sdk.Visibility.private,
|
||||
visibility:
|
||||
isPublicSpace ? sdk.Visibility.public : sdk.Visibility.private,
|
||||
);
|
||||
} else {
|
||||
roomId = await client.createGroupChat(
|
||||
enableEncryption: !isPublicSpace,
|
||||
groupName: names,
|
||||
preset: activeSpace.joinRules == JoinRules.public
|
||||
preset: isPublicSpace
|
||||
? CreateRoomPreset.publicChat
|
||||
: CreateRoomPreset.privateChat,
|
||||
visibility: activeSpace.joinRules == JoinRules.public
|
||||
? sdk.Visibility.public
|
||||
: sdk.Visibility.private,
|
||||
visibility:
|
||||
isPublicSpace ? sdk.Visibility.public : sdk.Visibility.private,
|
||||
initialState: isPublicSpace
|
||||
? null
|
||||
: [
|
||||
StateEvent(
|
||||
content: {
|
||||
'join_rule': 'restricted',
|
||||
'allow': [
|
||||
{
|
||||
'room_id': widget.spaceId,
|
||||
'type': 'm.room_membership',
|
||||
},
|
||||
],
|
||||
},
|
||||
type: EventTypes.RoomJoinRules,
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
await activeSpace.setSpaceChild(roomId);
|
||||
},
|
||||
);
|
||||
if (result.error != null) return;
|
||||
setState(() {
|
||||
_nextBatch = null;
|
||||
_discoveredChildren.clear();
|
||||
});
|
||||
_loadHierarchy();
|
||||
}
|
||||
|
||||
void _showSpaceChildEditMenu(BuildContext posContext, String roomId) async {
|
||||
final overlay =
|
||||
Overlay.of(posContext).context.findRenderObject() as RenderBox;
|
||||
|
||||
final button = posContext.findRenderObject() as RenderBox;
|
||||
|
||||
final position = RelativeRect.fromRect(
|
||||
Rect.fromPoints(
|
||||
button.localToGlobal(const Offset(0, -65), ancestor: overlay),
|
||||
button.localToGlobal(
|
||||
button.size.bottomRight(Offset.zero) + const Offset(-50, 0),
|
||||
ancestor: overlay,
|
||||
),
|
||||
),
|
||||
Offset.zero & overlay.size,
|
||||
);
|
||||
|
||||
final action = await showMenu<SpaceChildAction>(
|
||||
context: posContext,
|
||||
position: position,
|
||||
items: [
|
||||
PopupMenuItem(
|
||||
value: SpaceChildAction.moveToSpace,
|
||||
child: Row(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
const Icon(Icons.move_down_outlined),
|
||||
const SizedBox(width: 12),
|
||||
Text(L10n.of(context).moveToDifferentSpace),
|
||||
],
|
||||
),
|
||||
),
|
||||
PopupMenuItem(
|
||||
value: SpaceChildAction.edit,
|
||||
child: Row(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
const Icon(Icons.edit_outlined),
|
||||
const SizedBox(width: 12),
|
||||
Text(L10n.of(context).edit),
|
||||
],
|
||||
),
|
||||
),
|
||||
PopupMenuItem(
|
||||
value: SpaceChildAction.removeFromSpace,
|
||||
child: Row(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
const Icon(Icons.group_remove_outlined),
|
||||
const SizedBox(width: 12),
|
||||
Text(L10n.of(context).removeFromSpace),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
);
|
||||
if (action == null) return;
|
||||
if (!mounted) return;
|
||||
final space = Matrix.of(context).client.getRoomById(widget.spaceId);
|
||||
if (space == null) return;
|
||||
switch (action) {
|
||||
case SpaceChildAction.edit:
|
||||
context.push('/rooms/${widget.spaceId}/details');
|
||||
case SpaceChildAction.moveToSpace:
|
||||
final spacesWithPowerLevels = space.client.rooms
|
||||
.where(
|
||||
(room) =>
|
||||
room.isSpace &&
|
||||
room.canChangeStateEvent(EventTypes.SpaceChild) &&
|
||||
room.id != widget.spaceId,
|
||||
)
|
||||
.toList();
|
||||
final newSpace = await showModalActionPopup(
|
||||
context: context,
|
||||
title: L10n.of(context).space,
|
||||
actions: spacesWithPowerLevels
|
||||
.map(
|
||||
(space) => AdaptiveModalAction(
|
||||
value: space,
|
||||
label: space
|
||||
.getLocalizedDisplayname(MatrixLocals(L10n.of(context))),
|
||||
),
|
||||
)
|
||||
.toList(),
|
||||
);
|
||||
if (newSpace == null) return;
|
||||
final result = await showFutureLoadingDialog(
|
||||
context: context,
|
||||
future: () async {
|
||||
await newSpace.setSpaceChild(newSpace.id);
|
||||
await space.removeSpaceChild(roomId);
|
||||
},
|
||||
);
|
||||
if (result.isError) return;
|
||||
if (!mounted) return;
|
||||
_nextBatch = null;
|
||||
_loadHierarchy();
|
||||
return;
|
||||
|
||||
case SpaceChildAction.removeFromSpace:
|
||||
final consent = await showOkCancelAlertDialog(
|
||||
context: context,
|
||||
title: L10n.of(context).removeFromSpace,
|
||||
message: L10n.of(context).removeFromSpaceDescription,
|
||||
);
|
||||
if (consent != OkCancelResult.ok) return;
|
||||
if (!mounted) return;
|
||||
final result = await showFutureLoadingDialog(
|
||||
context: context,
|
||||
future: () => space.removeSpaceChild(roomId),
|
||||
);
|
||||
if (result.isError) return;
|
||||
if (!mounted) return;
|
||||
_nextBatch = null;
|
||||
_loadHierarchy();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
|
|
@ -228,6 +395,11 @@ class _SpaceViewState extends State<SpaceView> {
|
|||
final room = Matrix.of(context).client.getRoomById(widget.spaceId);
|
||||
final displayname =
|
||||
room?.getLocalizedDisplayname() ?? L10n.of(context).nothingFound;
|
||||
const avatarSize = Avatar.defaultSize / 1.5;
|
||||
final isAdmin = room?.canChangeStateEvent(
|
||||
EventTypes.SpaceChild,
|
||||
) ==
|
||||
true;
|
||||
return Scaffold(
|
||||
appBar: AppBar(
|
||||
leading: FluffyThemes.isColumnMode(context)
|
||||
|
|
@ -242,6 +414,7 @@ class _SpaceViewState extends State<SpaceView> {
|
|||
title: ListTile(
|
||||
contentPadding: EdgeInsets.zero,
|
||||
leading: Avatar(
|
||||
size: avatarSize,
|
||||
mxContent: room?.avatar,
|
||||
name: displayname,
|
||||
border: BorderSide(width: 1, color: theme.dividerColor),
|
||||
|
|
@ -252,19 +425,40 @@ class _SpaceViewState extends State<SpaceView> {
|
|||
maxLines: 1,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
),
|
||||
subtitle: room == null
|
||||
? null
|
||||
: Text(
|
||||
L10n.of(context).countChatsAndCountParticipants(
|
||||
room.spaceChildren.length,
|
||||
room.summary.mJoinedMemberCount ?? 1,
|
||||
),
|
||||
maxLines: 1,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
),
|
||||
),
|
||||
actions: [
|
||||
if (isAdmin)
|
||||
PopupMenuButton<AddRoomType>(
|
||||
icon: const Icon(Icons.add_outlined),
|
||||
onSelected: _addChatOrSubspace,
|
||||
tooltip: L10n.of(context).addChatOrSubSpace,
|
||||
itemBuilder: (context) => [
|
||||
PopupMenuItem(
|
||||
value: AddRoomType.chat,
|
||||
child: Row(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
const Icon(Icons.group_add_outlined),
|
||||
const SizedBox(width: 12),
|
||||
Text(L10n.of(context).newGroup),
|
||||
],
|
||||
),
|
||||
),
|
||||
PopupMenuItem(
|
||||
value: AddRoomType.subspace,
|
||||
child: Row(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
const Icon(Icons.workspaces_outlined),
|
||||
const SizedBox(width: 12),
|
||||
Text(L10n.of(context).newSubSpace),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
PopupMenuButton<SpaceActions>(
|
||||
useRootNavigator: true,
|
||||
onSelected: _onSpaceAction,
|
||||
itemBuilder: (context) => [
|
||||
PopupMenuItem(
|
||||
|
|
@ -289,6 +483,21 @@ class _SpaceViewState extends State<SpaceView> {
|
|||
],
|
||||
),
|
||||
),
|
||||
PopupMenuItem(
|
||||
value: SpaceActions.members,
|
||||
child: Row(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
const Icon(Icons.group_outlined),
|
||||
const SizedBox(width: 12),
|
||||
Text(
|
||||
L10n.of(context).countParticipants(
|
||||
room?.summary.mJoinedMemberCount ?? 1,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
PopupMenuItem(
|
||||
value: SpaceActions.leave,
|
||||
child: Row(
|
||||
|
|
@ -304,16 +513,6 @@ class _SpaceViewState extends State<SpaceView> {
|
|||
),
|
||||
],
|
||||
),
|
||||
floatingActionButton: room?.canChangeStateEvent(
|
||||
EventTypes.SpaceChild,
|
||||
) ==
|
||||
true
|
||||
? FloatingActionButton.extended(
|
||||
onPressed: _addChatOrSubspace,
|
||||
label: Text(L10n.of(context).group),
|
||||
icon: const Icon(Icons.group_add_outlined),
|
||||
)
|
||||
: null,
|
||||
body: room == null
|
||||
? const Center(
|
||||
child: Icon(
|
||||
|
|
@ -331,9 +530,11 @@ class _SpaceViewState extends State<SpaceView> {
|
|||
.whereType<String>()
|
||||
.toSet();
|
||||
|
||||
final joinedRooms = room.client.rooms
|
||||
final joinedRooms = Map.fromEntries(
|
||||
room.client.rooms
|
||||
.where((room) => childrenIds.remove(room.id))
|
||||
.toList();
|
||||
.map((room) => MapEntry(room.id, room)),
|
||||
);
|
||||
|
||||
final joinedParents = room.spaceParents
|
||||
.map((parent) {
|
||||
|
|
@ -348,7 +549,6 @@ class _SpaceViewState extends State<SpaceView> {
|
|||
slivers: [
|
||||
SliverAppBar(
|
||||
floating: true,
|
||||
toolbarHeight: 72,
|
||||
scrolledUnderElevation: 0,
|
||||
backgroundColor: Colors.transparent,
|
||||
automaticallyImplyLeading: false,
|
||||
|
|
@ -358,11 +558,6 @@ class _SpaceViewState extends State<SpaceView> {
|
|||
textInputAction: TextInputAction.search,
|
||||
decoration: InputDecoration(
|
||||
filled: true,
|
||||
fillColor: theme.colorScheme.secondaryContainer,
|
||||
border: OutlineInputBorder(
|
||||
borderSide: BorderSide.none,
|
||||
borderRadius: BorderRadius.circular(99),
|
||||
),
|
||||
contentPadding: EdgeInsets.zero,
|
||||
hintText: L10n.of(context).search,
|
||||
hintStyle: TextStyle(
|
||||
|
|
@ -422,42 +617,11 @@ class _SpaceViewState extends State<SpaceView> {
|
|||
},
|
||||
),
|
||||
SliverList.builder(
|
||||
itemCount: joinedRooms.length,
|
||||
itemCount: _discoveredChildren.length + 1,
|
||||
itemBuilder: (context, i) {
|
||||
final joinedRoom = joinedRooms[i];
|
||||
return ChatListItem(
|
||||
joinedRoom,
|
||||
filter: filter,
|
||||
onTap: () => widget.onChatTab(joinedRoom),
|
||||
onLongPress: (context) => widget.onChatContext(
|
||||
joinedRoom,
|
||||
context,
|
||||
),
|
||||
activeChat: widget.activeChat == joinedRoom.id,
|
||||
);
|
||||
},
|
||||
),
|
||||
SliverList.builder(
|
||||
itemCount: _discoveredChildren.length + 2,
|
||||
itemBuilder: (context, i) {
|
||||
if (i == 0) {
|
||||
return SearchTitle(
|
||||
title: L10n.of(context).discover,
|
||||
icon: const Icon(Icons.explore_outlined),
|
||||
);
|
||||
}
|
||||
i--;
|
||||
if (i == _discoveredChildren.length) {
|
||||
if (_noMoreRooms) {
|
||||
return Padding(
|
||||
padding: const EdgeInsets.all(12.0),
|
||||
child: Center(
|
||||
child: Text(
|
||||
L10n.of(context).noMoreChatsFound,
|
||||
style: const TextStyle(fontSize: 13),
|
||||
),
|
||||
),
|
||||
);
|
||||
return const SizedBox.shrink();
|
||||
}
|
||||
return Padding(
|
||||
padding: const EdgeInsets.symmetric(
|
||||
|
|
@ -467,11 +631,7 @@ class _SpaceViewState extends State<SpaceView> {
|
|||
child: TextButton(
|
||||
onPressed: _isLoading ? null : _loadHierarchy,
|
||||
child: _isLoading
|
||||
? LinearProgressIndicator(
|
||||
borderRadius: BorderRadius.circular(
|
||||
AppConfig.borderRadius,
|
||||
),
|
||||
)
|
||||
? const CircularProgressIndicator.adaptive()
|
||||
: Text(L10n.of(context).loadMore),
|
||||
),
|
||||
);
|
||||
|
|
@ -483,6 +643,7 @@ class _SpaceViewState extends State<SpaceView> {
|
|||
if (!displayname.toLowerCase().contains(filter)) {
|
||||
return const SizedBox.shrink();
|
||||
}
|
||||
final joinedRoom = joinedRooms[item.roomId];
|
||||
return Padding(
|
||||
padding: const EdgeInsets.symmetric(
|
||||
horizontal: 8,
|
||||
|
|
@ -492,51 +653,83 @@ class _SpaceViewState extends State<SpaceView> {
|
|||
borderRadius:
|
||||
BorderRadius.circular(AppConfig.borderRadius),
|
||||
clipBehavior: Clip.hardEdge,
|
||||
child: ListTile(
|
||||
color: joinedRoom != null &&
|
||||
widget.activeChat == joinedRoom.id
|
||||
? theme.colorScheme.secondaryContainer
|
||||
: Colors.transparent,
|
||||
child: HoverBuilder(
|
||||
builder: (context, hovered) => ListTile(
|
||||
visualDensity:
|
||||
const VisualDensity(vertical: -0.5),
|
||||
contentPadding:
|
||||
const EdgeInsets.symmetric(horizontal: 8),
|
||||
onTap: () => _joinChildRoom(item),
|
||||
leading: Avatar(
|
||||
onTap: joinedRoom != null
|
||||
? () => widget.onChatTab(joinedRoom)
|
||||
: () => _joinChildRoom(item),
|
||||
onLongPress: isAdmin
|
||||
? () => _showSpaceChildEditMenu(
|
||||
context,
|
||||
item.roomId,
|
||||
)
|
||||
: null,
|
||||
leading: hovered && isAdmin
|
||||
? SizedBox.square(
|
||||
dimension: avatarSize,
|
||||
child: IconButton(
|
||||
splashRadius: avatarSize,
|
||||
iconSize: 14,
|
||||
style: IconButton.styleFrom(
|
||||
foregroundColor: theme.colorScheme
|
||||
.onTertiaryContainer,
|
||||
backgroundColor: theme
|
||||
.colorScheme.tertiaryContainer,
|
||||
),
|
||||
onPressed: () =>
|
||||
_showSpaceChildEditMenu(
|
||||
context,
|
||||
item.roomId,
|
||||
),
|
||||
icon: const Icon(Icons.edit_outlined),
|
||||
),
|
||||
)
|
||||
: Avatar(
|
||||
size: avatarSize,
|
||||
mxContent: item.avatarUrl,
|
||||
name: displayname,
|
||||
name: '#',
|
||||
backgroundColor:
|
||||
theme.colorScheme.surfaceContainer,
|
||||
textColor: item.name?.darkColor ??
|
||||
theme.colorScheme.onSurface,
|
||||
border: item.roomType == 'm.space'
|
||||
? BorderSide(
|
||||
color: theme.colorScheme
|
||||
.surfaceContainerHighest,
|
||||
)
|
||||
: null,
|
||||
borderRadius: item.roomType == 'm.space'
|
||||
? BorderRadius.circular(
|
||||
AppConfig.borderRadius / 2,
|
||||
AppConfig.borderRadius / 4,
|
||||
)
|
||||
: null,
|
||||
),
|
||||
title: Row(
|
||||
children: [
|
||||
Expanded(
|
||||
child: Opacity(
|
||||
opacity: joinedRoom == null ? 0.5 : 1,
|
||||
child: Text(
|
||||
displayname,
|
||||
maxLines: 1,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
),
|
||||
),
|
||||
Text(
|
||||
item.numJoinedMembers.toString(),
|
||||
style: TextStyle(
|
||||
fontSize: 13,
|
||||
color: theme.textTheme.bodyMedium!.color,
|
||||
),
|
||||
),
|
||||
const SizedBox(width: 4),
|
||||
const Icon(
|
||||
Icons.people_outlined,
|
||||
size: 14,
|
||||
),
|
||||
if (joinedRoom != null)
|
||||
UnreadBubble(room: joinedRoom)
|
||||
else
|
||||
const Icon(Icons.chevron_right_outlined),
|
||||
],
|
||||
),
|
||||
subtitle: Text(
|
||||
item.topic ??
|
||||
L10n.of(context).countParticipants(
|
||||
item.numJoinedMembers,
|
||||
),
|
||||
maxLines: 1,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
),
|
||||
),
|
||||
),
|
||||
|
|
@ -551,9 +744,3 @@ class _SpaceViewState extends State<SpaceView> {
|
|||
);
|
||||
}
|
||||
}
|
||||
|
||||
enum SpaceActions {
|
||||
settings,
|
||||
invite,
|
||||
leave,
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,56 @@
|
|||
import 'package:flutter/material.dart';
|
||||
|
||||
import 'package:matrix/matrix.dart';
|
||||
|
||||
import 'package:extera_next/config/themes.dart';
|
||||
|
||||
class UnreadBubble extends StatelessWidget {
|
||||
final Room room;
|
||||
const UnreadBubble({required this.room, super.key});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final theme = Theme.of(context);
|
||||
final unread = room.isUnread;
|
||||
final hasNotifications = room.notificationCount > 0;
|
||||
final unreadBubbleSize = unread || room.hasNewMessages
|
||||
? room.notificationCount > 0
|
||||
? 20.0
|
||||
: 14.0
|
||||
: 0.0;
|
||||
return AnimatedContainer(
|
||||
duration: FluffyThemes.animationDuration,
|
||||
curve: FluffyThemes.animationCurve,
|
||||
alignment: Alignment.center,
|
||||
padding: const EdgeInsets.symmetric(horizontal: 7),
|
||||
height: unreadBubbleSize,
|
||||
width: !hasNotifications && !unread && !room.hasNewMessages
|
||||
? 0
|
||||
: (unreadBubbleSize - 9) * room.notificationCount.toString().length +
|
||||
9,
|
||||
decoration: BoxDecoration(
|
||||
color: room.highlightCount > 0
|
||||
? theme.colorScheme.error
|
||||
: hasNotifications || room.markedUnread
|
||||
? theme.colorScheme.primary
|
||||
: theme.colorScheme.primaryContainer,
|
||||
borderRadius: BorderRadius.circular(7),
|
||||
),
|
||||
child: hasNotifications
|
||||
? Text(
|
||||
room.notificationCount.toString(),
|
||||
style: TextStyle(
|
||||
color: room.highlightCount > 0
|
||||
? theme.colorScheme.onError
|
||||
: hasNotifications
|
||||
? theme.colorScheme.onPrimary
|
||||
: theme.colorScheme.onPrimaryContainer,
|
||||
fontSize: 13,
|
||||
fontWeight: FontWeight.w500,
|
||||
),
|
||||
textAlign: TextAlign.center,
|
||||
)
|
||||
: const SizedBox.shrink(),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,47 @@
|
|||
import 'package:extera_next/generated/l10n/l10n.dart';
|
||||
import 'package:extera_next/pages/chat/chat.dart';
|
||||
import 'package:extera_next/widgets/matrix.dart';
|
||||
import 'package:extera_next/widgets/share_scaffold_dialog.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
class ThreadPage extends StatelessWidget {
|
||||
final String roomId;
|
||||
final List<ShareItem>? shareItems;
|
||||
final String? threadRootEventId;
|
||||
final String? eventId;
|
||||
|
||||
const ThreadPage({
|
||||
super.key,
|
||||
required this.roomId,
|
||||
required this.threadRootEventId,
|
||||
this.eventId,
|
||||
this.shareItems,
|
||||
});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final client = Matrix.of(context).client;
|
||||
final room = client.getRoomById(roomId);
|
||||
if (room == null) {
|
||||
return Scaffold(
|
||||
appBar: AppBar(title: Text(L10n.of(context).oopsSomethingWentWrong)),
|
||||
body: Center(
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(16),
|
||||
child: Text(L10n.of(context).youAreNoLongerParticipatingInThisChat),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
final thread = room.threads[threadRootEventId];
|
||||
|
||||
return ChatPageWithRoom(
|
||||
key: Key('chat_page_${roomId}_${threadRootEventId}_$eventId'),
|
||||
room: room,
|
||||
thread: thread,
|
||||
shareItems: shareItems,
|
||||
eventId: eventId,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
@ -88,7 +88,7 @@ class ImageViewerView extends StatelessWidget {
|
|||
child: GestureDetector(
|
||||
// Ignore taps to not go back here:
|
||||
onTap: () {},
|
||||
child: EventVideoPlayer(event),
|
||||
child: EventVideoPlayer(event, controller),
|
||||
),
|
||||
),
|
||||
);
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
import 'dart:io';
|
||||
|
||||
import 'package:extera_next/pages/image_viewer/image_viewer.dart';
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
|
|
@ -18,9 +19,11 @@ import '../../widgets/mxc_image.dart';
|
|||
|
||||
class EventVideoPlayer extends StatefulWidget {
|
||||
final Event event;
|
||||
final ImageViewerController ivController;
|
||||
|
||||
const EventVideoPlayer(
|
||||
this.event, {
|
||||
this.event,
|
||||
this.ivController, {
|
||||
super.key,
|
||||
});
|
||||
|
||||
|
|
@ -69,6 +72,11 @@ class EventVideoPlayerState extends State<EventVideoPlayer> {
|
|||
|
||||
await videoPlayerController.initialize();
|
||||
|
||||
if (widget.ivController.currentEvent.eventId != widget.event.eventId) {
|
||||
dispose();
|
||||
return;
|
||||
}
|
||||
|
||||
// Create a ChewieController on top.
|
||||
setState(() {
|
||||
_chewieController = ChewieController(
|
||||
|
|
|
|||
|
|
@ -115,7 +115,7 @@ abstract class ClientManager {
|
|||
return Client(
|
||||
clientName,
|
||||
httpClient:
|
||||
PlatformInfos.isAndroid ? CustomHttpClient.createHTTPClient() : null,
|
||||
CustomHttpClient.createHTTPClient(),
|
||||
verificationMethods: {
|
||||
KeyVerificationMethod.numbers,
|
||||
if (kIsWeb || PlatformInfos.isMobile || PlatformInfos.isLinux)
|
||||
|
|
|
|||
|
|
@ -1,15 +1,20 @@
|
|||
import 'dart:convert';
|
||||
import 'dart:io';
|
||||
|
||||
import 'package:extera_next/config/app_config.dart';
|
||||
import 'package:extera_next/utils/platform_infos.dart';
|
||||
import 'package:http/http.dart' as http;
|
||||
import 'package:http/io_client.dart';
|
||||
|
||||
import 'package:extera_next/config/isrg_x1.dart';
|
||||
|
||||
class CustomHttpClient {
|
||||
static HttpClient customHttpClient(String? cert) {
|
||||
static HttpClient? customHttpClient(String? cert) {
|
||||
if (PlatformInfos.isWeb) return null;
|
||||
|
||||
final context = SecurityContext.defaultContext;
|
||||
|
||||
if (PlatformInfos.isAndroid) {
|
||||
try {
|
||||
if (cert != null) {
|
||||
final bytes = utf8.encode(cert);
|
||||
|
|
@ -22,8 +27,17 @@ class CustomHttpClient {
|
|||
rethrow;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return HttpClient(context: context);
|
||||
final client = HttpClient(context: context);
|
||||
|
||||
if (AppConfig.httpProxy != null) {
|
||||
client.findProxy = (uri) {
|
||||
return "PROXY ${AppConfig.httpProxy};";
|
||||
};
|
||||
}
|
||||
|
||||
return client;
|
||||
}
|
||||
|
||||
static http.Client createHTTPClient() => IOClient(customHttpClient(ISRG_X1));
|
||||
|
|
|
|||
|
|
@ -4,6 +4,14 @@ import 'package:matrix/matrix.dart';
|
|||
import '../../config/app_config.dart';
|
||||
|
||||
extension VisibleInGuiExtension on List<Event> {
|
||||
List<Event> filterByThreaded(bool threaded) {
|
||||
return where((e) => e.isThreaded == threaded || e.relationshipType == RelationshipTypes.edit || e.relationshipType == RelationshipTypes.reaction).toList();
|
||||
}
|
||||
|
||||
List<Event> filterThreadRoots() {
|
||||
return where((e) => e.room.threads.containsKey(e.eventId)).toList();
|
||||
}
|
||||
|
||||
List<Event> filterByVisibleInGui({String? exceptionEventId}) {
|
||||
final visibleEvents =
|
||||
where((e) => e.isVisibleInGui || e.eventId == exceptionEventId)
|
||||
|
|
@ -46,7 +54,9 @@ extension IsStateExtension on Event {
|
|||
// if we enabled to hide all redacted events, don't show those
|
||||
(!AppConfig.hideRedactedEvents || !redacted) &&
|
||||
// if we enabled to hide all unknown events, don't show those
|
||||
(!AppConfig.hideUnknownEvents || isEventTypeKnown || type == PollEvents.PollStart) &&
|
||||
(!AppConfig.hideUnknownEvents ||
|
||||
isEventTypeKnown ||
|
||||
type == PollEvents.PollStart) &&
|
||||
// remove state events that we don't want to render
|
||||
(isState || !AppConfig.hideAllStateEvents) &&
|
||||
// hide simple join/leave member events in public rooms
|
||||
|
|
@ -56,5 +66,9 @@ extension IsStateExtension on Event {
|
|||
content.tryGet<String>('membership') == 'ban' ||
|
||||
stateKey != senderId);
|
||||
|
||||
bool get isThreaded =>
|
||||
relationshipEventId != null &&
|
||||
relationshipType == RelationshipTypes.thread;
|
||||
|
||||
bool get isState => this.stateKey != null;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -10,7 +10,6 @@ import 'package:sqflite_common_ffi/sqflite_ffi.dart';
|
|||
import 'package:universal_html/html.dart' as html;
|
||||
|
||||
import 'package:extera_next/config/app_config.dart';
|
||||
import 'package:extera_next/generated/l10n/l10n.dart';
|
||||
import 'package:extera_next/utils/client_manager.dart';
|
||||
import 'package:extera_next/utils/platform_infos.dart';
|
||||
import 'cipher.dart';
|
||||
|
|
@ -69,7 +68,12 @@ Future<MatrixSdkDatabase> _constructDatabase(String clientName) async {
|
|||
|
||||
Directory? fileStorageLocation;
|
||||
try {
|
||||
fileStorageLocation = await getTemporaryDirectory();
|
||||
final tmpDir = await getTemporaryDirectory();
|
||||
final appTmpDir = Directory(join(tmpDir.path, clientName));
|
||||
if (!await appTmpDir.exists()) {
|
||||
await appTmpDir.create(recursive: true);
|
||||
}
|
||||
fileStorageLocation = appTmpDir;
|
||||
} on MissingPlatformDirectoryException catch (_) {
|
||||
Logs().w(
|
||||
'No temporary directory for file cache available on this platform.',
|
||||
|
|
@ -109,8 +113,7 @@ Future<MatrixSdkDatabase> _constructDatabase(String clientName) async {
|
|||
version: 1,
|
||||
// most important : apply encryption when opening the DB
|
||||
onConfigure: helper?.applyPragmaKey,
|
||||
singleInstance: false
|
||||
),
|
||||
singleInstance: false),
|
||||
);
|
||||
|
||||
return await MatrixSdkDatabase.init(
|
||||
|
|
|
|||
|
|
@ -7,11 +7,11 @@ extension SynapseAdmin on matrix.Client {
|
|||
Future<List<dynamic>> getEventReports({int from = 0, int limit = 10}) async {
|
||||
final requestUri = Uri(
|
||||
path: '/_synapse/admin/v1/event_reports',
|
||||
query: 'from=$from&limit=$limit&order_by=received_ts&dir=b'
|
||||
query: 'from=$from&limit=$limit&order_by=received_ts&dir=b',
|
||||
);
|
||||
|
||||
if (baseUri == null) return [];
|
||||
print(baseUri!.resolveUri(requestUri).toString());
|
||||
|
||||
final request = Request('GET', baseUri!.resolveUri(requestUri));
|
||||
request.headers['authorization'] = 'Bearer $accessToken';
|
||||
final response = await httpClient.send(request);
|
||||
|
|
@ -40,14 +40,13 @@ extension SynapseAdmin on matrix.Client {
|
|||
|
||||
if (room == null) return null;
|
||||
|
||||
print('Event content: ${jsonEncode(json['event_json'])}');
|
||||
|
||||
return new matrix.Event(
|
||||
return matrix.Event(
|
||||
content: json['event_json']['content'],
|
||||
type: json['event_json']['type'],
|
||||
eventId: json['event_id'],
|
||||
senderId: json['sender'],
|
||||
originServerTs: DateTime.fromMillisecondsSinceEpoch(json['event_json']['origin_server_ts']),
|
||||
originServerTs: DateTime.fromMillisecondsSinceEpoch(
|
||||
json['event_json']['origin_server_ts']),
|
||||
room: room,
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -30,7 +30,9 @@ class PublicRoomDialog extends StatelessWidget {
|
|||
final result = await showFutureLoadingDialog<String>(
|
||||
context: context,
|
||||
future: () async {
|
||||
if (chunk != null && client.getRoomById(chunk.roomId) != null) {
|
||||
if (chunk != null &&
|
||||
client.getRoomById(chunk.roomId) != null &&
|
||||
client.getRoomById(chunk.roomId)?.membership != Membership.leave) {
|
||||
return chunk.roomId;
|
||||
}
|
||||
final roomId = chunk != null && knock
|
||||
|
|
|
|||
|
|
@ -18,6 +18,8 @@ class Avatar extends StatelessWidget {
|
|||
final BorderRadius? borderRadius;
|
||||
final IconData? icon;
|
||||
final BorderSide? border;
|
||||
final Color? backgroundColor;
|
||||
final Color? textColor;
|
||||
|
||||
const Avatar({
|
||||
this.mxContent,
|
||||
|
|
@ -30,6 +32,8 @@ class Avatar extends StatelessWidget {
|
|||
this.borderRadius,
|
||||
this.border,
|
||||
this.icon,
|
||||
this.backgroundColor,
|
||||
this.textColor,
|
||||
super.key,
|
||||
});
|
||||
|
||||
|
|
@ -71,14 +75,16 @@ class Avatar extends StatelessWidget {
|
|||
height: size,
|
||||
placeholder: (_) => noPic
|
||||
? Container(
|
||||
decoration: BoxDecoration(color: name?.lightColorAvatar),
|
||||
decoration: BoxDecoration(
|
||||
color: backgroundColor ?? name?.lightColorAvatar,
|
||||
),
|
||||
alignment: Alignment.center,
|
||||
child: Text(
|
||||
fallbackLetters,
|
||||
textAlign: TextAlign.center,
|
||||
style: TextStyle(
|
||||
fontFamily: 'RobotoMono',
|
||||
color: Colors.white,
|
||||
color: textColor ?? Colors.white,
|
||||
fontWeight: FontWeight.bold,
|
||||
fontSize: (size / 2.5).roundToDouble(),
|
||||
),
|
||||
|
|
|
|||
|
|
@ -1203,10 +1203,10 @@ packages:
|
|||
description:
|
||||
path: "."
|
||||
ref: main
|
||||
resolved-ref: "58c4cf19d010d9ae193e9df10bd1f8fdf02277b0"
|
||||
resolved-ref: f678376e3a4825a6e1a00d89585d6bae0843950c
|
||||
url: "https://git.extera.xyz/OfficialDakari/matrix-dart-sdk.git"
|
||||
source: git
|
||||
version: "2.0.1"
|
||||
version: "3.0.1"
|
||||
meta:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
|
@ -2173,7 +2173,7 @@ packages:
|
|||
source: hosted
|
||||
version: "3.1.4"
|
||||
uuid:
|
||||
dependency: transitive
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: uuid
|
||||
sha256: a5be9ef6618a7ac1e964353ef476418026db906c4facdedaa299b7a2e71690ff
|
||||
|
|
|
|||
|
|
@ -101,6 +101,7 @@ dependencies:
|
|||
wakelock_plus: ^1.2.2
|
||||
webrtc_interface: ^1.0.13
|
||||
dio: ^5.9.0
|
||||
uuid: ^4.5.1
|
||||
|
||||
dev_dependencies:
|
||||
flutter_lints: ^3.0.0
|
||||
|
|
|
|||
Loading…
Reference in New Issue