feat: bring back old course pages (#5328)
This commit is contained in:
parent
e8bf2645a6
commit
6675cebfec
61 changed files with 1502 additions and 145 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 09:36:57.998979",
|
||||
"about": "حول",
|
||||
"@about": {
|
||||
"type": "String",
|
||||
|
|
@ -11117,5 +11117,19 @@
|
|||
"@knockDesc": {
|
||||
"type": "String",
|
||||
"placeholders": {}
|
||||
},
|
||||
"joinSpaceOnboardingDesc": "هل لديك رمز دعوة أو رابط لدورة عامة؟",
|
||||
"welcomeUser": "مرحبًا {user}",
|
||||
"@joinSpaceOnboardingDesc": {
|
||||
"type": "String",
|
||||
"placeholders": {}
|
||||
},
|
||||
"@welcomeUser": {
|
||||
"type": "String",
|
||||
"placeholders": {
|
||||
"user": {
|
||||
"type": "String"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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 09:36:46.926563",
|
||||
"@alwaysUse24HourFormat": {
|
||||
"type": "String",
|
||||
"placeholders": {}
|
||||
|
|
@ -11999,5 +11999,19 @@
|
|||
"@knockDesc": {
|
||||
"type": "String",
|
||||
"placeholders": {}
|
||||
},
|
||||
"joinSpaceOnboardingDesc": "Ці маеце вы код запрашэння або спасылку на публічны курс?",
|
||||
"welcomeUser": "Сардэчна запрашаем, {user}",
|
||||
"@joinSpaceOnboardingDesc": {
|
||||
"type": "String",
|
||||
"placeholders": {}
|
||||
},
|
||||
"@welcomeUser": {
|
||||
"type": "String",
|
||||
"placeholders": {
|
||||
"user": {
|
||||
"type": "String"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
{
|
||||
"@@last_modified": "2026-01-21 13:54:31.328626",
|
||||
"@@last_modified": "2026-01-22 09:37:11.081120",
|
||||
"about": "সম্পর্কে",
|
||||
"@about": {
|
||||
"type": "String",
|
||||
|
|
@ -12004,5 +12004,19 @@
|
|||
"@knockDesc": {
|
||||
"type": "String",
|
||||
"placeholders": {}
|
||||
},
|
||||
"joinSpaceOnboardingDesc": "আপনার কি একটি আমন্ত্রণ কোড বা একটি পাবলিক কোর্সের লিঙ্ক আছে?",
|
||||
"welcomeUser": "স্বাগতম {user}",
|
||||
"@joinSpaceOnboardingDesc": {
|
||||
"type": "String",
|
||||
"placeholders": {}
|
||||
},
|
||||
"@welcomeUser": {
|
||||
"type": "String",
|
||||
"placeholders": {
|
||||
"user": {
|
||||
"type": "String"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -4279,7 +4279,7 @@
|
|||
"joinPublicTrip": "མི་ཚེས་ལ་ལོག་འབད།",
|
||||
"startOwnTrip": "ངེད་རང་གི་ལོག་ལ་སྦྱོར་བཅོས།",
|
||||
"@@locale": "bo",
|
||||
"@@last_modified": "2026-01-21 13:54:28.767499",
|
||||
"@@last_modified": "2026-01-22 09:37:08.423146",
|
||||
"@alwaysUse24HourFormat": {
|
||||
"type": "String",
|
||||
"placeholders": {}
|
||||
|
|
@ -10654,5 +10654,19 @@
|
|||
"@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"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
{
|
||||
"@@last_modified": "2026-01-21 13:54:08.647836",
|
||||
"@@last_modified": "2026-01-22 09:36:49.492725",
|
||||
"about": "Quant a",
|
||||
"@about": {
|
||||
"type": "String",
|
||||
|
|
@ -10924,5 +10924,19 @@
|
|||
"@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"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"@@locale": "cs",
|
||||
"@@last_modified": "2026-01-21 13:54:04.800051",
|
||||
"@@last_modified": "2026-01-22 09:36:43.351703",
|
||||
"about": "O aplikaci",
|
||||
"@about": {
|
||||
"type": "String",
|
||||
|
|
@ -11507,5 +11507,19 @@
|
|||
"@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"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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 09:36:14.204217",
|
||||
"@aboutHomeserver": {
|
||||
"type": "String",
|
||||
"placeholders": {
|
||||
|
|
@ -11961,5 +11961,19 @@
|
|||
"@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"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"@@locale": "de",
|
||||
"@@last_modified": "2026-01-21 13:53:56.595777",
|
||||
"@@last_modified": "2026-01-22 09:36:34.415651",
|
||||
"alwaysUse24HourFormat": "true",
|
||||
"@alwaysUse24HourFormat": {
|
||||
"description": "Set to true to always display time of day in 24 hour format."
|
||||
|
|
@ -10907,5 +10907,19 @@
|
|||
"@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"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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 09:37:17.865903",
|
||||
"@alwaysUse24HourFormat": {
|
||||
"type": "String",
|
||||
"placeholders": {}
|
||||
|
|
@ -11958,5 +11958,19 @@
|
|||
"@knockDesc": {
|
||||
"type": "String",
|
||||
"placeholders": {}
|
||||
},
|
||||
"joinSpaceOnboardingDesc": "Έχετε έναν κωδικό πρόσκλησης ή σύνδεσμο για ένα δημόσιο μάθημα;",
|
||||
"welcomeUser": "Καλώς ήρθατε {user}",
|
||||
"@joinSpaceOnboardingDesc": {
|
||||
"type": "String",
|
||||
"placeholders": {}
|
||||
},
|
||||
"@welcomeUser": {
|
||||
"type": "String",
|
||||
"placeholders": {
|
||||
"user": {
|
||||
"type": "String"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -5058,5 +5058,15 @@
|
|||
"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"
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
{
|
||||
"@@last_modified": "2026-01-21 13:54:42.193114",
|
||||
"@@last_modified": "2026-01-22 09:37:22.593342",
|
||||
"about": "Prio",
|
||||
"@about": {
|
||||
"type": "String",
|
||||
|
|
@ -11989,5 +11989,19 @@
|
|||
"@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"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"@@locale": "es",
|
||||
"@@last_modified": "2026-01-21 13:53:29.857658",
|
||||
"@@last_modified": "2026-01-22 09:36:09.573972",
|
||||
"about": "Acerca de",
|
||||
"@about": {
|
||||
"type": "String",
|
||||
|
|
@ -8134,5 +8134,19 @@
|
|||
"@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"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"@@locale": "et",
|
||||
"@@last_modified": "2026-01-21 13:53:55.586614",
|
||||
"@@last_modified": "2026-01-22 09:36:33.207413",
|
||||
"about": "Rakenduse teave",
|
||||
"@about": {
|
||||
"type": "String",
|
||||
|
|
@ -11171,5 +11171,19 @@
|
|||
"@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"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"@@locale": "eu",
|
||||
"@@last_modified": "2026-01-21 13:53:53.122879",
|
||||
"@@last_modified": "2026-01-22 09:36:30.783445",
|
||||
"about": "Honi buruz",
|
||||
"@about": {
|
||||
"type": "String",
|
||||
|
|
@ -10900,5 +10900,19 @@
|
|||
"@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"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
{
|
||||
"@@last_modified": "2026-01-21 13:54:33.096668",
|
||||
"@@last_modified": "2026-01-22 09:37:12.739208",
|
||||
"repeatPassword": "تکرار رمزعبور",
|
||||
"@repeatPassword": {},
|
||||
"about": "درباره",
|
||||
|
|
@ -11632,5 +11632,19 @@
|
|||
"@knockDesc": {
|
||||
"type": "String",
|
||||
"placeholders": {}
|
||||
},
|
||||
"joinSpaceOnboardingDesc": "آیا کد دعوت یا لینکی به یک دوره عمومی دارید؟",
|
||||
"welcomeUser": "خوش آمدید {user}",
|
||||
"@joinSpaceOnboardingDesc": {
|
||||
"type": "String",
|
||||
"placeholders": {}
|
||||
},
|
||||
"@welcomeUser": {
|
||||
"type": "String",
|
||||
"placeholders": {
|
||||
"user": {
|
||||
"type": "String"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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 09:36:12.968075",
|
||||
"@alwaysUse24HourFormat": {
|
||||
"type": "String",
|
||||
"placeholders": {}
|
||||
|
|
@ -11523,5 +11523,19 @@
|
|||
"@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"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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 09:36:55.313694",
|
||||
"@setCustomPermissionLevel": {
|
||||
"type": "String",
|
||||
"placeholders": {}
|
||||
|
|
@ -11876,5 +11876,19 @@
|
|||
"@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"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"@@locale": "fr",
|
||||
"@@last_modified": "2026-01-21 13:54:48.318824",
|
||||
"@@last_modified": "2026-01-22 09:37:30.149848",
|
||||
"about": "À propos",
|
||||
"@about": {
|
||||
"type": "String",
|
||||
|
|
@ -11224,5 +11224,19 @@
|
|||
"@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"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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 09:37:28.516173",
|
||||
"@customReaction": {
|
||||
"type": "String",
|
||||
"placeholders": {}
|
||||
|
|
@ -10898,5 +10898,19 @@
|
|||
"@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"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"@@locale": "gl",
|
||||
"@@last_modified": "2026-01-21 13:53:31.619299",
|
||||
"@@last_modified": "2026-01-22 09:36:11.502910",
|
||||
"about": "Acerca de",
|
||||
"@about": {
|
||||
"type": "String",
|
||||
|
|
@ -10897,5 +10897,19 @@
|
|||
"@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"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
{
|
||||
"@@last_modified": "2026-01-21 13:53:47.592162",
|
||||
"@@last_modified": "2026-01-22 09:36:25.705220",
|
||||
"about": "אודות",
|
||||
"@about": {
|
||||
"type": "String",
|
||||
|
|
@ -11949,5 +11949,19 @@
|
|||
"@knockDesc": {
|
||||
"type": "String",
|
||||
"placeholders": {}
|
||||
},
|
||||
"joinSpaceOnboardingDesc": "האם יש לך קוד הזמנה או קישור לקורס ציבורי?",
|
||||
"welcomeUser": "ברוך הבא {user}",
|
||||
"@joinSpaceOnboardingDesc": {
|
||||
"type": "String",
|
||||
"placeholders": {}
|
||||
},
|
||||
"@welcomeUser": {
|
||||
"type": "String",
|
||||
"placeholders": {
|
||||
"user": {
|
||||
"type": "String"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -4483,7 +4483,7 @@
|
|||
"playWithAI": "अभी के लिए एआई के साथ खेलें",
|
||||
"courseStartDesc": "पैंजिया बॉट कभी भी जाने के लिए तैयार है!\n\n...लेकिन दोस्तों के साथ सीखना बेहतर है!",
|
||||
"@@locale": "hi",
|
||||
"@@last_modified": "2026-01-21 13:54:40.850433",
|
||||
"@@last_modified": "2026-01-22 09:37:20.935542",
|
||||
"@alwaysUse24HourFormat": {
|
||||
"type": "String",
|
||||
"placeholders": {}
|
||||
|
|
@ -11985,5 +11985,19 @@
|
|||
"@knockDesc": {
|
||||
"type": "String",
|
||||
"placeholders": {}
|
||||
},
|
||||
"joinSpaceOnboardingDesc": "क्या आपके पास एक आमंत्रण कोड या सार्वजनिक पाठ्यक्रम के लिए लिंक है?",
|
||||
"welcomeUser": "स्वागत है {user}",
|
||||
"@joinSpaceOnboardingDesc": {
|
||||
"type": "String",
|
||||
"placeholders": {}
|
||||
},
|
||||
"@welcomeUser": {
|
||||
"type": "String",
|
||||
"placeholders": {
|
||||
"user": {
|
||||
"type": "String"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"@@locale": "hr",
|
||||
"@@last_modified": "2026-01-21 13:53:46.524141",
|
||||
"@@last_modified": "2026-01-22 09:36:23.684413",
|
||||
"about": "Informacije",
|
||||
"@about": {
|
||||
"type": "String",
|
||||
|
|
@ -11272,5 +11272,19 @@
|
|||
"@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"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"@@locale": "hu",
|
||||
"@@last_modified": "2026-01-21 13:53:36.742109",
|
||||
"@@last_modified": "2026-01-22 09:36:15.788819",
|
||||
"about": "Névjegy",
|
||||
"@about": {
|
||||
"type": "String",
|
||||
|
|
@ -10901,5 +10901,19 @@
|
|||
"@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"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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 09:36:27.975426",
|
||||
"@alwaysUse24HourFormat": {
|
||||
"type": "String",
|
||||
"placeholders": {}
|
||||
|
|
@ -11978,5 +11978,19 @@
|
|||
"@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"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
{
|
||||
"@@last_modified": "2026-01-21 13:53:37.899898",
|
||||
"@@last_modified": "2026-01-22 09:36:18.048263",
|
||||
"setAsCanonicalAlias": "Atur sebagai alias utama",
|
||||
"@setAsCanonicalAlias": {
|
||||
"type": "String",
|
||||
|
|
@ -10891,5 +10891,19 @@
|
|||
"@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"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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 09:36:22.149976",
|
||||
"@alwaysUse24HourFormat": {
|
||||
"type": "String",
|
||||
"placeholders": {}
|
||||
|
|
@ -11874,5 +11874,19 @@
|
|||
"@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"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
{
|
||||
"@@last_modified": "2026-01-21 13:54:01.568848",
|
||||
"@@last_modified": "2026-01-22 09:36:40.074415",
|
||||
"about": "Informazioni",
|
||||
"@about": {
|
||||
"type": "String",
|
||||
|
|
@ -10903,5 +10903,19 @@
|
|||
"@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"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"@@locale": "ja",
|
||||
"@@last_modified": "2026-01-21 13:54:39.359536",
|
||||
"@@last_modified": "2026-01-22 09:37:19.372006",
|
||||
"about": "このアプリについて",
|
||||
"@about": {
|
||||
"type": "String",
|
||||
|
|
@ -11690,5 +11690,19 @@
|
|||
"@knockDesc": {
|
||||
"type": "String",
|
||||
"placeholders": {}
|
||||
},
|
||||
"joinSpaceOnboardingDesc": "招待コードまたは公開コースへのリンクはありますか?",
|
||||
"welcomeUser": "ようこそ {user} さん",
|
||||
"@joinSpaceOnboardingDesc": {
|
||||
"type": "String",
|
||||
"placeholders": {}
|
||||
},
|
||||
"@welcomeUser": {
|
||||
"type": "String",
|
||||
"placeholders": {
|
||||
"user": {
|
||||
"type": "String"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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 09:37:25.958869",
|
||||
"@alwaysUse24HourFormat": {
|
||||
"type": "String",
|
||||
"placeholders": {}
|
||||
|
|
@ -11930,5 +11930,19 @@
|
|||
"@knockDesc": {
|
||||
"type": "String",
|
||||
"placeholders": {}
|
||||
},
|
||||
"joinSpaceOnboardingDesc": "გაქვთ თუ არა მოწვევის კოდი ან ბმული საჯარო კურსზე?",
|
||||
"welcomeUser": "კეთილი იყოს თქვენი მობრძანება {user}",
|
||||
"@joinSpaceOnboardingDesc": {
|
||||
"type": "String",
|
||||
"placeholders": {}
|
||||
},
|
||||
"@welcomeUser": {
|
||||
"type": "String",
|
||||
"placeholders": {
|
||||
"user": {
|
||||
"type": "String"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
{
|
||||
"@@last_modified": "2026-01-21 13:53:28.417406",
|
||||
"@@last_modified": "2026-01-22 09:36:07.420159",
|
||||
"about": "소개",
|
||||
"@about": {
|
||||
"type": "String",
|
||||
|
|
@ -11008,5 +11008,19 @@
|
|||
"@knockDesc": {
|
||||
"type": "String",
|
||||
"placeholders": {}
|
||||
},
|
||||
"joinSpaceOnboardingDesc": "공개 과정에 대한 초대 코드나 링크가 있습니까?",
|
||||
"welcomeUser": "환영합니다 {user}",
|
||||
"@joinSpaceOnboardingDesc": {
|
||||
"type": "String",
|
||||
"placeholders": {}
|
||||
},
|
||||
"@welcomeUser": {
|
||||
"type": "String",
|
||||
"placeholders": {
|
||||
"user": {
|
||||
"type": "String"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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 09:37:02.748391",
|
||||
"@alwaysUse24HourFormat": {
|
||||
"type": "String",
|
||||
"placeholders": {}
|
||||
|
|
@ -11705,5 +11705,19 @@
|
|||
"@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"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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 09:36:56.779342",
|
||||
"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,19 @@
|
|||
"@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"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
{
|
||||
"@@last_modified": "2026-01-21 13:54:06.232198",
|
||||
"@@last_modified": "2026-01-22 09:36:44.562587",
|
||||
"about": "Om",
|
||||
"@about": {
|
||||
"type": "String",
|
||||
|
|
@ -11993,5 +11993,19 @@
|
|||
"@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"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
{
|
||||
"@@last_modified": "2026-01-21 13:54:27.649909",
|
||||
"@@last_modified": "2026-01-22 09:37:07.354119",
|
||||
"about": "Over ons",
|
||||
"@about": {
|
||||
"type": "String",
|
||||
|
|
@ -10900,5 +10900,19 @@
|
|||
"@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"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"@@locale": "pl",
|
||||
"@@last_modified": "2026-01-21 13:54:34.451816",
|
||||
"@@last_modified": "2026-01-22 09:37:14.175391",
|
||||
"about": "O aplikacji",
|
||||
"@about": {
|
||||
"type": "String",
|
||||
|
|
@ -10898,5 +10898,19 @@
|
|||
"@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"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
{
|
||||
"@@last_modified": "2026-01-21 13:53:54.148542",
|
||||
"@@last_modified": "2026-01-22 09:36:31.935958",
|
||||
"copiedToClipboard": "Copiada para a área de transferência",
|
||||
"@copiedToClipboard": {
|
||||
"type": "String",
|
||||
|
|
@ -12000,5 +12000,19 @@
|
|||
"@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"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
{
|
||||
"@@last_modified": "2026-01-21 13:53:51.587209",
|
||||
"@@last_modified": "2026-01-22 09:36:29.216087",
|
||||
"about": "Sobre",
|
||||
"@about": {
|
||||
"type": "String",
|
||||
|
|
@ -11258,5 +11258,19 @@
|
|||
"@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"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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 09:36:52.464279",
|
||||
"@alwaysUse24HourFormat": {
|
||||
"type": "String",
|
||||
"placeholders": {}
|
||||
|
|
@ -11929,5 +11929,19 @@
|
|||
"@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"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
{
|
||||
"@@last_modified": "2026-01-21 13:53:41.456181",
|
||||
"@@last_modified": "2026-01-22 09:36:19.487915",
|
||||
"about": "Despre",
|
||||
"@about": {
|
||||
"type": "String",
|
||||
|
|
@ -11635,5 +11635,19 @@
|
|||
"@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"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"@@locale": "ru",
|
||||
"@@last_modified": "2026-01-21 15:35:33.881278",
|
||||
"@@last_modified": "2026-01-22 09:37:24.211755",
|
||||
"about": "О проекте",
|
||||
"@about": {
|
||||
"type": "String",
|
||||
|
|
@ -11008,5 +11008,19 @@
|
|||
"@italicText": {
|
||||
"type": "String",
|
||||
"placeholders": {}
|
||||
},
|
||||
"joinSpaceOnboardingDesc": "У вас есть код приглашения или ссылка на публичный курс?",
|
||||
"welcomeUser": "Добро пожаловать {user}",
|
||||
"@joinSpaceOnboardingDesc": {
|
||||
"type": "String",
|
||||
"placeholders": {}
|
||||
},
|
||||
"@welcomeUser": {
|
||||
"type": "String",
|
||||
"placeholders": {
|
||||
"user": {
|
||||
"type": "String"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"@@locale": "sk",
|
||||
"@@last_modified": "2026-01-21 13:53:43.706457",
|
||||
"@@last_modified": "2026-01-22 09:36:21.123706",
|
||||
"about": "O aplikácii",
|
||||
"@about": {
|
||||
"type": "String",
|
||||
|
|
@ -11984,5 +11984,19 @@
|
|||
"@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"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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 09:36:36.017757",
|
||||
"@alwaysUse24HourFormat": {
|
||||
"type": "String",
|
||||
"placeholders": {}
|
||||
|
|
@ -11981,5 +11981,19 @@
|
|||
"@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"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
{
|
||||
"@@last_modified": "2026-01-21 13:54:45.561732",
|
||||
"@@last_modified": "2026-01-22 09:37:27.068492",
|
||||
"about": "О програму",
|
||||
"@about": {
|
||||
"type": "String",
|
||||
|
|
@ -12002,5 +12002,19 @@
|
|||
"@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"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
{
|
||||
"@@last_modified": "2026-01-21 13:54:35.931933",
|
||||
"@@last_modified": "2026-01-22 09:37:16.018226",
|
||||
"about": "Om",
|
||||
"@about": {
|
||||
"type": "String",
|
||||
|
|
@ -11378,5 +11378,19 @@
|
|||
"@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"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
{
|
||||
"@@last_modified": "2026-01-21 13:54:25.999605",
|
||||
"@@last_modified": "2026-01-22 09:37:06.101200",
|
||||
"acceptedTheInvitation": "👍 {username} அழைப்பை ஏற்றுக்கொண்டது",
|
||||
"@acceptedTheInvitation": {
|
||||
"type": "String",
|
||||
|
|
@ -11124,5 +11124,19 @@
|
|||
"@knockDesc": {
|
||||
"type": "String",
|
||||
"placeholders": {}
|
||||
},
|
||||
"joinSpaceOnboardingDesc": "உங்களுக்கு ஒரு அழைப்பு குறியீடு அல்லது பொது பாடத்திற்கு இணைப்பு உள்ளதா?",
|
||||
"welcomeUser": "வரவேற்கிறேன் {user}",
|
||||
"@joinSpaceOnboardingDesc": {
|
||||
"type": "String",
|
||||
"placeholders": {}
|
||||
},
|
||||
"@welcomeUser": {
|
||||
"type": "String",
|
||||
"placeholders": {
|
||||
"user": {
|
||||
"type": "String"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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 09:37:01.069487",
|
||||
"@setCustomPermissionLevel": {
|
||||
"type": "String",
|
||||
"placeholders": {}
|
||||
|
|
@ -11989,5 +11989,19 @@
|
|||
"@knockDesc": {
|
||||
"type": "String",
|
||||
"placeholders": {}
|
||||
},
|
||||
"joinSpaceOnboardingDesc": "మీకు పబ్లిక్ కోర్సుకు ఆహ్వాన కోడ్ లేదా లింక్ ఉందా?",
|
||||
"welcomeUser": "స్వాగతం {user}",
|
||||
"@joinSpaceOnboardingDesc": {
|
||||
"type": "String",
|
||||
"placeholders": {}
|
||||
},
|
||||
"@welcomeUser": {
|
||||
"type": "String",
|
||||
"placeholders": {
|
||||
"user": {
|
||||
"type": "String"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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 09:36:51.239616",
|
||||
"@alwaysUse24HourFormat": {
|
||||
"type": "String",
|
||||
"placeholders": {}
|
||||
|
|
@ -11958,5 +11958,19 @@
|
|||
"@knockDesc": {
|
||||
"type": "String",
|
||||
"placeholders": {}
|
||||
},
|
||||
"joinSpaceOnboardingDesc": "คุณมีรหัสเชิญหรือลิงก์ไปยังหลักสูตรสาธารณะหรือไม่?",
|
||||
"welcomeUser": "ยินดีต้อนรับ {user}",
|
||||
"@joinSpaceOnboardingDesc": {
|
||||
"type": "String",
|
||||
"placeholders": {}
|
||||
},
|
||||
"@welcomeUser": {
|
||||
"type": "String",
|
||||
"placeholders": {
|
||||
"user": {
|
||||
"type": "String"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"@@locale": "tr",
|
||||
"@@last_modified": "2026-01-21 13:54:19.467039",
|
||||
"@@last_modified": "2026-01-22 09:36:59.414494",
|
||||
"about": "Hakkında",
|
||||
"@about": {
|
||||
"type": "String",
|
||||
|
|
@ -11122,5 +11122,19 @@
|
|||
"@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"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"@@locale": "uk",
|
||||
"@@last_modified": "2026-01-21 13:54:03.403456",
|
||||
"@@last_modified": "2026-01-22 09:36:41.798719",
|
||||
"about": "Про застосунок",
|
||||
"@about": {
|
||||
"type": "String",
|
||||
|
|
@ -10894,5 +10894,19 @@
|
|||
"@knockDesc": {
|
||||
"type": "String",
|
||||
"placeholders": {}
|
||||
},
|
||||
"joinSpaceOnboardingDesc": "У вас є код запрошення або посилання на публічний курс?",
|
||||
"welcomeUser": "Ласкаво просимо {user}",
|
||||
"@joinSpaceOnboardingDesc": {
|
||||
"type": "String",
|
||||
"placeholders": {}
|
||||
},
|
||||
"@welcomeUser": {
|
||||
"type": "String",
|
||||
"placeholders": {
|
||||
"user": {
|
||||
"type": "String"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
{
|
||||
"@@last_modified": "2026-01-21 13:54:24.252269",
|
||||
"@@last_modified": "2026-01-22 09:37:04.643688",
|
||||
"about": "Giới thiệu",
|
||||
"@about": {
|
||||
"type": "String",
|
||||
|
|
@ -6470,5 +6470,19 @@
|
|||
"@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"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1856,7 +1856,7 @@
|
|||
"selectAll": "全選",
|
||||
"deselectAll": "取消全選",
|
||||
"@@locale": "yue",
|
||||
"@@last_modified": "2026-01-21 13:53:59.885092",
|
||||
"@@last_modified": "2026-01-22 09:36:38.546245",
|
||||
"@ignoreUser": {
|
||||
"type": "String",
|
||||
"placeholders": {}
|
||||
|
|
@ -11991,5 +11991,19 @@
|
|||
"@knockDesc": {
|
||||
"type": "String",
|
||||
"placeholders": {}
|
||||
},
|
||||
"joinSpaceOnboardingDesc": "你有邀請碼或公共課程的鏈接嗎?",
|
||||
"welcomeUser": "歡迎 {user}",
|
||||
"@joinSpaceOnboardingDesc": {
|
||||
"type": "String",
|
||||
"placeholders": {}
|
||||
},
|
||||
"@welcomeUser": {
|
||||
"type": "String",
|
||||
"placeholders": {
|
||||
"user": {
|
||||
"type": "String"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"@@locale": "zh",
|
||||
"@@last_modified": "2026-01-21 13:54:29.681537",
|
||||
"@@last_modified": "2026-01-22 09:37:09.563669",
|
||||
"about": "关于",
|
||||
"@about": {
|
||||
"type": "String",
|
||||
|
|
@ -10891,5 +10891,19 @@
|
|||
"@knockDesc": {
|
||||
"type": "String",
|
||||
"placeholders": {}
|
||||
},
|
||||
"joinSpaceOnboardingDesc": "您是否有邀请代码或公共课程的链接?",
|
||||
"welcomeUser": "欢迎 {user}",
|
||||
"@joinSpaceOnboardingDesc": {
|
||||
"type": "String",
|
||||
"placeholders": {}
|
||||
},
|
||||
"@welcomeUser": {
|
||||
"type": "String",
|
||||
"placeholders": {
|
||||
"user": {
|
||||
"type": "String"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
{
|
||||
"@@last_modified": "2026-01-21 13:54:13.165623",
|
||||
"@@last_modified": "2026-01-22 09:36:53.893925",
|
||||
"about": "關於",
|
||||
"@about": {
|
||||
"type": "String",
|
||||
|
|
@ -10898,5 +10898,19 @@
|
|||
"@knockDesc": {
|
||||
"type": "String",
|
||||
"placeholders": {}
|
||||
},
|
||||
"joinSpaceOnboardingDesc": "您是否有邀請碼或公共課程的鏈接?",
|
||||
"welcomeUser": "歡迎 {user}",
|
||||
"@joinSpaceOnboardingDesc": {
|
||||
"type": "String",
|
||||
"placeholders": {}
|
||||
},
|
||||
"@welcomeUser": {
|
||||
"type": "String",
|
||||
"placeholders": {
|
||||
"user": {
|
||||
"type": "String"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
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"),
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
@ -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',
|
||||
|
|
|
|||
|
|
@ -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