5259 bot settings language settings (#5305)
* feat: add voice to user model * update bot settings on language / learning settings update * use room summary to determine member count * translations
This commit is contained in:
parent
8a2f4747c9
commit
529f12e028
71 changed files with 625 additions and 618 deletions
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"@@locale": "ar",
|
||||
"@@last_modified": "2026-01-20 12:31:24.671375",
|
||||
"@@last_modified": "2026-01-21 10:42:52.513008",
|
||||
"about": "حول",
|
||||
"@about": {
|
||||
"type": "String",
|
||||
|
|
@ -11107,5 +11107,10 @@
|
|||
"@languageUpdated": {
|
||||
"type": "String",
|
||||
"placeholders": {}
|
||||
},
|
||||
"voiceDropdownTitle": "صوت بوت بانجيا",
|
||||
"@voiceDropdownTitle": {
|
||||
"type": "String",
|
||||
"placeholders": {}
|
||||
}
|
||||
}
|
||||
|
|
@ -1911,7 +1911,7 @@
|
|||
"playWithAI": "Пакуль гуляйце з ШІ",
|
||||
"courseStartDesc": "Pangea Bot гатовы да працы ў любы час!\n\n...але навучанне лепш з сябрамі!",
|
||||
"@@locale": "be",
|
||||
"@@last_modified": "2026-01-20 12:31:06.570011",
|
||||
"@@last_modified": "2026-01-21 10:42:45.087111",
|
||||
"@alwaysUse24HourFormat": {
|
||||
"type": "String",
|
||||
"placeholders": {}
|
||||
|
|
@ -11989,5 +11989,10 @@
|
|||
"@languageUpdated": {
|
||||
"type": "String",
|
||||
"placeholders": {}
|
||||
},
|
||||
"voiceDropdownTitle": "Голас Pangea Bot",
|
||||
"@voiceDropdownTitle": {
|
||||
"type": "String",
|
||||
"placeholders": {}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
{
|
||||
"@@last_modified": "2026-01-20 12:31:49.464406",
|
||||
"@@last_modified": "2026-01-21 10:43:01.204800",
|
||||
"about": "সম্পর্কে",
|
||||
"@about": {
|
||||
"type": "String",
|
||||
|
|
@ -11994,5 +11994,10 @@
|
|||
"@languageUpdated": {
|
||||
"type": "String",
|
||||
"placeholders": {}
|
||||
},
|
||||
"voiceDropdownTitle": "প্যাঙ্গিয়া বটের কণ্ঠ",
|
||||
"@voiceDropdownTitle": {
|
||||
"type": "String",
|
||||
"placeholders": {}
|
||||
}
|
||||
}
|
||||
|
|
@ -4279,7 +4279,7 @@
|
|||
"joinPublicTrip": "མི་ཚེས་ལ་ལོག་འབད།",
|
||||
"startOwnTrip": "ངེད་རང་གི་ལོག་ལ་སྦྱོར་བཅོས།",
|
||||
"@@locale": "bo",
|
||||
"@@last_modified": "2026-01-20 12:31:44.969872",
|
||||
"@@last_modified": "2026-01-21 10:42:59.058441",
|
||||
"@alwaysUse24HourFormat": {
|
||||
"type": "String",
|
||||
"placeholders": {}
|
||||
|
|
@ -10644,5 +10644,10 @@
|
|||
"@languageUpdated": {
|
||||
"type": "String",
|
||||
"placeholders": {}
|
||||
},
|
||||
"voiceDropdownTitle": "Pangea Bot voz",
|
||||
"@voiceDropdownTitle": {
|
||||
"type": "String",
|
||||
"placeholders": {}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
{
|
||||
"@@last_modified": "2026-01-20 12:31:09.126351",
|
||||
"@@last_modified": "2026-01-21 10:42:46.152113",
|
||||
"about": "Quant a",
|
||||
"@about": {
|
||||
"type": "String",
|
||||
|
|
@ -10914,5 +10914,10 @@
|
|||
"@languageUpdated": {
|
||||
"type": "String",
|
||||
"placeholders": {}
|
||||
},
|
||||
"voiceDropdownTitle": "Veu del bot Pangea",
|
||||
"@voiceDropdownTitle": {
|
||||
"type": "String",
|
||||
"placeholders": {}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"@@locale": "cs",
|
||||
"@@last_modified": "2026-01-20 12:31:00.323945",
|
||||
"@@last_modified": "2026-01-21 10:42:42.984636",
|
||||
"about": "O aplikaci",
|
||||
"@about": {
|
||||
"type": "String",
|
||||
|
|
@ -11497,5 +11497,10 @@
|
|||
"@languageUpdated": {
|
||||
"type": "String",
|
||||
"placeholders": {}
|
||||
},
|
||||
"voiceDropdownTitle": "Hlas Pangea Bota",
|
||||
"@voiceDropdownTitle": {
|
||||
"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-20 12:30:10.761209",
|
||||
"@@last_modified": "2026-01-21 10:42:22.819549",
|
||||
"@aboutHomeserver": {
|
||||
"type": "String",
|
||||
"placeholders": {
|
||||
|
|
@ -11951,5 +11951,10 @@
|
|||
"@languageUpdated": {
|
||||
"type": "String",
|
||||
"placeholders": {}
|
||||
},
|
||||
"voiceDropdownTitle": "Pangea Bot stemme",
|
||||
"@voiceDropdownTitle": {
|
||||
"type": "String",
|
||||
"placeholders": {}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"@@locale": "de",
|
||||
"@@last_modified": "2026-01-20 12:30:47.434524",
|
||||
"@@last_modified": "2026-01-21 10:42:37.466783",
|
||||
"alwaysUse24HourFormat": "true",
|
||||
"@alwaysUse24HourFormat": {
|
||||
"description": "Set to true to always display time of day in 24 hour format."
|
||||
|
|
@ -10897,5 +10897,10 @@
|
|||
"@languageUpdated": {
|
||||
"type": "String",
|
||||
"placeholders": {}
|
||||
},
|
||||
"voiceDropdownTitle": "Pangea Bot Stimme",
|
||||
"@voiceDropdownTitle": {
|
||||
"type": "String",
|
||||
"placeholders": {}
|
||||
}
|
||||
}
|
||||
|
|
@ -4456,7 +4456,7 @@
|
|||
"playWithAI": "Παίξτε με την Τεχνητή Νοημοσύνη προς το παρόν",
|
||||
"courseStartDesc": "Ο Pangea Bot είναι έτοιμος να ξεκινήσει οποιαδήποτε στιγμή!\n\n...αλλά η μάθηση είναι καλύτερη με φίλους!",
|
||||
"@@locale": "el",
|
||||
"@@last_modified": "2026-01-20 12:31:59.503296",
|
||||
"@@last_modified": "2026-01-21 10:43:05.204211",
|
||||
"@alwaysUse24HourFormat": {
|
||||
"type": "String",
|
||||
"placeholders": {}
|
||||
|
|
@ -11948,5 +11948,10 @@
|
|||
"@languageUpdated": {
|
||||
"type": "String",
|
||||
"placeholders": {}
|
||||
},
|
||||
"voiceDropdownTitle": "Φωνή Pangea Bot",
|
||||
"@voiceDropdownTitle": {
|
||||
"type": "String",
|
||||
"placeholders": {}
|
||||
}
|
||||
}
|
||||
|
|
@ -5056,5 +5056,6 @@
|
|||
"constructUseIncGEDesc": "Incorrect grammar error practice",
|
||||
"fillInBlank": "Fill in the blank with the correct choice",
|
||||
"learn": "Learn",
|
||||
"languageUpdated": "Target language updated!"
|
||||
"languageUpdated": "Target language updated!",
|
||||
"voiceDropdownTitle": "Pangea Bot voice"
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
{
|
||||
"@@last_modified": "2026-01-20 12:32:07.490560",
|
||||
"@@last_modified": "2026-01-21 10:43:08.060333",
|
||||
"about": "Prio",
|
||||
"@about": {
|
||||
"type": "String",
|
||||
|
|
@ -11979,5 +11979,10 @@
|
|||
"@languageUpdated": {
|
||||
"type": "String",
|
||||
"placeholders": {}
|
||||
},
|
||||
"voiceDropdownTitle": "Voĉo de Pangea Bot",
|
||||
"@voiceDropdownTitle": {
|
||||
"type": "String",
|
||||
"placeholders": {}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"@@locale": "es",
|
||||
"@@last_modified": "2026-01-20 12:29:59.898184",
|
||||
"@@last_modified": "2026-01-21 10:42:19.343875",
|
||||
"about": "Acerca de",
|
||||
"@about": {
|
||||
"type": "String",
|
||||
|
|
@ -8124,5 +8124,10 @@
|
|||
"@languageUpdated": {
|
||||
"type": "String",
|
||||
"placeholders": {}
|
||||
},
|
||||
"voiceDropdownTitle": "Voz del bot Pangea",
|
||||
"@voiceDropdownTitle": {
|
||||
"type": "String",
|
||||
"placeholders": {}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"@@locale": "et",
|
||||
"@@last_modified": "2026-01-20 12:30:45.162738",
|
||||
"@@last_modified": "2026-01-21 10:42:36.742735",
|
||||
"about": "Rakenduse teave",
|
||||
"@about": {
|
||||
"type": "String",
|
||||
|
|
@ -11161,5 +11161,10 @@
|
|||
"@languageUpdated": {
|
||||
"type": "String",
|
||||
"placeholders": {}
|
||||
},
|
||||
"voiceDropdownTitle": "Pangea Boti hääl",
|
||||
"@voiceDropdownTitle": {
|
||||
"type": "String",
|
||||
"placeholders": {}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"@@locale": "eu",
|
||||
"@@last_modified": "2026-01-20 12:30:40.144354",
|
||||
"@@last_modified": "2026-01-21 10:42:34.277635",
|
||||
"about": "Honi buruz",
|
||||
"@about": {
|
||||
"type": "String",
|
||||
|
|
@ -10890,5 +10890,10 @@
|
|||
"@languageUpdated": {
|
||||
"type": "String",
|
||||
"placeholders": {}
|
||||
},
|
||||
"voiceDropdownTitle": "Pangea Bot ahotsa",
|
||||
"@voiceDropdownTitle": {
|
||||
"type": "String",
|
||||
"placeholders": {}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
{
|
||||
"@@last_modified": "2026-01-20 12:31:52.231221",
|
||||
"@@last_modified": "2026-01-21 10:43:02.232868",
|
||||
"repeatPassword": "تکرار رمزعبور",
|
||||
"@repeatPassword": {},
|
||||
"about": "درباره",
|
||||
|
|
@ -11622,5 +11622,10 @@
|
|||
"@languageUpdated": {
|
||||
"type": "String",
|
||||
"placeholders": {}
|
||||
},
|
||||
"voiceDropdownTitle": "صدای ربات پانژیا",
|
||||
"@voiceDropdownTitle": {
|
||||
"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-20 12:30:08.099637",
|
||||
"@@last_modified": "2026-01-21 10:42:21.857816",
|
||||
"@alwaysUse24HourFormat": {
|
||||
"type": "String",
|
||||
"placeholders": {}
|
||||
|
|
@ -11513,5 +11513,10 @@
|
|||
"@languageUpdated": {
|
||||
"type": "String",
|
||||
"placeholders": {}
|
||||
},
|
||||
"voiceDropdownTitle": "Pangea Botin ääni",
|
||||
"@voiceDropdownTitle": {
|
||||
"type": "String",
|
||||
"placeholders": {}
|
||||
}
|
||||
}
|
||||
|
|
@ -2787,7 +2787,7 @@
|
|||
"selectAll": "Piliin lahat",
|
||||
"deselectAll": "Huwag piliin lahat",
|
||||
"@@locale": "fil",
|
||||
"@@last_modified": "2026-01-20 12:31:19.884620",
|
||||
"@@last_modified": "2026-01-21 10:42:50.349708",
|
||||
"@setCustomPermissionLevel": {
|
||||
"type": "String",
|
||||
"placeholders": {}
|
||||
|
|
@ -11866,5 +11866,10 @@
|
|||
"@languageUpdated": {
|
||||
"type": "String",
|
||||
"placeholders": {}
|
||||
},
|
||||
"voiceDropdownTitle": "Boses ng Pangea Bot",
|
||||
"@voiceDropdownTitle": {
|
||||
"type": "String",
|
||||
"placeholders": {}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"@@locale": "fr",
|
||||
"@@last_modified": "2026-01-20 12:32:20.398562",
|
||||
"@@last_modified": "2026-01-21 10:43:12.775361",
|
||||
"about": "À propos",
|
||||
"@about": {
|
||||
"type": "String",
|
||||
|
|
@ -11214,5 +11214,10 @@
|
|||
"@languageUpdated": {
|
||||
"type": "String",
|
||||
"placeholders": {}
|
||||
},
|
||||
"voiceDropdownTitle": "Voix du bot Pangea",
|
||||
"@voiceDropdownTitle": {
|
||||
"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-20 12:32:18.033824",
|
||||
"@@last_modified": "2026-01-21 10:43:11.760663",
|
||||
"@customReaction": {
|
||||
"type": "String",
|
||||
"placeholders": {}
|
||||
|
|
@ -10888,5 +10888,10 @@
|
|||
"@languageUpdated": {
|
||||
"type": "String",
|
||||
"placeholders": {}
|
||||
},
|
||||
"voiceDropdownTitle": "guth Pangea Bot",
|
||||
"@voiceDropdownTitle": {
|
||||
"type": "String",
|
||||
"placeholders": {}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"@@locale": "gl",
|
||||
"@@last_modified": "2026-01-20 12:30:05.234280",
|
||||
"@@last_modified": "2026-01-21 10:42:20.142432",
|
||||
"about": "Acerca de",
|
||||
"@about": {
|
||||
"type": "String",
|
||||
|
|
@ -10887,5 +10887,10 @@
|
|||
"@languageUpdated": {
|
||||
"type": "String",
|
||||
"placeholders": {}
|
||||
},
|
||||
"voiceDropdownTitle": "Voz do bot Pangea",
|
||||
"@voiceDropdownTitle": {
|
||||
"type": "String",
|
||||
"placeholders": {}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
{
|
||||
"@@last_modified": "2026-01-20 12:30:31.884050",
|
||||
"@@last_modified": "2026-01-21 10:42:30.598205",
|
||||
"about": "אודות",
|
||||
"@about": {
|
||||
"type": "String",
|
||||
|
|
@ -11939,5 +11939,10 @@
|
|||
"@languageUpdated": {
|
||||
"type": "String",
|
||||
"placeholders": {}
|
||||
},
|
||||
"voiceDropdownTitle": "קול של פנגיאה בוט",
|
||||
"@voiceDropdownTitle": {
|
||||
"type": "String",
|
||||
"placeholders": {}
|
||||
}
|
||||
}
|
||||
|
|
@ -4483,7 +4483,7 @@
|
|||
"playWithAI": "अभी के लिए एआई के साथ खेलें",
|
||||
"courseStartDesc": "पैंजिया बॉट कभी भी जाने के लिए तैयार है!\n\n...लेकिन दोस्तों के साथ सीखना बेहतर है!",
|
||||
"@@locale": "hi",
|
||||
"@@last_modified": "2026-01-20 12:32:05.240015",
|
||||
"@@last_modified": "2026-01-21 10:43:07.054066",
|
||||
"@alwaysUse24HourFormat": {
|
||||
"type": "String",
|
||||
"placeholders": {}
|
||||
|
|
@ -11975,5 +11975,10 @@
|
|||
"@languageUpdated": {
|
||||
"type": "String",
|
||||
"placeholders": {}
|
||||
},
|
||||
"voiceDropdownTitle": "पैंगिया बॉट की आवाज़",
|
||||
"@voiceDropdownTitle": {
|
||||
"type": "String",
|
||||
"placeholders": {}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"@@locale": "hr",
|
||||
"@@last_modified": "2026-01-20 12:30:29.823787",
|
||||
"@@last_modified": "2026-01-21 10:42:29.581714",
|
||||
"about": "Informacije",
|
||||
"@about": {
|
||||
"type": "String",
|
||||
|
|
@ -11262,5 +11262,10 @@
|
|||
"@languageUpdated": {
|
||||
"type": "String",
|
||||
"placeholders": {}
|
||||
},
|
||||
"voiceDropdownTitle": "Pangea Bot glas",
|
||||
"@voiceDropdownTitle": {
|
||||
"type": "String",
|
||||
"placeholders": {}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"@@locale": "hu",
|
||||
"@@last_modified": "2026-01-20 12:30:13.762355",
|
||||
"@@last_modified": "2026-01-21 10:42:24.298395",
|
||||
"about": "Névjegy",
|
||||
"@about": {
|
||||
"type": "String",
|
||||
|
|
@ -10891,5 +10891,10 @@
|
|||
"@languageUpdated": {
|
||||
"type": "String",
|
||||
"placeholders": {}
|
||||
},
|
||||
"voiceDropdownTitle": "Pangea Bot hang",
|
||||
"@voiceDropdownTitle": {
|
||||
"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-20 12:30:35.012898",
|
||||
"@@last_modified": "2026-01-21 10:42:31.403920",
|
||||
"@alwaysUse24HourFormat": {
|
||||
"type": "String",
|
||||
"placeholders": {}
|
||||
|
|
@ -11968,5 +11968,10 @@
|
|||
"@languageUpdated": {
|
||||
"type": "String",
|
||||
"placeholders": {}
|
||||
},
|
||||
"voiceDropdownTitle": "Voix du bot Pangea",
|
||||
"@voiceDropdownTitle": {
|
||||
"type": "String",
|
||||
"placeholders": {}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
{
|
||||
"@@last_modified": "2026-01-20 12:30:15.788809",
|
||||
"@@last_modified": "2026-01-21 10:42:25.871973",
|
||||
"setAsCanonicalAlias": "Atur sebagai alias utama",
|
||||
"@setAsCanonicalAlias": {
|
||||
"type": "String",
|
||||
|
|
@ -10881,5 +10881,10 @@
|
|||
"@languageUpdated": {
|
||||
"type": "String",
|
||||
"placeholders": {}
|
||||
},
|
||||
"voiceDropdownTitle": "Suara Pangea Bot",
|
||||
"@voiceDropdownTitle": {
|
||||
"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-20 12:30:26.700297",
|
||||
"@@last_modified": "2026-01-21 10:42:28.431424",
|
||||
"@alwaysUse24HourFormat": {
|
||||
"type": "String",
|
||||
"placeholders": {}
|
||||
|
|
@ -11864,5 +11864,10 @@
|
|||
"@languageUpdated": {
|
||||
"type": "String",
|
||||
"placeholders": {}
|
||||
},
|
||||
"voiceDropdownTitle": "Pangea Bot guth",
|
||||
"@voiceDropdownTitle": {
|
||||
"type": "String",
|
||||
"placeholders": {}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
{
|
||||
"@@last_modified": "2026-01-20 12:30:55.791406",
|
||||
"@@last_modified": "2026-01-21 10:42:40.690823",
|
||||
"about": "Informazioni",
|
||||
"@about": {
|
||||
"type": "String",
|
||||
|
|
@ -10893,5 +10893,10 @@
|
|||
"@languageUpdated": {
|
||||
"type": "String",
|
||||
"placeholders": {}
|
||||
},
|
||||
"voiceDropdownTitle": "Voce del bot Pangea",
|
||||
"@voiceDropdownTitle": {
|
||||
"type": "String",
|
||||
"placeholders": {}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"@@locale": "ja",
|
||||
"@@last_modified": "2026-01-20 12:32:02.883097",
|
||||
"@@last_modified": "2026-01-21 10:43:06.128364",
|
||||
"about": "このアプリについて",
|
||||
"@about": {
|
||||
"type": "String",
|
||||
|
|
@ -11680,5 +11680,10 @@
|
|||
"@languageUpdated": {
|
||||
"type": "String",
|
||||
"placeholders": {}
|
||||
},
|
||||
"voiceDropdownTitle": "パンゲアボットの声",
|
||||
"@voiceDropdownTitle": {
|
||||
"type": "String",
|
||||
"placeholders": {}
|
||||
}
|
||||
}
|
||||
|
|
@ -2594,7 +2594,7 @@
|
|||
"playWithAI": "ამ დროისთვის ითამაშეთ AI-თან",
|
||||
"courseStartDesc": "Pangea Bot მზადაა ნებისმიერ დროს გასასვლელად!\n\n...მაგრამ სწავლა უკეთესია მეგობრებთან ერთად!",
|
||||
"@@locale": "ka",
|
||||
"@@last_modified": "2026-01-20 12:32:12.611848",
|
||||
"@@last_modified": "2026-01-21 10:43:09.701292",
|
||||
"@alwaysUse24HourFormat": {
|
||||
"type": "String",
|
||||
"placeholders": {}
|
||||
|
|
@ -11920,5 +11920,10 @@
|
|||
"@languageUpdated": {
|
||||
"type": "String",
|
||||
"placeholders": {}
|
||||
},
|
||||
"voiceDropdownTitle": "პანჯეა ბოტის ხმა",
|
||||
"@voiceDropdownTitle": {
|
||||
"type": "String",
|
||||
"placeholders": {}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
{
|
||||
"@@last_modified": "2026-01-20 12:29:56.840054",
|
||||
"@@last_modified": "2026-01-21 10:42:17.603097",
|
||||
"about": "소개",
|
||||
"@about": {
|
||||
"type": "String",
|
||||
|
|
@ -10998,5 +10998,10 @@
|
|||
"@languageUpdated": {
|
||||
"type": "String",
|
||||
"placeholders": {}
|
||||
},
|
||||
"voiceDropdownTitle": "판게아 봇 음성",
|
||||
"@voiceDropdownTitle": {
|
||||
"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-20 12:31:36.164653",
|
||||
"@@last_modified": "2026-01-21 10:42:55.447627",
|
||||
"@alwaysUse24HourFormat": {
|
||||
"type": "String",
|
||||
"placeholders": {}
|
||||
|
|
@ -11695,5 +11695,10 @@
|
|||
"@languageUpdated": {
|
||||
"type": "String",
|
||||
"placeholders": {}
|
||||
},
|
||||
"voiceDropdownTitle": "Pangea Bot balsas",
|
||||
"@voiceDropdownTitle": {
|
||||
"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-20 12:31:22.453166",
|
||||
"@@last_modified": "2026-01-21 10:42:51.147364",
|
||||
"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",
|
||||
|
|
@ -10876,5 +10876,10 @@
|
|||
"@languageUpdated": {
|
||||
"type": "String",
|
||||
"placeholders": {}
|
||||
},
|
||||
"voiceDropdownTitle": "Pangea Bot balss",
|
||||
"@voiceDropdownTitle": {
|
||||
"type": "String",
|
||||
"placeholders": {}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
{
|
||||
"@@last_modified": "2026-01-20 12:31:02.821968",
|
||||
"@@last_modified": "2026-01-21 10:42:43.891386",
|
||||
"about": "Om",
|
||||
"@about": {
|
||||
"type": "String",
|
||||
|
|
@ -11983,5 +11983,10 @@
|
|||
"@languageUpdated": {
|
||||
"type": "String",
|
||||
"placeholders": {}
|
||||
},
|
||||
"voiceDropdownTitle": "Pangea Bot-stemme",
|
||||
"@voiceDropdownTitle": {
|
||||
"type": "String",
|
||||
"placeholders": {}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
{
|
||||
"@@last_modified": "2026-01-20 12:31:42.507524",
|
||||
"@@last_modified": "2026-01-21 10:42:58.326124",
|
||||
"about": "Over ons",
|
||||
"@about": {
|
||||
"type": "String",
|
||||
|
|
@ -10890,5 +10890,10 @@
|
|||
"@languageUpdated": {
|
||||
"type": "String",
|
||||
"placeholders": {}
|
||||
},
|
||||
"voiceDropdownTitle": "Pangea Bot stem",
|
||||
"@voiceDropdownTitle": {
|
||||
"type": "String",
|
||||
"placeholders": {}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"@@locale": "pl",
|
||||
"@@last_modified": "2026-01-20 12:31:54.796841",
|
||||
"@@last_modified": "2026-01-21 10:43:03.257336",
|
||||
"about": "O aplikacji",
|
||||
"@about": {
|
||||
"type": "String",
|
||||
|
|
@ -10888,5 +10888,10 @@
|
|||
"@languageUpdated": {
|
||||
"type": "String",
|
||||
"placeholders": {}
|
||||
},
|
||||
"voiceDropdownTitle": "Głos bota Pangea",
|
||||
"@voiceDropdownTitle": {
|
||||
"type": "String",
|
||||
"placeholders": {}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
{
|
||||
"@@last_modified": "2026-01-20 12:30:42.601068",
|
||||
"@@last_modified": "2026-01-21 10:42:35.392050",
|
||||
"copiedToClipboard": "Copiada para a área de transferência",
|
||||
"@copiedToClipboard": {
|
||||
"type": "String",
|
||||
|
|
@ -11990,5 +11990,10 @@
|
|||
"@languageUpdated": {
|
||||
"type": "String",
|
||||
"placeholders": {}
|
||||
},
|
||||
"voiceDropdownTitle": "Voz do Bot Pangea",
|
||||
"@voiceDropdownTitle": {
|
||||
"type": "String",
|
||||
"placeholders": {}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
{
|
||||
"@@last_modified": "2026-01-20 12:30:37.380939",
|
||||
"@@last_modified": "2026-01-21 10:42:32.545549",
|
||||
"about": "Sobre",
|
||||
"@about": {
|
||||
"type": "String",
|
||||
|
|
@ -11248,5 +11248,10 @@
|
|||
"@languageUpdated": {
|
||||
"type": "String",
|
||||
"placeholders": {}
|
||||
},
|
||||
"voiceDropdownTitle": "Voz do Bot Pangea",
|
||||
"@voiceDropdownTitle": {
|
||||
"type": "String",
|
||||
"placeholders": {}
|
||||
}
|
||||
}
|
||||
|
|
@ -3331,7 +3331,7 @@
|
|||
"selectAll": "Selecionar tudo",
|
||||
"deselectAll": "Desmarcar tudo",
|
||||
"@@locale": "pt_PT",
|
||||
"@@last_modified": "2026-01-20 12:31:13.609297",
|
||||
"@@last_modified": "2026-01-21 10:42:48.198355",
|
||||
"@alwaysUse24HourFormat": {
|
||||
"type": "String",
|
||||
"placeholders": {}
|
||||
|
|
@ -11919,5 +11919,10 @@
|
|||
"@languageUpdated": {
|
||||
"type": "String",
|
||||
"placeholders": {}
|
||||
},
|
||||
"voiceDropdownTitle": "Voz do Bot Pangea",
|
||||
"@voiceDropdownTitle": {
|
||||
"type": "String",
|
||||
"placeholders": {}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
{
|
||||
"@@last_modified": "2026-01-20 12:30:21.408747",
|
||||
"@@last_modified": "2026-01-21 10:42:26.609980",
|
||||
"about": "Despre",
|
||||
"@about": {
|
||||
"type": "String",
|
||||
|
|
@ -11625,5 +11625,10 @@
|
|||
"@languageUpdated": {
|
||||
"type": "String",
|
||||
"placeholders": {}
|
||||
},
|
||||
"voiceDropdownTitle": "Vocea Pangea Bot",
|
||||
"@voiceDropdownTitle": {
|
||||
"type": "String",
|
||||
"placeholders": {}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"@@locale": "ru",
|
||||
"@@last_modified": "2026-01-20 12:32:09.850624",
|
||||
"@@last_modified": "2026-01-21 10:43:08.936913",
|
||||
"about": "О проекте",
|
||||
"@about": {
|
||||
"type": "String",
|
||||
|
|
@ -10995,5 +10995,10 @@
|
|||
"@languageUpdated": {
|
||||
"type": "String",
|
||||
"placeholders": {}
|
||||
},
|
||||
"voiceDropdownTitle": "Голос бота Pangea",
|
||||
"@voiceDropdownTitle": {
|
||||
"type": "String",
|
||||
"placeholders": {}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"@@locale": "sk",
|
||||
"@@last_modified": "2026-01-20 12:30:24.498564",
|
||||
"@@last_modified": "2026-01-21 10:42:27.675920",
|
||||
"about": "O aplikácii",
|
||||
"@about": {
|
||||
"type": "String",
|
||||
|
|
@ -11974,5 +11974,10 @@
|
|||
"@languageUpdated": {
|
||||
"type": "String",
|
||||
"placeholders": {}
|
||||
},
|
||||
"voiceDropdownTitle": "Hlas Pangea Bota",
|
||||
"@voiceDropdownTitle": {
|
||||
"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-20 12:30:51.399294",
|
||||
"@@last_modified": "2026-01-21 10:42:38.801732",
|
||||
"@alwaysUse24HourFormat": {
|
||||
"type": "String",
|
||||
"placeholders": {}
|
||||
|
|
@ -11971,5 +11971,10 @@
|
|||
"@languageUpdated": {
|
||||
"type": "String",
|
||||
"placeholders": {}
|
||||
},
|
||||
"voiceDropdownTitle": "Glas Pangea Bota",
|
||||
"@voiceDropdownTitle": {
|
||||
"type": "String",
|
||||
"placeholders": {}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
{
|
||||
"@@last_modified": "2026-01-20 12:32:14.799697",
|
||||
"@@last_modified": "2026-01-21 10:43:10.733270",
|
||||
"about": "О програму",
|
||||
"@about": {
|
||||
"type": "String",
|
||||
|
|
@ -11992,5 +11992,10 @@
|
|||
"@languageUpdated": {
|
||||
"type": "String",
|
||||
"placeholders": {}
|
||||
},
|
||||
"voiceDropdownTitle": "Glas Pangea Bota",
|
||||
"@voiceDropdownTitle": {
|
||||
"type": "String",
|
||||
"placeholders": {}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
{
|
||||
"@@last_modified": "2026-01-20 12:31:57.066428",
|
||||
"@@last_modified": "2026-01-21 10:43:04.367889",
|
||||
"about": "Om",
|
||||
"@about": {
|
||||
"type": "String",
|
||||
|
|
@ -11368,5 +11368,10 @@
|
|||
"@languageUpdated": {
|
||||
"type": "String",
|
||||
"placeholders": {}
|
||||
},
|
||||
"voiceDropdownTitle": "Pangea Bot röst",
|
||||
"@voiceDropdownTitle": {
|
||||
"type": "String",
|
||||
"placeholders": {}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
{
|
||||
"@@last_modified": "2026-01-20 12:31:40.562260",
|
||||
"@@last_modified": "2026-01-21 10:42:57.399546",
|
||||
"acceptedTheInvitation": "👍 {username} அழைப்பை ஏற்றுக்கொண்டது",
|
||||
"@acceptedTheInvitation": {
|
||||
"type": "String",
|
||||
|
|
@ -11114,5 +11114,10 @@
|
|||
"@languageUpdated": {
|
||||
"type": "String",
|
||||
"placeholders": {}
|
||||
},
|
||||
"voiceDropdownTitle": "பாஙேஆ பாட்டின் குரல்",
|
||||
"@voiceDropdownTitle": {
|
||||
"type": "String",
|
||||
"placeholders": {}
|
||||
}
|
||||
}
|
||||
|
|
@ -1920,7 +1920,7 @@
|
|||
"playWithAI": "ఇప్పుడే AI తో ఆడండి",
|
||||
"courseStartDesc": "పాంజియా బాట్ ఎప్పుడైనా సిద్ధంగా ఉంటుంది!\n\n...కానీ స్నేహితులతో నేర్చుకోవడం మెరుగైనది!",
|
||||
"@@locale": "te",
|
||||
"@@last_modified": "2026-01-20 12:31:32.903548",
|
||||
"@@last_modified": "2026-01-21 10:42:54.652537",
|
||||
"@setCustomPermissionLevel": {
|
||||
"type": "String",
|
||||
"placeholders": {}
|
||||
|
|
@ -11979,5 +11979,10 @@
|
|||
"@languageUpdated": {
|
||||
"type": "String",
|
||||
"placeholders": {}
|
||||
},
|
||||
"voiceDropdownTitle": "పాంజియా బాట్ శబ్దం",
|
||||
"@voiceDropdownTitle": {
|
||||
"type": "String",
|
||||
"placeholders": {}
|
||||
}
|
||||
}
|
||||
|
|
@ -4456,7 +4456,7 @@
|
|||
"playWithAI": "เล่นกับ AI ชั่วคราว",
|
||||
"courseStartDesc": "Pangea Bot พร้อมที่จะเริ่มต้นได้ทุกเมื่อ!\n\n...แต่การเรียนรู้ดีกว่ากับเพื่อน!",
|
||||
"@@locale": "th",
|
||||
"@@last_modified": "2026-01-20 12:31:11.891533",
|
||||
"@@last_modified": "2026-01-21 10:42:47.175182",
|
||||
"@alwaysUse24HourFormat": {
|
||||
"type": "String",
|
||||
"placeholders": {}
|
||||
|
|
@ -11948,5 +11948,10 @@
|
|||
"@languageUpdated": {
|
||||
"type": "String",
|
||||
"placeholders": {}
|
||||
},
|
||||
"voiceDropdownTitle": "เสียงของ Pangea Bot",
|
||||
"@voiceDropdownTitle": {
|
||||
"type": "String",
|
||||
"placeholders": {}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"@@locale": "tr",
|
||||
"@@last_modified": "2026-01-20 12:31:28.469826",
|
||||
"@@last_modified": "2026-01-21 10:42:53.424381",
|
||||
"about": "Hakkında",
|
||||
"@about": {
|
||||
"type": "String",
|
||||
|
|
@ -11112,5 +11112,10 @@
|
|||
"@languageUpdated": {
|
||||
"type": "String",
|
||||
"placeholders": {}
|
||||
},
|
||||
"voiceDropdownTitle": "Pangea Bot sesi",
|
||||
"@voiceDropdownTitle": {
|
||||
"type": "String",
|
||||
"placeholders": {}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"@@locale": "uk",
|
||||
"@@last_modified": "2026-01-20 12:30:57.869011",
|
||||
"@@last_modified": "2026-01-21 10:42:41.558170",
|
||||
"about": "Про застосунок",
|
||||
"@about": {
|
||||
"type": "String",
|
||||
|
|
@ -10884,5 +10884,10 @@
|
|||
"@languageUpdated": {
|
||||
"type": "String",
|
||||
"placeholders": {}
|
||||
},
|
||||
"voiceDropdownTitle": "Голос Pangea Bot",
|
||||
"@voiceDropdownTitle": {
|
||||
"type": "String",
|
||||
"placeholders": {}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
{
|
||||
"@@last_modified": "2026-01-20 12:31:38.101874",
|
||||
"@@last_modified": "2026-01-21 10:42:56.498587",
|
||||
"about": "Giới thiệu",
|
||||
"@about": {
|
||||
"type": "String",
|
||||
|
|
@ -6460,5 +6460,10 @@
|
|||
"@languageUpdated": {
|
||||
"type": "String",
|
||||
"placeholders": {}
|
||||
},
|
||||
"voiceDropdownTitle": "Giọng nói của Pangea Bot",
|
||||
"@voiceDropdownTitle": {
|
||||
"type": "String",
|
||||
"placeholders": {}
|
||||
}
|
||||
}
|
||||
|
|
@ -1856,7 +1856,7 @@
|
|||
"selectAll": "全選",
|
||||
"deselectAll": "取消全選",
|
||||
"@@locale": "yue",
|
||||
"@@last_modified": "2026-01-20 12:30:53.854617",
|
||||
"@@last_modified": "2026-01-21 10:42:39.595731",
|
||||
"@ignoreUser": {
|
||||
"type": "String",
|
||||
"placeholders": {}
|
||||
|
|
@ -11981,5 +11981,10 @@
|
|||
"@languageUpdated": {
|
||||
"type": "String",
|
||||
"placeholders": {}
|
||||
},
|
||||
"voiceDropdownTitle": "Pangea Bot 聲音",
|
||||
"@voiceDropdownTitle": {
|
||||
"type": "String",
|
||||
"placeholders": {}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"@@locale": "zh",
|
||||
"@@last_modified": "2026-01-20 12:31:47.017242",
|
||||
"@@last_modified": "2026-01-21 10:43:00.180549",
|
||||
"about": "关于",
|
||||
"@about": {
|
||||
"type": "String",
|
||||
|
|
@ -10881,5 +10881,10 @@
|
|||
"@languageUpdated": {
|
||||
"type": "String",
|
||||
"placeholders": {}
|
||||
},
|
||||
"voiceDropdownTitle": "潘吉亚机器人声音",
|
||||
"@voiceDropdownTitle": {
|
||||
"type": "String",
|
||||
"placeholders": {}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
{
|
||||
"@@last_modified": "2026-01-20 12:31:16.140892",
|
||||
"@@last_modified": "2026-01-21 10:42:49.437032",
|
||||
"about": "關於",
|
||||
"@about": {
|
||||
"type": "String",
|
||||
|
|
@ -10888,5 +10888,10 @@
|
|||
"@languageUpdated": {
|
||||
"type": "String",
|
||||
"placeholders": {}
|
||||
},
|
||||
"voiceDropdownTitle": "Pangea Bot 語音",
|
||||
"@voiceDropdownTitle": {
|
||||
"type": "String",
|
||||
"placeholders": {}
|
||||
}
|
||||
}
|
||||
|
|
@ -13,8 +13,6 @@ import 'package:fluffychat/pages/chat/events/room_creation_state_event.dart';
|
|||
import 'package:fluffychat/pangea/activity_sessions/activity_room_extension.dart';
|
||||
import 'package:fluffychat/pangea/activity_sessions/activity_session_chat/activity_roles_event_widget.dart';
|
||||
import 'package:fluffychat/pangea/activity_sessions/activity_summary_widget.dart';
|
||||
import 'package:fluffychat/pangea/bot/utils/bot_name.dart';
|
||||
import 'package:fluffychat/pangea/bot/widgets/bot_settings_language_icon.dart';
|
||||
import 'package:fluffychat/pangea/chat/extensions/custom_room_display_extension.dart';
|
||||
import 'package:fluffychat/pangea/common/widgets/pressable_button.dart';
|
||||
import 'package:fluffychat/pangea/common/widgets/shimmer_background.dart';
|
||||
|
|
@ -477,18 +475,6 @@ class Message extends StatelessWidget {
|
|||
presenceBackgroundColor: wallpaperMode
|
||||
? Colors.transparent
|
||||
: null,
|
||||
// #Pangea
|
||||
miniIcon:
|
||||
user.id == BotName.byEnvironment
|
||||
? BotSettingsLanguageIcon(
|
||||
user: user,
|
||||
)
|
||||
: null,
|
||||
presenceOffset:
|
||||
user.id == BotName.byEnvironment
|
||||
? const Offset(0, 0)
|
||||
: null,
|
||||
// Pangea#
|
||||
);
|
||||
},
|
||||
),
|
||||
|
|
|
|||
|
|
@ -6,8 +6,6 @@ import 'package:shimmer/shimmer.dart';
|
|||
|
||||
import 'package:fluffychat/config/app_config.dart';
|
||||
import 'package:fluffychat/l10n/l10n.dart';
|
||||
import 'package:fluffychat/pangea/bot/utils/bot_name.dart';
|
||||
import 'package:fluffychat/pangea/bot/widgets/bot_settings_language_icon.dart';
|
||||
import 'package:fluffychat/utils/string_color.dart';
|
||||
import 'package:fluffychat/widgets/avatar.dart';
|
||||
import 'package:fluffychat/widgets/hover_builder.dart';
|
||||
|
|
@ -70,14 +68,6 @@ class ActivityParticipantIndicator extends StatelessWidget {
|
|||
name: userId!.localpart,
|
||||
size: 60.0,
|
||||
userId: userId,
|
||||
miniIcon:
|
||||
room != null && userId == BotName.byEnvironment
|
||||
? BotSettingsLanguageIcon(user: user!)
|
||||
: null,
|
||||
presenceOffset:
|
||||
room != null && userId == BotName.byEnvironment
|
||||
? const Offset(0, 0)
|
||||
: null,
|
||||
)
|
||||
: ClipRRect(
|
||||
borderRadius: BorderRadius.circular(30),
|
||||
|
|
|
|||
|
|
@ -1,194 +0,0 @@
|
|||
import 'package:flutter/material.dart';
|
||||
|
||||
import 'package:dropdown_button2/dropdown_button2.dart';
|
||||
import 'package:matrix/matrix.dart';
|
||||
|
||||
import 'package:fluffychat/l10n/l10n.dart';
|
||||
import 'package:fluffychat/pangea/activity_sessions/activity_room_extension.dart';
|
||||
import 'package:fluffychat/pangea/bot/utils/bot_room_extension.dart';
|
||||
import 'package:fluffychat/pangea/chat_settings/models/bot_options_model.dart';
|
||||
import 'package:fluffychat/pangea/chat_settings/widgets/language_level_dropdown.dart';
|
||||
import 'package:fluffychat/pangea/common/utils/error_handler.dart';
|
||||
import 'package:fluffychat/pangea/common/widgets/dropdown_text_button.dart';
|
||||
import 'package:fluffychat/pangea/languages/language_model.dart';
|
||||
import 'package:fluffychat/pangea/languages/p_language_store.dart';
|
||||
import 'package:fluffychat/pangea/learning_settings/language_level_type_enum.dart';
|
||||
import 'package:fluffychat/pangea/learning_settings/p_language_dropdown.dart';
|
||||
import 'package:fluffychat/widgets/matrix.dart';
|
||||
|
||||
class BotChatSettingsDialog extends StatefulWidget {
|
||||
final Room room;
|
||||
|
||||
const BotChatSettingsDialog({
|
||||
required this.room,
|
||||
super.key,
|
||||
});
|
||||
|
||||
@override
|
||||
BotChatSettingsDialogState createState() => BotChatSettingsDialogState();
|
||||
}
|
||||
|
||||
class BotChatSettingsDialogState extends State<BotChatSettingsDialog> {
|
||||
LanguageModel? _selectedLang;
|
||||
LanguageLevelTypeEnum? _selectedLevel;
|
||||
String? _selectedVoice;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
final botSettings = widget.room.botOptions;
|
||||
final activityPlan = _isActivity ? widget.room.activityPlan : null;
|
||||
|
||||
_selectedLevel = activityPlan?.req.cefrLevel ?? botSettings?.languageLevel;
|
||||
_selectedVoice = botSettings?.targetVoice;
|
||||
final lang =
|
||||
activityPlan?.req.targetLanguage ?? botSettings?.targetLanguage;
|
||||
if (lang != null) {
|
||||
_selectedLang = PLanguageStore.byLangCode(lang);
|
||||
}
|
||||
super.initState();
|
||||
}
|
||||
|
||||
bool get _isActivity => widget.room.isActivitySession;
|
||||
|
||||
Future<void> _setLanguage(LanguageModel? lang) async {
|
||||
setState(() {
|
||||
_selectedLang = lang;
|
||||
_selectedVoice = null;
|
||||
});
|
||||
|
||||
final model = widget.room.botOptions ?? BotOptionsModel();
|
||||
model.targetLanguage = lang?.langCode;
|
||||
model.targetVoice = null;
|
||||
|
||||
try {
|
||||
await widget.room.setBotOptions(model);
|
||||
} catch (e, s) {
|
||||
ErrorHandler.logError(
|
||||
e: e,
|
||||
s: s,
|
||||
data: {
|
||||
'roomId': widget.room.id,
|
||||
'langCode': lang?.langCode,
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> _setLevel(LanguageLevelTypeEnum? level) async {
|
||||
if (level == null) return;
|
||||
|
||||
setState(() => _selectedLevel = level);
|
||||
final model = widget.room.botOptions ?? BotOptionsModel();
|
||||
model.languageLevel = level;
|
||||
try {
|
||||
await widget.room.setBotOptions(model);
|
||||
} catch (e, s) {
|
||||
ErrorHandler.logError(
|
||||
e: e,
|
||||
s: s,
|
||||
data: {
|
||||
'roomId': widget.room.id,
|
||||
'level': level.name,
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> _setVoice(String? voice) async {
|
||||
setState(() => _selectedVoice = voice);
|
||||
final model = widget.room.botOptions ?? BotOptionsModel();
|
||||
model.targetVoice = voice;
|
||||
try {
|
||||
await widget.room.setBotOptions(model);
|
||||
} catch (e, s) {
|
||||
ErrorHandler.logError(
|
||||
e: e,
|
||||
s: s,
|
||||
data: {
|
||||
'roomId': widget.room.id,
|
||||
'voice': voice,
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Material(
|
||||
type: MaterialType.transparency,
|
||||
child: Column(
|
||||
spacing: 12.0,
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
crossAxisAlignment: CrossAxisAlignment.stretch,
|
||||
children: [
|
||||
if (widget.room.isActivitySession)
|
||||
ListTile(
|
||||
contentPadding: const EdgeInsets.all(0.0),
|
||||
minLeadingWidth: 12.0,
|
||||
leading: Icon(
|
||||
Icons.info_outline,
|
||||
size: 12.0,
|
||||
color: Theme.of(context).disabledColor,
|
||||
),
|
||||
title: Text(
|
||||
L10n.of(context).activitySettingsOverrideWarning,
|
||||
style: TextStyle(
|
||||
color: Theme.of(context).disabledColor,
|
||||
fontSize: 12.0,
|
||||
),
|
||||
),
|
||||
)
|
||||
else
|
||||
const SizedBox(),
|
||||
PLanguageDropdown(
|
||||
onChange: _setLanguage,
|
||||
initialLanguage: _selectedLang,
|
||||
languages:
|
||||
MatrixState.pangeaController.pLanguageStore.targetOptions,
|
||||
isL2List: true,
|
||||
decorationText: L10n.of(context).targetLanguage,
|
||||
enabled: !widget.room.isActivitySession,
|
||||
),
|
||||
LanguageLevelDropdown(
|
||||
initialLevel: _selectedLevel,
|
||||
onChanged: _setLevel,
|
||||
enabled: !widget.room.isActivitySession,
|
||||
width: 300,
|
||||
maxHeight: 300,
|
||||
),
|
||||
DropdownButtonFormField2<String>(
|
||||
customButton: _selectedVoice != null
|
||||
? CustomDropdownTextButton(text: _selectedVoice!)
|
||||
: null,
|
||||
menuItemStyleData: const MenuItemStyleData(
|
||||
padding: EdgeInsets.symmetric(
|
||||
vertical: 8.0,
|
||||
horizontal: 16.0,
|
||||
),
|
||||
),
|
||||
decoration: InputDecoration(
|
||||
labelText: L10n.of(context).voice,
|
||||
),
|
||||
isExpanded: true,
|
||||
dropdownStyleData: DropdownStyleData(
|
||||
maxHeight: 250,
|
||||
decoration: BoxDecoration(
|
||||
color: Theme.of(context).colorScheme.surfaceContainerHigh,
|
||||
borderRadius: BorderRadius.circular(14.0),
|
||||
),
|
||||
),
|
||||
items: (_selectedLang?.voices ?? <String>[]).map((voice) {
|
||||
return DropdownMenuItem(
|
||||
value: voice,
|
||||
child: Text(voice),
|
||||
);
|
||||
}).toList(),
|
||||
onChanged: _setVoice,
|
||||
value: _selectedVoice,
|
||||
),
|
||||
const SizedBox(),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,57 +0,0 @@
|
|||
import 'package:flutter/material.dart';
|
||||
|
||||
import 'package:matrix/matrix.dart';
|
||||
|
||||
import 'package:fluffychat/pangea/activity_sessions/activity_room_extension.dart';
|
||||
import 'package:fluffychat/pangea/bot/utils/bot_room_extension.dart';
|
||||
import 'package:fluffychat/pangea/extensions/pangea_room_extension.dart';
|
||||
import 'package:fluffychat/widgets/member_actions_popup_menu_button.dart';
|
||||
|
||||
class BotSettingsLanguageIcon extends StatelessWidget {
|
||||
final User user;
|
||||
|
||||
const BotSettingsLanguageIcon({
|
||||
super.key,
|
||||
required this.user,
|
||||
});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final room = user.room;
|
||||
String? langCode = room.botOptions?.targetLanguage;
|
||||
if (room.isActivitySession && room.activityPlan != null) {
|
||||
langCode = room.activityPlan!.req.targetLanguage;
|
||||
}
|
||||
if (langCode == null) {
|
||||
return const SizedBox();
|
||||
}
|
||||
|
||||
langCode = langCode.split('-').first;
|
||||
return InkWell(
|
||||
borderRadius: BorderRadius.circular(32.0),
|
||||
onTap: room.isRoomAdmin
|
||||
? () => showMemberActionsPopupMenu(
|
||||
context: context,
|
||||
user: user,
|
||||
room: room,
|
||||
)
|
||||
: null,
|
||||
child: Container(
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: BorderRadius.circular(16.0),
|
||||
color: Theme.of(context).colorScheme.primaryContainer,
|
||||
),
|
||||
padding: const EdgeInsets.symmetric(horizontal: 4.0),
|
||||
child: Text(
|
||||
langCode,
|
||||
style: TextStyle(
|
||||
fontSize: 10.0,
|
||||
color: Theme.of(context).colorScheme.onPrimaryContainer,
|
||||
fontWeight: FontWeight.bold,
|
||||
),
|
||||
textAlign: TextAlign.center,
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
@ -8,23 +8,23 @@ import 'package:fluffychat/pangea/common/utils/error_handler.dart';
|
|||
import 'package:fluffychat/pangea/learning_settings/language_level_type_enum.dart';
|
||||
|
||||
class BotOptionsModel {
|
||||
LanguageLevelTypeEnum languageLevel;
|
||||
String topic;
|
||||
List<String> keywords;
|
||||
bool safetyModeration;
|
||||
String mode;
|
||||
String? discussionTopic;
|
||||
String? discussionKeywords;
|
||||
bool? discussionTriggerReactionEnabled;
|
||||
String? discussionTriggerReactionKey;
|
||||
String? customSystemPrompt;
|
||||
bool? customTriggerReactionEnabled;
|
||||
String? customTriggerReactionKey;
|
||||
String? textAdventureGameMasterInstructions;
|
||||
String? targetLanguage;
|
||||
String? targetVoice;
|
||||
final LanguageLevelTypeEnum languageLevel;
|
||||
final String topic;
|
||||
final List<String> keywords;
|
||||
final bool safetyModeration;
|
||||
final String mode;
|
||||
final String? discussionTopic;
|
||||
final String? discussionKeywords;
|
||||
final bool? discussionTriggerReactionEnabled;
|
||||
final String? discussionTriggerReactionKey;
|
||||
final String? customSystemPrompt;
|
||||
final bool? customTriggerReactionEnabled;
|
||||
final String? customTriggerReactionKey;
|
||||
final String? textAdventureGameMasterInstructions;
|
||||
final String? targetLanguage;
|
||||
final String? targetVoice;
|
||||
|
||||
BotOptionsModel({
|
||||
const BotOptionsModel({
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
// General Bot Options
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -133,50 +133,45 @@ class BotOptionsModel {
|
|||
}
|
||||
}
|
||||
|
||||
//TODO: define enum with all possible values
|
||||
updateBotOption(String key, dynamic value) {
|
||||
switch (key) {
|
||||
case ModelKey.languageLevel:
|
||||
languageLevel = value;
|
||||
break;
|
||||
case ModelKey.safetyModeration:
|
||||
safetyModeration = value;
|
||||
break;
|
||||
case ModelKey.mode:
|
||||
mode = value;
|
||||
break;
|
||||
case ModelKey.discussionTopic:
|
||||
discussionTopic = value;
|
||||
break;
|
||||
case ModelKey.discussionKeywords:
|
||||
discussionKeywords = value;
|
||||
break;
|
||||
case ModelKey.discussionTriggerReactionEnabled:
|
||||
discussionTriggerReactionEnabled = value;
|
||||
break;
|
||||
case ModelKey.discussionTriggerReactionKey:
|
||||
discussionTriggerReactionKey = value;
|
||||
break;
|
||||
case ModelKey.customSystemPrompt:
|
||||
customSystemPrompt = value;
|
||||
break;
|
||||
case ModelKey.customTriggerReactionEnabled:
|
||||
customTriggerReactionEnabled = value;
|
||||
break;
|
||||
case ModelKey.customTriggerReactionKey:
|
||||
customTriggerReactionKey = value;
|
||||
break;
|
||||
case ModelKey.textAdventureGameMasterInstructions:
|
||||
textAdventureGameMasterInstructions = value;
|
||||
break;
|
||||
case ModelKey.targetLanguage:
|
||||
targetLanguage = value;
|
||||
break;
|
||||
case ModelKey.targetVoice:
|
||||
targetVoice = value;
|
||||
break;
|
||||
default:
|
||||
throw Exception('Invalid key for bot options - $key');
|
||||
}
|
||||
BotOptionsModel copyWith({
|
||||
LanguageLevelTypeEnum? languageLevel,
|
||||
String? topic,
|
||||
List<String>? keywords,
|
||||
bool? safetyModeration,
|
||||
String? mode,
|
||||
String? discussionTopic,
|
||||
String? discussionKeywords,
|
||||
bool? discussionTriggerReactionEnabled,
|
||||
String? discussionTriggerReactionKey,
|
||||
String? customSystemPrompt,
|
||||
bool? customTriggerReactionEnabled,
|
||||
String? customTriggerReactionKey,
|
||||
String? textAdventureGameMasterInstructions,
|
||||
String? targetLanguage,
|
||||
String? targetVoice,
|
||||
}) {
|
||||
return BotOptionsModel(
|
||||
languageLevel: languageLevel ?? this.languageLevel,
|
||||
topic: topic ?? this.topic,
|
||||
keywords: keywords ?? this.keywords,
|
||||
safetyModeration: safetyModeration ?? this.safetyModeration,
|
||||
mode: mode ?? this.mode,
|
||||
discussionTopic: discussionTopic ?? this.discussionTopic,
|
||||
discussionKeywords: discussionKeywords ?? this.discussionKeywords,
|
||||
discussionTriggerReactionEnabled: discussionTriggerReactionEnabled ??
|
||||
this.discussionTriggerReactionEnabled,
|
||||
discussionTriggerReactionKey:
|
||||
discussionTriggerReactionKey ?? this.discussionTriggerReactionKey,
|
||||
customSystemPrompt: customSystemPrompt ?? this.customSystemPrompt,
|
||||
customTriggerReactionEnabled:
|
||||
customTriggerReactionEnabled ?? this.customTriggerReactionEnabled,
|
||||
customTriggerReactionKey:
|
||||
customTriggerReactionKey ?? this.customTriggerReactionKey,
|
||||
textAdventureGameMasterInstructions:
|
||||
textAdventureGameMasterInstructions ??
|
||||
this.textAdventureGameMasterInstructions,
|
||||
targetLanguage: targetLanguage ?? this.targetLanguage,
|
||||
targetVoice: targetVoice ?? this.targetVoice,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,23 +7,19 @@ import 'package:fluffychat/pangea/chat/constants/default_power_level.dart';
|
|||
import 'package:fluffychat/pangea/chat_settings/constants/bot_mode.dart';
|
||||
import 'package:fluffychat/pangea/chat_settings/models/bot_options_model.dart';
|
||||
import 'package:fluffychat/pangea/events/constants/pangea_event_types.dart';
|
||||
import 'package:fluffychat/pangea/user/user_model.dart';
|
||||
import 'package:fluffychat/widgets/matrix.dart';
|
||||
|
||||
extension BotClientExtension on Client {
|
||||
bool get hasBotDM => rooms.any((r) => r.isBotDM);
|
||||
Room? get botDM => rooms.firstWhereOrNull((r) => r.isBotDM);
|
||||
|
||||
Room? get botDM => rooms.firstWhereOrNull(
|
||||
(room) {
|
||||
if (room.isDirectChat &&
|
||||
room.directChatMatrixID == BotName.byEnvironment) {
|
||||
return true;
|
||||
}
|
||||
if (room.botOptions?.mode == BotMode.directChat) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
},
|
||||
);
|
||||
// All 2-member rooms with the bot
|
||||
List<Room> get targetBotChats => rooms.where((r) {
|
||||
if (r.isBotDM) return true;
|
||||
if (r.summary.mJoinedMemberCount != 2) return false;
|
||||
return r.getParticipants().any((u) => u.id == BotName.byEnvironment);
|
||||
}).toList();
|
||||
|
||||
Future<String> startChatWithBot() => startDirectChat(
|
||||
BotName.byEnvironment,
|
||||
|
|
@ -45,27 +41,31 @@ extension BotClientExtension on Client {
|
|||
],
|
||||
);
|
||||
|
||||
Future<void> updateBotOptions() async {
|
||||
if (!isLogged() || botDM == null) return;
|
||||
Future<void> updateBotOptions(UserSettings userSettings) async {
|
||||
final rooms = targetBotChats;
|
||||
if (rooms.isEmpty) return;
|
||||
|
||||
final targetLanguage =
|
||||
MatrixState.pangeaController.userController.userL2?.langCode;
|
||||
final cefrLevel = MatrixState
|
||||
.pangeaController.userController.profile.userSettings.cefrLevel;
|
||||
final updateBotOptions = botDM!.botOptions ?? BotOptionsModel();
|
||||
final futures = <Future>[];
|
||||
for (final room in rooms) {
|
||||
final botOptions = room.botOptions ?? const BotOptionsModel();
|
||||
final targetLanguage = userSettings.targetLanguage;
|
||||
final languageLevel = userSettings.cefrLevel;
|
||||
final voice = userSettings.voice;
|
||||
|
||||
if (updateBotOptions.targetLanguage == targetLanguage &&
|
||||
updateBotOptions.languageLevel == cefrLevel) {
|
||||
return;
|
||||
if (botOptions.targetLanguage == targetLanguage &&
|
||||
botOptions.languageLevel == languageLevel &&
|
||||
botOptions.targetVoice == voice) {
|
||||
continue;
|
||||
}
|
||||
|
||||
final updated = botOptions.copyWith(
|
||||
targetLanguage: targetLanguage,
|
||||
languageLevel: languageLevel,
|
||||
targetVoice: voice,
|
||||
);
|
||||
futures.add(room.setBotOptions(updated));
|
||||
}
|
||||
|
||||
if (targetLanguage != null &&
|
||||
updateBotOptions.targetLanguage != targetLanguage) {
|
||||
updateBotOptions.targetVoice = null;
|
||||
}
|
||||
|
||||
updateBotOptions.targetLanguage = targetLanguage;
|
||||
updateBotOptions.languageLevel = cefrLevel;
|
||||
await botDM!.setBotOptions(updateBotOptions);
|
||||
await Future.wait(futures);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -117,8 +117,9 @@ class PangeaController {
|
|||
userController.languageStream.stream.listen(_onLanguageUpdate);
|
||||
|
||||
_settingsSubscription?.cancel();
|
||||
_settingsSubscription = userController.settingsUpdateStream.stream
|
||||
.listen((_) => matrixState.client.updateBotOptions());
|
||||
_settingsSubscription = userController.settingsUpdateStream.stream.listen(
|
||||
(update) => matrixState.client.updateBotOptions(update.userSettings),
|
||||
);
|
||||
|
||||
_joinSpaceSubscription?.cancel();
|
||||
_joinSpaceSubscription ??= matrixState.client.onSync.stream
|
||||
|
|
@ -176,7 +177,7 @@ class PangeaController {
|
|||
}
|
||||
|
||||
_clearCache(exclude: exclude);
|
||||
matrixState.client.updateBotOptions();
|
||||
matrixState.client.updateBotOptions(userController.profile.userSettings);
|
||||
}
|
||||
|
||||
static final List<String> _storageKeys = [
|
||||
|
|
|
|||
|
|
@ -44,7 +44,6 @@ class PSettingsSwitchListTileState
|
|||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return SwitchListTile.adaptive(
|
||||
contentPadding: EdgeInsets.zero,
|
||||
value: currentValue,
|
||||
title: Text(widget.title),
|
||||
activeThumbColor: AppConfig.activeToggleColor,
|
||||
|
|
|
|||
|
|
@ -41,7 +41,6 @@ class SettingsLearningController extends State<SettingsLearning> {
|
|||
PangeaController pangeaController = MatrixState.pangeaController;
|
||||
late Profile _profile;
|
||||
|
||||
final GlobalKey<FormState> formKey = GlobalKey<FormState>();
|
||||
String? languageMatchError;
|
||||
|
||||
final ScrollController scrollController = ScrollController();
|
||||
|
|
@ -110,18 +109,16 @@ class SettingsLearningController extends State<SettingsLearning> {
|
|||
updateToolSetting(ToolSetting.enableTTS, false);
|
||||
}
|
||||
|
||||
if (formKey.currentState!.validate()) {
|
||||
await showFutureLoadingDialog(
|
||||
context: context,
|
||||
future: () async => pangeaController.userController
|
||||
.updateProfile(
|
||||
(_) => _profile,
|
||||
waitForDataInSync: true,
|
||||
)
|
||||
.timeout(const Duration(seconds: 15)),
|
||||
);
|
||||
Navigator.of(context).pop();
|
||||
}
|
||||
await showFutureLoadingDialog(
|
||||
context: context,
|
||||
future: () async => pangeaController.userController
|
||||
.updateProfile(
|
||||
(_) => _profile,
|
||||
waitForDataInSync: true,
|
||||
)
|
||||
.timeout(const Duration(seconds: 15)),
|
||||
);
|
||||
Navigator.of(context).pop();
|
||||
}
|
||||
|
||||
Future<void> resetInstructionTooltips() async {
|
||||
|
|
@ -153,11 +150,12 @@ class SettingsLearningController extends State<SettingsLearning> {
|
|||
LanguageModel? sourceLanguage,
|
||||
LanguageModel? targetLanguage,
|
||||
}) async {
|
||||
if (sourceLanguage != null) {
|
||||
if (sourceLanguage != null && sourceLanguage != selectedSourceLanguage) {
|
||||
_profile.userSettings.sourceLanguage = sourceLanguage.langCode;
|
||||
}
|
||||
if (targetLanguage != null) {
|
||||
if (targetLanguage != null && targetLanguage != selectedTargetLanguage) {
|
||||
_profile.userSettings.targetLanguage = targetLanguage.langCode;
|
||||
_profile.userSettings.voice = null;
|
||||
if (!_profile.toolSettings.enableTTS && isTTSSupported) {
|
||||
updateToolSetting(ToolSetting.enableTTS, true);
|
||||
}
|
||||
|
|
@ -181,6 +179,11 @@ class SettingsLearningController extends State<SettingsLearning> {
|
|||
if (mounted) setState(() {});
|
||||
}
|
||||
|
||||
void setVoice(String? voice) {
|
||||
_profile.userSettings.voice = voice;
|
||||
if (mounted) setState(() {});
|
||||
}
|
||||
|
||||
void changeCountry(Country? country) {
|
||||
_profile.userSettings.country = country?.name;
|
||||
if (mounted) setState(() {});
|
||||
|
|
@ -343,6 +346,8 @@ class SettingsLearningController extends State<SettingsLearning> {
|
|||
|
||||
LanguageLevelTypeEnum get cefrLevel => _profile.userSettings.cefrLevel;
|
||||
|
||||
String? get selectedVoice => _profile.userSettings.voice;
|
||||
|
||||
Country? get country =>
|
||||
CountryService().findByName(_profile.userSettings.country);
|
||||
|
||||
|
|
|
|||
|
|
@ -1,7 +1,6 @@
|
|||
import 'package:flutter/material.dart';
|
||||
|
||||
import 'package:fluffychat/config/app_config.dart';
|
||||
import 'package:fluffychat/config/themes.dart';
|
||||
import 'package:fluffychat/l10n/l10n.dart';
|
||||
import 'package:fluffychat/pangea/chat_settings/widgets/language_level_dropdown.dart';
|
||||
import 'package:fluffychat/pangea/common/constants/model_keys.dart';
|
||||
|
|
@ -14,6 +13,7 @@ import 'package:fluffychat/pangea/learning_settings/p_language_dropdown.dart';
|
|||
import 'package:fluffychat/pangea/learning_settings/p_settings_switch_list_tile.dart';
|
||||
import 'package:fluffychat/pangea/learning_settings/settings_learning.dart';
|
||||
import 'package:fluffychat/pangea/learning_settings/tool_settings_enum.dart';
|
||||
import 'package:fluffychat/pangea/learning_settings/voice_dropdown.dart';
|
||||
import 'package:fluffychat/widgets/layouts/max_width_body.dart';
|
||||
import 'package:fluffychat/widgets/matrix.dart';
|
||||
|
||||
|
|
@ -45,21 +45,23 @@ class SettingsLearningView extends StatelessWidget {
|
|||
)
|
||||
: null,
|
||||
),
|
||||
body: Form(
|
||||
key: controller.formKey,
|
||||
child: ListTileTheme(
|
||||
iconColor: Theme.of(context).textTheme.bodyLarge!.color,
|
||||
child: MaxWidthBody(
|
||||
withScrolling: false,
|
||||
child: Column(
|
||||
children: [
|
||||
Expanded(
|
||||
child: SingleChildScrollView(
|
||||
controller: controller.scrollController,
|
||||
body: ListTileTheme(
|
||||
iconColor: Theme.of(context).textTheme.bodyLarge!.color,
|
||||
child: MaxWidthBody(
|
||||
withScrolling: false,
|
||||
child: Column(
|
||||
children: [
|
||||
Expanded(
|
||||
child: SingleChildScrollView(
|
||||
controller: controller.scrollController,
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.symmetric(vertical: 32.0),
|
||||
child: Column(
|
||||
spacing: 16.0,
|
||||
children: [
|
||||
Padding(
|
||||
padding: const EdgeInsets.all(16.0),
|
||||
padding:
|
||||
const EdgeInsets.symmetric(horizontal: 16.0),
|
||||
child: Column(
|
||||
spacing: 16.0,
|
||||
children: [
|
||||
|
|
@ -99,171 +101,112 @@ class SettingsLearningView extends StatelessWidget {
|
|||
.colorScheme
|
||||
.surfaceContainerHigh,
|
||||
),
|
||||
AnimatedSize(
|
||||
duration: FluffyThemes.animationDuration,
|
||||
curve: FluffyThemes.animationCurve,
|
||||
child: controller.userL1?.langCodeShort ==
|
||||
controller.userL2?.langCodeShort
|
||||
? Padding(
|
||||
padding: const EdgeInsets.symmetric(
|
||||
horizontal: 16.0,
|
||||
if (controller.userL1?.langCodeShort ==
|
||||
controller.userL2?.langCodeShort)
|
||||
Padding(
|
||||
padding: const EdgeInsets.symmetric(
|
||||
horizontal: 16.0,
|
||||
),
|
||||
child: Row(
|
||||
spacing: 8.0,
|
||||
children: [
|
||||
Icon(
|
||||
Icons.info_outlined,
|
||||
color: Theme.of(context)
|
||||
.colorScheme
|
||||
.error,
|
||||
),
|
||||
Flexible(
|
||||
child: Text(
|
||||
L10n.of(context)
|
||||
.noIdenticalLanguages,
|
||||
style: TextStyle(
|
||||
color: Theme.of(context)
|
||||
.colorScheme
|
||||
.error,
|
||||
),
|
||||
),
|
||||
child: Row(
|
||||
spacing: 8.0,
|
||||
children: [
|
||||
Icon(
|
||||
Icons.info_outlined,
|
||||
color: Theme.of(context)
|
||||
.colorScheme
|
||||
.error,
|
||||
),
|
||||
Flexible(
|
||||
child: Text(
|
||||
L10n.of(context)
|
||||
.noIdenticalLanguages,
|
||||
style: TextStyle(
|
||||
color: Theme.of(context)
|
||||
.colorScheme
|
||||
.error,
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
)
|
||||
: const SizedBox.shrink(),
|
||||
),
|
||||
CountryPickerDropdown(controller),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
LanguageLevelDropdown(
|
||||
initialLevel: controller.cefrLevel,
|
||||
onChanged: controller.setCefrLevel,
|
||||
),
|
||||
VoiceDropdown(
|
||||
value: controller.selectedVoice,
|
||||
language: controller.selectedTargetLanguage,
|
||||
onChanged: controller.setVoice,
|
||||
),
|
||||
CountryPickerDropdown(controller),
|
||||
GenderDropdown(
|
||||
initialGender: controller.gender,
|
||||
onChanged: controller.setGender,
|
||||
),
|
||||
Container(
|
||||
decoration: BoxDecoration(
|
||||
border: Border.all(
|
||||
color: Colors.white54,
|
||||
),
|
||||
borderRadius: BorderRadius.circular(8.0),
|
||||
),
|
||||
padding: const EdgeInsets.all(8.0),
|
||||
child: Column(
|
||||
children: [
|
||||
ProfileSettingsSwitchListTile.adaptive(
|
||||
defaultValue:
|
||||
controller.getToolSetting(
|
||||
ToolSetting.autoIGC,
|
||||
),
|
||||
title: ToolSetting.autoIGC
|
||||
.toolName(context),
|
||||
subtitle: ToolSetting.autoIGC
|
||||
.toolDescription(context),
|
||||
onChange: (bool value) =>
|
||||
controller.updateToolSetting(
|
||||
ToolSetting.autoIGC,
|
||||
value,
|
||||
),
|
||||
enabled: true,
|
||||
),
|
||||
ProfileSettingsSwitchListTile.adaptive(
|
||||
defaultValue:
|
||||
controller.getToolSetting(
|
||||
ToolSetting.enableAutocorrect,
|
||||
),
|
||||
title: ToolSetting.enableAutocorrect
|
||||
.toolName(context),
|
||||
subtitle: ToolSetting
|
||||
.enableAutocorrect
|
||||
.toolDescription(context),
|
||||
onChange: (bool value) {
|
||||
controller.updateToolSetting(
|
||||
ToolSetting.enableAutocorrect,
|
||||
value,
|
||||
);
|
||||
if (value) {
|
||||
controller
|
||||
.showKeyboardSettingsDialog();
|
||||
}
|
||||
},
|
||||
enabled: true,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
for (final toolSetting
|
||||
in ToolSetting.values.where(
|
||||
(tool) =>
|
||||
tool.isAvailableSetting &&
|
||||
tool != ToolSetting.autoIGC &&
|
||||
tool != ToolSetting.enableAutocorrect,
|
||||
))
|
||||
Column(
|
||||
children: [
|
||||
ProfileSettingsSwitchListTile.adaptive(
|
||||
defaultValue: controller
|
||||
.getToolSetting(toolSetting),
|
||||
title: toolSetting.toolName(context),
|
||||
subtitle: toolSetting ==
|
||||
ToolSetting.enableTTS &&
|
||||
!controller.isTTSSupported
|
||||
? null
|
||||
: toolSetting
|
||||
.toolDescription(context),
|
||||
onChange: (bool value) =>
|
||||
controller.updateToolSetting(
|
||||
toolSetting,
|
||||
value,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
SwitchListTile.adaptive(
|
||||
value: controller.publicProfile,
|
||||
onChanged: controller.setPublicProfile,
|
||||
title: Text(
|
||||
L10n.of(context).publicProfileTitle,
|
||||
),
|
||||
subtitle: Text(
|
||||
L10n.of(context).publicProfileDesc,
|
||||
),
|
||||
activeThumbColor:
|
||||
AppConfig.activeToggleColor,
|
||||
contentPadding: EdgeInsets.zero,
|
||||
),
|
||||
ResetInstructionsListTile(
|
||||
controller: controller,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
...ToolSetting.values
|
||||
.where(
|
||||
(tool) => tool.isAvailableSetting,
|
||||
)
|
||||
.map(
|
||||
(toolSetting) => _ProfileSwitchTile(
|
||||
value:
|
||||
controller.getToolSetting(toolSetting),
|
||||
setting: toolSetting,
|
||||
onChanged: (v) {
|
||||
controller.updateToolSetting(
|
||||
toolSetting,
|
||||
v,
|
||||
);
|
||||
if (v &&
|
||||
toolSetting ==
|
||||
ToolSetting.enableTTS) {
|
||||
controller.showKeyboardSettingsDialog();
|
||||
}
|
||||
},
|
||||
),
|
||||
),
|
||||
SwitchListTile.adaptive(
|
||||
value: controller.publicProfile,
|
||||
onChanged: controller.setPublicProfile,
|
||||
title: Text(
|
||||
L10n.of(context).publicProfileTitle,
|
||||
),
|
||||
subtitle: Text(
|
||||
L10n.of(context).publicProfileDesc,
|
||||
),
|
||||
activeThumbColor: AppConfig.activeToggleColor,
|
||||
),
|
||||
ResetInstructionsListTile(
|
||||
controller: controller,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
Padding(
|
||||
padding: const EdgeInsets.all(16.0),
|
||||
child: SizedBox(
|
||||
width: double.infinity,
|
||||
child: ElevatedButton(
|
||||
onPressed: controller.haveSettingsBeenChanged
|
||||
? controller.submit
|
||||
: null,
|
||||
child: Text(L10n.of(context).saveChanges),
|
||||
),
|
||||
),
|
||||
Padding(
|
||||
padding: const EdgeInsets.all(16.0),
|
||||
child: SizedBox(
|
||||
width: double.infinity,
|
||||
child: ElevatedButton(
|
||||
onPressed: controller.haveSettingsBeenChanged
|
||||
? controller.submit
|
||||
: null,
|
||||
child: Text(L10n.of(context).saveChanges),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
if (!controller.widget.isDialog) return dialogContent;
|
||||
|
||||
return FullWidthDialog(
|
||||
dialogContent: dialogContent,
|
||||
maxWidth: 600,
|
||||
|
|
@ -273,3 +216,25 @@ class SettingsLearningView extends StatelessWidget {
|
|||
);
|
||||
}
|
||||
}
|
||||
|
||||
class _ProfileSwitchTile extends StatelessWidget {
|
||||
final bool value;
|
||||
final ToolSetting setting;
|
||||
final Function(bool) onChanged;
|
||||
|
||||
const _ProfileSwitchTile({
|
||||
required this.value,
|
||||
required this.setting,
|
||||
required this.onChanged,
|
||||
});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return ProfileSettingsSwitchListTile.adaptive(
|
||||
defaultValue: value,
|
||||
title: setting.toolName(context),
|
||||
subtitle: setting.toolDescription(context),
|
||||
onChange: onChanged,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
53
lib/pangea/learning_settings/voice_dropdown.dart
Normal file
53
lib/pangea/learning_settings/voice_dropdown.dart
Normal file
|
|
@ -0,0 +1,53 @@
|
|||
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/languages/language_model.dart';
|
||||
|
||||
class VoiceDropdown extends StatelessWidget {
|
||||
final String? value;
|
||||
final LanguageModel? language;
|
||||
final Function(String?) onChanged;
|
||||
|
||||
const VoiceDropdown({
|
||||
super.key,
|
||||
this.value,
|
||||
this.language,
|
||||
required this.onChanged,
|
||||
});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return DropdownButtonFormField2<String>(
|
||||
customButton:
|
||||
value != null ? CustomDropdownTextButton(text: value!) : null,
|
||||
menuItemStyleData: const MenuItemStyleData(
|
||||
padding: EdgeInsets.symmetric(
|
||||
vertical: 8.0,
|
||||
horizontal: 16.0,
|
||||
),
|
||||
),
|
||||
decoration: InputDecoration(
|
||||
labelText: L10n.of(context).voiceDropdownTitle,
|
||||
),
|
||||
isExpanded: true,
|
||||
dropdownStyleData: DropdownStyleData(
|
||||
maxHeight: 250,
|
||||
decoration: BoxDecoration(
|
||||
color: Theme.of(context).colorScheme.surfaceContainerHigh,
|
||||
borderRadius: BorderRadius.circular(14.0),
|
||||
),
|
||||
),
|
||||
items: (language?.voices ?? <String>[]).map((voice) {
|
||||
return DropdownMenuItem(
|
||||
value: voice,
|
||||
child: Text(voice),
|
||||
);
|
||||
}).toList(),
|
||||
onChanged: onChanged,
|
||||
value: value,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
@ -8,10 +8,10 @@ import 'package:matrix/matrix.dart';
|
|||
import 'package:fluffychat/config/app_config.dart';
|
||||
import 'package:fluffychat/pages/chat/events/audio_player.dart';
|
||||
import 'package:fluffychat/pangea/analytics_misc/text_loading_shimmer.dart';
|
||||
import 'package:fluffychat/pangea/bot/utils/bot_room_extension.dart';
|
||||
import 'package:fluffychat/pangea/common/utils/error_handler.dart';
|
||||
import 'package:fluffychat/pangea/events/event_wrappers/pangea_message_event.dart';
|
||||
import 'package:fluffychat/pangea/text_to_speech/text_to_speech_response_model.dart';
|
||||
import 'package:fluffychat/widgets/matrix.dart';
|
||||
|
||||
class MessageAudioCard extends StatefulWidget {
|
||||
final PangeaMessageEvent messageEvent;
|
||||
|
|
@ -44,7 +44,7 @@ class MessageAudioCardState extends State<MessageAudioCard> {
|
|||
try {
|
||||
audioFile = await widget.messageEvent.requestTextToSpeech(
|
||||
widget.messageEvent.messageDisplayLangCode,
|
||||
widget.messageEvent.room.botOptions?.targetVoice,
|
||||
MatrixState.pangeaController.userController.voice,
|
||||
);
|
||||
debugPrint("audio file is now: $audioFile. setting starts and ends...");
|
||||
if (mounted) setState(() => _isLoading = false);
|
||||
|
|
|
|||
|
|
@ -7,7 +7,6 @@ import 'package:matrix/matrix.dart';
|
|||
import 'package:path_provider/path_provider.dart';
|
||||
|
||||
import 'package:fluffychat/pangea/analytics_misc/lemma_emoji_setter_mixin.dart';
|
||||
import 'package:fluffychat/pangea/bot/utils/bot_room_extension.dart';
|
||||
import 'package:fluffychat/pangea/common/utils/async_state.dart';
|
||||
import 'package:fluffychat/pangea/events/event_wrappers/pangea_message_event.dart';
|
||||
import 'package:fluffychat/pangea/events/models/pangea_token_text_model.dart';
|
||||
|
|
@ -58,7 +57,7 @@ class _AudioLoader extends AsyncLoader<(PangeaAudioFile, File?)> {
|
|||
Future<(PangeaAudioFile, File?)> fetch() async {
|
||||
final audioBytes = await messageEvent.requestTextToSpeech(
|
||||
messageEvent.messageDisplayLangCode,
|
||||
messageEvent.room.botOptions?.targetVoice,
|
||||
MatrixState.pangeaController.userController.voice,
|
||||
);
|
||||
|
||||
File? audioFile;
|
||||
|
|
|
|||
|
|
@ -431,6 +431,8 @@ class UserController {
|
|||
: langModel;
|
||||
}
|
||||
|
||||
String? get voice => profile.userSettings.voice;
|
||||
|
||||
bool get languagesSet =>
|
||||
userL1Code != null &&
|
||||
userL2Code != null &&
|
||||
|
|
|
|||
|
|
@ -19,6 +19,7 @@ class UserSettings {
|
|||
GenderEnum gender;
|
||||
String? country;
|
||||
LanguageLevelTypeEnum cefrLevel;
|
||||
String? voice;
|
||||
|
||||
UserSettings({
|
||||
this.dateOfBirth,
|
||||
|
|
@ -29,6 +30,7 @@ class UserSettings {
|
|||
this.gender = GenderEnum.unselected,
|
||||
this.country,
|
||||
this.cefrLevel = LanguageLevelTypeEnum.a1,
|
||||
this.voice,
|
||||
});
|
||||
|
||||
factory UserSettings.fromJson(Map<String, dynamic> json) => UserSettings(
|
||||
|
|
@ -52,6 +54,7 @@ class UserSettings {
|
|||
json[ModelKey.cefrLevel],
|
||||
)
|
||||
: LanguageLevelTypeEnum.a1,
|
||||
voice: json[ModelKey.voice],
|
||||
);
|
||||
|
||||
Map<String, dynamic> toJson() {
|
||||
|
|
@ -64,6 +67,7 @@ class UserSettings {
|
|||
data[ModelKey.userGender] = gender.string;
|
||||
data[ModelKey.userCountry] = country;
|
||||
data[ModelKey.cefrLevel] = cefrLevel.string;
|
||||
data[ModelKey.voice] = voice;
|
||||
return data;
|
||||
}
|
||||
|
||||
|
|
@ -123,6 +127,7 @@ class UserSettings {
|
|||
gender: gender,
|
||||
country: country,
|
||||
cefrLevel: cefrLevel,
|
||||
voice: voice,
|
||||
);
|
||||
}
|
||||
|
||||
|
|
@ -138,7 +143,8 @@ class UserSettings {
|
|||
other.sourceLanguage == sourceLanguage &&
|
||||
other.gender == gender &&
|
||||
other.country == country &&
|
||||
other.cefrLevel == cefrLevel;
|
||||
other.cefrLevel == cefrLevel &&
|
||||
other.voice == voice;
|
||||
}
|
||||
|
||||
@override
|
||||
|
|
@ -151,6 +157,7 @@ class UserSettings {
|
|||
gender.hashCode,
|
||||
country.hashCode,
|
||||
cefrLevel.hashCode,
|
||||
voice.hashCode,
|
||||
]);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -28,7 +28,6 @@ class Avatar extends StatelessWidget {
|
|||
|
||||
final double? presenceSize;
|
||||
final Offset? presenceOffset;
|
||||
final Widget? miniIcon;
|
||||
// Pangea#
|
||||
|
||||
const Avatar({
|
||||
|
|
@ -48,7 +47,6 @@ class Avatar extends StatelessWidget {
|
|||
this.userId,
|
||||
this.presenceSize,
|
||||
this.presenceOffset,
|
||||
this.miniIcon,
|
||||
// Pangea#
|
||||
super.key,
|
||||
});
|
||||
|
|
@ -140,13 +138,7 @@ class Avatar extends StatelessWidget {
|
|||
),
|
||||
// #Pangea
|
||||
// if (presenceUserId != null)
|
||||
if (miniIcon != null)
|
||||
Positioned(
|
||||
bottom: presenceOffset?.dy ?? -3,
|
||||
right: presenceOffset?.dx ?? -3,
|
||||
child: miniIcon!,
|
||||
)
|
||||
else if (presenceUserId != null && size >= 32.0 && showPresence)
|
||||
if (presenceUserId != null && size >= 32.0 && showPresence)
|
||||
// Pangea#
|
||||
PresenceBuilder(
|
||||
client: client,
|
||||
|
|
|
|||
|
|
@ -6,8 +6,6 @@ import 'package:matrix/matrix.dart';
|
|||
import 'package:fluffychat/l10n/l10n.dart';
|
||||
import 'package:fluffychat/pangea/analytics_misc/level_display_name.dart';
|
||||
import 'package:fluffychat/pangea/bot/utils/bot_name.dart';
|
||||
import 'package:fluffychat/pangea/bot/widgets/bot_chat_settings_dialog.dart';
|
||||
import 'package:fluffychat/pangea/extensions/pangea_room_extension.dart';
|
||||
import 'package:fluffychat/widgets/avatar.dart';
|
||||
import 'package:fluffychat/widgets/permission_slider_dialog.dart';
|
||||
import 'adaptive_dialogs/show_ok_cancel_alert_dialog.dart';
|
||||
|
|
@ -108,15 +106,15 @@ void showMemberActionsPopupMenu({
|
|||
],
|
||||
),
|
||||
),
|
||||
if (user.id == BotName.byEnvironment && room != null && room.isRoomAdmin)
|
||||
PopupMenuItem(
|
||||
enabled: false,
|
||||
padding: const EdgeInsets.only(
|
||||
left: 12.0,
|
||||
right: 12.0,
|
||||
),
|
||||
child: BotChatSettingsDialog(room: room),
|
||||
),
|
||||
// if (user.id == BotName.byEnvironment && room != null && room.isRoomAdmin)
|
||||
// PopupMenuItem(
|
||||
// enabled: false,
|
||||
// padding: const EdgeInsets.only(
|
||||
// left: 12.0,
|
||||
// right: 12.0,
|
||||
// ),
|
||||
// child: BotChatSettingsDialog(room: room),
|
||||
// ),
|
||||
const PopupMenuDivider(),
|
||||
// #Pangea
|
||||
if (user.room.client.userID != user.id)
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue