Merge branch 'main' into 5244-grammar-practice-ui-updates
This commit is contained in:
commit
fa0489e401
73 changed files with 2185 additions and 311 deletions
|
|
@ -22,6 +22,7 @@ import 'package:fluffychat/pages/device_settings/device_settings.dart';
|
|||
import 'package:fluffychat/pages/login/login.dart';
|
||||
import 'package:fluffychat/pages/new_group/new_group.dart';
|
||||
import 'package:fluffychat/pages/new_private_chat/new_private_chat.dart';
|
||||
import 'package:fluffychat/pages/onboarding/space_code_onboarding.dart';
|
||||
import 'package:fluffychat/pages/settings/settings.dart';
|
||||
import 'package:fluffychat/pages/settings_3pid/settings_3pid.dart';
|
||||
import 'package:fluffychat/pages/settings_chat/settings_chat.dart';
|
||||
|
|
@ -50,9 +51,9 @@ import 'package:fluffychat/pangea/course_creation/course_invite_page.dart';
|
|||
import 'package:fluffychat/pangea/course_creation/selected_course_page.dart';
|
||||
import 'package:fluffychat/pangea/join_codes/join_with_link_page.dart';
|
||||
import 'package:fluffychat/pangea/learning_settings/settings_learning.dart';
|
||||
import 'package:fluffychat/pangea/login/pages/add_course_page.dart';
|
||||
import 'package:fluffychat/pangea/login/pages/course_code_page.dart';
|
||||
import 'package:fluffychat/pangea/login/pages/create_pangea_account_page.dart';
|
||||
import 'package:fluffychat/pangea/login/pages/find_course_page.dart';
|
||||
import 'package:fluffychat/pangea/login/pages/language_selection_page.dart';
|
||||
import 'package:fluffychat/pangea/login/pages/login_or_signup_view.dart';
|
||||
import 'package:fluffychat/pangea/login/pages/new_course_page.dart';
|
||||
|
|
@ -213,93 +214,8 @@ abstract class AppRoutes {
|
|||
pageBuilder: (context, state) => defaultPageBuilder(
|
||||
context,
|
||||
state,
|
||||
const AddCoursePage(route: 'registration'),
|
||||
const SpaceCodeOnboarding(),
|
||||
),
|
||||
routes: [
|
||||
GoRoute(
|
||||
path: 'private',
|
||||
pageBuilder: (context, state) {
|
||||
return defaultPageBuilder(
|
||||
context,
|
||||
state,
|
||||
const CourseCodePage(),
|
||||
);
|
||||
},
|
||||
),
|
||||
GoRoute(
|
||||
path: 'public',
|
||||
pageBuilder: (context, state) {
|
||||
return defaultPageBuilder(
|
||||
context,
|
||||
state,
|
||||
const PublicCoursesPage(
|
||||
route: 'registration',
|
||||
showFilters: false,
|
||||
),
|
||||
);
|
||||
},
|
||||
routes: [
|
||||
GoRoute(
|
||||
path: ':courseid',
|
||||
pageBuilder: (context, state) {
|
||||
return defaultPageBuilder(
|
||||
context,
|
||||
state,
|
||||
SelectedCourse(
|
||||
state.pathParameters['courseid']!,
|
||||
SelectedCourseMode.join,
|
||||
roomChunk: state.extra as PublicRoomsChunk?,
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
],
|
||||
),
|
||||
GoRoute(
|
||||
path: 'own',
|
||||
pageBuilder: (context, state) {
|
||||
return defaultPageBuilder(
|
||||
context,
|
||||
state,
|
||||
const NewCoursePage(
|
||||
route: 'registration',
|
||||
showFilters: false,
|
||||
),
|
||||
);
|
||||
},
|
||||
routes: [
|
||||
GoRoute(
|
||||
path: ':courseid',
|
||||
pageBuilder: (context, state) {
|
||||
return defaultPageBuilder(
|
||||
context,
|
||||
state,
|
||||
SelectedCourse(
|
||||
state.pathParameters['courseid']!,
|
||||
SelectedCourseMode.launch,
|
||||
),
|
||||
);
|
||||
},
|
||||
routes: [
|
||||
GoRoute(
|
||||
path: 'invite',
|
||||
pageBuilder: (context, state) {
|
||||
return defaultPageBuilder(
|
||||
context,
|
||||
state,
|
||||
CourseInvitePage(
|
||||
state.pathParameters['courseid']!,
|
||||
courseCreationCompleter:
|
||||
state.extra as Completer<String>?,
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
|
|
@ -434,7 +350,7 @@ abstract class AppRoutes {
|
|||
pageBuilder: (context, state) => defaultPageBuilder(
|
||||
context,
|
||||
state,
|
||||
const AddCoursePage(route: 'rooms'),
|
||||
const FindCoursePage(),
|
||||
),
|
||||
routes: [
|
||||
GoRoute(
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"@@locale": "ar",
|
||||
"@@last_modified": "2026-01-21 13:54:18.388293",
|
||||
"@@last_modified": "2026-01-22 12:01:48.002470",
|
||||
"about": "حول",
|
||||
"@about": {
|
||||
"type": "String",
|
||||
|
|
@ -11117,5 +11117,29 @@
|
|||
"@knockDesc": {
|
||||
"type": "String",
|
||||
"placeholders": {}
|
||||
},
|
||||
"joinSpaceOnboardingDesc": "هل لديك رمز دعوة أو رابط لدورة عامة؟",
|
||||
"welcomeUser": "مرحبًا {user}",
|
||||
"@joinSpaceOnboardingDesc": {
|
||||
"type": "String",
|
||||
"placeholders": {}
|
||||
},
|
||||
"@welcomeUser": {
|
||||
"type": "String",
|
||||
"placeholders": {
|
||||
"user": {
|
||||
"type": "String"
|
||||
}
|
||||
}
|
||||
},
|
||||
"publicInviteDescChat": "ابحث عن المستخدمين لدعوتهم إلى هذه الدردشة.",
|
||||
"publicInviteDescSpace": "ابحث عن المستخدمين لدعوتهم إلى هذا الفضاء.",
|
||||
"@publicInviteDescChat": {
|
||||
"type": "String",
|
||||
"placeholders": {}
|
||||
},
|
||||
"@publicInviteDescSpace": {
|
||||
"type": "String",
|
||||
"placeholders": {}
|
||||
}
|
||||
}
|
||||
|
|
@ -1911,7 +1911,7 @@
|
|||
"playWithAI": "Пакуль гуляйце з ШІ",
|
||||
"courseStartDesc": "Pangea Bot гатовы да працы ў любы час!\n\n...але навучанне лепш з сябрамі!",
|
||||
"@@locale": "be",
|
||||
"@@last_modified": "2026-01-21 13:54:07.402936",
|
||||
"@@last_modified": "2026-01-22 12:01:33.641094",
|
||||
"@alwaysUse24HourFormat": {
|
||||
"type": "String",
|
||||
"placeholders": {}
|
||||
|
|
@ -11999,5 +11999,29 @@
|
|||
"@knockDesc": {
|
||||
"type": "String",
|
||||
"placeholders": {}
|
||||
},
|
||||
"joinSpaceOnboardingDesc": "Ці маеце вы код запрашэння або спасылку на публічны курс?",
|
||||
"welcomeUser": "Сардэчна запрашаем, {user}",
|
||||
"@joinSpaceOnboardingDesc": {
|
||||
"type": "String",
|
||||
"placeholders": {}
|
||||
},
|
||||
"@welcomeUser": {
|
||||
"type": "String",
|
||||
"placeholders": {
|
||||
"user": {
|
||||
"type": "String"
|
||||
}
|
||||
}
|
||||
},
|
||||
"publicInviteDescChat": "Шукаць карыстальнікаў, каб запрасіць іх у гэты чат.",
|
||||
"publicInviteDescSpace": "Шукаць карыстальнікаў, каб запрасіць іх у гэтае прастору.",
|
||||
"@publicInviteDescChat": {
|
||||
"type": "String",
|
||||
"placeholders": {}
|
||||
},
|
||||
"@publicInviteDescSpace": {
|
||||
"type": "String",
|
||||
"placeholders": {}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
{
|
||||
"@@last_modified": "2026-01-21 13:54:31.328626",
|
||||
"@@last_modified": "2026-01-22 12:02:02.719528",
|
||||
"about": "সম্পর্কে",
|
||||
"@about": {
|
||||
"type": "String",
|
||||
|
|
@ -12004,5 +12004,29 @@
|
|||
"@knockDesc": {
|
||||
"type": "String",
|
||||
"placeholders": {}
|
||||
},
|
||||
"joinSpaceOnboardingDesc": "আপনার কি একটি আমন্ত্রণ কোড বা একটি পাবলিক কোর্সের লিঙ্ক আছে?",
|
||||
"welcomeUser": "স্বাগতম {user}",
|
||||
"@joinSpaceOnboardingDesc": {
|
||||
"type": "String",
|
||||
"placeholders": {}
|
||||
},
|
||||
"@welcomeUser": {
|
||||
"type": "String",
|
||||
"placeholders": {
|
||||
"user": {
|
||||
"type": "String"
|
||||
}
|
||||
}
|
||||
},
|
||||
"publicInviteDescChat": "এই চ্যাটে আমন্ত্রণ জানানোর জন্য ব্যবহারকারীদের খুঁজুন।",
|
||||
"publicInviteDescSpace": "এই স্পেসে আমন্ত্রণ জানানোর জন্য ব্যবহারকারীদের খুঁজুন।",
|
||||
"@publicInviteDescChat": {
|
||||
"type": "String",
|
||||
"placeholders": {}
|
||||
},
|
||||
"@publicInviteDescSpace": {
|
||||
"type": "String",
|
||||
"placeholders": {}
|
||||
}
|
||||
}
|
||||
|
|
@ -4279,7 +4279,7 @@
|
|||
"joinPublicTrip": "མི་ཚེས་ལ་ལོག་འབད།",
|
||||
"startOwnTrip": "ངེད་རང་གི་ལོག་ལ་སྦྱོར་བཅོས།",
|
||||
"@@locale": "bo",
|
||||
"@@last_modified": "2026-01-21 13:54:28.767499",
|
||||
"@@last_modified": "2026-01-22 12:01:59.937396",
|
||||
"@alwaysUse24HourFormat": {
|
||||
"type": "String",
|
||||
"placeholders": {}
|
||||
|
|
@ -10654,5 +10654,29 @@
|
|||
"@knockDesc": {
|
||||
"type": "String",
|
||||
"placeholders": {}
|
||||
},
|
||||
"joinSpaceOnboardingDesc": "Do you have an invite code or link to a public course?",
|
||||
"welcomeUser": "Welcome {user}",
|
||||
"@joinSpaceOnboardingDesc": {
|
||||
"type": "String",
|
||||
"placeholders": {}
|
||||
},
|
||||
"@welcomeUser": {
|
||||
"type": "String",
|
||||
"placeholders": {
|
||||
"user": {
|
||||
"type": "String"
|
||||
}
|
||||
}
|
||||
},
|
||||
"publicInviteDescChat": "Searc for users to invite them to this chat.",
|
||||
"publicInviteDescSpace": "Searc for users to invite them to this space.",
|
||||
"@publicInviteDescChat": {
|
||||
"type": "String",
|
||||
"placeholders": {}
|
||||
},
|
||||
"@publicInviteDescSpace": {
|
||||
"type": "String",
|
||||
"placeholders": {}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
{
|
||||
"@@last_modified": "2026-01-21 13:54:08.647836",
|
||||
"@@last_modified": "2026-01-22 12:01:35.625715",
|
||||
"about": "Quant a",
|
||||
"@about": {
|
||||
"type": "String",
|
||||
|
|
@ -10924,5 +10924,29 @@
|
|||
"@knockDesc": {
|
||||
"type": "String",
|
||||
"placeholders": {}
|
||||
},
|
||||
"joinSpaceOnboardingDesc": "Tens un codi d'invitació o un enllaç a un curs públic?",
|
||||
"welcomeUser": "Benvingut {user}",
|
||||
"@joinSpaceOnboardingDesc": {
|
||||
"type": "String",
|
||||
"placeholders": {}
|
||||
},
|
||||
"@welcomeUser": {
|
||||
"type": "String",
|
||||
"placeholders": {
|
||||
"user": {
|
||||
"type": "String"
|
||||
}
|
||||
}
|
||||
},
|
||||
"publicInviteDescChat": "Cerca usuaris per convidar-los a aquest xat.",
|
||||
"publicInviteDescSpace": "Cerca usuaris per convidar-los a aquest espai.",
|
||||
"@publicInviteDescChat": {
|
||||
"type": "String",
|
||||
"placeholders": {}
|
||||
},
|
||||
"@publicInviteDescSpace": {
|
||||
"type": "String",
|
||||
"placeholders": {}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"@@locale": "cs",
|
||||
"@@last_modified": "2026-01-21 13:54:04.800051",
|
||||
"@@last_modified": "2026-01-22 12:01:30.360444",
|
||||
"about": "O aplikaci",
|
||||
"@about": {
|
||||
"type": "String",
|
||||
|
|
@ -11507,5 +11507,29 @@
|
|||
"@knockDesc": {
|
||||
"type": "String",
|
||||
"placeholders": {}
|
||||
},
|
||||
"joinSpaceOnboardingDesc": "Máte pozvánkový kód nebo odkaz na veřejný kurz?",
|
||||
"welcomeUser": "Vítejte {user}",
|
||||
"@joinSpaceOnboardingDesc": {
|
||||
"type": "String",
|
||||
"placeholders": {}
|
||||
},
|
||||
"@welcomeUser": {
|
||||
"type": "String",
|
||||
"placeholders": {
|
||||
"user": {
|
||||
"type": "String"
|
||||
}
|
||||
}
|
||||
},
|
||||
"publicInviteDescChat": "Hledejte uživatele, které chcete pozvat do tohoto chatu.",
|
||||
"publicInviteDescSpace": "Hledejte uživatele, které chcete pozvat do tohoto prostoru.",
|
||||
"@publicInviteDescChat": {
|
||||
"type": "String",
|
||||
"placeholders": {}
|
||||
},
|
||||
"@publicInviteDescSpace": {
|
||||
"type": "String",
|
||||
"placeholders": {}
|
||||
}
|
||||
}
|
||||
|
|
@ -1930,7 +1930,7 @@
|
|||
"playWithAI": "Leg med AI for nu",
|
||||
"courseStartDesc": "Pangea Bot er klar til at starte når som helst!\n\n...men læring er bedre med venner!",
|
||||
"@@locale": "da",
|
||||
"@@last_modified": "2026-01-21 13:53:34.885532",
|
||||
"@@last_modified": "2026-01-22 12:00:57.389253",
|
||||
"@aboutHomeserver": {
|
||||
"type": "String",
|
||||
"placeholders": {
|
||||
|
|
@ -11961,5 +11961,29 @@
|
|||
"@knockDesc": {
|
||||
"type": "String",
|
||||
"placeholders": {}
|
||||
},
|
||||
"joinSpaceOnboardingDesc": "Har du en invitationskode eller et link til et offentligt kursus?",
|
||||
"welcomeUser": "Velkommen {user}",
|
||||
"@joinSpaceOnboardingDesc": {
|
||||
"type": "String",
|
||||
"placeholders": {}
|
||||
},
|
||||
"@welcomeUser": {
|
||||
"type": "String",
|
||||
"placeholders": {
|
||||
"user": {
|
||||
"type": "String"
|
||||
}
|
||||
}
|
||||
},
|
||||
"publicInviteDescChat": "Søg efter brugere for at invitere dem til denne chat.",
|
||||
"publicInviteDescSpace": "Søg efter brugere for at invitere dem til dette rum.",
|
||||
"@publicInviteDescChat": {
|
||||
"type": "String",
|
||||
"placeholders": {}
|
||||
},
|
||||
"@publicInviteDescSpace": {
|
||||
"type": "String",
|
||||
"placeholders": {}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"@@locale": "de",
|
||||
"@@last_modified": "2026-01-21 13:53:56.595777",
|
||||
"@@last_modified": "2026-01-22 12:01:22.683777",
|
||||
"alwaysUse24HourFormat": "true",
|
||||
"@alwaysUse24HourFormat": {
|
||||
"description": "Set to true to always display time of day in 24 hour format."
|
||||
|
|
@ -10907,5 +10907,29 @@
|
|||
"@knockDesc": {
|
||||
"type": "String",
|
||||
"placeholders": {}
|
||||
},
|
||||
"joinSpaceOnboardingDesc": "Haben Sie einen Einladungscode oder einen Link zu einem öffentlichen Kurs?",
|
||||
"welcomeUser": "Willkommen {user}",
|
||||
"@joinSpaceOnboardingDesc": {
|
||||
"type": "String",
|
||||
"placeholders": {}
|
||||
},
|
||||
"@welcomeUser": {
|
||||
"type": "String",
|
||||
"placeholders": {
|
||||
"user": {
|
||||
"type": "String"
|
||||
}
|
||||
}
|
||||
},
|
||||
"publicInviteDescChat": "Suchen Sie nach Benutzern, um sie zu diesem Chat einzuladen.",
|
||||
"publicInviteDescSpace": "Suchen Sie nach Benutzern, um sie zu diesem Raum einzuladen.",
|
||||
"@publicInviteDescChat": {
|
||||
"type": "String",
|
||||
"placeholders": {}
|
||||
},
|
||||
"@publicInviteDescSpace": {
|
||||
"type": "String",
|
||||
"placeholders": {}
|
||||
}
|
||||
}
|
||||
|
|
@ -4456,7 +4456,7 @@
|
|||
"playWithAI": "Παίξτε με την Τεχνητή Νοημοσύνη προς το παρόν",
|
||||
"courseStartDesc": "Ο Pangea Bot είναι έτοιμος να ξεκινήσει οποιαδήποτε στιγμή!\n\n...αλλά η μάθηση είναι καλύτερη με φίλους!",
|
||||
"@@locale": "el",
|
||||
"@@last_modified": "2026-01-21 13:54:37.783088",
|
||||
"@@last_modified": "2026-01-22 12:02:10.279313",
|
||||
"@alwaysUse24HourFormat": {
|
||||
"type": "String",
|
||||
"placeholders": {}
|
||||
|
|
@ -11958,5 +11958,29 @@
|
|||
"@knockDesc": {
|
||||
"type": "String",
|
||||
"placeholders": {}
|
||||
},
|
||||
"joinSpaceOnboardingDesc": "Έχετε έναν κωδικό πρόσκλησης ή σύνδεσμο για ένα δημόσιο μάθημα;",
|
||||
"welcomeUser": "Καλώς ήρθατε {user}",
|
||||
"@joinSpaceOnboardingDesc": {
|
||||
"type": "String",
|
||||
"placeholders": {}
|
||||
},
|
||||
"@welcomeUser": {
|
||||
"type": "String",
|
||||
"placeholders": {
|
||||
"user": {
|
||||
"type": "String"
|
||||
}
|
||||
}
|
||||
},
|
||||
"publicInviteDescChat": "Αναζητήστε χρήστες για να τους προσκαλέσετε σε αυτήν την συνομιλία.",
|
||||
"publicInviteDescSpace": "Αναζητήστε χρήστες για να τους προσκαλέσετε σε αυτόν τον χώρο.",
|
||||
"@publicInviteDescChat": {
|
||||
"type": "String",
|
||||
"placeholders": {}
|
||||
},
|
||||
"@publicInviteDescSpace": {
|
||||
"type": "String",
|
||||
"placeholders": {}
|
||||
}
|
||||
}
|
||||
|
|
@ -5058,5 +5058,17 @@
|
|||
"learn": "Learn",
|
||||
"languageUpdated": "Target language updated!",
|
||||
"voiceDropdownTitle": "Pangea Bot voice",
|
||||
"knockDesc": "Your request has been sent to course admin! You'll be let in if they approve."
|
||||
"knockDesc": "Your request has been sent to course admin! You'll be let in if they approve.",
|
||||
"joinSpaceOnboardingDesc": "Do you have an invite code or link to a public course?",
|
||||
"welcomeUser": "Welcome {user}",
|
||||
"@welcomeUser": {
|
||||
"placeholders": {
|
||||
"user": {
|
||||
"type": "String"
|
||||
}
|
||||
}
|
||||
},
|
||||
"findCourse": "Find a course",
|
||||
"publicInviteDescChat": "Search for users to invite them to this chat.",
|
||||
"publicInviteDescSpace": "Search for users to invite them to this space."
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
{
|
||||
"@@last_modified": "2026-01-21 13:54:42.193114",
|
||||
"@@last_modified": "2026-01-22 12:02:15.725740",
|
||||
"about": "Prio",
|
||||
"@about": {
|
||||
"type": "String",
|
||||
|
|
@ -11989,5 +11989,29 @@
|
|||
"@knockDesc": {
|
||||
"type": "String",
|
||||
"placeholders": {}
|
||||
},
|
||||
"joinSpaceOnboardingDesc": "Ĉu vi havas invitkodon aŭ ligon al publika kurso?",
|
||||
"welcomeUser": "Bonvenon {user}",
|
||||
"@joinSpaceOnboardingDesc": {
|
||||
"type": "String",
|
||||
"placeholders": {}
|
||||
},
|
||||
"@welcomeUser": {
|
||||
"type": "String",
|
||||
"placeholders": {
|
||||
"user": {
|
||||
"type": "String"
|
||||
}
|
||||
}
|
||||
},
|
||||
"publicInviteDescChat": "Serĉu uzantojn por inviti ilin al ĉi tiu konversacio.",
|
||||
"publicInviteDescSpace": "Serĉu uzantojn por inviti ilin al ĉi tiu spaco.",
|
||||
"@publicInviteDescChat": {
|
||||
"type": "String",
|
||||
"placeholders": {}
|
||||
},
|
||||
"@publicInviteDescSpace": {
|
||||
"type": "String",
|
||||
"placeholders": {}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"@@locale": "es",
|
||||
"@@last_modified": "2026-01-21 13:53:29.857658",
|
||||
"@@last_modified": "2026-01-22 12:00:51.625942",
|
||||
"about": "Acerca de",
|
||||
"@about": {
|
||||
"type": "String",
|
||||
|
|
@ -8134,5 +8134,29 @@
|
|||
"@knockDesc": {
|
||||
"type": "String",
|
||||
"placeholders": {}
|
||||
},
|
||||
"joinSpaceOnboardingDesc": "¿Tienes un código de invitación o un enlace a un curso público?",
|
||||
"welcomeUser": "Bienvenido {user}",
|
||||
"@joinSpaceOnboardingDesc": {
|
||||
"type": "String",
|
||||
"placeholders": {}
|
||||
},
|
||||
"@welcomeUser": {
|
||||
"type": "String",
|
||||
"placeholders": {
|
||||
"user": {
|
||||
"type": "String"
|
||||
}
|
||||
}
|
||||
},
|
||||
"publicInviteDescChat": "Busca usuarios para invitarlos a este chat.",
|
||||
"publicInviteDescSpace": "Busca usuarios para invitarlos a este espacio.",
|
||||
"@publicInviteDescChat": {
|
||||
"type": "String",
|
||||
"placeholders": {}
|
||||
},
|
||||
"@publicInviteDescSpace": {
|
||||
"type": "String",
|
||||
"placeholders": {}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"@@locale": "et",
|
||||
"@@last_modified": "2026-01-21 13:53:55.586614",
|
||||
"@@last_modified": "2026-01-22 12:01:20.400166",
|
||||
"about": "Rakenduse teave",
|
||||
"@about": {
|
||||
"type": "String",
|
||||
|
|
@ -11171,5 +11171,29 @@
|
|||
"@knockDesc": {
|
||||
"type": "String",
|
||||
"placeholders": {}
|
||||
},
|
||||
"joinSpaceOnboardingDesc": "Kas sul on kutsekood või link avalikule kursusele?",
|
||||
"welcomeUser": "Tere tulemast {user}",
|
||||
"@joinSpaceOnboardingDesc": {
|
||||
"type": "String",
|
||||
"placeholders": {}
|
||||
},
|
||||
"@welcomeUser": {
|
||||
"type": "String",
|
||||
"placeholders": {
|
||||
"user": {
|
||||
"type": "String"
|
||||
}
|
||||
}
|
||||
},
|
||||
"publicInviteDescChat": "Otsi kasutajaid, et neid sellesse vestlusse kutsuda.",
|
||||
"publicInviteDescSpace": "Otsi kasutajaid, et neid sellesse ruumi kutsuda.",
|
||||
"@publicInviteDescChat": {
|
||||
"type": "String",
|
||||
"placeholders": {}
|
||||
},
|
||||
"@publicInviteDescSpace": {
|
||||
"type": "String",
|
||||
"placeholders": {}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"@@locale": "eu",
|
||||
"@@last_modified": "2026-01-21 13:53:53.122879",
|
||||
"@@last_modified": "2026-01-22 12:01:17.457241",
|
||||
"about": "Honi buruz",
|
||||
"@about": {
|
||||
"type": "String",
|
||||
|
|
@ -10900,5 +10900,29 @@
|
|||
"@knockDesc": {
|
||||
"type": "String",
|
||||
"placeholders": {}
|
||||
},
|
||||
"joinSpaceOnboardingDesc": "Baduzu gonbidapen kodea edo lotura publiko baten ikastaroarentzako?",
|
||||
"welcomeUser": "Ongi etorri {user}",
|
||||
"@joinSpaceOnboardingDesc": {
|
||||
"type": "String",
|
||||
"placeholders": {}
|
||||
},
|
||||
"@welcomeUser": {
|
||||
"type": "String",
|
||||
"placeholders": {
|
||||
"user": {
|
||||
"type": "String"
|
||||
}
|
||||
}
|
||||
},
|
||||
"publicInviteDescChat": "Bilatu erabiltzaileak txat honetara gonbidatzeko.",
|
||||
"publicInviteDescSpace": "Bilatu erabiltzaileak espazio honetara gonbidatzeko.",
|
||||
"@publicInviteDescChat": {
|
||||
"type": "String",
|
||||
"placeholders": {}
|
||||
},
|
||||
"@publicInviteDescSpace": {
|
||||
"type": "String",
|
||||
"placeholders": {}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
{
|
||||
"@@last_modified": "2026-01-21 13:54:33.096668",
|
||||
"@@last_modified": "2026-01-22 12:02:04.083596",
|
||||
"repeatPassword": "تکرار رمزعبور",
|
||||
"@repeatPassword": {},
|
||||
"about": "درباره",
|
||||
|
|
@ -11632,5 +11632,29 @@
|
|||
"@knockDesc": {
|
||||
"type": "String",
|
||||
"placeholders": {}
|
||||
},
|
||||
"joinSpaceOnboardingDesc": "آیا کد دعوت یا لینکی به یک دوره عمومی دارید؟",
|
||||
"welcomeUser": "خوش آمدید {user}",
|
||||
"@joinSpaceOnboardingDesc": {
|
||||
"type": "String",
|
||||
"placeholders": {}
|
||||
},
|
||||
"@welcomeUser": {
|
||||
"type": "String",
|
||||
"placeholders": {
|
||||
"user": {
|
||||
"type": "String"
|
||||
}
|
||||
}
|
||||
},
|
||||
"publicInviteDescChat": "برای دعوت کاربران به این چت، جستجو کنید.",
|
||||
"publicInviteDescSpace": "برای دعوت کاربران به این فضا، جستجو کنید.",
|
||||
"@publicInviteDescChat": {
|
||||
"type": "String",
|
||||
"placeholders": {}
|
||||
},
|
||||
"@publicInviteDescSpace": {
|
||||
"type": "String",
|
||||
"placeholders": {}
|
||||
}
|
||||
}
|
||||
|
|
@ -4009,7 +4009,7 @@
|
|||
"playWithAI": "Leiki tekoälyn kanssa nyt",
|
||||
"courseStartDesc": "Pangea Bot on valmis milloin tahansa!\n\n...mutta oppiminen on parempaa ystävien kanssa!",
|
||||
"@@locale": "fi",
|
||||
"@@last_modified": "2026-01-21 13:53:33.564588",
|
||||
"@@last_modified": "2026-01-22 12:00:55.098205",
|
||||
"@alwaysUse24HourFormat": {
|
||||
"type": "String",
|
||||
"placeholders": {}
|
||||
|
|
@ -11523,5 +11523,29 @@
|
|||
"@knockDesc": {
|
||||
"type": "String",
|
||||
"placeholders": {}
|
||||
},
|
||||
"joinSpaceOnboardingDesc": "Onko sinulla kutsukoodia tai linkkiä julkiseen kurssiin?",
|
||||
"welcomeUser": "Tervetuloa {user}",
|
||||
"@joinSpaceOnboardingDesc": {
|
||||
"type": "String",
|
||||
"placeholders": {}
|
||||
},
|
||||
"@welcomeUser": {
|
||||
"type": "String",
|
||||
"placeholders": {
|
||||
"user": {
|
||||
"type": "String"
|
||||
}
|
||||
}
|
||||
},
|
||||
"publicInviteDescChat": "Etsi käyttäjiä kutsuaksesi heidät tähän keskusteluun.",
|
||||
"publicInviteDescSpace": "Etsi käyttäjiä kutsuaksesi heidät tähän tilaan.",
|
||||
"@publicInviteDescChat": {
|
||||
"type": "String",
|
||||
"placeholders": {}
|
||||
},
|
||||
"@publicInviteDescSpace": {
|
||||
"type": "String",
|
||||
"placeholders": {}
|
||||
}
|
||||
}
|
||||
|
|
@ -2787,7 +2787,7 @@
|
|||
"selectAll": "Piliin lahat",
|
||||
"deselectAll": "Huwag piliin lahat",
|
||||
"@@locale": "fil",
|
||||
"@@last_modified": "2026-01-21 13:54:14.817261",
|
||||
"@@last_modified": "2026-01-22 12:01:44.028462",
|
||||
"@setCustomPermissionLevel": {
|
||||
"type": "String",
|
||||
"placeholders": {}
|
||||
|
|
@ -11876,5 +11876,29 @@
|
|||
"@knockDesc": {
|
||||
"type": "String",
|
||||
"placeholders": {}
|
||||
},
|
||||
"joinSpaceOnboardingDesc": "Mayroon ka bang invite code o link sa isang pampublikong kurso?",
|
||||
"welcomeUser": "Maligayang pagdating {user}",
|
||||
"@joinSpaceOnboardingDesc": {
|
||||
"type": "String",
|
||||
"placeholders": {}
|
||||
},
|
||||
"@welcomeUser": {
|
||||
"type": "String",
|
||||
"placeholders": {
|
||||
"user": {
|
||||
"type": "String"
|
||||
}
|
||||
}
|
||||
},
|
||||
"publicInviteDescChat": "Maghanap ng mga gumagamit upang imbitahan sila sa chat na ito.",
|
||||
"publicInviteDescSpace": "Maghanap ng mga gumagamit upang imbitahan sila sa espasyong ito.",
|
||||
"@publicInviteDescChat": {
|
||||
"type": "String",
|
||||
"placeholders": {}
|
||||
},
|
||||
"@publicInviteDescSpace": {
|
||||
"type": "String",
|
||||
"placeholders": {}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"@@locale": "fr",
|
||||
"@@last_modified": "2026-01-21 13:54:48.318824",
|
||||
"@@last_modified": "2026-01-22 12:02:23.383738",
|
||||
"about": "À propos",
|
||||
"@about": {
|
||||
"type": "String",
|
||||
|
|
@ -11224,5 +11224,29 @@
|
|||
"@knockDesc": {
|
||||
"type": "String",
|
||||
"placeholders": {}
|
||||
},
|
||||
"joinSpaceOnboardingDesc": "Avez-vous un code d'invitation ou un lien vers un cours public ?",
|
||||
"welcomeUser": "Bienvenue {user}",
|
||||
"@joinSpaceOnboardingDesc": {
|
||||
"type": "String",
|
||||
"placeholders": {}
|
||||
},
|
||||
"@welcomeUser": {
|
||||
"type": "String",
|
||||
"placeholders": {
|
||||
"user": {
|
||||
"type": "String"
|
||||
}
|
||||
}
|
||||
},
|
||||
"publicInviteDescChat": "Recherchez des utilisateurs pour les inviter à ce chat.",
|
||||
"publicInviteDescSpace": "Recherchez des utilisateurs pour les inviter à cet espace.",
|
||||
"@publicInviteDescChat": {
|
||||
"type": "String",
|
||||
"placeholders": {}
|
||||
},
|
||||
"@publicInviteDescSpace": {
|
||||
"type": "String",
|
||||
"placeholders": {}
|
||||
}
|
||||
}
|
||||
|
|
@ -4517,7 +4517,7 @@
|
|||
"playWithAI": "Imir le AI faoi láthair",
|
||||
"courseStartDesc": "Tá Bot Pangea réidh chun dul am ar bith!\n\n...ach is fearr foghlaim le cairde!",
|
||||
"@@locale": "ga",
|
||||
"@@last_modified": "2026-01-21 13:54:46.978792",
|
||||
"@@last_modified": "2026-01-22 12:02:22.009738",
|
||||
"@customReaction": {
|
||||
"type": "String",
|
||||
"placeholders": {}
|
||||
|
|
@ -10898,5 +10898,29 @@
|
|||
"@knockDesc": {
|
||||
"type": "String",
|
||||
"placeholders": {}
|
||||
},
|
||||
"joinSpaceOnboardingDesc": "An bhfuil cód cuireadh nó nasc agat do chúrsa poiblí?",
|
||||
"welcomeUser": "Fáilte {user}",
|
||||
"@joinSpaceOnboardingDesc": {
|
||||
"type": "String",
|
||||
"placeholders": {}
|
||||
},
|
||||
"@welcomeUser": {
|
||||
"type": "String",
|
||||
"placeholders": {
|
||||
"user": {
|
||||
"type": "String"
|
||||
}
|
||||
}
|
||||
},
|
||||
"publicInviteDescChat": "Cuardaigh úsáideoirí le cuireadh a thabhairt dóibh chuig an gcomhrá seo.",
|
||||
"publicInviteDescSpace": "Cuardaigh úsáideoirí le cuireadh a thabhairt dóibh chuig an spás seo.",
|
||||
"@publicInviteDescChat": {
|
||||
"type": "String",
|
||||
"placeholders": {}
|
||||
},
|
||||
"@publicInviteDescSpace": {
|
||||
"type": "String",
|
||||
"placeholders": {}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"@@locale": "gl",
|
||||
"@@last_modified": "2026-01-21 13:53:31.619299",
|
||||
"@@last_modified": "2026-01-22 12:00:52.883998",
|
||||
"about": "Acerca de",
|
||||
"@about": {
|
||||
"type": "String",
|
||||
|
|
@ -10897,5 +10897,29 @@
|
|||
"@knockDesc": {
|
||||
"type": "String",
|
||||
"placeholders": {}
|
||||
},
|
||||
"joinSpaceOnboardingDesc": "Tes un código de invitación ou un enlace a un curso público?",
|
||||
"welcomeUser": "Benvido {user}",
|
||||
"@joinSpaceOnboardingDesc": {
|
||||
"type": "String",
|
||||
"placeholders": {}
|
||||
},
|
||||
"@welcomeUser": {
|
||||
"type": "String",
|
||||
"placeholders": {
|
||||
"user": {
|
||||
"type": "String"
|
||||
}
|
||||
}
|
||||
},
|
||||
"publicInviteDescChat": "Busca usuarios para convidalos a este chat.",
|
||||
"publicInviteDescSpace": "Busca usuarios para convidalos a este espazo.",
|
||||
"@publicInviteDescChat": {
|
||||
"type": "String",
|
||||
"placeholders": {}
|
||||
},
|
||||
"@publicInviteDescSpace": {
|
||||
"type": "String",
|
||||
"placeholders": {}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
{
|
||||
"@@last_modified": "2026-01-21 13:53:47.592162",
|
||||
"@@last_modified": "2026-01-22 12:01:11.911490",
|
||||
"about": "אודות",
|
||||
"@about": {
|
||||
"type": "String",
|
||||
|
|
@ -11949,5 +11949,29 @@
|
|||
"@knockDesc": {
|
||||
"type": "String",
|
||||
"placeholders": {}
|
||||
},
|
||||
"joinSpaceOnboardingDesc": "האם יש לך קוד הזמנה או קישור לקורס ציבורי?",
|
||||
"welcomeUser": "ברוך הבא {user}",
|
||||
"@joinSpaceOnboardingDesc": {
|
||||
"type": "String",
|
||||
"placeholders": {}
|
||||
},
|
||||
"@welcomeUser": {
|
||||
"type": "String",
|
||||
"placeholders": {
|
||||
"user": {
|
||||
"type": "String"
|
||||
}
|
||||
}
|
||||
},
|
||||
"publicInviteDescChat": "חפש משתמשים כדי להזמין אותם לצ'אט הזה.",
|
||||
"publicInviteDescSpace": "חפש משתמשים כדי להזמין אותם למקום הזה.",
|
||||
"@publicInviteDescChat": {
|
||||
"type": "String",
|
||||
"placeholders": {}
|
||||
},
|
||||
"@publicInviteDescSpace": {
|
||||
"type": "String",
|
||||
"placeholders": {}
|
||||
}
|
||||
}
|
||||
|
|
@ -4483,7 +4483,7 @@
|
|||
"playWithAI": "अभी के लिए एआई के साथ खेलें",
|
||||
"courseStartDesc": "पैंजिया बॉट कभी भी जाने के लिए तैयार है!\n\n...लेकिन दोस्तों के साथ सीखना बेहतर है!",
|
||||
"@@locale": "hi",
|
||||
"@@last_modified": "2026-01-21 13:54:40.850433",
|
||||
"@@last_modified": "2026-01-22 12:02:13.864252",
|
||||
"@alwaysUse24HourFormat": {
|
||||
"type": "String",
|
||||
"placeholders": {}
|
||||
|
|
@ -11985,5 +11985,29 @@
|
|||
"@knockDesc": {
|
||||
"type": "String",
|
||||
"placeholders": {}
|
||||
},
|
||||
"joinSpaceOnboardingDesc": "क्या आपके पास एक आमंत्रण कोड या सार्वजनिक पाठ्यक्रम के लिए लिंक है?",
|
||||
"welcomeUser": "स्वागत है {user}",
|
||||
"@joinSpaceOnboardingDesc": {
|
||||
"type": "String",
|
||||
"placeholders": {}
|
||||
},
|
||||
"@welcomeUser": {
|
||||
"type": "String",
|
||||
"placeholders": {
|
||||
"user": {
|
||||
"type": "String"
|
||||
}
|
||||
}
|
||||
},
|
||||
"publicInviteDescChat": "इस चैट में आमंत्रित करने के लिए उपयोगकर्ताओं की खोज करें।",
|
||||
"publicInviteDescSpace": "इस स्थान में आमंत्रित करने के लिए उपयोगकर्ताओं की खोज करें।",
|
||||
"@publicInviteDescChat": {
|
||||
"type": "String",
|
||||
"placeholders": {}
|
||||
},
|
||||
"@publicInviteDescSpace": {
|
||||
"type": "String",
|
||||
"placeholders": {}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"@@locale": "hr",
|
||||
"@@last_modified": "2026-01-21 13:53:46.524141",
|
||||
"@@last_modified": "2026-01-22 12:01:10.402528",
|
||||
"about": "Informacije",
|
||||
"@about": {
|
||||
"type": "String",
|
||||
|
|
@ -11272,5 +11272,29 @@
|
|||
"@knockDesc": {
|
||||
"type": "String",
|
||||
"placeholders": {}
|
||||
},
|
||||
"joinSpaceOnboardingDesc": "Imate li pozivni kod ili link za javni tečaj?",
|
||||
"welcomeUser": "Dobrodošli {user}",
|
||||
"@joinSpaceOnboardingDesc": {
|
||||
"type": "String",
|
||||
"placeholders": {}
|
||||
},
|
||||
"@welcomeUser": {
|
||||
"type": "String",
|
||||
"placeholders": {
|
||||
"user": {
|
||||
"type": "String"
|
||||
}
|
||||
}
|
||||
},
|
||||
"publicInviteDescChat": "Pretražite korisnike kako biste ih pozvali u ovaj chat.",
|
||||
"publicInviteDescSpace": "Pretražite korisnike kako biste ih pozvali u ovaj prostor.",
|
||||
"@publicInviteDescChat": {
|
||||
"type": "String",
|
||||
"placeholders": {}
|
||||
},
|
||||
"@publicInviteDescSpace": {
|
||||
"type": "String",
|
||||
"placeholders": {}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"@@locale": "hu",
|
||||
"@@last_modified": "2026-01-21 13:53:36.742109",
|
||||
"@@last_modified": "2026-01-22 12:01:00.971468",
|
||||
"about": "Névjegy",
|
||||
"@about": {
|
||||
"type": "String",
|
||||
|
|
@ -10901,5 +10901,29 @@
|
|||
"@knockDesc": {
|
||||
"type": "String",
|
||||
"placeholders": {}
|
||||
},
|
||||
"joinSpaceOnboardingDesc": "Van meghívó kódod vagy linked egy nyilvános kurzushoz?",
|
||||
"welcomeUser": "Üdvözöljük {user}",
|
||||
"@joinSpaceOnboardingDesc": {
|
||||
"type": "String",
|
||||
"placeholders": {}
|
||||
},
|
||||
"@welcomeUser": {
|
||||
"type": "String",
|
||||
"placeholders": {
|
||||
"user": {
|
||||
"type": "String"
|
||||
}
|
||||
}
|
||||
},
|
||||
"publicInviteDescChat": "Keresd meg a felhasználókat, hogy meghívd őket erre a csevegésre.",
|
||||
"publicInviteDescSpace": "Keresd meg a felhasználókat, hogy meghívd őket erre a térre.",
|
||||
"@publicInviteDescChat": {
|
||||
"type": "String",
|
||||
"placeholders": {}
|
||||
},
|
||||
"@publicInviteDescSpace": {
|
||||
"type": "String",
|
||||
"placeholders": {}
|
||||
}
|
||||
}
|
||||
|
|
@ -1958,7 +1958,7 @@
|
|||
"playWithAI": "Joca con le IA pro ora",
|
||||
"courseStartDesc": "Pangea Bot es preste a comenzar a qualunque momento!\n\n...ma apprender es melior con amicos!",
|
||||
"@@locale": "ia",
|
||||
"@@last_modified": "2026-01-21 13:53:49.028067",
|
||||
"@@last_modified": "2026-01-22 12:01:13.730279",
|
||||
"@alwaysUse24HourFormat": {
|
||||
"type": "String",
|
||||
"placeholders": {}
|
||||
|
|
@ -11978,5 +11978,29 @@
|
|||
"@knockDesc": {
|
||||
"type": "String",
|
||||
"placeholders": {}
|
||||
},
|
||||
"joinSpaceOnboardingDesc": "¿Tienes un código de invitación o un enlace a un curso público?",
|
||||
"welcomeUser": "Bienvenido {user}",
|
||||
"@joinSpaceOnboardingDesc": {
|
||||
"type": "String",
|
||||
"placeholders": {}
|
||||
},
|
||||
"@welcomeUser": {
|
||||
"type": "String",
|
||||
"placeholders": {
|
||||
"user": {
|
||||
"type": "String"
|
||||
}
|
||||
}
|
||||
},
|
||||
"publicInviteDescChat": "Cerca per utenti per invitarli a questa chat.",
|
||||
"publicInviteDescSpace": "Cerca per utenti per invitarli a questo spazio.",
|
||||
"@publicInviteDescChat": {
|
||||
"type": "String",
|
||||
"placeholders": {}
|
||||
},
|
||||
"@publicInviteDescSpace": {
|
||||
"type": "String",
|
||||
"placeholders": {}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
{
|
||||
"@@last_modified": "2026-01-21 13:53:37.899898",
|
||||
"@@last_modified": "2026-01-22 12:01:02.729155",
|
||||
"setAsCanonicalAlias": "Atur sebagai alias utama",
|
||||
"@setAsCanonicalAlias": {
|
||||
"type": "String",
|
||||
|
|
@ -10891,5 +10891,29 @@
|
|||
"@knockDesc": {
|
||||
"type": "String",
|
||||
"placeholders": {}
|
||||
},
|
||||
"joinSpaceOnboardingDesc": "Apakah Anda memiliki kode undangan atau tautan ke kursus publik?",
|
||||
"welcomeUser": "Selamat datang {user}",
|
||||
"@joinSpaceOnboardingDesc": {
|
||||
"type": "String",
|
||||
"placeholders": {}
|
||||
},
|
||||
"@welcomeUser": {
|
||||
"type": "String",
|
||||
"placeholders": {
|
||||
"user": {
|
||||
"type": "String"
|
||||
}
|
||||
}
|
||||
},
|
||||
"publicInviteDescChat": "Cari pengguna untuk mengundang mereka ke obrolan ini.",
|
||||
"publicInviteDescSpace": "Cari pengguna untuk mengundang mereka ke ruang ini.",
|
||||
"@publicInviteDescChat": {
|
||||
"type": "String",
|
||||
"placeholders": {}
|
||||
},
|
||||
"@publicInviteDescSpace": {
|
||||
"type": "String",
|
||||
"placeholders": {}
|
||||
}
|
||||
}
|
||||
|
|
@ -4372,7 +4372,7 @@
|
|||
"playWithAI": "Joca con AI pro ora",
|
||||
"courseStartDesc": "Pangea Bot es preste a partir a qualunque momento!\n\n...ma apprender es melior con amicos!",
|
||||
"@@locale": "ie",
|
||||
"@@last_modified": "2026-01-21 13:53:45.416677",
|
||||
"@@last_modified": "2026-01-22 12:01:08.955250",
|
||||
"@alwaysUse24HourFormat": {
|
||||
"type": "String",
|
||||
"placeholders": {}
|
||||
|
|
@ -11874,5 +11874,29 @@
|
|||
"@knockDesc": {
|
||||
"type": "String",
|
||||
"placeholders": {}
|
||||
},
|
||||
"joinSpaceOnboardingDesc": "¿Tienes un código de invitación o un enlace a un curso público?",
|
||||
"welcomeUser": "Bienvenido {user}",
|
||||
"@joinSpaceOnboardingDesc": {
|
||||
"type": "String",
|
||||
"placeholders": {}
|
||||
},
|
||||
"@welcomeUser": {
|
||||
"type": "String",
|
||||
"placeholders": {
|
||||
"user": {
|
||||
"type": "String"
|
||||
}
|
||||
}
|
||||
},
|
||||
"publicInviteDescChat": "Cuir fiosrúcháin ar úsáideoirí chun iad a gcuir isteach sa chomhrá seo.",
|
||||
"publicInviteDescSpace": "Cuir fiosrúcháin ar úsáideoirí chun iad a gcuir isteach sa spás seo.",
|
||||
"@publicInviteDescChat": {
|
||||
"type": "String",
|
||||
"placeholders": {}
|
||||
},
|
||||
"@publicInviteDescSpace": {
|
||||
"type": "String",
|
||||
"placeholders": {}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
{
|
||||
"@@last_modified": "2026-01-21 13:54:01.568848",
|
||||
"@@last_modified": "2026-01-22 12:01:27.366543",
|
||||
"about": "Informazioni",
|
||||
"@about": {
|
||||
"type": "String",
|
||||
|
|
@ -10903,5 +10903,29 @@
|
|||
"@knockDesc": {
|
||||
"type": "String",
|
||||
"placeholders": {}
|
||||
},
|
||||
"joinSpaceOnboardingDesc": "Hai un codice di invito o un link per un corso pubblico?",
|
||||
"welcomeUser": "Benvenuto {user}",
|
||||
"@joinSpaceOnboardingDesc": {
|
||||
"type": "String",
|
||||
"placeholders": {}
|
||||
},
|
||||
"@welcomeUser": {
|
||||
"type": "String",
|
||||
"placeholders": {
|
||||
"user": {
|
||||
"type": "String"
|
||||
}
|
||||
}
|
||||
},
|
||||
"publicInviteDescChat": "Cerca utenti per invitarli a questa chat.",
|
||||
"publicInviteDescSpace": "Cerca utenti per invitarli a questo spazio.",
|
||||
"@publicInviteDescChat": {
|
||||
"type": "String",
|
||||
"placeholders": {}
|
||||
},
|
||||
"@publicInviteDescSpace": {
|
||||
"type": "String",
|
||||
"placeholders": {}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"@@locale": "ja",
|
||||
"@@last_modified": "2026-01-21 13:54:39.359536",
|
||||
"@@last_modified": "2026-01-22 12:02:12.048814",
|
||||
"about": "このアプリについて",
|
||||
"@about": {
|
||||
"type": "String",
|
||||
|
|
@ -11690,5 +11690,29 @@
|
|||
"@knockDesc": {
|
||||
"type": "String",
|
||||
"placeholders": {}
|
||||
},
|
||||
"joinSpaceOnboardingDesc": "招待コードまたは公開コースへのリンクはありますか?",
|
||||
"welcomeUser": "ようこそ {user} さん",
|
||||
"@joinSpaceOnboardingDesc": {
|
||||
"type": "String",
|
||||
"placeholders": {}
|
||||
},
|
||||
"@welcomeUser": {
|
||||
"type": "String",
|
||||
"placeholders": {
|
||||
"user": {
|
||||
"type": "String"
|
||||
}
|
||||
}
|
||||
},
|
||||
"publicInviteDescChat": "このチャットに招待するユーザーを検索します。",
|
||||
"publicInviteDescSpace": "このスペースに招待するユーザーを検索します。",
|
||||
"@publicInviteDescChat": {
|
||||
"type": "String",
|
||||
"placeholders": {}
|
||||
},
|
||||
"@publicInviteDescSpace": {
|
||||
"type": "String",
|
||||
"placeholders": {}
|
||||
}
|
||||
}
|
||||
|
|
@ -2594,7 +2594,7 @@
|
|||
"playWithAI": "ამ დროისთვის ითამაშეთ AI-თან",
|
||||
"courseStartDesc": "Pangea Bot მზადაა ნებისმიერ დროს გასასვლელად!\n\n...მაგრამ სწავლა უკეთესია მეგობრებთან ერთად!",
|
||||
"@@locale": "ka",
|
||||
"@@last_modified": "2026-01-21 13:54:44.486907",
|
||||
"@@last_modified": "2026-01-22 12:02:18.860564",
|
||||
"@alwaysUse24HourFormat": {
|
||||
"type": "String",
|
||||
"placeholders": {}
|
||||
|
|
@ -11930,5 +11930,29 @@
|
|||
"@knockDesc": {
|
||||
"type": "String",
|
||||
"placeholders": {}
|
||||
},
|
||||
"joinSpaceOnboardingDesc": "გაქვთ თუ არა მოწვევის კოდი ან ბმული საჯარო კურსზე?",
|
||||
"welcomeUser": "კეთილი იყოს თქვენი მობრძანება {user}",
|
||||
"@joinSpaceOnboardingDesc": {
|
||||
"type": "String",
|
||||
"placeholders": {}
|
||||
},
|
||||
"@welcomeUser": {
|
||||
"type": "String",
|
||||
"placeholders": {
|
||||
"user": {
|
||||
"type": "String"
|
||||
}
|
||||
}
|
||||
},
|
||||
"publicInviteDescChat": "მომხმარებლების ძიება, რათა მათ ამ ჩატში მოიწვიოთ.",
|
||||
"publicInviteDescSpace": "მომხმარებლების ძიება, რათა მათ ამ სივრცეში მოიწვიოთ.",
|
||||
"@publicInviteDescChat": {
|
||||
"type": "String",
|
||||
"placeholders": {}
|
||||
},
|
||||
"@publicInviteDescSpace": {
|
||||
"type": "String",
|
||||
"placeholders": {}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
{
|
||||
"@@last_modified": "2026-01-21 13:53:28.417406",
|
||||
"@@last_modified": "2026-01-22 12:00:49.883642",
|
||||
"about": "소개",
|
||||
"@about": {
|
||||
"type": "String",
|
||||
|
|
@ -11008,5 +11008,29 @@
|
|||
"@knockDesc": {
|
||||
"type": "String",
|
||||
"placeholders": {}
|
||||
},
|
||||
"joinSpaceOnboardingDesc": "공개 과정에 대한 초대 코드나 링크가 있습니까?",
|
||||
"welcomeUser": "환영합니다 {user}",
|
||||
"@joinSpaceOnboardingDesc": {
|
||||
"type": "String",
|
||||
"placeholders": {}
|
||||
},
|
||||
"@welcomeUser": {
|
||||
"type": "String",
|
||||
"placeholders": {
|
||||
"user": {
|
||||
"type": "String"
|
||||
}
|
||||
}
|
||||
},
|
||||
"publicInviteDescChat": "이 채팅에 초대할 사용자를 검색하세요.",
|
||||
"publicInviteDescSpace": "이 공간에 초대할 사용자를 검색하세요.",
|
||||
"@publicInviteDescChat": {
|
||||
"type": "String",
|
||||
"placeholders": {}
|
||||
},
|
||||
"@publicInviteDescSpace": {
|
||||
"type": "String",
|
||||
"placeholders": {}
|
||||
}
|
||||
}
|
||||
|
|
@ -3861,7 +3861,7 @@
|
|||
"playWithAI": "Žaiskite su dirbtiniu intelektu dabar",
|
||||
"courseStartDesc": "Pangea botas pasiruošęs bet kada pradėti!\n\n...bet mokymasis yra geresnis su draugais!",
|
||||
"@@locale": "lt",
|
||||
"@@last_modified": "2026-01-21 13:54:22.729769",
|
||||
"@@last_modified": "2026-01-22 12:01:53.612206",
|
||||
"@alwaysUse24HourFormat": {
|
||||
"type": "String",
|
||||
"placeholders": {}
|
||||
|
|
@ -11705,5 +11705,29 @@
|
|||
"@knockDesc": {
|
||||
"type": "String",
|
||||
"placeholders": {}
|
||||
},
|
||||
"joinSpaceOnboardingDesc": "Ar turite kvietimo kodą arba nuorodą į viešą kursą?",
|
||||
"welcomeUser": "Sveiki atvykę, {user}",
|
||||
"@joinSpaceOnboardingDesc": {
|
||||
"type": "String",
|
||||
"placeholders": {}
|
||||
},
|
||||
"@welcomeUser": {
|
||||
"type": "String",
|
||||
"placeholders": {
|
||||
"user": {
|
||||
"type": "String"
|
||||
}
|
||||
}
|
||||
},
|
||||
"publicInviteDescChat": "Ieškokite vartotojų, kad juos pakviestumėte į šį pokalbį.",
|
||||
"publicInviteDescSpace": "Ieškokite vartotojų, kad juos pakviestumėte į šią erdvę.",
|
||||
"@publicInviteDescChat": {
|
||||
"type": "String",
|
||||
"placeholders": {}
|
||||
},
|
||||
"@publicInviteDescSpace": {
|
||||
"type": "String",
|
||||
"placeholders": {}
|
||||
}
|
||||
}
|
||||
|
|
@ -4482,7 +4482,7 @@
|
|||
"playWithAI": "Tagad spēlējiet ar AI",
|
||||
"courseStartDesc": "Pangea bots ir gatavs jebkurā laikā!\n\n...bet mācīties ir labāk ar draugiem!",
|
||||
"@@locale": "lv",
|
||||
"@@last_modified": "2026-01-21 13:54:16.883169",
|
||||
"@@last_modified": "2026-01-22 12:01:46.451812",
|
||||
"analyticsInactiveTitle": "Pieprasījumi neaktīviem lietotājiem nevar tikt nosūtīti",
|
||||
"analyticsInactiveDesc": "Neaktīvi lietotāji, kuri nav pieteikušies kopš šīs funkcijas ieviešanas, neredzēs jūsu pieprasījumu.\n\nPieprasījuma poga parādīsies, kad viņi atgriezīsies. Jūs varat atkārtoti nosūtīt pieprasījumu vēlāk, noklikšķinot uz pieprasījuma pogas viņu vārdā, kad tā būs pieejama.",
|
||||
"accessRequestedTitle": "Pieprasījums piekļūt analītikai",
|
||||
|
|
@ -10886,5 +10886,29 @@
|
|||
"@knockDesc": {
|
||||
"type": "String",
|
||||
"placeholders": {}
|
||||
},
|
||||
"joinSpaceOnboardingDesc": "Vai jums ir uzaicinājuma kods vai saite uz publisku kursu?",
|
||||
"welcomeUser": "Laipni lūdzam, {user}",
|
||||
"@joinSpaceOnboardingDesc": {
|
||||
"type": "String",
|
||||
"placeholders": {}
|
||||
},
|
||||
"@welcomeUser": {
|
||||
"type": "String",
|
||||
"placeholders": {
|
||||
"user": {
|
||||
"type": "String"
|
||||
}
|
||||
}
|
||||
},
|
||||
"publicInviteDescChat": "Meklējiet lietotājus, lai viņus aicinātu uz šo čatu.",
|
||||
"publicInviteDescSpace": "Meklējiet lietotājus, lai viņus aicinātu uz šo telpu.",
|
||||
"@publicInviteDescChat": {
|
||||
"type": "String",
|
||||
"placeholders": {}
|
||||
},
|
||||
"@publicInviteDescSpace": {
|
||||
"type": "String",
|
||||
"placeholders": {}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
{
|
||||
"@@last_modified": "2026-01-21 13:54:06.232198",
|
||||
"@@last_modified": "2026-01-22 12:01:31.934487",
|
||||
"about": "Om",
|
||||
"@about": {
|
||||
"type": "String",
|
||||
|
|
@ -11993,5 +11993,29 @@
|
|||
"@knockDesc": {
|
||||
"type": "String",
|
||||
"placeholders": {}
|
||||
},
|
||||
"joinSpaceOnboardingDesc": "Har du en invitasjonskode eller lenke til et offentlig kurs?",
|
||||
"welcomeUser": "Velkommen {user}",
|
||||
"@joinSpaceOnboardingDesc": {
|
||||
"type": "String",
|
||||
"placeholders": {}
|
||||
},
|
||||
"@welcomeUser": {
|
||||
"type": "String",
|
||||
"placeholders": {
|
||||
"user": {
|
||||
"type": "String"
|
||||
}
|
||||
}
|
||||
},
|
||||
"publicInviteDescChat": "Søk etter brukere for å invitere dem til denne chatten.",
|
||||
"publicInviteDescSpace": "Søk etter brukere for å invitere dem til dette rommet.",
|
||||
"@publicInviteDescChat": {
|
||||
"type": "String",
|
||||
"placeholders": {}
|
||||
},
|
||||
"@publicInviteDescSpace": {
|
||||
"type": "String",
|
||||
"placeholders": {}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
{
|
||||
"@@last_modified": "2026-01-21 13:54:27.649909",
|
||||
"@@last_modified": "2026-01-22 12:01:58.109571",
|
||||
"about": "Over ons",
|
||||
"@about": {
|
||||
"type": "String",
|
||||
|
|
@ -10900,5 +10900,29 @@
|
|||
"@knockDesc": {
|
||||
"type": "String",
|
||||
"placeholders": {}
|
||||
},
|
||||
"joinSpaceOnboardingDesc": "Heb je een uitnodigingscode of link naar een openbare cursus?",
|
||||
"welcomeUser": "Welkom {user}",
|
||||
"@joinSpaceOnboardingDesc": {
|
||||
"type": "String",
|
||||
"placeholders": {}
|
||||
},
|
||||
"@welcomeUser": {
|
||||
"type": "String",
|
||||
"placeholders": {
|
||||
"user": {
|
||||
"type": "String"
|
||||
}
|
||||
}
|
||||
},
|
||||
"publicInviteDescChat": "Zoek naar gebruikers om ze uit te nodigen voor deze chat.",
|
||||
"publicInviteDescSpace": "Zoek naar gebruikers om ze uit te nodigen voor deze ruimte.",
|
||||
"@publicInviteDescChat": {
|
||||
"type": "String",
|
||||
"placeholders": {}
|
||||
},
|
||||
"@publicInviteDescSpace": {
|
||||
"type": "String",
|
||||
"placeholders": {}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"@@locale": "pl",
|
||||
"@@last_modified": "2026-01-21 13:54:34.451816",
|
||||
"@@last_modified": "2026-01-22 12:02:06.402870",
|
||||
"about": "O aplikacji",
|
||||
"@about": {
|
||||
"type": "String",
|
||||
|
|
@ -10898,5 +10898,29 @@
|
|||
"@knockDesc": {
|
||||
"type": "String",
|
||||
"placeholders": {}
|
||||
},
|
||||
"joinSpaceOnboardingDesc": "Czy masz kod zaproszenia lub link do publicznego kursu?",
|
||||
"welcomeUser": "Witaj {user}",
|
||||
"@joinSpaceOnboardingDesc": {
|
||||
"type": "String",
|
||||
"placeholders": {}
|
||||
},
|
||||
"@welcomeUser": {
|
||||
"type": "String",
|
||||
"placeholders": {
|
||||
"user": {
|
||||
"type": "String"
|
||||
}
|
||||
}
|
||||
},
|
||||
"publicInviteDescChat": "Szukaj użytkowników, aby zaprosić ich do tej rozmowy.",
|
||||
"publicInviteDescSpace": "Szukaj użytkowników, aby zaprosić ich do tej przestrzeni.",
|
||||
"@publicInviteDescChat": {
|
||||
"type": "String",
|
||||
"placeholders": {}
|
||||
},
|
||||
"@publicInviteDescSpace": {
|
||||
"type": "String",
|
||||
"placeholders": {}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
{
|
||||
"@@last_modified": "2026-01-21 13:53:54.148542",
|
||||
"@@last_modified": "2026-01-22 12:01:18.883594",
|
||||
"copiedToClipboard": "Copiada para a área de transferência",
|
||||
"@copiedToClipboard": {
|
||||
"type": "String",
|
||||
|
|
@ -12000,5 +12000,29 @@
|
|||
"@knockDesc": {
|
||||
"type": "String",
|
||||
"placeholders": {}
|
||||
},
|
||||
"joinSpaceOnboardingDesc": "Você tem um código de convite ou link para um curso público?",
|
||||
"welcomeUser": "Bem-vindo {user}",
|
||||
"@joinSpaceOnboardingDesc": {
|
||||
"type": "String",
|
||||
"placeholders": {}
|
||||
},
|
||||
"@welcomeUser": {
|
||||
"type": "String",
|
||||
"placeholders": {
|
||||
"user": {
|
||||
"type": "String"
|
||||
}
|
||||
}
|
||||
},
|
||||
"publicInviteDescChat": "Procure usuários para convidá-los para este chat.",
|
||||
"publicInviteDescSpace": "Procure usuários para convidá-los para este espaço.",
|
||||
"@publicInviteDescChat": {
|
||||
"type": "String",
|
||||
"placeholders": {}
|
||||
},
|
||||
"@publicInviteDescSpace": {
|
||||
"type": "String",
|
||||
"placeholders": {}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
{
|
||||
"@@last_modified": "2026-01-21 13:53:51.587209",
|
||||
"@@last_modified": "2026-01-22 12:01:15.782911",
|
||||
"about": "Sobre",
|
||||
"@about": {
|
||||
"type": "String",
|
||||
|
|
@ -11258,5 +11258,29 @@
|
|||
"@knockDesc": {
|
||||
"type": "String",
|
||||
"placeholders": {}
|
||||
},
|
||||
"joinSpaceOnboardingDesc": "Você tem um código de convite ou link para um curso público?",
|
||||
"welcomeUser": "Bem-vindo {user}",
|
||||
"@joinSpaceOnboardingDesc": {
|
||||
"type": "String",
|
||||
"placeholders": {}
|
||||
},
|
||||
"@welcomeUser": {
|
||||
"type": "String",
|
||||
"placeholders": {
|
||||
"user": {
|
||||
"type": "String"
|
||||
}
|
||||
}
|
||||
},
|
||||
"publicInviteDescChat": "Procure usuários para convidá-los para este chat.",
|
||||
"publicInviteDescSpace": "Procure usuários para convidá-los para este espaço.",
|
||||
"@publicInviteDescChat": {
|
||||
"type": "String",
|
||||
"placeholders": {}
|
||||
},
|
||||
"@publicInviteDescSpace": {
|
||||
"type": "String",
|
||||
"placeholders": {}
|
||||
}
|
||||
}
|
||||
|
|
@ -3331,7 +3331,7 @@
|
|||
"selectAll": "Selecionar tudo",
|
||||
"deselectAll": "Desmarcar tudo",
|
||||
"@@locale": "pt_PT",
|
||||
"@@last_modified": "2026-01-21 13:54:11.801274",
|
||||
"@@last_modified": "2026-01-22 12:01:38.348686",
|
||||
"@alwaysUse24HourFormat": {
|
||||
"type": "String",
|
||||
"placeholders": {}
|
||||
|
|
@ -11929,5 +11929,29 @@
|
|||
"@knockDesc": {
|
||||
"type": "String",
|
||||
"placeholders": {}
|
||||
},
|
||||
"joinSpaceOnboardingDesc": "Você tem um código de convite ou link para um curso público?",
|
||||
"welcomeUser": "Bem-vindo {user}",
|
||||
"@joinSpaceOnboardingDesc": {
|
||||
"type": "String",
|
||||
"placeholders": {}
|
||||
},
|
||||
"@welcomeUser": {
|
||||
"type": "String",
|
||||
"placeholders": {
|
||||
"user": {
|
||||
"type": "String"
|
||||
}
|
||||
}
|
||||
},
|
||||
"publicInviteDescChat": "Procure usuários para convidá-los para este chat.",
|
||||
"publicInviteDescSpace": "Procure usuários para convidá-los para este espaço.",
|
||||
"@publicInviteDescChat": {
|
||||
"type": "String",
|
||||
"placeholders": {}
|
||||
},
|
||||
"@publicInviteDescSpace": {
|
||||
"type": "String",
|
||||
"placeholders": {}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
{
|
||||
"@@last_modified": "2026-01-21 13:53:41.456181",
|
||||
"@@last_modified": "2026-01-22 12:01:04.721303",
|
||||
"about": "Despre",
|
||||
"@about": {
|
||||
"type": "String",
|
||||
|
|
@ -11635,5 +11635,29 @@
|
|||
"@knockDesc": {
|
||||
"type": "String",
|
||||
"placeholders": {}
|
||||
},
|
||||
"joinSpaceOnboardingDesc": "Ai un cod de invitație sau un link pentru un curs public?",
|
||||
"welcomeUser": "Bine ai venit {user}",
|
||||
"@joinSpaceOnboardingDesc": {
|
||||
"type": "String",
|
||||
"placeholders": {}
|
||||
},
|
||||
"@welcomeUser": {
|
||||
"type": "String",
|
||||
"placeholders": {
|
||||
"user": {
|
||||
"type": "String"
|
||||
}
|
||||
}
|
||||
},
|
||||
"publicInviteDescChat": "Caută utilizatori pentru a-i invita în acest chat.",
|
||||
"publicInviteDescSpace": "Caută utilizatori pentru a-i invita în acest spațiu.",
|
||||
"@publicInviteDescChat": {
|
||||
"type": "String",
|
||||
"placeholders": {}
|
||||
},
|
||||
"@publicInviteDescSpace": {
|
||||
"type": "String",
|
||||
"placeholders": {}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"@@locale": "ru",
|
||||
"@@last_modified": "2026-01-21 13:54:43.229000",
|
||||
"@@last_modified": "2026-01-22 12:02:17.097388",
|
||||
"about": "О проекте",
|
||||
"@about": {
|
||||
"type": "String",
|
||||
|
|
@ -3132,8 +3132,6 @@
|
|||
"@invalidUrl": {},
|
||||
"addLink": "Добавить ссылку",
|
||||
"@addLink": {},
|
||||
"italicText": "Italic",
|
||||
"@italicText": {},
|
||||
"unableToJoinChat": "Невозможно присоединиться к чату. Возможно, другая сторона уже закончила разговор.",
|
||||
"@unableToJoinChat": {},
|
||||
"serverLimitReached": "Ограничения сервера. Ожидайте{seconds} секунд...",
|
||||
|
|
@ -3689,13 +3687,6 @@
|
|||
"acceptSelection": "Принять исправление",
|
||||
"why": "Почему?",
|
||||
"definition": "Определение",
|
||||
"exampleSentence": "Приклад речення",
|
||||
"reportToTeacher": "Кому ви хочете повідомити про це повідомлення?",
|
||||
"reportMessageTitle": "{reportingUserId} повідомив про повідомлення від {reportedUserId} у чаті {roomName}",
|
||||
"reportMessageBody": "Повідомлення: {reportedMessage}\nПричина: {reason}",
|
||||
"noTeachersFound": "Вчителі не знайдені для повідомлення",
|
||||
"trialExpiration": "Ваша безкоштовна пробна версія закінчується {expiration}",
|
||||
"freeTrialDesc": "Нові користувачі отримують тижневу безкоштовну пробну версію Pangea Chat",
|
||||
"activateTrial": "Безкоштовна 7-денна пробна версія",
|
||||
"successfullySubscribed": "Ви успішно підписалися!",
|
||||
"clickToManageSubscription": "Натисніть тут, щоб керувати підпискою.",
|
||||
|
|
@ -4078,13 +4069,6 @@
|
|||
"constructUseIncMDesc": "Некорректно в деятельности по грамматике",
|
||||
"constructUseIgnMDesc": "Игнорируется в деятельности по грамматике",
|
||||
"constructUseEmojiDesc": "Правильно в деятельности по эмодзи",
|
||||
"constructUseCollected": "Thu thập trong trò chuyện",
|
||||
"constructUseNanDesc": "Không áp dụng được",
|
||||
"xpIntoLevel": "{currentXP} / {maxXP} XP",
|
||||
"enableTTSToolName": "Bật chuyển đổi văn bản thành giọng nói",
|
||||
"enableTTSToolDescription": "Cho phép ứng dụng tạo ra đầu ra chuyển đổi văn bản thành giọng nói cho các phần của văn bản bằng ngôn ngữ mục tiêu của bạn.",
|
||||
"yourUsername": "Tên người dùng của bạn",
|
||||
"yourEmail": "Email của bạn",
|
||||
"iWantToLearn": "Я хочу учиться",
|
||||
"pleaseEnterEmail": "Пожалуйста, введите действительный адрес электронной почты.",
|
||||
"myBaseLanguage": "Мой основной язык",
|
||||
|
|
@ -11005,5 +10989,48 @@
|
|||
"@knockDesc": {
|
||||
"type": "String",
|
||||
"placeholders": {}
|
||||
},
|
||||
"italicText": "Курсивный текст",
|
||||
"exampleSentence": "Пример предложения",
|
||||
"reportToTeacher": "Кому вы хотите пожаловаться на это сообщение?",
|
||||
"reportMessageTitle": "{reportingUserId} пожаловался на сообщение от {reportedUserId} в чате {roomName}",
|
||||
"reportMessageBody": "Сообщение: {reportedMessage}\nПричина: {reason}",
|
||||
"noTeachersFound": "Учителя для жалобы не найдены",
|
||||
"trialExpiration": "Ваш бесплатный пробный период истекает {expiration}",
|
||||
"freeTrialDesc": "Новые пользователи получают бесплатную пробную неделю в Pangea Chat",
|
||||
"constructUseCollected": "Собрано в чате",
|
||||
"constructUseNanDesc": "Не применимо",
|
||||
"xpIntoLevel": "{currentXP} / {maxXP} XP",
|
||||
"enableTTSToolName": "Включен преобразователь текста в речь",
|
||||
"enableTTSToolDescription": "Позволяет приложению генерировать озвучивание текста на вашем целевом языке.",
|
||||
"yourUsername": "Ваше имя пользователя",
|
||||
"yourEmail": "Ваш email",
|
||||
"@italicText": {
|
||||
"type": "String",
|
||||
"placeholders": {}
|
||||
},
|
||||
"joinSpaceOnboardingDesc": "У вас есть код приглашения или ссылка на публичный курс?",
|
||||
"welcomeUser": "Добро пожаловать {user}",
|
||||
"@joinSpaceOnboardingDesc": {
|
||||
"type": "String",
|
||||
"placeholders": {}
|
||||
},
|
||||
"@welcomeUser": {
|
||||
"type": "String",
|
||||
"placeholders": {
|
||||
"user": {
|
||||
"type": "String"
|
||||
}
|
||||
}
|
||||
},
|
||||
"publicInviteDescChat": "Ищите пользователей, чтобы пригласить их в этот чат.",
|
||||
"publicInviteDescSpace": "Ищите пользователей, чтобы пригласить их в это пространство.",
|
||||
"@publicInviteDescChat": {
|
||||
"type": "String",
|
||||
"placeholders": {}
|
||||
},
|
||||
"@publicInviteDescSpace": {
|
||||
"type": "String",
|
||||
"placeholders": {}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"@@locale": "sk",
|
||||
"@@last_modified": "2026-01-21 13:53:43.706457",
|
||||
"@@last_modified": "2026-01-22 12:01:06.427460",
|
||||
"about": "O aplikácii",
|
||||
"@about": {
|
||||
"type": "String",
|
||||
|
|
@ -11984,5 +11984,29 @@
|
|||
"@knockDesc": {
|
||||
"type": "String",
|
||||
"placeholders": {}
|
||||
},
|
||||
"joinSpaceOnboardingDesc": "Máte pozývací kód alebo odkaz na verejný kurz?",
|
||||
"welcomeUser": "Vitaj {user}",
|
||||
"@joinSpaceOnboardingDesc": {
|
||||
"type": "String",
|
||||
"placeholders": {}
|
||||
},
|
||||
"@welcomeUser": {
|
||||
"type": "String",
|
||||
"placeholders": {
|
||||
"user": {
|
||||
"type": "String"
|
||||
}
|
||||
}
|
||||
},
|
||||
"publicInviteDescChat": "Hľadajte používateľov, aby ste ich pozvali do tohto chatu.",
|
||||
"publicInviteDescSpace": "Hľadajte používateľov, aby ste ich pozvali do tohto priestoru.",
|
||||
"@publicInviteDescChat": {
|
||||
"type": "String",
|
||||
"placeholders": {}
|
||||
},
|
||||
"@publicInviteDescSpace": {
|
||||
"type": "String",
|
||||
"placeholders": {}
|
||||
}
|
||||
}
|
||||
|
|
@ -2464,7 +2464,7 @@
|
|||
"playWithAI": "Za zdaj igrajte z AI-jem",
|
||||
"courseStartDesc": "Pangea Bot je pripravljen kadarkoli!\n\n...ampak je bolje učiti se s prijatelji!",
|
||||
"@@locale": "sl",
|
||||
"@@last_modified": "2026-01-21 13:53:58.241980",
|
||||
"@@last_modified": "2026-01-22 12:01:24.219945",
|
||||
"@alwaysUse24HourFormat": {
|
||||
"type": "String",
|
||||
"placeholders": {}
|
||||
|
|
@ -11981,5 +11981,29 @@
|
|||
"@knockDesc": {
|
||||
"type": "String",
|
||||
"placeholders": {}
|
||||
},
|
||||
"joinSpaceOnboardingDesc": "Imate kodo za povabilo ali povezavo do javnega tečaja?",
|
||||
"welcomeUser": "Dobrodošli {user}",
|
||||
"@joinSpaceOnboardingDesc": {
|
||||
"type": "String",
|
||||
"placeholders": {}
|
||||
},
|
||||
"@welcomeUser": {
|
||||
"type": "String",
|
||||
"placeholders": {
|
||||
"user": {
|
||||
"type": "String"
|
||||
}
|
||||
}
|
||||
},
|
||||
"publicInviteDescChat": "Išči uporabnike, da jih povabiš v ta klepet.",
|
||||
"publicInviteDescSpace": "Išči uporabnike, da jih povabiš v ta prostor.",
|
||||
"@publicInviteDescChat": {
|
||||
"type": "String",
|
||||
"placeholders": {}
|
||||
},
|
||||
"@publicInviteDescSpace": {
|
||||
"type": "String",
|
||||
"placeholders": {}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
{
|
||||
"@@last_modified": "2026-01-21 13:54:45.561732",
|
||||
"@@last_modified": "2026-01-22 12:02:20.533801",
|
||||
"about": "О програму",
|
||||
"@about": {
|
||||
"type": "String",
|
||||
|
|
@ -12002,5 +12002,29 @@
|
|||
"@knockDesc": {
|
||||
"type": "String",
|
||||
"placeholders": {}
|
||||
},
|
||||
"joinSpaceOnboardingDesc": "Imate li pozivni kod ili link za javni kurs?",
|
||||
"welcomeUser": "Dobrodošli {user}",
|
||||
"@joinSpaceOnboardingDesc": {
|
||||
"type": "String",
|
||||
"placeholders": {}
|
||||
},
|
||||
"@welcomeUser": {
|
||||
"type": "String",
|
||||
"placeholders": {
|
||||
"user": {
|
||||
"type": "String"
|
||||
}
|
||||
}
|
||||
},
|
||||
"publicInviteDescChat": "Pretražite korisnike da ih pozovete u ovaj čat.",
|
||||
"publicInviteDescSpace": "Pretražite korisnike da ih pozovete u ovaj prostor.",
|
||||
"@publicInviteDescChat": {
|
||||
"type": "String",
|
||||
"placeholders": {}
|
||||
},
|
||||
"@publicInviteDescSpace": {
|
||||
"type": "String",
|
||||
"placeholders": {}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
{
|
||||
"@@last_modified": "2026-01-21 13:54:35.931933",
|
||||
"@@last_modified": "2026-01-22 12:02:08.064498",
|
||||
"about": "Om",
|
||||
"@about": {
|
||||
"type": "String",
|
||||
|
|
@ -11378,5 +11378,29 @@
|
|||
"@knockDesc": {
|
||||
"type": "String",
|
||||
"placeholders": {}
|
||||
},
|
||||
"joinSpaceOnboardingDesc": "Har du en inbjudningskod eller länk till en offentlig kurs?",
|
||||
"welcomeUser": "Välkommen {user}",
|
||||
"@joinSpaceOnboardingDesc": {
|
||||
"type": "String",
|
||||
"placeholders": {}
|
||||
},
|
||||
"@welcomeUser": {
|
||||
"type": "String",
|
||||
"placeholders": {
|
||||
"user": {
|
||||
"type": "String"
|
||||
}
|
||||
}
|
||||
},
|
||||
"publicInviteDescChat": "Sök efter användare för att bjuda in dem till den här chatten.",
|
||||
"publicInviteDescSpace": "Sök efter användare för att bjuda in dem till det här utrymmet.",
|
||||
"@publicInviteDescChat": {
|
||||
"type": "String",
|
||||
"placeholders": {}
|
||||
},
|
||||
"@publicInviteDescSpace": {
|
||||
"type": "String",
|
||||
"placeholders": {}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
{
|
||||
"@@last_modified": "2026-01-21 13:54:25.999605",
|
||||
"@@last_modified": "2026-01-22 12:01:56.352823",
|
||||
"acceptedTheInvitation": "👍 {username} அழைப்பை ஏற்றுக்கொண்டது",
|
||||
"@acceptedTheInvitation": {
|
||||
"type": "String",
|
||||
|
|
@ -11124,5 +11124,29 @@
|
|||
"@knockDesc": {
|
||||
"type": "String",
|
||||
"placeholders": {}
|
||||
},
|
||||
"joinSpaceOnboardingDesc": "உங்களுக்கு ஒரு அழைப்பு குறியீடு அல்லது பொது பாடத்திற்கு இணைப்பு உள்ளதா?",
|
||||
"welcomeUser": "வரவேற்கிறேன் {user}",
|
||||
"@joinSpaceOnboardingDesc": {
|
||||
"type": "String",
|
||||
"placeholders": {}
|
||||
},
|
||||
"@welcomeUser": {
|
||||
"type": "String",
|
||||
"placeholders": {
|
||||
"user": {
|
||||
"type": "String"
|
||||
}
|
||||
}
|
||||
},
|
||||
"publicInviteDescChat": "இந்த உரையாடலுக்கு அழைக்க பயனர்களை தேடுங்கள்.",
|
||||
"publicInviteDescSpace": "இந்த இடத்திற்கு அழைக்க பயனர்களை தேடுங்கள்.",
|
||||
"@publicInviteDescChat": {
|
||||
"type": "String",
|
||||
"placeholders": {}
|
||||
},
|
||||
"@publicInviteDescSpace": {
|
||||
"type": "String",
|
||||
"placeholders": {}
|
||||
}
|
||||
}
|
||||
|
|
@ -1920,7 +1920,7 @@
|
|||
"playWithAI": "ఇప్పుడే AI తో ఆడండి",
|
||||
"courseStartDesc": "పాంజియా బాట్ ఎప్పుడైనా సిద్ధంగా ఉంటుంది!\n\n...కానీ స్నేహితులతో నేర్చుకోవడం మెరుగైనది!",
|
||||
"@@locale": "te",
|
||||
"@@last_modified": "2026-01-21 13:54:20.897642",
|
||||
"@@last_modified": "2026-01-22 12:01:51.350363",
|
||||
"@setCustomPermissionLevel": {
|
||||
"type": "String",
|
||||
"placeholders": {}
|
||||
|
|
@ -11989,5 +11989,29 @@
|
|||
"@knockDesc": {
|
||||
"type": "String",
|
||||
"placeholders": {}
|
||||
},
|
||||
"joinSpaceOnboardingDesc": "మీకు పబ్లిక్ కోర్సుకు ఆహ్వాన కోడ్ లేదా లింక్ ఉందా?",
|
||||
"welcomeUser": "స్వాగతం {user}",
|
||||
"@joinSpaceOnboardingDesc": {
|
||||
"type": "String",
|
||||
"placeholders": {}
|
||||
},
|
||||
"@welcomeUser": {
|
||||
"type": "String",
|
||||
"placeholders": {
|
||||
"user": {
|
||||
"type": "String"
|
||||
}
|
||||
}
|
||||
},
|
||||
"publicInviteDescChat": "ఈ చాట్లో ఆహ్వానించడానికి వినియోగదారులను శోధించండి.",
|
||||
"publicInviteDescSpace": "ఈ స్థలంలో ఆహ్వానించడానికి వినియోగదారులను శోధించండి.",
|
||||
"@publicInviteDescChat": {
|
||||
"type": "String",
|
||||
"placeholders": {}
|
||||
},
|
||||
"@publicInviteDescSpace": {
|
||||
"type": "String",
|
||||
"placeholders": {}
|
||||
}
|
||||
}
|
||||
|
|
@ -4456,7 +4456,7 @@
|
|||
"playWithAI": "เล่นกับ AI ชั่วคราว",
|
||||
"courseStartDesc": "Pangea Bot พร้อมที่จะเริ่มต้นได้ทุกเมื่อ!\n\n...แต่การเรียนรู้ดีกว่ากับเพื่อน!",
|
||||
"@@locale": "th",
|
||||
"@@last_modified": "2026-01-21 13:54:10.758435",
|
||||
"@@last_modified": "2026-01-22 12:01:36.919446",
|
||||
"@alwaysUse24HourFormat": {
|
||||
"type": "String",
|
||||
"placeholders": {}
|
||||
|
|
@ -11958,5 +11958,29 @@
|
|||
"@knockDesc": {
|
||||
"type": "String",
|
||||
"placeholders": {}
|
||||
},
|
||||
"joinSpaceOnboardingDesc": "คุณมีรหัสเชิญหรือลิงก์ไปยังหลักสูตรสาธารณะหรือไม่?",
|
||||
"welcomeUser": "ยินดีต้อนรับ {user}",
|
||||
"@joinSpaceOnboardingDesc": {
|
||||
"type": "String",
|
||||
"placeholders": {}
|
||||
},
|
||||
"@welcomeUser": {
|
||||
"type": "String",
|
||||
"placeholders": {
|
||||
"user": {
|
||||
"type": "String"
|
||||
}
|
||||
}
|
||||
},
|
||||
"publicInviteDescChat": "ค้นหาผู้ใช้เพื่อนำไปเชิญเข้าร่วมแชทนี้。",
|
||||
"publicInviteDescSpace": "ค้นหาผู้ใช้เพื่อนำไปเชิญเข้าร่วมพื้นที่นี้。",
|
||||
"@publicInviteDescChat": {
|
||||
"type": "String",
|
||||
"placeholders": {}
|
||||
},
|
||||
"@publicInviteDescSpace": {
|
||||
"type": "String",
|
||||
"placeholders": {}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"@@locale": "tr",
|
||||
"@@last_modified": "2026-01-21 13:54:19.467039",
|
||||
"@@last_modified": "2026-01-22 12:01:49.339268",
|
||||
"about": "Hakkında",
|
||||
"@about": {
|
||||
"type": "String",
|
||||
|
|
@ -11122,5 +11122,29 @@
|
|||
"@knockDesc": {
|
||||
"type": "String",
|
||||
"placeholders": {}
|
||||
},
|
||||
"joinSpaceOnboardingDesc": "Bir davet kodunuz veya halka açık bir kursa bağlantınız var mı?",
|
||||
"welcomeUser": "Hoş geldin {user}",
|
||||
"@joinSpaceOnboardingDesc": {
|
||||
"type": "String",
|
||||
"placeholders": {}
|
||||
},
|
||||
"@welcomeUser": {
|
||||
"type": "String",
|
||||
"placeholders": {
|
||||
"user": {
|
||||
"type": "String"
|
||||
}
|
||||
}
|
||||
},
|
||||
"publicInviteDescChat": "Bu sohbete davet etmek için kullanıcıları arayın.",
|
||||
"publicInviteDescSpace": "Bu alana davet etmek için kullanıcıları arayın.",
|
||||
"@publicInviteDescChat": {
|
||||
"type": "String",
|
||||
"placeholders": {}
|
||||
},
|
||||
"@publicInviteDescSpace": {
|
||||
"type": "String",
|
||||
"placeholders": {}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"@@locale": "uk",
|
||||
"@@last_modified": "2026-01-21 13:54:03.403456",
|
||||
"@@last_modified": "2026-01-22 12:01:28.947095",
|
||||
"about": "Про застосунок",
|
||||
"@about": {
|
||||
"type": "String",
|
||||
|
|
@ -10894,5 +10894,29 @@
|
|||
"@knockDesc": {
|
||||
"type": "String",
|
||||
"placeholders": {}
|
||||
},
|
||||
"joinSpaceOnboardingDesc": "У вас є код запрошення або посилання на публічний курс?",
|
||||
"welcomeUser": "Ласкаво просимо {user}",
|
||||
"@joinSpaceOnboardingDesc": {
|
||||
"type": "String",
|
||||
"placeholders": {}
|
||||
},
|
||||
"@welcomeUser": {
|
||||
"type": "String",
|
||||
"placeholders": {
|
||||
"user": {
|
||||
"type": "String"
|
||||
}
|
||||
}
|
||||
},
|
||||
"publicInviteDescChat": "Шукайте користувачів, щоб запросити їх до цього чату.",
|
||||
"publicInviteDescSpace": "Шукайте користувачів, щоб запросити їх до цього простору.",
|
||||
"@publicInviteDescChat": {
|
||||
"type": "String",
|
||||
"placeholders": {}
|
||||
},
|
||||
"@publicInviteDescSpace": {
|
||||
"type": "String",
|
||||
"placeholders": {}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
{
|
||||
"@@last_modified": "2026-01-21 13:54:24.252269",
|
||||
"@@last_modified": "2026-01-22 12:01:54.904291",
|
||||
"about": "Giới thiệu",
|
||||
"@about": {
|
||||
"type": "String",
|
||||
|
|
@ -6470,5 +6470,29 @@
|
|||
"@knockDesc": {
|
||||
"type": "String",
|
||||
"placeholders": {}
|
||||
},
|
||||
"joinSpaceOnboardingDesc": "Bạn có mã mời hoặc liên kết đến một khóa học công khai không?",
|
||||
"welcomeUser": "Chào mừng {user}",
|
||||
"@joinSpaceOnboardingDesc": {
|
||||
"type": "String",
|
||||
"placeholders": {}
|
||||
},
|
||||
"@welcomeUser": {
|
||||
"type": "String",
|
||||
"placeholders": {
|
||||
"user": {
|
||||
"type": "String"
|
||||
}
|
||||
}
|
||||
},
|
||||
"publicInviteDescChat": "Tìm kiếm người dùng để mời họ tham gia trò chuyện này.",
|
||||
"publicInviteDescSpace": "Tìm kiếm người dùng để mời họ tham gia không gian này.",
|
||||
"@publicInviteDescChat": {
|
||||
"type": "String",
|
||||
"placeholders": {}
|
||||
},
|
||||
"@publicInviteDescSpace": {
|
||||
"type": "String",
|
||||
"placeholders": {}
|
||||
}
|
||||
}
|
||||
|
|
@ -1856,7 +1856,7 @@
|
|||
"selectAll": "全選",
|
||||
"deselectAll": "取消全選",
|
||||
"@@locale": "yue",
|
||||
"@@last_modified": "2026-01-21 13:53:59.885092",
|
||||
"@@last_modified": "2026-01-22 12:01:25.863585",
|
||||
"@ignoreUser": {
|
||||
"type": "String",
|
||||
"placeholders": {}
|
||||
|
|
@ -11991,5 +11991,29 @@
|
|||
"@knockDesc": {
|
||||
"type": "String",
|
||||
"placeholders": {}
|
||||
},
|
||||
"joinSpaceOnboardingDesc": "你有邀請碼或公共課程的鏈接嗎?",
|
||||
"welcomeUser": "歡迎 {user}",
|
||||
"@joinSpaceOnboardingDesc": {
|
||||
"type": "String",
|
||||
"placeholders": {}
|
||||
},
|
||||
"@welcomeUser": {
|
||||
"type": "String",
|
||||
"placeholders": {
|
||||
"user": {
|
||||
"type": "String"
|
||||
}
|
||||
}
|
||||
},
|
||||
"publicInviteDescChat": "搜尋用戶以邀請他們加入此聊天。",
|
||||
"publicInviteDescSpace": "搜尋用戶以邀請他們加入此空間。",
|
||||
"@publicInviteDescChat": {
|
||||
"type": "String",
|
||||
"placeholders": {}
|
||||
},
|
||||
"@publicInviteDescSpace": {
|
||||
"type": "String",
|
||||
"placeholders": {}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"@@locale": "zh",
|
||||
"@@last_modified": "2026-01-21 13:54:29.681537",
|
||||
"@@last_modified": "2026-01-22 12:02:00.962577",
|
||||
"about": "关于",
|
||||
"@about": {
|
||||
"type": "String",
|
||||
|
|
@ -10891,5 +10891,29 @@
|
|||
"@knockDesc": {
|
||||
"type": "String",
|
||||
"placeholders": {}
|
||||
},
|
||||
"joinSpaceOnboardingDesc": "您是否有邀请代码或公共课程的链接?",
|
||||
"welcomeUser": "欢迎 {user}",
|
||||
"@joinSpaceOnboardingDesc": {
|
||||
"type": "String",
|
||||
"placeholders": {}
|
||||
},
|
||||
"@welcomeUser": {
|
||||
"type": "String",
|
||||
"placeholders": {
|
||||
"user": {
|
||||
"type": "String"
|
||||
}
|
||||
}
|
||||
},
|
||||
"publicInviteDescChat": "搜索用户以邀请他们加入此聊天。",
|
||||
"publicInviteDescSpace": "搜索用户以邀请他们加入此空间。",
|
||||
"@publicInviteDescChat": {
|
||||
"type": "String",
|
||||
"placeholders": {}
|
||||
},
|
||||
"@publicInviteDescSpace": {
|
||||
"type": "String",
|
||||
"placeholders": {}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
{
|
||||
"@@last_modified": "2026-01-21 13:54:13.165623",
|
||||
"@@last_modified": "2026-01-22 12:01:42.417971",
|
||||
"about": "關於",
|
||||
"@about": {
|
||||
"type": "String",
|
||||
|
|
@ -10898,5 +10898,29 @@
|
|||
"@knockDesc": {
|
||||
"type": "String",
|
||||
"placeholders": {}
|
||||
},
|
||||
"joinSpaceOnboardingDesc": "您是否有邀請碼或公共課程的鏈接?",
|
||||
"welcomeUser": "歡迎 {user}",
|
||||
"@joinSpaceOnboardingDesc": {
|
||||
"type": "String",
|
||||
"placeholders": {}
|
||||
},
|
||||
"@welcomeUser": {
|
||||
"type": "String",
|
||||
"placeholders": {
|
||||
"user": {
|
||||
"type": "String"
|
||||
}
|
||||
}
|
||||
},
|
||||
"publicInviteDescChat": "搜尋用戶以邀請他們加入此聊天。",
|
||||
"publicInviteDescSpace": "搜尋用戶以邀請他們加入此空間。",
|
||||
"@publicInviteDescChat": {
|
||||
"type": "String",
|
||||
"placeholders": {}
|
||||
},
|
||||
"@publicInviteDescSpace": {
|
||||
"type": "String",
|
||||
"placeholders": {}
|
||||
}
|
||||
}
|
||||
|
|
@ -952,6 +952,9 @@ class ChatController extends State<ChatPageWithRoom>
|
|||
}
|
||||
|
||||
final previousEdit = editEvent;
|
||||
if (showEmojiPicker) {
|
||||
hideEmojiPicker();
|
||||
}
|
||||
|
||||
room
|
||||
.pangeaSendTextEvent(
|
||||
|
|
|
|||
|
|
@ -49,8 +49,19 @@ class ChatEmojiPicker extends StatelessWidget {
|
|||
backgroundColor:
|
||||
theme.colorScheme.onInverseSurface,
|
||||
),
|
||||
bottomActionBarConfig: const BottomActionBarConfig(
|
||||
enabled: false,
|
||||
bottomActionBarConfig: BottomActionBarConfig(
|
||||
// #Pangea
|
||||
// enabled: false,
|
||||
showBackspaceButton: false,
|
||||
backgroundColor: Theme.of(context)
|
||||
.colorScheme
|
||||
.surfaceContainer,
|
||||
buttonColor: Theme.of(context)
|
||||
.colorScheme
|
||||
.surfaceContainer,
|
||||
buttonIconColor:
|
||||
Theme.of(context).colorScheme.onSurface,
|
||||
// Pangea#
|
||||
),
|
||||
categoryViewConfig: CategoryViewConfig(
|
||||
backspaceColor: theme.colorScheme.primary,
|
||||
|
|
@ -68,6 +79,17 @@ class ChatEmojiPicker extends StatelessWidget {
|
|||
)!,
|
||||
indicatorColor: theme.colorScheme.onSurface,
|
||||
),
|
||||
// #Pangea
|
||||
viewOrderConfig: const ViewOrderConfig(
|
||||
middle: EmojiPickerItem.searchBar,
|
||||
top: EmojiPickerItem.categoryBar,
|
||||
bottom: EmojiPickerItem.emojiView,
|
||||
),
|
||||
searchViewConfig: SearchViewConfig(
|
||||
backgroundColor: theme.colorScheme.surface,
|
||||
buttonIconColor: theme.colorScheme.onSurface,
|
||||
),
|
||||
// Pangea#
|
||||
),
|
||||
),
|
||||
// #Pangea
|
||||
|
|
|
|||
|
|
@ -111,9 +111,12 @@ class ChatListController extends State<ChatList>
|
|||
// StreamSubscription? _intentUriStreamSubscription;
|
||||
// Pangea#
|
||||
|
||||
ActiveFilter activeFilter = AppConfig.separateChatTypes
|
||||
? ActiveFilter.messages
|
||||
: ActiveFilter.allChats;
|
||||
// #Pangea
|
||||
// ActiveFilter activeFilter = AppConfig.separateChatTypes
|
||||
// ? ActiveFilter.messages
|
||||
// : ActiveFilter.allChats;
|
||||
ActiveFilter activeFilter = ActiveFilter.allChats;
|
||||
// Pangea#
|
||||
|
||||
// #Pangea
|
||||
String? get activeSpaceId => widget.activeSpaceId;
|
||||
|
|
|
|||
83
lib/pages/onboarding/space_code_onboarding.dart
Normal file
83
lib/pages/onboarding/space_code_onboarding.dart
Normal file
|
|
@ -0,0 +1,83 @@
|
|||
import 'package:flutter/material.dart';
|
||||
|
||||
import 'package:go_router/go_router.dart';
|
||||
import 'package:matrix/matrix.dart';
|
||||
|
||||
import 'package:fluffychat/pages/onboarding/space_code_onboarding_view.dart';
|
||||
import 'package:fluffychat/pangea/common/utils/error_handler.dart';
|
||||
import 'package:fluffychat/pangea/join_codes/space_code_controller.dart';
|
||||
import 'package:fluffychat/pangea/spaces/space_constants.dart';
|
||||
import 'package:fluffychat/widgets/matrix.dart';
|
||||
|
||||
class SpaceCodeOnboarding extends StatefulWidget {
|
||||
const SpaceCodeOnboarding({super.key});
|
||||
|
||||
@override
|
||||
State<SpaceCodeOnboarding> createState() => SpaceCodeOnboardingState();
|
||||
}
|
||||
|
||||
class SpaceCodeOnboardingState extends State<SpaceCodeOnboarding> {
|
||||
Profile? profile;
|
||||
Client get client => Matrix.of(context).client;
|
||||
|
||||
final TextEditingController codeController = TextEditingController();
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
_setProfile();
|
||||
codeController.addListener(() {
|
||||
if (mounted) setState(() {});
|
||||
});
|
||||
super.initState();
|
||||
}
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
codeController.dispose();
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
Future<void> _setProfile() async {
|
||||
try {
|
||||
profile = await client.getProfileFromUserId(
|
||||
client.userID!,
|
||||
);
|
||||
} catch (e, s) {
|
||||
ErrorHandler.logError(
|
||||
e: e,
|
||||
s: s,
|
||||
data: {
|
||||
'userId': client.userID,
|
||||
},
|
||||
);
|
||||
} finally {
|
||||
if (mounted) setState(() {});
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> submitCode() async {
|
||||
String code = codeController.text.trim();
|
||||
if (code.isEmpty) return;
|
||||
|
||||
try {
|
||||
final link = Uri.parse(Uri.parse(code).fragment);
|
||||
if (link.queryParameters.containsKey(SpaceConstants.classCode)) {
|
||||
code = link.queryParameters[SpaceConstants.classCode]!;
|
||||
}
|
||||
} catch (e) {
|
||||
debugPrint("Text input is not a URL: $e");
|
||||
}
|
||||
|
||||
final roomId = await SpaceCodeController.joinSpaceWithCode(context, code);
|
||||
if (roomId != null) {
|
||||
final room = Matrix.of(context).client.getRoomById(roomId);
|
||||
room?.isSpace ?? true
|
||||
? context.go('/rooms/spaces/$roomId/details')
|
||||
: context.go('/rooms/$roomId');
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) =>
|
||||
SpaceCodeOnboardingView(controller: this);
|
||||
}
|
||||
82
lib/pages/onboarding/space_code_onboarding_view.dart
Normal file
82
lib/pages/onboarding/space_code_onboarding_view.dart
Normal file
|
|
@ -0,0 +1,82 @@
|
|||
import 'package:flutter/material.dart';
|
||||
|
||||
import 'package:go_router/go_router.dart';
|
||||
import 'package:matrix/matrix.dart';
|
||||
|
||||
import 'package:fluffychat/l10n/l10n.dart';
|
||||
import 'package:fluffychat/pages/onboarding/space_code_onboarding.dart';
|
||||
import 'package:fluffychat/pangea/authentication/p_logout.dart';
|
||||
import 'package:fluffychat/pangea/login/pages/pangea_login_scaffold.dart';
|
||||
|
||||
class SpaceCodeOnboardingView extends StatelessWidget {
|
||||
final SpaceCodeOnboardingState controller;
|
||||
const SpaceCodeOnboardingView({
|
||||
super.key,
|
||||
required this.controller,
|
||||
});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return PangeaLoginScaffold(
|
||||
customAppBar: AppBar(
|
||||
leading: BackButton(
|
||||
onPressed: () => pLogoutAction(
|
||||
context,
|
||||
bypassWarning: true,
|
||||
),
|
||||
),
|
||||
),
|
||||
showAppName: false,
|
||||
mainAssetUrl: controller.profile?.avatarUrl,
|
||||
children: [
|
||||
Column(
|
||||
spacing: 8.0,
|
||||
children: [
|
||||
Text(
|
||||
L10n.of(context).welcomeUser(
|
||||
controller.profile?.displayName ??
|
||||
controller.client.userID?.localpart ??
|
||||
"",
|
||||
),
|
||||
style: Theme.of(context)
|
||||
.textTheme
|
||||
.titleLarge
|
||||
?.copyWith(fontWeight: FontWeight.bold),
|
||||
),
|
||||
Text(
|
||||
L10n.of(context).joinSpaceOnboardingDesc,
|
||||
textAlign: TextAlign.center,
|
||||
),
|
||||
TextField(
|
||||
decoration: InputDecoration(
|
||||
hintText: L10n.of(context).enterCodeToJoin,
|
||||
),
|
||||
controller: controller.codeController,
|
||||
onSubmitted: (_) => controller.submitCode,
|
||||
),
|
||||
ElevatedButton(
|
||||
onPressed: controller.codeController.text.isNotEmpty
|
||||
? controller.submitCode
|
||||
: null,
|
||||
style: ElevatedButton.styleFrom(
|
||||
backgroundColor: Theme.of(context).colorScheme.primaryContainer,
|
||||
foregroundColor:
|
||||
Theme.of(context).colorScheme.onPrimaryContainer,
|
||||
),
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
Text(L10n.of(context).join),
|
||||
],
|
||||
),
|
||||
),
|
||||
TextButton(
|
||||
child: Text(L10n.of(context).skipForNow),
|
||||
onPressed: () => context.go("/rooms"),
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
@ -147,9 +147,7 @@ class SettingsView extends StatelessWidget {
|
|||
displayname,
|
||||
maxLines: 1,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
style: const TextStyle(
|
||||
fontSize: 18,
|
||||
),
|
||||
style: const TextStyle(fontSize: 18),
|
||||
),
|
||||
),
|
||||
TextButton.icon(
|
||||
|
|
@ -171,25 +169,6 @@ class SettingsView extends StatelessWidget {
|
|||
// style: const TextStyle(fontSize: 12),
|
||||
),
|
||||
),
|
||||
// #Pangea
|
||||
TextButton.icon(
|
||||
onPressed: controller.setStatus,
|
||||
icon: const Icon(
|
||||
Icons.add,
|
||||
size: 14,
|
||||
),
|
||||
style: TextButton.styleFrom(
|
||||
foregroundColor:
|
||||
theme.colorScheme.secondary,
|
||||
iconColor: theme.colorScheme.secondary,
|
||||
),
|
||||
label: Text(
|
||||
L10n.of(context).setStatus,
|
||||
maxLines: 1,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
),
|
||||
),
|
||||
// Pangea#
|
||||
],
|
||||
),
|
||||
),
|
||||
|
|
|
|||
|
|
@ -353,14 +353,14 @@ class SettingsStyleView extends StatelessWidget {
|
|||
storeKey: SettingKeys.showPresences,
|
||||
defaultValue: AppConfig.showPresences,
|
||||
),
|
||||
SettingsSwitchListTile.adaptive(
|
||||
title: L10n.of(context).separateChatTypes,
|
||||
onChanged: (b) => AppConfig.separateChatTypes = b,
|
||||
storeKey: SettingKeys.separateChatTypes,
|
||||
defaultValue: AppConfig.separateChatTypes,
|
||||
),
|
||||
// #Pangea
|
||||
// SettingsSwitchListTile.adaptive(
|
||||
// title: L10n.of(context).separateChatTypes,
|
||||
// onChanged: (b) => AppConfig.separateChatTypes = b,
|
||||
// storeKey: SettingKeys.separateChatTypes,
|
||||
// defaultValue: AppConfig.separateChatTypes,
|
||||
// ),
|
||||
// SettingsSwitchListTile.adaptive(
|
||||
// title: L10n.of(context).displayNavigationRail,
|
||||
// onChanged: (b) => AppConfig.displayNavigationRail = b,
|
||||
// storeKey: SettingKeys.displayNavigationRail,
|
||||
|
|
|
|||
|
|
@ -44,15 +44,9 @@ extension ActivityMenuLogic on ChatController {
|
|||
return false;
|
||||
}
|
||||
|
||||
final l1 =
|
||||
MatrixState.pangeaController.userController.userL1?.langCodeShort;
|
||||
final l2 =
|
||||
MatrixState.pangeaController.userController.userL2?.langCodeShort;
|
||||
final activityLang = room.activityPlan?.req.targetLanguage.split('-').first;
|
||||
|
||||
return activityLang != null &&
|
||||
l2 != null &&
|
||||
l2 != activityLang &&
|
||||
l1 != activityLang;
|
||||
return activityLang != null && l2 != activityLang;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,7 +8,6 @@ import 'package:matrix/matrix.dart';
|
|||
import 'package:fluffychat/l10n/l10n.dart';
|
||||
import 'package:fluffychat/pangea/extensions/pangea_rooms_chunk_extension.dart';
|
||||
import 'package:fluffychat/pangea/join_codes/space_code_controller.dart';
|
||||
import 'package:fluffychat/pangea/navigation/navigation_util.dart';
|
||||
import 'package:fluffychat/utils/adaptive_bottom_sheet.dart';
|
||||
import 'package:fluffychat/widgets/avatar.dart';
|
||||
import 'package:fluffychat/widgets/future_loading_dialog.dart';
|
||||
|
|
@ -30,7 +29,7 @@ class PublicRoomBottomSheet extends StatefulWidget {
|
|||
assert(roomAlias != null || chunk != null);
|
||||
}
|
||||
|
||||
static Future<bool?> show({
|
||||
static Future<String?> show({
|
||||
required BuildContext context,
|
||||
String? roomAlias,
|
||||
PublicRoomsChunk? chunk,
|
||||
|
|
@ -91,26 +90,13 @@ class PublicRoomBottomSheetState extends State<PublicRoomBottomSheet> {
|
|||
notFoundError: L10n.of(context).notTheCodeError,
|
||||
);
|
||||
if (resp != null) {
|
||||
Navigator.of(context).pop(true);
|
||||
}
|
||||
}
|
||||
|
||||
void _goToRoom(String roomID) {
|
||||
if (chunk?.roomType != 'm.space' && !client.getRoomById(roomID)!.isSpace) {
|
||||
NavigationUtil.goToSpaceRoute(
|
||||
roomID,
|
||||
[],
|
||||
context,
|
||||
);
|
||||
} else {
|
||||
context.go('/rooms/spaces/$roomID/details');
|
||||
Navigator.of(context).pop(resp);
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> _joinRoom() async {
|
||||
if (_isRoomMember) {
|
||||
_goToRoom(room!.id);
|
||||
Navigator.of(context).pop();
|
||||
Navigator.of(context).pop(room!.id);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -131,15 +117,13 @@ class PublicRoomBottomSheetState extends State<PublicRoomBottomSheet> {
|
|||
);
|
||||
|
||||
if (result.result != null) {
|
||||
_goToRoom(result.result!);
|
||||
Navigator.of(context).pop(true);
|
||||
Navigator.of(context).pop(result.result!);
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> _knockRoom() async {
|
||||
if (_isRoomMember) {
|
||||
_goToRoom(room!.id);
|
||||
Navigator.of(context).pop();
|
||||
Navigator.of(context).pop(room!.id);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -148,6 +148,20 @@ class PangeaInvitationSelectionController
|
|||
return parents.first;
|
||||
}
|
||||
|
||||
bool get showInviteAllInSpaceButton {
|
||||
final roomParticipants = participants;
|
||||
if (roomParticipants == null ||
|
||||
filter != InvitationFilter.space ||
|
||||
spaceParent == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
final spaceParticipants = spaceParent!.getParticipants();
|
||||
return spaceParticipants.any(
|
||||
(participant) => !roomParticipants.any((p) => p.id == participant.id),
|
||||
);
|
||||
}
|
||||
|
||||
List<InvitationFilter> get availableFilters => InvitationFilter.values
|
||||
.where(
|
||||
(f) => switch (f) {
|
||||
|
|
|
|||
|
|
@ -157,27 +157,34 @@ class PangeaInvitationSelectionView extends StatelessWidget {
|
|||
final participants =
|
||||
room.getParticipants().map((user) => user.id).toSet();
|
||||
return controller.filter == InvitationFilter.public
|
||||
? ListView.builder(
|
||||
itemCount: controller.foundProfiles.length,
|
||||
itemBuilder: (BuildContext context, int i) =>
|
||||
_InviteContactListTile(
|
||||
profile: controller.foundProfiles[i],
|
||||
isMember: participants.contains(
|
||||
controller.foundProfiles[i].userId,
|
||||
),
|
||||
onTap: () => controller.inviteAction(
|
||||
controller.foundProfiles[i].userId,
|
||||
),
|
||||
controller: controller,
|
||||
),
|
||||
)
|
||||
? controller.foundProfiles.isEmpty
|
||||
? Padding(
|
||||
padding: const EdgeInsets.all(24.0),
|
||||
child: Text(
|
||||
room.isSpace
|
||||
? L10n.of(context).publicInviteDescSpace
|
||||
: L10n.of(context).publicInviteDescChat,
|
||||
),
|
||||
)
|
||||
: ListView.builder(
|
||||
itemCount: controller.foundProfiles.length,
|
||||
itemBuilder: (BuildContext context, int i) =>
|
||||
_InviteContactListTile(
|
||||
profile: controller.foundProfiles[i],
|
||||
isMember: participants.contains(
|
||||
controller.foundProfiles[i].userId,
|
||||
),
|
||||
onTap: () => controller.inviteAction(
|
||||
controller.foundProfiles[i].userId,
|
||||
),
|
||||
controller: controller,
|
||||
),
|
||||
)
|
||||
: ListView.builder(
|
||||
itemCount: contacts.length + 2,
|
||||
itemBuilder: (BuildContext context, int i) {
|
||||
if (i == 0) {
|
||||
return controller.filter ==
|
||||
InvitationFilter.space &&
|
||||
controller.spaceParent != null
|
||||
return controller.showInviteAllInSpaceButton
|
||||
? ListTile(
|
||||
leading: ClipPath(
|
||||
clipper: MapClipper(),
|
||||
|
|
|
|||
|
|
@ -1,94 +1,68 @@
|
|||
import 'package:flutter/foundation.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
import 'package:dropdown_button2/dropdown_button2.dart';
|
||||
|
||||
import 'package:fluffychat/l10n/l10n.dart';
|
||||
import 'package:fluffychat/pangea/common/widgets/dropdown_text_button.dart';
|
||||
import 'package:fluffychat/pangea/learning_settings/language_level_type_enum.dart';
|
||||
|
||||
class LanguageLevelDropdown extends StatelessWidget {
|
||||
final LanguageLevelTypeEnum? initialLevel;
|
||||
final Function(LanguageLevelTypeEnum)? onChanged;
|
||||
final FormFieldValidator<Object>? validator;
|
||||
final bool enabled;
|
||||
final Color? backgroundColor;
|
||||
final double? width;
|
||||
final double? maxHeight;
|
||||
|
||||
const LanguageLevelDropdown({
|
||||
super.key,
|
||||
this.initialLevel = LanguageLevelTypeEnum.a1,
|
||||
this.onChanged,
|
||||
this.validator,
|
||||
this.enabled = true,
|
||||
this.backgroundColor,
|
||||
this.width,
|
||||
this.maxHeight,
|
||||
});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final l10n = L10n.of(context);
|
||||
|
||||
return DropdownButtonFormField2<LanguageLevelTypeEnum>(
|
||||
customButton: initialLevel != null &&
|
||||
LanguageLevelTypeEnum.values.contains(initialLevel)
|
||||
? CustomDropdownTextButton(text: initialLevel!.title(context))
|
||||
: null,
|
||||
menuItemStyleData: const MenuItemStyleData(
|
||||
padding: EdgeInsets.symmetric(
|
||||
vertical: 8.0,
|
||||
horizontal: 16.0,
|
||||
return ButtonTheme(
|
||||
alignedDropdown: true,
|
||||
child: DropdownButtonFormField<LanguageLevelTypeEnum>(
|
||||
itemHeight: null,
|
||||
decoration: InputDecoration(
|
||||
labelText: l10n.cefrLevelLabel,
|
||||
),
|
||||
height: 100.0,
|
||||
),
|
||||
decoration: InputDecoration(
|
||||
labelText: l10n.cefrLevelLabel,
|
||||
),
|
||||
isExpanded: true,
|
||||
dropdownStyleData: DropdownStyleData(
|
||||
maxHeight: maxHeight ?? (kIsWeb ? 500 : null),
|
||||
decoration: BoxDecoration(
|
||||
color: backgroundColor ??
|
||||
Theme.of(context).colorScheme.surfaceContainerHigh,
|
||||
borderRadius: BorderRadius.circular(14.0),
|
||||
),
|
||||
width: width,
|
||||
),
|
||||
items:
|
||||
LanguageLevelTypeEnum.values.map((LanguageLevelTypeEnum levelOption) {
|
||||
return DropdownMenuItem(
|
||||
value: levelOption,
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
Text(levelOption.title(context)),
|
||||
Flexible(
|
||||
child: Text(
|
||||
levelOption.description(context),
|
||||
style: TextStyle(
|
||||
color: Theme.of(context).colorScheme.onSurfaceVariant,
|
||||
fontSize: 14,
|
||||
selectedItemBuilder: (context) => LanguageLevelTypeEnum.values
|
||||
.map((levelOption) => Text(levelOption.title(context)))
|
||||
.toList(),
|
||||
isExpanded: true,
|
||||
dropdownColor: Theme.of(context).colorScheme.surfaceContainerHigh,
|
||||
borderRadius: BorderRadius.circular(14.0),
|
||||
onChanged: (value) {
|
||||
if (value != null) onChanged?.call(value);
|
||||
},
|
||||
initialValue: initialLevel,
|
||||
items: LanguageLevelTypeEnum.values
|
||||
.map((LanguageLevelTypeEnum levelOption) {
|
||||
return DropdownMenuItem(
|
||||
value: levelOption,
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.symmetric(vertical: 8.0),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
Text(levelOption.title(context)),
|
||||
Flexible(
|
||||
child: Text(
|
||||
levelOption.description(context),
|
||||
style: TextStyle(
|
||||
color: Theme.of(context).colorScheme.onSurfaceVariant,
|
||||
fontSize: 14,
|
||||
),
|
||||
maxLines: 5,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
),
|
||||
),
|
||||
maxLines: 5,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}).toList(),
|
||||
onChanged: enabled
|
||||
? (value) {
|
||||
if (value != null) onChanged?.call(value);
|
||||
}
|
||||
: null,
|
||||
value: initialLevel,
|
||||
validator: validator,
|
||||
enableFeedback: enabled,
|
||||
),
|
||||
);
|
||||
}).toList(),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -438,7 +438,7 @@ class CourseChatsController extends State<CourseChats>
|
|||
|
||||
void joinChildRoom(SpaceRoomsChunk item) async {
|
||||
final space = widget.client.getRoomById(widget.roomId);
|
||||
final joined = await PublicRoomBottomSheet.show(
|
||||
final roomId = await PublicRoomBottomSheet.show(
|
||||
context: context,
|
||||
chunk: item,
|
||||
via: space?.spaceChildren
|
||||
|
|
@ -447,10 +447,12 @@ class CourseChatsController extends State<CourseChats>
|
|||
)
|
||||
?.via,
|
||||
);
|
||||
if (mounted && joined == true) {
|
||||
if (mounted && roomId != null) {
|
||||
setState(() {
|
||||
discoveredChildren?.remove(item);
|
||||
});
|
||||
|
||||
NavigationUtil.goToSpaceRoute(roomId, [], context);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ import 'package:go_router/go_router.dart';
|
|||
import 'package:fluffychat/config/app_config.dart';
|
||||
import 'package:fluffychat/l10n/l10n.dart';
|
||||
import 'package:fluffychat/pangea/join_codes/space_code_controller.dart';
|
||||
import 'package:fluffychat/pangea/login/pages/add_course_page.dart';
|
||||
import 'package:fluffychat/pangea/spaces/space_constants.dart';
|
||||
import 'package:fluffychat/widgets/matrix.dart';
|
||||
|
||||
class CourseCodePage extends StatefulWidget {
|
||||
|
|
@ -72,7 +72,7 @@ class CourseCodePageState extends State<CourseCodePage> {
|
|||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
SvgPicture.network(
|
||||
"${AppConfig.assetsBaseURL}/${AddCoursePage.mapUnlockFileName}",
|
||||
"${AppConfig.assetsBaseURL}/${SpaceConstants.mapUnlockFileName}",
|
||||
width: 100.0,
|
||||
height: 100.0,
|
||||
colorFilter: ColorFilter.mode(
|
||||
|
|
|
|||
523
lib/pangea/login/pages/find_course_page.dart
Normal file
523
lib/pangea/login/pages/find_course_page.dart
Normal file
|
|
@ -0,0 +1,523 @@
|
|||
import 'dart:async';
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
import 'package:go_router/go_router.dart';
|
||||
import 'package:matrix/matrix.dart';
|
||||
|
||||
import 'package:fluffychat/config/themes.dart';
|
||||
import 'package:fluffychat/l10n/l10n.dart';
|
||||
import 'package:fluffychat/pangea/common/utils/error_handler.dart';
|
||||
import 'package:fluffychat/pangea/common/widgets/error_indicator.dart';
|
||||
import 'package:fluffychat/pangea/common/widgets/url_image_widget.dart';
|
||||
import 'package:fluffychat/pangea/course_creation/course_info_chip_widget.dart';
|
||||
import 'package:fluffychat/pangea/course_creation/course_language_filter.dart';
|
||||
import 'package:fluffychat/pangea/course_plans/courses/course_plan_model.dart';
|
||||
import 'package:fluffychat/pangea/course_plans/courses/course_plans_repo.dart';
|
||||
import 'package:fluffychat/pangea/course_plans/courses/get_localized_courses_request.dart';
|
||||
import 'package:fluffychat/pangea/languages/language_model.dart';
|
||||
import 'package:fluffychat/pangea/spaces/public_course_extension.dart';
|
||||
import 'package:fluffychat/widgets/avatar.dart';
|
||||
import 'package:fluffychat/widgets/hover_builder.dart';
|
||||
import 'package:fluffychat/widgets/layouts/max_width_body.dart';
|
||||
import 'package:fluffychat/widgets/matrix.dart';
|
||||
|
||||
class FindCoursePage extends StatefulWidget {
|
||||
const FindCoursePage({super.key});
|
||||
|
||||
@override
|
||||
State<FindCoursePage> createState() => FindCoursePageState();
|
||||
}
|
||||
|
||||
class FindCoursePageState extends State<FindCoursePage> {
|
||||
final TextEditingController searchController = TextEditingController();
|
||||
|
||||
bool loading = true;
|
||||
bool _fullyLoaded = false;
|
||||
Object? error;
|
||||
Timer? _coolDown;
|
||||
|
||||
LanguageModel? targetLanguageFilter;
|
||||
|
||||
List<PublicCoursesChunk> discoveredCourses = [];
|
||||
Map<String, CoursePlanModel> coursePlans = {};
|
||||
String? nextBatch;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
|
||||
final target = MatrixState.pangeaController.userController.userL2;
|
||||
if (target != null) {
|
||||
setTargetLanguageFilter(target);
|
||||
}
|
||||
|
||||
_loadCourses();
|
||||
}
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
searchController.dispose();
|
||||
_coolDown?.cancel();
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
void setTargetLanguageFilter(LanguageModel? language) {
|
||||
if (targetLanguageFilter?.langCodeShort == language?.langCodeShort) return;
|
||||
setState(() => targetLanguageFilter = language);
|
||||
_loadCourses();
|
||||
}
|
||||
|
||||
void onSearchEnter(String text, {bool globalSearch = true}) {
|
||||
if (text.isEmpty) {
|
||||
_loadCourses();
|
||||
return;
|
||||
}
|
||||
|
||||
_coolDown?.cancel();
|
||||
_coolDown = Timer(const Duration(milliseconds: 500), _loadCourses);
|
||||
}
|
||||
|
||||
List<PublicCoursesChunk> get filteredCourses {
|
||||
List<PublicCoursesChunk> filtered = discoveredCourses
|
||||
.where(
|
||||
(c) =>
|
||||
!Matrix.of(context).client.rooms.any(
|
||||
(r) =>
|
||||
r.id == c.room.roomId &&
|
||||
r.membership == Membership.join,
|
||||
) &&
|
||||
coursePlans.containsKey(c.courseId),
|
||||
)
|
||||
.toList();
|
||||
|
||||
if (targetLanguageFilter != null) {
|
||||
filtered = filtered.where(
|
||||
(chunk) {
|
||||
final course = coursePlans[chunk.courseId];
|
||||
if (course == null) return false;
|
||||
return course.targetLanguage.split('-').first ==
|
||||
targetLanguageFilter!.langCodeShort;
|
||||
},
|
||||
).toList();
|
||||
}
|
||||
|
||||
final searchText = searchController.text.trim().toLowerCase();
|
||||
if (searchText.isNotEmpty) {
|
||||
filtered = filtered.where(
|
||||
(chunk) {
|
||||
final course = coursePlans[chunk.courseId];
|
||||
if (course == null) return false;
|
||||
final name = chunk.room.name?.toLowerCase() ?? '';
|
||||
final description = course.description.toLowerCase();
|
||||
return name.contains(searchText) || description.contains(searchText);
|
||||
},
|
||||
).toList();
|
||||
}
|
||||
|
||||
// sort by join rule, with knock rooms at the end
|
||||
filtered.sort((a, b) {
|
||||
final aKnock = a.room.joinRule == JoinRules.knock.name;
|
||||
final bKnock = b.room.joinRule == JoinRules.knock.name;
|
||||
if (aKnock && !bKnock) return 1;
|
||||
if (!aKnock && bKnock) return -1;
|
||||
return 0;
|
||||
});
|
||||
|
||||
return filtered;
|
||||
}
|
||||
|
||||
Future<void> _loadPublicSpaces() async {
|
||||
try {
|
||||
final resp = await Matrix.of(context).client.requestPublicCourses(
|
||||
since: nextBatch,
|
||||
);
|
||||
|
||||
for (final room in resp.courses) {
|
||||
if (!discoveredCourses.any((e) => e.room.roomId == room.room.roomId)) {
|
||||
discoveredCourses.add(room);
|
||||
}
|
||||
}
|
||||
|
||||
nextBatch = resp.nextBatch;
|
||||
} catch (e, s) {
|
||||
error = e;
|
||||
ErrorHandler.logError(
|
||||
e: e,
|
||||
s: s,
|
||||
data: {
|
||||
'nextBatch': nextBatch,
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> _loadCourses() async {
|
||||
if (_fullyLoaded && nextBatch == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
setState(() {
|
||||
loading = true;
|
||||
error = null;
|
||||
});
|
||||
|
||||
await _loadPublicSpaces();
|
||||
|
||||
int timesLoaded = 0;
|
||||
while (error == null && timesLoaded < 5 && nextBatch != null) {
|
||||
await _loadPublicSpaces();
|
||||
timesLoaded++;
|
||||
}
|
||||
|
||||
if (nextBatch == null) {
|
||||
_fullyLoaded = true;
|
||||
}
|
||||
|
||||
try {
|
||||
final resp = await CoursePlansRepo.search(
|
||||
GetLocalizedCoursesRequest(
|
||||
coursePlanIds:
|
||||
discoveredCourses.map((c) => c.courseId).toSet().toList(),
|
||||
l1: MatrixState.pangeaController.userController.userL1Code!,
|
||||
),
|
||||
);
|
||||
final searchResult = resp.coursePlans;
|
||||
|
||||
coursePlans.clear();
|
||||
for (final entry in searchResult.entries) {
|
||||
coursePlans[entry.key] = entry.value;
|
||||
}
|
||||
} catch (e, s) {
|
||||
ErrorHandler.logError(
|
||||
e: e,
|
||||
s: s,
|
||||
data: {
|
||||
'discoveredCourses':
|
||||
discoveredCourses.map((c) => c.courseId).toList(),
|
||||
},
|
||||
);
|
||||
} finally {
|
||||
if (mounted) {
|
||||
setState(() => loading = false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return FindCoursePageView(controller: this);
|
||||
}
|
||||
}
|
||||
|
||||
class FindCoursePageView extends StatelessWidget {
|
||||
final FindCoursePageState controller;
|
||||
|
||||
const FindCoursePageView({
|
||||
super.key,
|
||||
required this.controller,
|
||||
});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final theme = Theme.of(context);
|
||||
final isColumnMode = FluffyThemes.isColumnMode(context);
|
||||
|
||||
return Scaffold(
|
||||
appBar: AppBar(title: Text(L10n.of(context).findCourse)),
|
||||
body: MaxWidthBody(
|
||||
showBorder: false,
|
||||
withScrolling: false,
|
||||
maxWidth: 600.0,
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 20.0),
|
||||
child: Column(
|
||||
spacing: 16.0,
|
||||
children: [
|
||||
TextField(
|
||||
controller: controller.searchController,
|
||||
textInputAction: TextInputAction.search,
|
||||
onChanged: controller.onSearchEnter,
|
||||
decoration: InputDecoration(
|
||||
filled: !isColumnMode,
|
||||
fillColor: isColumnMode
|
||||
? null
|
||||
: theme.colorScheme.secondaryContainer,
|
||||
border: OutlineInputBorder(
|
||||
borderSide:
|
||||
isColumnMode ? const BorderSide() : BorderSide.none,
|
||||
borderRadius: BorderRadius.circular(100),
|
||||
),
|
||||
contentPadding: const EdgeInsets.fromLTRB(
|
||||
0,
|
||||
0,
|
||||
20.0,
|
||||
0,
|
||||
),
|
||||
hintText: L10n.of(context).findCourse,
|
||||
hintStyle: TextStyle(
|
||||
color: theme.colorScheme.onPrimaryContainer,
|
||||
fontWeight: FontWeight.normal,
|
||||
fontSize: 16.0,
|
||||
),
|
||||
floatingLabelBehavior: FloatingLabelBehavior.never,
|
||||
prefixIcon: IconButton(
|
||||
onPressed: () {},
|
||||
icon: Icon(
|
||||
Icons.search_outlined,
|
||||
color: theme.colorScheme.onPrimaryContainer,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
LayoutBuilder(
|
||||
builder: (context, constrained) {
|
||||
return Row(
|
||||
spacing: 12.0,
|
||||
children: [
|
||||
Expanded(
|
||||
child: CourseLanguageFilter(
|
||||
value: controller.targetLanguageFilter,
|
||||
onChanged: controller.setTargetLanguageFilter,
|
||||
),
|
||||
),
|
||||
if (constrained.maxWidth >= 500) ...[
|
||||
TextButton(
|
||||
child: Row(
|
||||
spacing: 8.0,
|
||||
children: [
|
||||
const Icon(Icons.add),
|
||||
Text(L10n.of(context).newCourse),
|
||||
],
|
||||
),
|
||||
onPressed: () => context.go("/rooms/course/own"),
|
||||
),
|
||||
TextButton(
|
||||
child: Row(
|
||||
spacing: 8.0,
|
||||
children: [
|
||||
const Icon(Icons.join_full),
|
||||
Text(L10n.of(context).joinWithCode),
|
||||
],
|
||||
),
|
||||
onPressed: () => context.go("/rooms/course/private"),
|
||||
),
|
||||
] else
|
||||
PopupMenuButton(
|
||||
icon: const Icon(Icons.more_vert),
|
||||
itemBuilder: (context) => [
|
||||
PopupMenuItem(
|
||||
onTap: () => context.go("/rooms/course/own"),
|
||||
child: Row(
|
||||
spacing: 8.0,
|
||||
children: [
|
||||
const Icon(Icons.add),
|
||||
Text(L10n.of(context).newCourse),
|
||||
],
|
||||
),
|
||||
),
|
||||
PopupMenuItem(
|
||||
onTap: () => context.go("/rooms/course/private"),
|
||||
child: Row(
|
||||
spacing: 8.0,
|
||||
children: [
|
||||
const Icon(Icons.join_full),
|
||||
Text(L10n.of(context).joinWithCode),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
);
|
||||
},
|
||||
),
|
||||
ValueListenableBuilder(
|
||||
valueListenable: controller.searchController,
|
||||
builder: (context, _, __) {
|
||||
if (controller.error != null) {
|
||||
return ErrorIndicator(
|
||||
message: L10n.of(context).oopsSomethingWentWrong,
|
||||
);
|
||||
}
|
||||
|
||||
if (controller.loading) {
|
||||
return const CircularProgressIndicator.adaptive();
|
||||
}
|
||||
|
||||
if (controller.filteredCourses.isEmpty) {
|
||||
return Text(
|
||||
L10n.of(context).nothingFound,
|
||||
);
|
||||
}
|
||||
|
||||
return Expanded(
|
||||
child: ListView.builder(
|
||||
itemCount: controller.filteredCourses.length,
|
||||
itemBuilder: (context, index) {
|
||||
final space = controller.filteredCourses[index];
|
||||
return _PublicCourseTile(
|
||||
chunk: space,
|
||||
course: controller.coursePlans[space.courseId],
|
||||
);
|
||||
},
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class _PublicCourseTile extends StatelessWidget {
|
||||
final PublicCoursesChunk chunk;
|
||||
final CoursePlanModel? course;
|
||||
|
||||
const _PublicCourseTile({
|
||||
required this.chunk,
|
||||
this.course,
|
||||
});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final theme = Theme.of(context);
|
||||
final isColumnMode = FluffyThemes.isColumnMode(context);
|
||||
final space = chunk.room;
|
||||
final courseId = chunk.courseId;
|
||||
final displayname =
|
||||
space.name ?? space.canonicalAlias ?? L10n.of(context).emptyChat;
|
||||
|
||||
return Padding(
|
||||
padding: isColumnMode
|
||||
? const EdgeInsets.only(
|
||||
bottom: 32.0,
|
||||
)
|
||||
: const EdgeInsets.only(
|
||||
bottom: 16.0,
|
||||
),
|
||||
child: Material(
|
||||
type: MaterialType.transparency,
|
||||
child: InkWell(
|
||||
onTap: () => context.go(
|
||||
'/rooms/course/public/$courseId',
|
||||
extra: space,
|
||||
),
|
||||
borderRadius: BorderRadius.circular(12.0),
|
||||
child: Container(
|
||||
padding: const EdgeInsets.all(12.0),
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: BorderRadius.circular(12.0),
|
||||
border: Border.all(
|
||||
color: theme.colorScheme.primary,
|
||||
),
|
||||
),
|
||||
child: Column(
|
||||
spacing: 4.0,
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Row(
|
||||
spacing: 8.0,
|
||||
children: [
|
||||
ImageByUrl(
|
||||
imageUrl: space.avatarUrl?.toString(),
|
||||
width: 58.0,
|
||||
borderRadius: BorderRadius.circular(10.0),
|
||||
replacement: Avatar(
|
||||
name: displayname,
|
||||
borderRadius: BorderRadius.circular(
|
||||
10.0,
|
||||
),
|
||||
size: 58.0,
|
||||
),
|
||||
),
|
||||
Flexible(
|
||||
child: Column(
|
||||
spacing: 0.0,
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
displayname,
|
||||
style: theme.textTheme.bodyLarge,
|
||||
maxLines: 2,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
),
|
||||
Row(
|
||||
spacing: 4.0,
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
const Icon(
|
||||
Icons.group,
|
||||
size: 16.0,
|
||||
),
|
||||
Text(
|
||||
L10n.of(context).countParticipants(
|
||||
space.numJoinedMembers,
|
||||
),
|
||||
style: theme.textTheme.bodyMedium,
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
if (course != null) ...[
|
||||
CourseInfoChips(
|
||||
courseId,
|
||||
iconSize: 12.0,
|
||||
fontSize: 12.0,
|
||||
),
|
||||
Text(
|
||||
course!.description,
|
||||
style: theme.textTheme.bodyMedium,
|
||||
),
|
||||
],
|
||||
const SizedBox(height: 12.0),
|
||||
HoverBuilder(
|
||||
builder: (context, hovered) => ElevatedButton(
|
||||
onPressed: () => context.go(
|
||||
'/rooms/course/public/$courseId',
|
||||
extra: space,
|
||||
),
|
||||
style: ElevatedButton.styleFrom(
|
||||
backgroundColor:
|
||||
theme.colorScheme.primaryContainer.withAlpha(
|
||||
hovered ? 255 : 200,
|
||||
),
|
||||
foregroundColor: theme.colorScheme.onPrimaryContainer,
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(
|
||||
12.0,
|
||||
),
|
||||
),
|
||||
),
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
Text(
|
||||
space.joinRule == JoinRules.knock.name
|
||||
? L10n.of(
|
||||
context,
|
||||
).knock
|
||||
: L10n.of(
|
||||
context,
|
||||
).join,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
@ -5,6 +5,7 @@ class SpaceConstants {
|
|||
static const String classCode = 'classcode';
|
||||
static const String introductionChatAlias = 'introductionChat';
|
||||
static const String announcementsChatAlias = 'announcementsChat';
|
||||
static String mapUnlockFileName = "unlock_trip.svg";
|
||||
|
||||
static List<String> introChatIcons = [
|
||||
'${AppConfig.assetsBaseURL}/Introduction_1.jpg',
|
||||
|
|
|
|||
|
|
@ -39,7 +39,7 @@ class UnderlineText extends StatelessWidget {
|
|||
),
|
||||
),
|
||||
Positioned(
|
||||
bottom: 2, // fixed distance from baseline
|
||||
bottom: 0,
|
||||
left: 0,
|
||||
right: 0,
|
||||
child: Container(
|
||||
|
|
|
|||
|
|
@ -202,7 +202,7 @@ class SpacesNavigationRail extends StatelessWidget {
|
|||
child: const Icon(Icons.add),
|
||||
),
|
||||
),
|
||||
toolTip: L10n.of(context).addCourse,
|
||||
toolTip: L10n.of(context).findCourse,
|
||||
expanded: expanded,
|
||||
// Pangea#
|
||||
);
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue