礼物动画以及多语言翻译修复

This commit is contained in:
NIGGER SLAYER 2026-04-17 15:21:23 +08:00
parent ea99051267
commit 61c670b9ff
33 changed files with 2975 additions and 2083 deletions

View File

@ -1,4 +1,7 @@
org.gradle.jvmargs=-Xmx8G -XX:MaxMetaspaceSize=4G -XX:ReservedCodeCacheSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dhttps.protocols=TLSv1.2 -Djdk.tls.client.protocols=TLSv1.2 -Djava.net.preferIPv4Stack=true
org.gradle.daemon=true
org.gradle.parallel=true
org.gradle.caching=true
android.useAndroidX=true
android.enableJetifier=true
systemProp.https.protocols=TLSv1.2

View File

@ -1,13 +1,13 @@
{
"signInWithGoogle": "سيج إنويسجوغل",
"or": "اور",
"signInWithYourAccount": "سيج ، إن ، فايس ، ويوا كونتي",
"signInWithApple": "سيج إنويس أبل",
"loginRepresentsAgreementTo": "تسجيل الدخول يمثل الموافقة على",
"termsofService": "تيمز بنسيفيتش",
"privaceyPolicy": "بريفاسيبوليس",
"tips": يبس",
"mine": "خاصتي",
"signInWithGoogle": "تسجيل الدخول باستخدام جوجل",
"or": "أو",
"signInWithYourAccount": "تسجيل الدخول باستخدام حسابك",
"signInWithApple": "تسجيل الدخول باستخدام آبل",
"loginRepresentsAgreementTo": "يعني تسجيل الدخول موافقتك على",
"termsofService": "شروط الخدمة",
"privaceyPolicy": "سياسة الخصوصية",
"tips": نبيه",
"mine": "حسابي",
"searchNoDataTips": "أدخل معرف الغرفة أو المستخدم الذي تريد البحث عنه.",
"party": "حفلة",
"event": "حدث",
@ -15,16 +15,16 @@
"sound2": "صوت",
"games": "ألعاب",
"myRoom": "غرفتي",
"other": "آخر",
"other": "أخرى",
"startYourBrandNewJourney": "ابدأ رحلتك الجديدة تمامًا",
"maliciousHarassment": "التحرش الخبيث",
"maliciousHarassment": "التحرش المسيء",
"aboutMe": "عنّي",
"bag": "حقيبة",
"roomEdit": "تحرير الغرفة",
"cancelRoomPassword": "هل أنت متأكد أنك تريد حذف كلمة مرور الغرفة؟",
"roomMemberFee": "رسوم عضو الغرفة",
"blockedList2": "قائمة المحظورين",
"roomTheme2": "موضوع الغرفة",
"roomTheme2": "سمة الغرفة",
"roomPassword": "كلمة مرور الغرفة",
"numberOfMic": "عدد الميكروفونات",
"pleaseEnterContent": "يرجى إدخال المحتوى",
@ -38,14 +38,14 @@
"gameCenter": "مركز الألعاب",
"returnToVoiceChat": "العودة إلى الدردشة الصوتية؟",
"game": "لعبة",
"invite": "يدعو",
"claim": "مطالبة",
"recent": "حديث",
"popularEvents": "الأحداث الشهيرة",
"invite": "دعوة",
"claim": "استلام",
"recent": "الأحدث",
"popularEvents": "الأحداث الرائجة",
"exitGameMode": "الخروج من وضع اللعبة",
"enterTheRoom": "ادخل الغرفة",
"enterTheRoom": "دخول الغرفة",
"inviteGoRoomTips": "دائمًا هنا من أجلك، في المطر أو الشمس. تعال وقل مرحبًا!",
"confirmInviteThisUserToTheRoom": "هل تؤكد دعوة هذا المستخدم (المعرف: {1}) إلى الغرفة؟",
"confirmInviteThisUserToTheRoom": "هل تؤكد دعوة هذا المستخدم (المعرّف: {1}) إلى الغرفة؟",
"complete": "مكتمل",
"copyLink": "نسخ الرابط",
"shareTo": "مشاركة إلى",
@ -55,9 +55,9 @@
"taskNameRoomOwnerSendRedPacket": "مالك الغرفة يرسل مظروفًا أحمر",
"taskNameRoomNewMember": "أعضاء جدد في الغرفة",
"taskNameRoomOwnerSendGiftUser": "مالك الغرفة يرسل هدية",
"taskNameRoomMicUser120Min": "الأعضاء بقضاء 120+ دقيقة على الميكروفون",
"taskNameRoomMicUser60Min": "الأعضاء بقضاء 60+ دقيقة على الميكروفون",
"taskNameRoomMicUser30Min": "الأعضاء بقضاء 30+ دقيقة على الميكروفون",
"taskNameRoomMicUser120Min": "أعضاء أمضوا 120+ دقيقة على الميكروفون",
"taskNameRoomMicUser60Min": "أعضاء أمضوا 60+ دقيقة على الميكروفون",
"taskNameRoomMicUser30Min": "أعضاء أمضوا 30+ دقيقة على الميكروفون",
"taskNamePersonalSendGift": "أرسل هدية لمستخدم",
"taskNameRoomOnlineUserCount": "الأعضاء المتصلون في الغرفة",
"taskNameRoomOwnerInviteMic": "دعوة عضو إلى الميكروفون",
@ -67,25 +67,25 @@
"taskNamePersonalLuckyGiftGold": "العملات المكتسبة من إرسال هدايا الحظ",
"taskNameRoomOwnerMicTime": "مالك الغرفة يتحدث عبر الميكروفون في الغرفة",
"taskNamePersonalActiveInRoom": "كن نشطًا في غرف الآخرين",
"taskNamePersonalGameConsume": "إنفاق في اللعبة",
"taskNamePersonalMicInRoom": "اذهب إلى المايك",
"taskNamePersonalGameConsume": "الإنفاق داخل الألعاب",
"taskNamePersonalMicInRoom": "الصعود إلى الميكروفون",
"dailyCoinBonanzaRules": "قواعد مهرجان العملات اليومي",
"magic": "سحر",
"dailyCoinBonanzaRulesDetail": "1. يمكن إكمال المهام الشخصية اليومية ومهام صاحب الغرفة اليومية مرة واحدة لكل مستخدم يوميًا. يتم إعادة تعيين المهام عند الساعة 00:00:00 بتوقيت السعودية.\n2. يمكن إكمال المهام الشخصية اليومية فقط في غرف الآخرين؛ ويمكن إكمال مهام صاحب الغرفة فقط في غرفتك الخاصة.\n3. يتم احتساب مهام تقديم الهدايا فقط على الهدايا المرسلة في الغرف، وليس الهدايا المرسلة في الخلاصات.\n4. إذا تم إنشاء عدة حسابات باستخدام نفس الجهاز أو نفس بطاقة SIM بأي شكل من الأشكال، يمكن المطالبة بالمكافآت لجميع المهام مرة واحدة فقط.",
"roomOwnerTasks": "مهام صاحب الغرفة",
"personalTasks": "المهام الشخصية",
"noPromptsToday": "لا توجد مطالبات اليوم.",
"noPromptsToday": "لا توجد مهام متاحة اليوم.",
"coins4": "عملات",
"getPaidToRefer": "احصل على أجر عن الإحالة",
"getPaidToRefer": "اكسب من دعوة الأصدقاء",
"forMoreRewardsPleaseCheckTheTaskCenter": "لمزيد من المكافآت، يرجى التحقق من مركز المهام",
"weekStart": "بداية الأسبوع",
"kingQuuen": "ملك-ملكة",
"kingQuuen": "الملك والملكة",
"ramadan": "رمضان",
"like": "مثل",
"like": "إعجاب",
"updateNow": "تحديث الآن",
"skip2": "تخطي",
"importantReminder": "تذكير مهم",
"discard": خلص",
"discard": جاهل",
"deleteCommentTips": "هل أنت متأكد أنك تريد حذف هذا التعليق؟",
"deleteSuccessful": "تم الحذف بنجاح!",
"itemsLeft": "الأصناف المتبقية",
@ -101,17 +101,17 @@
"catchFirstComment": "التقط التعليق الأول",
"posting": "نشر",
"trend": "اتجاه",
"reply": "إجابة",
"reply": "رد",
"customizedGiftRules": "قواعد الهدايا المخصصة",
"rulesUpload": "القواعد والرفع",
"customized": "مخصص",
"coins3": "عملات",
"customizedGiftRulesContent": "كيفية الحصول على هديتي المُخصصة:\n\n1. يتم تحديد أهلية المستخدم للحصول على هدية مُخصصة بناءً على مستوى ثروته الحالي.\n\n(1) إذا كان مستوى ثروة المستخدم ≥ 35: يمكن للمستخدم تحميل فيديو واحد فقط للهدية المُخصصة. سنستخدم صورة ملفه الشخصي الحالية كصورة للهدية، والفيديو المُقدم كتأثير على الهدية في قسم \"التخصيص\". سيستغرق الإنتاج بعض الوقت، وسنُعلمك فور توفر الهدية في المتجر.\n\n(2) إذا كان مستوى ثروة المستخدم ≥ 45: يمكن للمستخدم تحميل فيديو واحد فقط للهدية المُخصصة. سنستخدم صورة ملفه الشخصي الحالية كصورة للهدية، والفيديو المُقدم كتأثير على الهدية في قسم \"التخصيص\". سيستغرق الإنتاج بعض الوقت، وسنُعلمك فور توفر الهدية في المتجر.\n\n2. يمكنك المشاركة في أنشطة مُحددة على التطبيق، وبعد استيفاء الشروط، تواصل معنا عبر قسم \"الرسائل\" ← \"اتصل بنا\". يرجى تزويدنا بلقطات شاشة للنشاط والفيديو الذي ترغب باستخدامه في الهدية المُخصصة. سنستخدم صورة ملفك الشخصي الحالية كصورة للهدية، والفيديو المُقدم كتأثير لها، ثم نُدرجها ضمن قسم \"مُخصصة\". سيستغرق الإنتاج بعض الوقت، وسنُعلمك فور توفرها في المتجر.\n\nمدة صلاحية الهدايا المُخصصة وكيفية تمديدها:\nستكون الهدايا المُخصصة الحصرية متاحة لمدة 30 يومًا. ولتمكين المستخدمين المؤثرين والمُلهمين من الاستمرار في الاستمتاع بهذه التجربة الجديدة وعرض أسلوبهم الشخصي، يُمكن لمستخدمي الهدايا المُخصصة تمديد مدة صلاحية جميع هداياهم المُخصصة لمدة 30 يومًا إضافية عن طريق شحن رصيدهم بمبلغ 500 دولار أمريكي شهريًا.",
"clearCache": "مسح الكاش",
"clearCache": "مسح ذاكرة التخزين المؤقت",
"multiple": "متعدد",
"areYouSureYouWantToClearLocalCache": "هل أنت متأكد أنك تريد مسح الذاكرة المؤقتة المحلية؟",
"luckGiftSpecialEffects": "تأثيرات الرسوم المتحركة للهدية السعيدة",
"receivedFromALuckyGift": "تم الاستلام من هدية محظوظة/سحرية",
"luckGiftSpecialEffects": "تأثيرات هدايا الحظ",
"receivedFromALuckyGift": "تم الاستلام من هدية حظ/سحر",
"successfullyRemovedFromTheBlacklist": "تمت الإزالة من القائمة السوداء بنجاح!",
"successfullyAddedToTheBlacklist": "تمت الإضافة إلى القائمة السوداء بنجاح!",
"youAreCurrentlyCPRelationshipPleaseDissolve": "أنت حاليا في علاقة CP. الرجاء حلها أولا.",
@ -122,15 +122,15 @@
"userBlacklist": "قائمة الحظر للمستخدمين",
"redEnvelopeNotYetClaimed": "المظروف الأحمر لم يُستلم بعد",
"redEnvelopeAmount": "مبلغ الظرف الأحمر: {1} عملات",
"followed": بع",
"followed": مت المتابعة",
"newMessage": "رسالة جديدة",
"keep": "يحفظ",
"keep": "الاحتفاظ",
"open": "فتح",
"clearCacheSuccessfully": "تم مسح ذاكرة التخزين المؤقت بنجاح",
"thisUserHasBeenBlacklisted": "تم إدراج هذا المستخدم في القائمة السوداء.",
"thisFeatureIsCurrentlyUnavailable": "هذه الخاصية غير متوفرة حاليا.",
"pleaseSelectTheRecipient": "المرجو اختيار المستلم",
"searchMemberIdHint": "يرجى إدخال رقم هوية العضو",
"thisFeatureIsCurrentlyUnavailable": "هذه الميزة غير متاحة حاليًا.",
"pleaseSelectTheRecipient": "يرجى اختيار المستلم.",
"searchMemberIdHint": "يرجى إدخال معرّف العضو",
"unclaimedRedEnvelopes": "الأظرفة الحمراء غير المطالب بها يتم استردادها خلال 24 ساعة.",
"sentARedEnvelope": "أرسل ظرف أحمر.",
"theRedEnvelopeHasExpired": "الظرف الأحمر منتهي الصلاحية",
@ -145,7 +145,7 @@
"systemAnnouncementTips1": "احذر الاحتيال:",
"systemAnnouncementTips": "تحقق من المعلومات عن طريق القنوات الرسمية فقط. لا تقم بتنزيل برامج من طرف ثالث، ولا تشارك البيانات الشخصية، ولا تحول المال بناءً على طلبات خارجية. بطاقات هوية الموظفين الرسمية هي فقط 10000 و10003 و10086. في حالة أي شك، توقف وقدم التقرير عبر",
"systemAnnouncement": "إعلان النظام",
"doNotClickUnfamiliarTips": "ماتضغطش على الروابط الغير معروفة، حيث قد تكشف معلوماتك الشخصية. متشاركش أبدا بطاقة الهوية أو معلومات البطاقة البنكية ديالك مع أي واحد.",
"doNotClickUnfamiliarTips": "لا تضغط على الروابط غير المألوفة، فقد تكشف معلوماتك الشخصية. لا تشارك رقم هويتك أو بيانات بطاقتك البنكية مع أي شخص.",
"atTag": "@تاغ",
"sayHi2": "قل مرحبا",
"roomBottomGreeting": "مرحبًا...",
@ -153,33 +153,33 @@
"reapply": "أعد التقديم",
"cancelRequest": "إلغاء الطلب",
"supporter": "مشجع",
"numberOfSign": "عدد العلامة: {1}",
"numberOfSign": "عدد مرات التوقيع: {1}",
"hostWeeklyRank": "تصنيف المضيف الأسبوعي",
"supporterWeeklyRank": رتيب الأسبوعي للمشجعين",
"supporterWeeklyRank": صنيف الداعمين الأسبوعي",
"memberList": "قائمة الأعضاء",
"treasureChest": "صندوق الكنز",
"applicationRecord": "سجل الطلبات",
"pending": "قيد الانتظار",
"appUpdateTip": "التطبيق لديه نسخة جديدة ({1})، هل تود الذهاب وتحميلها؟",
"reconcile": "يصالح",
"appUpdateTip": "يتوفر إصدار جديد من التطبيق ({1})، هل تريد تنزيله الآن؟",
"reconcile": "مصالحة",
"separated": "منفصل",
"areYouSureYouWantToSpend5": "{1} اعترف بالمشاعر ليك؛ إذا قبلتي، غادي توليو ثنائي.",
"areYouSureYouWantToSpend6": "{1} يريد العودة للتقارب معك. إذا قررت المصالحة، سيتم استعادة جميع بياناتك السابقة.",
"reconcileInvitationTips": "إذا الطرف الآخر رفض دعوة CP، غتترجع العملات ديالك للمحفظة ديالك.",
"areYouSureYouWantToSpend5": "{1} اعترف لك بمشاعره؛ إذا وافقت، ستصبحان ثنائيًا.",
"areYouSureYouWantToSpend6": "{1} يريد العودة إليك. إذا قررت المصالحة، فستتم استعادة جميع بياناتكما السابقة.",
"reconcileInvitationTips": "*إذا رفض الطرف الآخر دعوة CP، فستُعاد عملاتك إلى محفظتك.",
"reconcileInvitation": "دعوة للمصالحة",
"areYouSureYouWantToSpend4": "إرسال دعوة للمصالحة لهدا المستخدم؟",
"areYouSureYouWantToSpend4": "هل تريد إرسال دعوة مصالحة إلى هذا المستخدم؟",
"partWaysTips": "إذا قرر أحد الشريكين في العلاقة الانفصال، سيكون هناك فترة تهدئة لمدة 7 أيام. خلال هذه الفترة، يمكن للطرفين اختيار المصالحة، وسيتم استعادة كل البيانات عند المصالحة. إذا لم يتم اختيار المصالحة بنهاية فترة السبعة أيام، سيتم مسح بيانات الزوجين.",
"areYouSureYouWantToPartWaysWithYourCP": "هل أنت متأكد أنك تريد الانفصال عن شريكك؟",
"partWays": "افترقوا",
"partWays": "الانفصال",
"firstDay": "اليوم الأول:{1}",
"timeSpentTogether": "الوقت المشترك: {1} أيام",
"areYouSureYouWantToSpend3": "إذا الطرف الآخر رفض دعوة CP، غتترجع العملات ديالك للمحفظة ديالك.",
"areYouSureYouWantToSpend3": "*إذا رفض الطرف الآخر دعوة CP، فستُعاد عملاتك إلى محفظتك.",
"areYouSureYouWantToSpend2": "هل تريد إرسال دعوة CP لهذا المستخدم؟",
"areYouSureYouWantToSpend": "هل أنت متأكد أنك تريد أن تنفق",
"underReview": "قيد المراجعة",
"doYouWantToDeleteIt": "هل تريد حذفه؟",
"myPhoto": "صورتي",
"balanceNotEnough": "رصيد العملات الذهبية غير كافي. واش بغيت تزود الرصيد؟",
"balanceNotEnough": "رصيد العملات الذهبية غير كافٍ. هل تريد إعادة الشحن؟",
"skip": "تخطي {1}",
"chooseFromAblum": "اختر من الألبوم",
"information": "معلومات",
@ -187,16 +187,16 @@
"editProfile": "تعديل الملف الشخصي",
"sendTheCpRequest": "أرسل طلب CP",
"addCp": "أضف CP",
"numberOfMyCPs": "عدد نقاط السيطرة ديالي:({1}/{2})",
"numberOfMyCPs": "عدد علاقات CP الخاصة بي:({1}/{2})",
"relationShip": "علاقة",
"props": "الدعائم",
"couple2": "زوج",
"couple2": "ثنائي",
"dice": "نرد",
"operationsAreTooFrequent": "العمليات متكررة بشكل مفرط",
"luckNumber": "رقم الحظ",
"rps": "حجر ورقة مقص",
"couple": "زوج {1}:",
"noMatchedCP": "لا يوجد CP مطابق",
"noMatchedCP": "لا توجد علاقة CP مطابقة",
"adminInviteRechargeAgent": "ندعوك لتصبح وكيلا لإعادة الشحن.",
"ownerIncomeCoins": "دخل المالك: {1} عملة",
"allGames": "كل الألعاب",
@ -207,9 +207,9 @@
"greedyClass": "الفئة الجشعة",
"hotGames": "الألعاب الرائجة",
"sent": "أُرسل",
"termsOfServicePrivacyPolicyTips": متابعتك، أنت توافق على شروط الخدمة و سياسة الخصوصية",
"and": " اندر ",
"chatBox": "صندوق الشات",
"termsOfServicePrivacyPolicyTips": المتابعة، فإنك توافق على شروط الخدمة وسياسة الخصوصية",
"and": " و ",
"chatBox": "صندوق الدردشة",
"confirm": "تأكيد",
"cancel": "إلغاء",
"join": "انضم",
@ -217,23 +217,23 @@
"fans": "المعجبون",
"items": "عناصر",
"letGoToWatch": "هيا نذهب للمشاهدة!",
"launchedARocket": "أطلق صاروخ",
"launchedARocket": "أطلق صاروخًا",
"sendUserId": "أرسل معرف المستخدم:{1}",
"giveUpIdentity": "تخلى عن الهوية",
"leaveRoomIdentityTips": "هل أنت متأكد من أنك تريد التخلي عن هوية الغرفة؟",
"joinMemberTips2": "هل تريد تأكيد انضمامك إلى الغرفة كعضو؟",
"sureUnfollowThisRoom": "متأكد بغيتي تحيد المتابعة لهاذ الغرفة؟",
"sureUnfollowThisRoom": "هل أنت متأكد من إلغاء متابعة هذه الغرفة؟",
"settings": "الإعدادات",
"alreadyAnTourist": "أنت بالفعل سائح",
"deleteConversationTips": "هل أنت متأكد أنك تريد حذف سجل المحادثة مع هذا المستخدم؟",
"account": "أكونتي",
"account": "الحساب",
"youHaventFollowed": "أنت لم تتابع أي غرفة",
"messageHasBeenRecalled": "تم استرجاع هذه الرسالة",
"propMessagePrompt": "موجه رسالة دعائية",
"deleteFromMyDevice": "احذف من جهازي",
"deleteOnAllDevices": "حذف على جميع الأجهزة",
"inputUserId": "أدخل معرف المستخدم",
"common": "شائع",
"common": "عام",
"useCoupontips": "هل أنت متأكد أنك تريد استخدام القسيمة؟",
"searchUserId": "ابحث عن معرف المستخدم",
"receiveSucc": "تم المطالبة بنجاح",
@ -242,22 +242,22 @@
"bio": "معلومات شخصية",
"delete": "حذف",
"sendCoupontips": "هل أنت متأكد أنك تريد إرسال هذه القسيمة لهذا المستخدم؟",
"recallThisMessage": "تذكر هذه الرسالة؟",
"recallThisMessage": "هل تريد استرجاع هذه الرسالة؟",
"copy": "نسخ",
"youDontHaveAnyCouponsYet": "ليس لديك أي كوبونات بعد",
"hobby": "هواية",
"recall": "استدعاء",
"accept": "اقبل",
"signedin": "تم التوقيع",
"following": "التالي",
"inviteYouToBecomeBD": "ندعوك لتصبح BD",
"recall": "استرجاع",
"accept": "قبول",
"signedin": "تم تسجيل الدخول",
"following": "يتابع",
"inviteYouToBecomeBD": "ندعوك للانضمام كـ BD.",
"confirmAcceptTheInvitation": "هل تريد تأكيد قبول الدعوة؟",
"confirmDeclineTheInvitation": "تأكيد رفض الدعوة؟",
"friends": "أصدقاء",
"language": "اللغة",
"feedback": "تعليق",
"feedback": "ملاحظات",
"coupon": "قسيمة",
"get": "احصل",
"get": "احصل على",
"couponRecord": "سجل استخدام القسيمة",
"inRoom": "في الغرفة",
"inRocket": "في الصاروخ",
@ -265,21 +265,21 @@
"searchCouponHint": "ابحث عن كوبون",
"search": "بحث",
"checkInSuccessful": "تسجيل الوصول ناجح",
"about": "حوالي",
"about": "حول",
"inviteYouToBecomeHost": "ندعوك لتصبح مضيفًا",
"receive": "استقبل",
"receive": "استلام",
"sginTips": "ستحصل على المكافأة في أول مرة تسجل دخولك فيها كل يوم. إذا قمت بقطع تسجيل دخولك، ستُحسب المكافأة من أول يوم تسجل فيه دخولك مرة أخرى.",
"aboutUs": "حولنا",
"theme": "موضوع",
"home": "المنزل",
"aboutUs": "من نحن",
"theme": "السمة",
"home": "الرئيسية",
"luck": "حظ",
"bDLeaderInviteYouToBecomeBDLeader": "ندعوك لتصبح قائد تطوير الأعمال",
"win2": "فوز {1}",
"level": "مستوى",
"wealthLevel": "مستوى الثروة",
"userLevel": "مستوى المستخدم",
"themeGoToUploadTips": "1.سيتم مراجعة التحميل خلال 24 ساعة بعد نجاحه. 2.\n سيتم إرجاع جميع العملات إذا فشلت المراجعة.",
"goToUpload": "اذهب لتحميل",
"themeGoToUploadTips": "1. ستتم مراجعة التحميل خلال 24 ساعة بعد نجاحه.\n2. ستُعاد جميع العملات إذا فشلت المراجعة.",
"goToUpload": "الانتقال للرفع",
"rechargeAgency": "وكالة الشحن",
"logout": "تسجيل الخروج",
"adminCenter": "مركز الإدارة",
@ -289,7 +289,7 @@
"fansList": "قائمة المعجبين",
"pleaseSelectTheTypeContent": "يرجى اختيار نوع المحتوى المخالف",
"me": "أنا",
"socialPrivilege": "امتياز اجتماعي",
"socialPrivilege": "امتيازات اجتماعية",
"spam": "بريد مزعج",
"inappropriateContent": "محتوى غير لائق",
"illegalInformation": "معلومات غير قانونية",
@ -297,11 +297,11 @@
"identity": "الهوية",
"adjust": "تعديل",
"roomReward": "مكافأة الغرفة",
"insufhcientGoldsGoToRecharge": "الذهب غير كافي، عاود الشحن دابا!",
"insufhcientGoldsGoToRecharge": "الرصيد غير كافٍ، يرجى إعادة الشحن الآن!",
"received": "تم الاستلام",
"goToRecharge": "اذهب لإعادة الشحن",
"warning": "تحذير",
"ownerSendTheRedEnvelope": "المالك أرسل عملات المكافأة",
"ownerSendTheRedEnvelope": "أرسل مالك الغرفة عملات المكافأة.",
"rewardCoins": "عملات المكافأة:{1} عملة",
"lastWeekProgress": "تقدم الأسبوع الماضي",
"currentProgress": "التقدم الحالي",
@ -313,7 +313,7 @@
"remainingNumberTips": "العدد المتبقي المتاح: ({1}/{2})",
"collectionTimeTips": "وقت الجمع:{1}({2}/{3})",
"sendARedEnvelope": "أرسل ظرفاً أحمر",
"sendRedPackConfirmTips": "هل أنت متأكد أنك تريد إرسال الحزمة الحمراء؟",
"sendRedPackConfirmTips": "هل أنت متأكد أنك تريد إرسال الظرف الأحمر؟",
"redEnvelopeSendingRecords": "سجلات إرسال الظرف الأحمر:",
"countdownMinutes": "دقائق العد التنازلي:",
"number2": "رقم:",
@ -326,12 +326,12 @@
"roomTools": "أدوات الغرفة:",
"entertainment": "الترفيه:",
"reportSucc": "تم الإبلاغ بنجاح",
"reportInputTips": "من فضلك وصف المشكل بأكبر قدر ممكن من التفاصيل باش نقدر نفهموه ونحلوه.",
"pornography": "الاباحية",
"reportInputTips": "يرجى وصف المشكلة بأكبر قدر ممكن من التفاصيل حتى نتمكن من فهمها وحلها.",
"pornography": "إباحية",
"screenshotTips": "لقطة شاشة (حتى 3)",
"roomEditing": "تحرير الغرفة",
"picture": "صورة",
"inputDesHint": "من فضلك وصف المشكلة بأكبر قدر ممكن من التفاصيل باش نقدر نفهموها ونحلها.",
"inputDesHint": "يرجى وصف المشكلة بأكبر قدر ممكن من التفاصيل حتى نتمكن من فهمها وحلها.",
"description": "الوصف:",
"roomNotice": "إشعار الغرفة",
"roomTheme": "موضوع الغرفة",
@ -343,25 +343,25 @@
"enterTheUserId": "أدخل معرف المستخدم",
"enterTheRoomId": "أدخل رقم الغرفة",
"theImageSizeCannotExceed": "حجم الصورة لا يمكن أن يتجاوز 4 ميغابايت",
"bdLeader": "زعيم بنك التنمية",
"bdLeader": "قائد BD",
"kickedOutOfRoom": "تم طرده من الغرفة",
"lockTheMic": "اقفل الميكروفون",
"openTheMic": "افتح الميكروفون",
"finish": "أنهى",
"lockTheMic": "قفل الميكروفون",
"openTheMic": "فتح الميكروفون",
"finish": "إنهاء",
"removeTheMic": "أزل الميكروفون",
"leavelTheMic": "اترك الميكروفون",
"unlockTheMic": "افتح الميكروفون",
"unlockTheMic": "إلغاء قفل الميكروفون",
"muteTheMic": "كتم الميكروفون",
"inviteToTheMicrophone": "دعوة للتحدث في الميكروفون",
"takeTheMic": "خذ الميكروفون",
"openUserProfleCard": "افتح بطاقة ملف المستخدم",
"crop": "محصول",
"crop": "قص",
"host": "مضيف",
"agent": "وكالة",
"ra": "را",
"bd": "بي دي",
"agent": "وكيل",
"ra": "RA",
"bd": "BD",
"unread": "غير مقروء",
"read": "اقرأ",
"read": "مقروء",
"image": "[صورة]",
"video": "[فيديو]",
"sound": "[صوت]",
@ -371,13 +371,13 @@
"giftCounter": "عداد الهدايا",
"wins": "يفوز",
"deleteAccount": "حذف الحساب",
"becomeAgent": "أصبح وكيلا",
"becomeAgent": "كن وكيلاً",
"male": "ذكر",
"setAccount": "تعيين الحساب",
"setAccount": "إعداد الحساب",
"female": "أنثى",
"album": "ألبوم",
"loadingFailedClickToRetry": "فشل التحميل، انقر لإعادة المحاولة",
"releaseToLoadMore": "حرر للتحميل المزيد",
"releaseToLoadMore": "حرر للتحميل",
"haveMyLimits": "---لدي حدودي.---",
"pullToLoadMore": "اسحب للتحميل المزيد",
"enterNickname": "أدخل الاسم المستعار",
@ -394,17 +394,17 @@
"saturday": "السبت {1}",
"sunday": "الأحد {1}",
"notifcation": "إشعار",
"inviteYouToBecomeAgent": "ندعوك لتصبح وكالة",
"inviteYouToBecomeAgent": "ندعوك لتصبح وكيلاً.",
"theVideoSizeCannotExceed": "لا يمكن أن يتجاوز حجم الفيديو 50 ميغابايت",
"fromLuckyGifts": "من الهدايا المحظوظة",
"fromLuckyGifts": "من هدايا الحظ/السحر",
"confirmSwitchMicModelTips": "هل تؤكد تغيير وضعية الجلوس؟",
"classicMic": "ميكروفون كلاسيكي {1}",
"number": "رقم",
"micTheme": "ثيم المايك",
"micTheme": "سمة الميكروفون",
"chat": "دردشة",
"rejected": "مرفوض",
"refuse": "رفض",
"boxContributeTips": "لقد تم الاستثمار بالفعل اليوم، رجاءً لا تستثمر مرة أخرى",
"boxContributeTips": "تم الاستثمار اليوم بالفعل، يرجى عدم الاستثمار مرة أخرى.",
"help": "مساعدة",
"approved": "معتمد",
"onlineUsers": "المستخدمون عبر الإنترنت ({1}/{2}):",
@ -418,14 +418,14 @@
"joinRequest": "طلب الانضمام",
"gameRules": "قوانين اللعبة:",
"gift": "هدية",
"charmGameRulesTips": "قم بتشغيل لوحة التحكم لعرض العملات الهدايا المستلمة لجميع المستخدمين على الميكروفون، 1 عملة = 1 نقطة (هدية محظوظة 1 عملة = 0.04 نقطة).",
"charm": "تعويذة هدية",
"charmGameRulesTips": "شغّل لوحة التحكم لعرض عملات الهدايا المستلمة لجميع المستخدمين على الميكروفون؛ 1 عملة = 1 نقطة (هدية الحظ: 1 عملة = 0.04 نقطة).",
"charm": "سحر الهدايا",
"chats": "الدردشات",
"myMusic": "موسيقاي",
"membershipFeeTips1": "من فضلك حدد رسوم الانضمام لغرفتك. يمكن للمستخدمين الانضمام إلى غرفتك من خلال دفع الرسوم.",
"membershipFeeTips2": "الذهب المطلوب للعضو في الغرفة. صاحب الغرفة سيحصل على 50٪ من الذهب.",
"membershipFee": "رسوم العضوية",
"touristsSendText": "السائح يرسل نص",
"touristsSendText": "إرسال النص للزوار",
"freePrice": "الرسوم: 0-10000",
"pleaseChatFfriendly": "رجاءً تحدث بطريقة ودية",
"kickPrevention": "الوقاية من الركلات",
@ -435,39 +435,39 @@
"stop": "توقف",
"add": "أضف",
"scrollToTheBottom": "قم بالتمرير إلى الأسفل",
"apple": "تفاحة",
"apple": "آبل",
"music": "موسيقى",
"free": "مجاناً",
"goToUpgrade": "اذهب إلى الترقية",
"free": "مجاني",
"goToUpgrade": "الانتقال للترقية",
"google": "جوجل",
"exclusiveEmojiWillBeReleasedAfterBecoming": "سيتم إصدار الرموز التعبيرية الحصرية بعد أن تصبح",
"preventBeingBlocked": "منع الحظر",
"enableRankIncognitoMode": "تمكين وضع الترتيب الخفي",
"avoidBeingKicked": "تجنب الركل",
"privileges": "{1} الامتيازات",
"andAboveUsers": "{1} والمستخدمون أعلاه",
"privileges": "امتيازات {1}",
"andAboveUsers": "مستخدمو {1} فما فوق",
"everyone": "الجميع",
"basicPermissions": "الأذونات الأساسية",
"mysteriousInvisibility": "الاختفاء الغامض",
"antiBlock": "مضاد للانسداد",
"antiBlock": "مضاد للحظر",
"privateChat": "دردشة خاصة",
"storeDiscount": "خصم المتجر {1}",
"membershipFreeChatSpeak": "دردشة وتحدث بدون عضوية",
"priorityRoomSorting": "فرز الغرف حسب الأولوية",
"userColoredID": "معرّف المستخدم الملون",
"setLoginPassword": "حدد كلمة مرور تسجيل الدخول",
"setLoginPassword": "تعيين كلمة مرور تسجيل الدخول",
"theTwoPasswordsDoNotMatch": "كلمتا المرور لا تتطابقتان.",
"resetLoginPasswordtTips2": "كلمة المرور يجب أن تكون بطول 8-16 حرف ويجب أن تكون مزيج من الأحرف الإنجليزية الكبيرة والصغيرة والأرقام (ليس فقط أرقام)",
"resetLoginPasswordtTips2": "يجب أن تتكون كلمة المرور من 8 إلى 16 حرفًا، وأن تجمع بين الأحرف الإنجليزية الكبيرة والصغيرة والأرقام (وليس الأرقام فقط).",
"confirmYourPassword": "أكد كلمة المرور الخاصة بك",
"enterYourNewPassword": "أدخل كلمة مرورك الجديدة",
"setYourPassword": "عيّن كلمة المرور ديالك",
"setYourPassword": "عيّن كلمة المرور الخاصة بك",
"enterYourOldPassword": "أدخل كلمة السر القديمة الخاصة بك",
"inputYourOldPassword": "أدخل كلمة المرور القديمة الخاصة بك",
"resetLoginPasswordtTips1": "سجل الدخول باستخدام معرف المستخدم أو معرف النمط. من الآمن أكثر تسجيل الدخول باستخدام حساب لايكي.",
"resetLoginPasswordtTips1": "سجّل الدخول باستخدام معرّف المستخدم أو المعرّف المميز. ويُعد تسجيل الدخول بحساب yumi أكثر أمانًا.",
"resetLoginPassword": "إعادة تعيين كلمة مرور تسجيل الدخول",
"localMusic": "الموسيقى المحلية",
"confirmSwitchMicThemeTips": "هل تؤكد تغيير نمط المقعد؟",
"follow2": "اتبع:{1}",
"follow2": "المتابَعون: {1}",
"fans2": "المعجبون:{1}",
"vistors2": "الزوار:{1}",
"personal2": "شخصي:",
@ -476,30 +476,30 @@
"enterRoomName": "أدخل اسم الغرفة",
"theMembershipFee": "رسوم العضوية",
"theModificationsMade": "التعديلات التي تمت هذه المرة لن يتم حفظها بعد الخروج.",
"touristsTakeToTheMic": "السياح ياخذو الميكروفون.",
"touristsTakeToTheMic": "صعود الزوار إلى الميكروفون",
"weekly": "أسبوعي",
"conntinue": "استمر",
"logIn": "تسجيل الدخول",
"sayHi": ُل مرحبا..",
"sayHi": ل مرحبًا..",
"password": "كلمة السر",
"enterAccount": "دخول الحساب",
"enterAccount": "أدخل الحساب",
"enterPassword": "أدخل كلمة المرور",
"roomName": "اسم الغرفة",
"enterRoomTips": "{1} ادخل الغرفة",
"enterRoomTips": "{1} دخل الغرفة",
"startVoiceParty": "ابدأ حفلة صوتية!",
"freeChatSpeak": "دردش بحرية وتحدث",
"roomMember": "عضو الغرفة",
"popular": "مشهور",
"popular": "الأكثر رواجًا",
"coinsReceived": "العملات المستلمة",
"hotRooms": "غرف حارة",
"hotRooms": "الغرف الرائجة",
"viewMore": "عرض المزيد",
"noData": "لا توجد بيانات",
"recommend": "يوصي",
"follow": "تابع",
"recommend": "موصى به",
"follow": "متابعة",
"monthly": "شهريًا",
"message": "رسالة",
"bdCenter": "مركز BD",
"history": "تاريخ",
"history": "السجل",
"users": "المستخدمون",
"rooms": "غرف",
"days": "أيام",
@ -507,61 +507,61 @@
"unFollow": "إلغاء المتابعة",
"searchInputHint": "أدخل رقم الحساب / الغرفة",
"kickRoomTips": "لقد تم طردك من الغرفة",
"joinRoomTips": "غرفة متضامة!",
"roomSetting": "تجهيز الغرفة",
"joinRoomTips": "انضم إلى الغرفة!",
"roomSetting": "إعدادات الغرفة",
"roomDetails": "تفاصيل الغرفة",
"systemRoomTips": "كن مهذبا ومحترما. يُمنع منعاً باتاً أي محتوى إباحي أو مبتذل في yumi. بمجرد اكتشافه، سيتم حظر الحساب بشكل دائم. يرجى الالتزام بوعي بلوائح منصة yumi.",
"copiedToClipboard": "تم النسخ إلى الحافظة",
"recharge": "إعادة الشحن",
"agentCenter": "مركز الوكالة",
"report": "تقرير",
"report": "إبلاغ",
"done": "تمّ",
"improvementTasks": "مهام التحسين",
"followedYou": "تابعتك",
"followedYou": "قام بمتابعتك",
"followSucc": "تمت المتابعة بنجاح",
"edit": "تحرير",
"task": "مهمة",
"save": "احفظ",
"save": "حفظ",
"go": "اذهب",
"deleteAccount2": "حذف الحساب({1}s)",
"deleteAccount2": "حذف الحساب ({1}ث)",
"areYouSureYouWantToDeleteYourAccount": "هل أنت متأكد أنك تريد حذف حسابك؟",
"enterRoomConfirmTips": "هل أنت متأكد أنك تريد دخول الغرفة؟",
"dailyTasks": "المهام اليومية",
"nickName": "لقب",
"giftSpecialEffects": "هدية المؤثرات الخاصة",
"nickName": "الاسم المستعار",
"giftSpecialEffects": "تأثيرات الهدايا الخاصة",
"country": "دولة",
"basicFeatures": "الميزات الأساسية",
"floatingAnimationInGlobal": "الرسوم المتحركة العائمة في العالم",
"joinMemberTips": "إذا كنت زائرًا في الغرفة، لا يمكنك أخذ الميكروفون.",
"countryRegion": "البلد والمنطقة",
"gender": "جنس",
"likedYourComment": "أعجبتني طاقتك.",
"gender": "الجنس",
"likedYourComment": "أعجب بتعليقك.",
"deleteAccountTips2": "*إذا غيرت رأيك، يمكنك تسجيل الدخول مرة أخرى إلى حسابك الحالي خلال سبعة أيام، وسنقوم تلقائيًا باستعادة حسابك. إذا لم تتم عملية الاستعادة خلال سبعة أيام، فسيتم حذف الحساب نهائيًا",
"deleteAccountTips": "لديك صلاحيات إدارية كاملة على هذا الحساب. إذا كنت تنوي حذف الحساب، يُرجى الانتباه إلى المخاطر التالية المرتبطة بهذه العملية:\n\n1. بمجرد حذف الحساب بنجاح، لن تتمكن من تسجيل الدخول إليه. حذف الحساب إجراء نهائي.\n\n2. بعد حذف الحساب بنجاح، لن تتمكن من استعادة أي بيانات. سيتم حذف جميع المعلومات (بما في ذلك الغرف، والأصدقاء)، والعملة الافتراضية، والهدايا، والعناصر الافتراضية نهائيًا ولن يكون بالإمكان استعادتها.\n\n3. فترة السماح: إذا لم تقم باستعادة الحساب، فلن تتمكن من الوصول إلى صفحة الشراء، أو صفحة السحب، أو أي صفحات أخرى في التطبيق.\n\n4. خلال فترة السماح أو بعد حذف الحساب، ستشير صفحة الملف الشخصي إلى أنه قد تم حذفه. لحماية حسابك من البحث أو الوصول إليه من قِبل الآخرين، سيتم حذف معلوماتك الشخصية من الأنظمة المتعلقة بالوظائف اليومية. عندما يتعلق حذف الحساب بالأمن القومي، أو الإجراءات المدنية أو الجنائية، أو حماية الحقوق والمصالح المشروعة لأطراف ثالثة، يحتفظ المسؤول بحقه في رفض طلب حذف حساب المستخدم.\n\nإذا كنت متأكدًا من رغبتك في حذف جميع بياناتك الشخصية من حسابك الحالي، يُرجى النقر على \"حذف الحساب\".",
"accountDeletionNotice": "إشعار حذف الحساب:",
"entryVehicleAnimation2": "يمكن للمستخدمين الحاصلين على صلاحيات VlP4 أو أعلى استخدام هذه الوظيفة لتعطيل رسوميات المركبات المتحركة.",
"entryVehicleAnimation2": "يمكن للمستخدمين ذوي امتياز VIP4 أو أعلى استخدام هذه الميزة لتعطيل رسوم دخول المركبات المتحركة.",
"entryVehicleAnimation": "الرسوم المتحركة لدخول السيارة",
"man": "رجل",
"woman": "امرأة",
"all": "الكل",
"activity": "نشاط",
"knapsack": "حقيبه",
"areYouRureRoRecharge": "هل أنت متأكد من شحن ؟",
"knapsack": "الحقيبة",
"areYouRureRoRecharge": "هل أنت متأكد أنك تريد إعادة الشحن؟",
"clearMessage": "مسح رسائل الشاشة",
"pleaseSelectaItem": "يرجى اختيار البند",
"pleaseSelectaItem": "يرجى اختيار عنصر",
"birthday": "عيد ميلاد",
"pleaseEnterNickname": "يرجى إدخال لقب.",
"pleaseSelectYourCountry": "يرجى تحديد بلدك.",
"pleaseSelectYourGender": "يرجى تحديد جنسك.",
"dateOfBirth": "تاريخ الميلاد",
"mute": "صامت",
"mute": "كتم",
"exit": "خروج",
"send": "أرسل",
"goldList": "القائمة الذهبية",
"coins": "النقود المعدنية",
"coins": "عملات",
"lockTheRoom": "أغلق الغرفة",
"giftGivingSuccessful": "إن تقديم الهدايا كان ناجحًا.",
"hostCenter": "مركز الاستضافة",
"giftGivingSuccessful": "تم إرسال الهدية بنجاح.",
"hostCenter": "مركز المضيف",
"allOnMicrophone": "الجميع على الميكروفون",
"usersOnMicrophone": "المستخدمون على الميكروفون",
"mInimize": "احتفظ",
@ -572,33 +572,33 @@
"admin": "المشرف",
"member": "عضو",
"guest": "ضيف",
"submit": "تقديم",
"enter": "دخل",
"submit": "إرسال",
"enter": "دخول",
"unLockTheRoom": "افتح الغرفة",
"setRoomPassword": "تعيين كلمة مرور الغرفة",
"inputRoomPassword": "إدخال كلمة مرور الغرفة",
"operationSuccessful": "كانت العملية ناجحة.",
"adminByHomeowner": "يتم تعيين كمسؤول من قبل مالك المنزل.",
"memberByHomeowner": "يتم تعيين كأعضاء من قبل صاحب المنزل.",
"touristByHomeowner": "تم تعيين كسائح من قبل صاحب المنزل.",
"setUpAnIdentity": "أعد إعداد هوية.",
"allInTheRoom": "كل شيء في الغرفة.",
"operationSuccessful": "تمت العملية بنجاح.",
"adminByHomeowner": "تم تعيينه مشرفًا بواسطة مالك الغرفة.",
"memberByHomeowner": "تم تعيينه عضوًا بواسطة مالك الغرفة.",
"touristByHomeowner": "تم تعيينه زائرًا بواسطة مالك الغرفة.",
"setUpAnIdentity": "تعيين هوية",
"allInTheRoom": "الجميع داخل الغرفة",
"theAccountPasswordCannotBeEmpty": "لا يمكن أن يكون الحساب أو كلمة المرور خالية.",
"goldListort": "القائمة الذهبية",
"rechargeList": "قائمة إعادة الشحن",
"becomeHost": "قدّم لتصبح مضيفًاً",
"alreadyAnAdministrator": "مسؤول بالفعل.ً",
"alreadyAnMember": "أنت بالفعل عضو.ً",
"becomeHost": "التقدم لتصبح مضيفًا",
"alreadyAnAdministrator": "هو مشرف بالفعل.",
"alreadyAnMember": "هو عضو بالفعل.",
"touristsCannotSendMessages": "لا يستطيع السائحون إرسال الرسائل",
"touristsAreNotAllowedToGoOnTheMic": "لا يسمح للسياح بالدخول إلى الميكروفون",
"superFans": "المشجعين الخارقين:ً",
"touristsAreNotAllowedToGoOnTheMic": "لا يُسمح للزوار بالصعود إلى الميكروفون",
"superFans": "كبار المعجبين:",
"special": "خاص",
"custom": "مخصص",
"store": "دكان",
"store": "المتجر",
"viewFrame": "عرض الإطار",
"headdress": "إطارات",
"mountains": "مركبات",
"buy": "ابتاع",
"buy": "شراء",
"visitorList": "قائمة الزوار",
"spendCoinsToGainExperiencePoints": "اصرف العملات لكسب نقاط الخبرة",
"howToUpgrade": "كيف يمكن الترقية؟",
@ -609,26 +609,26 @@
"obtain": "الحصول على",
"backTheRoom": "الغرفة الخلفية",
"toConsume": "الاستهلاك",
"profile": "بروفايل",
"profile": "الملف الشخصي",
"wallet": "محفظة",
"giftwall": يفت وول",
"giftwall": دار الهدايا",
"announcement": "إعلان",
"blockedList": "قائمة محظورة",
"blockedList": "قائمة الحظر",
"renewal": "تجديد",
"country2": "بلد:",
"sendTo": "أرسل إلى",
"credits": "الاعتمادات: {1}",
"successfullyUnloaded": "تم تفريغها بنجاح",
"unUse": "استخدام واحد",
"successfulWear": "ملابس ناجحة",
"confirmUnUseTips": "هل تؤكد على إزالته؟",
"successfullyUnloaded": "تمت الإزالة بنجاح",
"unUse": "إزالة الاستخدام",
"successfulWear": "تم الارتداء بنجاح",
"confirmUnUseTips": "هل تؤكد إزالة استخدامه؟",
"inUse": "قيد الاستخدام",
"confirmUseTips": "هل تريد التأكيد على استخدامه؟",
"pleaseUploadUserAvatar": "يرجى رفع صورة شخصية.",
"myItems": "أشيائي",
"myItems": "مقتنياتي",
"confirmBuyTips": "هل أنت متأكد من أنك تريد الشراء؟",
"purchaseIsSuccessful": "الشراء ناجح",
"purchase": "ابتاع",
"purchase": "شراء",
"invitesYouToTheMicrophone": "{1} يدعوك إلى الميكروفون",
"english": "الإنجليزية",
"chinese": "الصينية",
@ -636,6 +636,9 @@
"darkMode": "الوضع الداكن",
"lightMode": "الوضع الفاتح",
"systemDefault": "النظام الافتراضي",
"pleaseGetOnTheMicFirst": "من فضلك استخدم الميكروفون أولاً.",
"pleaseGetOnTheMicFirst": "يرجى الصعود إلى الميكروفون أولاً.",
"welcomeMessage": "مرحبًا بك في تطبيقنا، {name}!",
"operationFail": "فشلت العملية.",
"doYouWantToKeepTheDraft": "هل تريد الاحتفاظ بالمسودة؟",
"duration2": "المدة:{1}"
}

View File

@ -8,7 +8,7 @@
"privaceyPolicy": "গোপনীয়তা নীতি",
"tips": "টিপস",
"mine": "আমার",
"games": "খেলাধুলা",
"games": "গেমস",
"party": "পার্টি",
"yes": "হ্যাঁ",
"bag": "ব্যাগ",
@ -16,9 +16,9 @@
"startYourBrandNewJourney": "আপনার সম্পূর্ণ নতুন যাত্রা শুরু করুন",
"searchNoDataTips": "আপনি যে রুম বা ব্যবহারকারীর আইডি অনুসন্ধান করতে চান তা লিখুন।",
"event": "ইভেন্ট",
"other": "অন্য",
"maliciousHarassment": "দূরাচার হয়রানি",
"roomEdit": "রুম এডিট",
"other": "অন্যান্য",
"maliciousHarassment": "বিদ্বেষমূলক হয়রানি",
"roomEdit": "রুম সম্পাদনা",
"cancelRoomPassword": "আপনি কি নিশ্চিত যে আপনি রুমের পাসওয়ার্ডটি মুছে ফেলতে চান?",
"roomMemberFee": "রুম সদস্য ফি",
"blockedList2": "ব্লক করা তালিকা",
@ -31,25 +31,25 @@
"noHistoricalRecordsAvailable": "কোনও ঐতিহাসিক রেকর্ড পাওয়া যায়নি।",
"inviteNewUsersToEarnCoins": "নতুন ব্যবহারকারীকে আমন্ত্রণ করুন কয়েন উপার্জনের জন্য",
"crateMyRoom": "নিজের রুম তৈরি করুন।",
"myRoom": "আমার র",
"myRoom": "আমার ুম",
"recent": "সাম্প্রতিক",
"popularEvents": "জনপ্রিয় ইভেন্ট",
"casualInteraction": "সাধারণ আলোচনাচিত্র",
"casualInteraction": "সাধারণ আলাপচারিতা",
"haveGamePlayingTips": "আপনার গেমটি চলমান আছে, দয়া করে প্রথমে বর্তমান গেমটি ছাড়ুন, আপনি কি নিশ্চিতভাবে বের হতে চান?",
"historicalTour": "ঐতিহাসিক ভ্রমণ",
"gameCenter": "গেম সেন্টার",
"returnToVoiceChat": "ভয়েস চ্যাটে ফিরে যেতে চাই?",
"returnToVoiceChat": "ভয়েস চ্যাটে ফিরবেন?",
"exitGameMode": "গেম মোড থেকে বের হন",
"enterTheRoom": "ঘরে প্রবেশ করো",
"enterTheRoom": "রুমে প্রবেশ করুন",
"inviteGoRoomTips": "সব সময় তোমার জন্য এখানে আছি, বৃষ্টি হোক বা রোদ। এসে সালাম জানাও!",
"invite": "আমন্ত্রণ করা",
"confirmInviteThisUserToTheRoom": "এই ব্যবহারকারী (ID:{1}) কে রুমে নিমন্ত্রণ নিশ্চিত করবেন?",
"invite": "আমন্ত্রণ",
"confirmInviteThisUserToTheRoom": "এই ব্যবহারকারীকে (ID:{1}) রুমে আমন্ত্রণ জানানো নিশ্চিত করবেন?",
"clearCacheSuccessfully": "ক্যাশ সফলভাবে মুছে ফেলা হয়েছে",
"sent": "পাঠানো হয়েছে",
"keep": "রাখুন",
"open": "খুলুন",
"deleteAccountTips2": "*আপনি যদি মন পরিবর্তন করেন, তবে সাত দিনের মধ্যে আপনার বর্তমান অ্যাকাউন্টে আবার লগইন করতে পারবেন এবং আপনার অ্যাকাউন্ট স্বয়ংক্রিয়ভাবে পুনরুদ্ধার করা হবে। সাত দিনের মধ্যে পুনরুদ্ধার না করলে, অ্যাকাউন্ট স্থায়ীভাবে মুছে ফেলা হবে",
"deleteAccountTips": "আপনার এই অ্যাকাউন্টে সম্পূর্ণ প্রশাসনিক অধিকার রয়েছে। আপনি যদি অ্যাকাউন্ট মুছে ফেলতে চান, তবে এই ক্রিয়াটির সাথে সম্পর্কিত নিম্নলিখিত ঝুঁকিগুলি কृপয়া ভুলবেন না:\n1.অ্যাকাউন্ট সফলভাবে মুছে ফেলা হলে, আপনি আর আপনার বর্তমান অ্যাকাউন্টে লগইন করতে পারবেন না। অ্যাকাউন্ট মুছে ফেলা একটি স্থায়ী ক্রিয়া।\n2. অ্যাকাউন্ট সফলভাবে মুছে ফেলা হলে, আপনি অ্যাকাউন্টের কোনো ডেটা পুনরুদ্ধার করতে পারবেন না। সমস্ত তথ্য (রুম, বন্ধু সহ), ভার্চুয়াল মুদ্রা, উপহার এবং ভার্চুয়াল আইটেম স্থায়ীভাবে মুছে ফেলা হবে এবং পুনরুদ্ধার করা যাবে না।\n3. কুলডাউন সময়: আপনি যদি অ্যাকাউন্ট পুনরুদ্ধার না করেন, তবে আপনি অ্যাপের ক্রয় পৃষ্ঠা, পেমেন্ট উত্তোলন পৃষ্ঠা বা অন্য কোনো পৃষ্ঠায় অ্যাক্সেস করতে পারবেন না।\n4.কুলডাউন সময়কালীন বা অ্যাকাউন্ট মুছে ফেলার পর, প্রোফাইল পৃষ্ঠা এটি মুছে ফেলা হয়েছে বলে দেখাবে। আপনার অ্যাকাউন্ট অন্যদের দ্বারা সনাক্ত বা অ্যাক্সেস করা থেকে বাধা দেওয়ার জন্য, আপনার ব্যক্তিগত তথ্য দৈনন্দিন ফাংশন সম্পর্কিত সিস্টেম থেকে মুছে ফেলা হবে। অ্যাকাউন্ট মুছে ফেলা জাতীয় নিরাপত্তা, নাগরিক বা দণ্ডী মামলা বা তৃতীয় পক্ষের বৈধ অধিকার ও সুবিধার রক্ষণসংস্কারকে অন্তর্ভুক্ত করলে, সরকারি প্রশাসন ব্যবহারকারীর অ্যাকাউন্ট মুছে ফেলার অনুরোধ প্রত্যাখ্যান করার অধিকার সংরক্ষণ করে।\nআপনি যদি আপনার বর্তমান অ্যাকাউন্টের সমস্ত ব্যক্তিগত ডেটা মুছে ফেলতে নিশ্চিত হন, তবে কृপয়া \"অ্যাকাউন্ট মুছে ফেলুন\" বোতামে ক্লিক করুন।",
"deleteAccountTips": "আপনার এই অ্যাকাউন্টে সম্পূর্ণ প্রশাসনিক অধিকার রয়েছে। আপনি যদি অ্যাকাউন্ট মুছে ফেলতে চান, তবে এই ক্রিয়াটির সাথে সম্পর্কিত নিম্নলিখিত ঝুঁকিগুলি অনুগ্রহ করে ভুলবেন না:\n1.অ্যাকাউন্ট সফলভাবে মুছে ফেলা হলে, আপনি আর আপনার বর্তমান অ্যাকাউন্টে লগইন করতে পারবেন না। অ্যাকাউন্ট মুছে ফেলা একটি স্থায়ী ক্রিয়া।\n2. অ্যাকাউন্ট সফলভাবে মুছে ফেলা হলে, আপনি অ্যাকাউন্টের কোনো ডেটা পুনরুদ্ধার করতে পারবেন না। সমস্ত তথ্য (রুম, বন্ধু সহ), ভার্চুয়াল মুদ্রা, উপহার এবং ভার্চুয়াল আইটেম স্থায়ীভাবে মুছে ফেলা হবে এবং পুনরুদ্ধার করা যাবে না।\n3. কুলডাউন সময়: আপনি যদি অ্যাকাউন্ট পুনরুদ্ধার না করেন, তবে আপনি অ্যাপের ক্রয় পৃষ্ঠা, পেমেন্ট উত্তোলন পৃষ্ঠা বা অন্য কোনো পৃষ্ঠায় অ্যাক্সেস করতে পারবেন না।\n4.কুলডাউন সময়কালীন বা অ্যাকাউন্ট মুছে ফেলার পর, প্রোফাইল পৃষ্ঠা এটি মুছে ফেলা হয়েছে বলে দেখাবে। আপনার অ্যাকাউন্ট অন্যদের দ্বারা সনাক্ত বা অ্যাক্সেস করা থেকে বাধা দেওয়ার জন্য, আপনার ব্যক্তিগত তথ্য দৈনন্দিন ফাংশন সম্পর্কিত সিস্টেম থেকে মুছে ফেলা হবে। অ্যাকাউন্ট মুছে ফেলা জাতীয় নিরাপত্তা, নাগরিক বা দণ্ডী মামলা বা তৃতীয় পক্ষের বৈধ অধিকার ও সুবিধার রক্ষণসংস্কারকে অন্তর্ভুক্ত করলে, সরকারি প্রশাসন ব্যবহারকারীর অ্যাকাউন্ট মুছে ফেলার অনুরোধ প্রত্যাখ্যান করার অধিকার সংরক্ষণ করে।\nআপনি যদি আপনার বর্তমান অ্যাকাউন্টের সমস্ত ব্যক্তিগত ডেটা মুছে ফেলতে নিশ্চিত হন, তবে অনুগ্রহ করে \"অ্যাকাউন্ট মুছে ফেলুন\" বোতামে ক্লিক করুন।",
"accountDeletionNotice": "অ্যাকাউন্ট মুছে ফেলার নোটিশ:",
"thisUserHasBeenBlacklisted": "এই ব্যবহারকারী ব্ল্যাকলিস্টে যুক্ত করা হয়েছে।",
"trend": "ট্রেন্ড",
@ -62,7 +62,7 @@
"multiple": "একাধিক",
"successfullyRemovedFromTheBlacklist": "ব্ল্যাকলিস্ট থেকে সফলভাবে সরানো হয়েছে!",
"successfullyAddedToTheBlacklist": "ব্ল্যাকলিস্টে সফলভাবে যুক্ত করা হয়েছে!",
"youAreCurrentlyCPRelationshipPleaseDissolve": "আপনি বর্তমানে একটি CP সম্পর্কে আছেন।\nকृপয়া প্রথমে সম্পর্কটি সমাধান করুন।",
"youAreCurrentlyCPRelationshipPleaseDissolve": "আপনি বর্তমানে একটি CP সম্পর্কে আছেন।\nঅনুগ্রহ করে আগে সম্পর্কটি শেষ করুন।",
"areYouSureToCancelBlacklist": "আপনি কি ব্ল্যাকলিস্ট বাতিল করতে চান?",
"areYouSureYouWantToBlockThisUser": "আপনি কি এই ব্যবহারকারীকে ব্লক করতে চান?",
"removeFromBlacklist": "ব্ল্যাকলিস্ট থেকে সরান",
@ -73,14 +73,14 @@
"newMessage": "নতুন বার্তা",
"createRoomSuccsess": "রুম সফলভাবে তৈরি হয়েছে!",
"contactUs": "আমাদের সাথে যোগাযোগ করুন",
"systemAnnouncementTips1": "ধোঁকাধন্ডা থেকে সতর্ক:",
"systemAnnouncementTips1": "প্রতারণা থেকে সতর্ক থাকুন:",
"systemAnnouncementTips": "শুধুমাত্র অফিসিয়াল চ্যানেলের মাধ্যমে তথ্য যাচাই করুন। কখনওই তৃতীয় পক্ষের সফটওয়্যার ডাউনলোড করবেন না, ব্যক্তিগত তথ্য শেয়ার করবেন না বা বাহ্যিক অনুরোধের উপর অর্থ ট্রান্সফার করবেন না। অফিসিয়াল কর্মী আইডি শুধুমাত্র 10000, 10003 এবং 10086। আপনার কোনো সন্দেহ থাকলে, ক্রিয়াটি বন্ধ করুন এবং এর মাধ্যমে রিপোর্ট করুন",
"systemAnnouncement": "সিস্টেম ঘোষণা",
"doNotClickUnfamiliarTips": "অপরিচিত লিঙ্কে ক্লিক করবেন না, কারণ এগুলি আপনার ব্যক্তিগত তথ্য প্রকাশ করতে পারে। আপনার আইডি নম্বর বা ব্যাংক কার্ডের বিবরণ কখনওই কারো সাথে শেয়ার করবেন না।",
"atTag": "@ট্যাগ",
"sayHi2": "হাই",
"sayHi2": "হাই বলুন",
"canSendMsgTips": "ব্যক্তিগত বার্তা পাঠানোর জন্য উভয় পক্ষকে একে অপরকে ফলো করতে হবে।",
"msgSendRedEnvelopeTips": "*লাল খাম之上 10% সেবা ফি কেটে নেওয়া হবে এবং প্রাপক শুধুমাত্র লাল খামের মানের 90% পাবেন। প্রেরকের সম্পদ স্তর 10 তম স্তরের থেকে বেশি হতে হবে।",
"msgSendRedEnvelopeTips": "*লাল খামের ওপর 10% সেবা ফি কাটা হবে এবং প্রাপক কেবল লাল খামের মূল্যের 90% পাবেন। প্রেরকের সম্পদ স্তর 10-এর উপরে হতে হবে।",
"reapply": "আবার আবেদন করুন",
"cancelRequest": "অনুরোধ বাতিল করুন",
"pending": "পেন্ডিং",
@ -97,7 +97,7 @@
"game": "গেম",
"skip2": "স্কিপ করুন",
"coins4": "কয়েন",
"claim": "দাবি",
"claim": "গ্রহণ",
"complete": "সম্পূর্ণ",
"shareTo": "শেয়ার করুন",
"copyLink": "লিঙ্ক কপি করুন",
@ -106,12 +106,12 @@
"whatsApp": "হোয়াটসঅ্যাপ",
"snapChat": "স্ন্যাপচ্যাট",
"taskNameRoomNewMember": "রুমে নতুন সদস্যের সংখ্যা",
"taskNameRoomOwnerSendRedPacket": "রুম মালিক একটি লাল লিফলেট পাঠান",
"taskNameRoomOwnerSendRedPacket": "রুমের মালিক একটি লাল খাম পাঠান",
"taskNameRoomOwnerSendGiftUser": "রুম মালিক উপহার পাঠান",
"taskNameRoomMicUser120Min": "১২০+ মিনিট মাইকে কাটানো সদস্য",
"taskNameRoomMicUser60Min": "৬০+ মিনিট মাইকে কাটানো সদস্য",
"taskNameRoomMicUser30Min": "৩০+ মিনিট মাইকে কাটানো সদস্য",
"taskNamePersonalSendGift": "অন্যের রুমে মাইক্রোফোনে আসুন",
"taskNamePersonalSendGift": "একজন ব্যবহারকারীকে উপহার পাঠান",
"taskNameRoomOnlineUserCount": "রুমের অনলাইন সদস্যরা",
"taskNameRoomOwnerInviteMic": "সদস্যকে মাইকে আমন্ত্রণ করুন",
"taskNameRoomUserSendGiftGold": "সদস্যদের দেওয়া উপহার কয়েন",
@ -122,16 +122,16 @@
"taskNamePersonalActiveInRoom": "অন্যের রুমে সক্রিয় হোন",
"taskNamePersonalGameConsume": "গেম ব্যয়",
"taskNamePersonalMicInRoom": "মাইকে যান",
"forMoreRewardsPleaseCheckTheTaskCenter": "আরও পুরস্কারের জন্য কृপয়া টাস্ক সেন্টার চেক করুন",
"forMoreRewardsPleaseCheckTheTaskCenter": "আরও পুরস্কারের জন্য অনুগ্রহ করে টাস্ক সেন্টার দেখুন",
"kingQuuen": "রাজা-রানী",
"dailyCoinBonanzaRulesDetail": "১. দৈনিক ব্যক্তিগত কাজ এবং দৈনিক রুম মালিকের কাজ প্রতিটি ব্যবহারকারীর জন্য দিনে একবার সম্পন্ন করা যেতে পারে। কাজগুলি সৌদি সময় :: এ রিসেট হয়।\n২. দৈনিক ব্যক্তিগত কাজ কেবল অন্যের রুমে সম্পন্ন করা যায়; রুম মালিকের কাজ কেবল আপনার নিজের রুমে সম্পন্ন করা যায়।\n৩. উপহার দেওয়ার কাজগুলিতে কেবল রুমে পাঠানো উপহারগুলি গণ্য হবে, ফিডে পাঠানো উপহার নয়।\n. যদি একই ডিভাইস বা একই সিম কার্ড ব্যবহার করে একাধিক অ্যাকাউন্ট তৈরি করা হয়, সমস্ত কাজের পুরস্কার কেবল একবারই দাবি করা যেতে পারে।",
"dailyCoinBonanzaRules": "দৈনিক কয়েন বোনাঞ্জার নিয়ম",
"roomOwnerTasks": "রুম মালিকের কাজ",
"personalTasks": "ব্যক্তিগত কাজ",
"getPaidToRefer": "প্রস্তাব দেওয়ার জন্য অর্থ উপার্জন করুন",
"getPaidToRefer": "রেফার করে আয় করুন",
"ramadan": "রমজান",
"noPromptsToday": "আজ কোনো প্রম্পট নেই।",
"updateNow": "এখন update করুন",
"noPromptsToday": "আজ কোনো কাজ নেই।",
"updateNow": "এখনই আপডেট করুন",
"allGames": "সমস্ত গেম",
"fishClass": "মাছ শ্রেণী",
"greedyClass": "লোভী শ্রেণী",
@ -142,7 +142,7 @@
"chatBox": "চ্যাট বক্স",
"termsOfServicePrivacyPolicyTips": "এগিয়ে যাওয়ার মাধ্যমে আপনি সেবা শর্তাবলী এবং গোপনীয়তা নীতি স্বীকার করছেন",
"and": " এবং ",
"pleaseSelectTheTypeContent": "কृপয়া লঙ্ঘনকারী কন্টেন্টের টাইপ নির্বাচন করুন।",
"pleaseSelectTheTypeContent": "অনুগ্রহ করে লঙ্ঘনকারী কনটেন্টের ধরন নির্বাচন করুন।",
"illegalInformation": "বেআইনি তথ্য",
"inappropriateContent": "অনুপযুক্ত কন্টেন্ট",
"personalAttack": "ব্যক্তিগত আক্রমণ",
@ -150,7 +150,7 @@
"spam": "স্প্যাম",
"countdownMinutes": "কাউন্টডাউন মিনিট :",
"number2": "নম্বর:",
"fraud": "ধোঁকাধন্ডা",
"fraud": "প্রতারণা",
"received": "প্রাপ্ত হয়েছে",
"currentProgress": "বর্তমান অগ্রগতি",
"currentStage": "বর্তমান স্টেজ:{1}",
@ -161,7 +161,7 @@
"lastWeekProgress": "গত সপ্তাহের অগ্রগতি",
"redEnvelopeTips2": "*লাল খাম সময়সীমার মধ্যে দাবি না করলে, বাকি কয়েন প্রেরক ব্যবহারকারীকে ফেরত দেওয়া হবে।",
"goToRecharge": "রিচার্জ করতে যান",
"deleteAccount2": " অ্যাকাউন্ট মুছে ফেলুন({1}সেকেন্ড)",
"deleteAccount2": " অ্যাকাউন্ট মুছে ফেলুন ({1} সেকেন্ড)",
"areYouSureYouWantToDeleteYourAccount": " আপনি কি আপনার অ্যাকাউন্ট মুছে ফেলতে চান?",
"insufhcientGoldsGoToRecharge": "সোনা অপর্যাপ্ত, দ্রুত রিচার্জ করুন!",
"coins2": "{1}কয়েন",
@ -180,7 +180,7 @@
"entertainment": "বিনোদন:",
"reportSucc": "রিপোর্ট সফল",
"pornography": "পর্নোগ্রাফি",
"reportInputTips": "সমস্যাটি বুঝতে এবং সমাধান করতে আমাদের সাহায্য করার জন্য কृপয়া সমস্যাটি যতটা সম্ভব বিস্তারিতভাবে বর্ণনা করুন।",
"reportInputTips": "সমস্যাটি বুঝতে এবং সমাধান করতে আমাদের সাহায্য করার জন্য অনুগ্রহ করে সমস্যাটি যতটা সম্ভব বিস্তারিতভাবে বর্ণনা করুন।",
"cancel": "বাতিল করুন",
"join": "যোগদান করুন",
"items": "আইটেম",
@ -209,12 +209,12 @@
"hobby": "শখ",
"sendCoupontips": "আপনি কি এই কুপনটি এই ব্যবহারকারীকে পাঠাতে চান?",
"youDontHaveAnyCouponsYet": "আপনার এখনও কোনো কুপন নেই।",
"recall": "ফিরে ডাকুন",
"recall": "প্রত্যাহার করুন",
"youHaventFollowed": "আপনি কোনো রুম ফলো করেন না",
"deleteFromMyDevice": "আমার ডিভাইস থেকে মুছে ফেলুন",
"deleteOnAllDevices": "সমস্ত ডিভাইসে মুছে ফেলুন",
"messageHasBeenRecalled": "এই বার্তা ফিরে ডাকা হয়েছে",
"recallThisMessage": "আপনি কি এই বার্তা ফিরে ডাকতে চান?",
"messageHasBeenRecalled": "এই বার্তাটি প্রত্যাহার করা হয়েছে",
"recallThisMessage": "আপনি কি এই বার্তাটি প্রত্যাহার করতে চান?",
"language": "ভাষা",
"feedback": "ফিডব্যাক",
"signedin": "সাইন ইন করা হয়েছে",
@ -245,8 +245,8 @@
"editProfile": "প্রোফাইল সম্পাদনা করুন",
"sendTheCpRequest": "CP অনুরোধ পাঠান",
"addCp": "CP যোগ করুন",
"partWays": "পথ ভেদ করুন",
"reconcile": "মিল করুন",
"partWays": "আলাদা হয়ে যান",
"reconcile": "মিলমিশ করুন",
"separated": "বিচ্ছিন্ন",
"areYouSureYouWantToSpend5": "{1} আপনাকে তার অনুভূতি প্রকাশ করেছে; আপনি যদি গ্রহণ করেন তবে আপনি জোড়া হবেন।",
"areYouSureYouWantToSpend6": "{1} আপনার সাথে আবার মিলিত হতে চান। আপনি যদি মিলনের সিদ্ধান্ত নেন, তবে আপনার সমস্ত পূর্বের ডেটা পুনরুদ্ধার করা হবে।",
@ -254,14 +254,14 @@
"reconcileInvitation": "মিলন আমন্ত্রণ",
"areYouSureYouWantToSpend4": "এই ব্যবহারকারীকে মিলন আমন্ত্রণ পাঠাতে?",
"partWaysTips": "*জোড়ার একজন পার্টনার পথ ভেদ করার সিদ্ধান্ত নিলে, 7 দিনের কুলডাউন সময় থাকবে। এই সময়কালীন উভয় পক্ষই মিলনের সিদ্ধান্ত নিতে পারে এবং মিলনের ক্ষেত্রে সমস্ত ডেটা পুনরুদ্ধার করা হবে। 7 দিনের সময় শেষ হলে মিলন না করলে, জোড়া ডেটা মুছে ফেলা হবে।",
"areYouSureYouWantToPartWaysWithYourCP": "আপনি কি আপনার CP와 পথ ভেদ করতে চান?",
"areYouSureYouWantToPartWaysWithYourCP": "আপনি কি আপনার CP-এর সঙ্গে আলাদা হতে চান?",
"timeSpentTogether": "একসাথে কাটানো সময়: {1} দিন",
"firstDay": "প্রথম দিন:{1}",
"numberOfMyCPs": "আমার CP সংখ্যা:({1}/{2})",
"props": "প্রপস",
"win": "বিজয়ী",
"dice": "ডাইস",
"rps": "কাগজ-কাঁচা-কামড়া",
"rps": "পাথর-কাগজ-কাঁচি",
"operationFail": "অপারেশন ব্যর্থ হয়েছে।",
"likedYourComment": "আপনার মন্তব্য পছন্দ করেছেন।",
"doYouWantToKeepTheDraft": "আপনি কি ড্রাফট রাখতে চান?",
@ -273,8 +273,8 @@
"reject": "প্রত্যাখ্যান করুন",
"accept": "গ্রহণ করুন",
"noMatchedCP": "মিলে যাওয়া CP নেই",
"inviteYouToBecomeBD": "আপনাকে BD बनতে আমন্ত্রণ জানাচ্ছি।",
"adminInviteRechargeAgent": "আপনাকে রিচার্জ এজেন্ট बनতে আমন্ত্রণ জানাচ্ছি।",
"inviteYouToBecomeBD": "আপনাকে BD তে আমন্ত্রণ জানাচ্ছি।",
"adminInviteRechargeAgent": "আপনাকে রিচার্জ এজেন্ট তে আমন্ত্রণ জানাচ্ছি।",
"confirmAcceptTheInvitation": "আপনি কি আমন্ত্রণ গ্রহণ করতে নিশ্চিত করছেন?",
"confirmDeclineTheInvitation": "আপনি কি আমন্ত্রণ প্রত্যাখ্যান করতে নিশ্চিত করছেন?",
"host": "হোস্ট",
@ -292,25 +292,25 @@
"roomAnnouncement": "রুম ঘোষণা",
"help": "সহায়তা",
"rejected": "প্রত্যাখ্যান করা হয়েছে",
"boxContributeTips": "আজ ইতিমধ্যে অবদান রাখা হয়েছে, কृপয়া আবার অবদান না রাখুন",
"boxContributeTips": "আজ ইতিমধ্যে অবদান রাখা হয়েছে, অনুগ্রহ করে আবার অবদান রাখবেন না।",
"bd": "BD",
"coupon": "কুপন",
"search": "সার্চ",
"get": "পান করুন",
"get": "পান",
"inRocket": "রকেটে",
"roomRocketHelpTips": "1. রুমে উপহার পাঠান রকেট শক্তি বাড়ায়। *1 সোনা কয়েন উপহার = 1 রকেট শক্তি পয়েন্ট; ভাগ্যশালী উপহার রকেট শক্তি উপহারের সোনা কয়েন মানের 4% পরিমাণে বাড়ায়।\n2. রকেট শক্তি সম্পূর্ণভাবে পূর্ণ হলে, রুম রকেট চালু করতে পারে। চালু করার পর পুরস্কার স্বয়ংক্রিয়ভাবে বিতরণ করা হবে।\n3. বিভিন্ন রকেট স্তর বিভিন্ন পুরস্কার প্রদান করে।\n4. রকেট চালু হলে, রুমের সমস্ত ব্যবহারকারী রকেট পুরস্কার দাবি করতে পারে।5. রকেট শক্তি প্রতিদিন 00:00 এ শূন্য হয়ে যায়।",
"roomRocketHelpTips": "1. রুমে উপহার পাঠালে রকেটের শক্তি বাড়ে। *1 সোনা কয়েনের উপহার = 1 রকেট শক্তি পয়েন্ট; ভাগ্যবান উপহার রকেটের শক্তি উপহারের সোনা কয়েন মূল্যের 4% পরিমাণে বাড়ায়।\n2. রকেটের শক্তি পুরোপুরি পূর্ণ হলে, রুম থেকে রকেট চালু করা যাবে। চালুর পর পুরস্কার স্বয়ংক্রিয়ভাবে বিতরণ করা হবে।\n3. বিভিন্ন রকেট স্তরে বিভিন্ন পুরস্কার রয়েছে।\n4. রকেট চালু হলে, রুমের সব ব্যবহারকারী রকেট পুরস্কার গ্রহণ করতে পারবেন।\n5. রকেটের শক্তি প্রতিদিন 00:00-এ শূন্য হয়ে যায়।",
"couponRecord": "কুপন ব্যবহার রেকর্ড",
"inRoom": "রুমে",
"searchCouponHint": "কুপন সার্চ করুন",
"giftCounter": "উপহার কাউন্টার",
"bDLeaderInviteYouToBecomeBDLeader": "আপনাকে BD লিডার बनতে আমন্ত্রণ জানাচ্ছি",
"bDLeaderInviteYouToBecomeBDLeader": "আপনাকে BD লিডার তে আমন্ত্রণ জানাচ্ছি",
"wins": "বিজয়",
"inviteYouToBecomeHost": "আপনাকে হোস্ট बनতে আমন্ত্রণ জানাচ্ছি।",
"inviteYouToBecomeHost": "আপনাকে হোস্ট তে আমন্ত্রণ জানাচ্ছি।",
"friends": "বন্ধু",
"deleteConversationTips": "আপনি কি এই ব্যবহারকারীর সাথে চ্যাট ইতিহাস মুছে ফেলতে চান?",
"propMessagePrompt": "প্রপ মেসেজ টিপস",
"inputUserId": "ব্যবহারকারী ID লিখুন",
"fromLuckyGifts": "ভাগ্যশালী/জাদुई উপহার থেকে",
"fromLuckyGifts": "ভাগ্যবান/জাদুকরী উপহার থেকে",
"receive": "প্রাপ্ত করুন",
"checkInSuccessful": "সাইন ইন সফল",
"sginTips": "আপনি প্রতিদিন প্রথমবার সাইন ইন করলে পুরস্কার পাবেন। আপনি যদি সাইন ইন বন্ধ করেন, তবে আবার সাইন ইন করলে পুরস্কার প্রথম দিন থেকে গণনা করা হবে।",
@ -338,7 +338,7 @@
"camera": "ক্যামেরা",
"system": "সিস্টেম",
"notifcation": "নোটিফিকেশন",
"inviteYouToBecomeAgent": "আপনাকে এজেন্ট बनতে আমন্ত্রণ জানাচ্ছি।",
"inviteYouToBecomeAgent": "আপনাকে এজেন্ট তে আমন্ত্রণ জানাচ্ছি।",
"myMusic": "আমার মিউজিক",
"add": "যোগ করুন",
"pullToLoadMore": "লোড করার জন্য টানুন",
@ -354,8 +354,8 @@
"refuse": "প্রত্যাখ্যান করুন",
"agree": "সম্মত হন",
"thisFeatureIsCurrentlyUnavailable": "এই ফিচারটি বর্তমানে অনুপলব্ধ।",
"pleaseSelectTheRecipient": "কृপয়া প্রাপক নির্বাচন করুন।",
"searchMemberIdHint": "কৃপয়া সদস্যের আইডি নম্বর লিখুন",
"pleaseSelectTheRecipient": "অনুগ্রহ করে প্রাপক নির্বাচন করুন।",
"searchMemberIdHint": "অনুগ্রহ করে সদস্যের আইডি নম্বর লিখুন",
"unclaimedRedEnvelopes": "দাবি না করা লাল খাম 24 ঘন্টার মধ্যে ফেরত দেওয়া হবে।",
"redEnvelopeNotYetClaimed": "লাল খাম এখনও দাবি করা হয়নি।",
"redEnvelopeAmount": "লাল খামের পরিমাণ: {1} কয়েন",
@ -364,7 +364,7 @@
"joinRequest": "যোগদানের অনুরোধ",
"scrollToTheBottom": "নিচে স্ক্রোল করুন",
"gameRules": "গেম নিয়ম:",
"charmGameRulesTips": "মিটার প্যানেল খুলুন, মাইক্রোফোনে সমস্ত ব্যবহারকারী প্রাপ্ত উপহার কয়েন দেখান,1 কয়েন উপহার = 1 পয়েন্ট (ভাগ্যশালী উপহার 0.04 পয়েন্ট)।",
"charmGameRulesTips": "ড্যাশবোর্ড চালু করলে মাইকে থাকা সব ব্যবহারকারীর প্রাপ্ত উপহার কয়েন দেখা যাবে; 1 কয়েন = 1 পয়েন্ট (ভাগ্যবান উপহার: 1 কয়েন = 0.04 পয়েন্ট)।",
"inputYourOldPassword": "আপনার পুরানো পাসওয়ার্ড লিখুন",
"enterYourOldPassword": "আপনার পুরানো পাসওয়ার্ড লিখুন",
"setYourPassword": "আপনার পাসওয়ার্ড সেট করুন",
@ -373,7 +373,7 @@
"theTwoPasswordsDoNotMatch": "দুটি পাসওয়ার্ড মিলছে না।",
"resetLoginPasswordtTips2": "পাসওয়ার্ড 8-16 অক্ষরের দৈর্ঘ্যের হতে হবে এবং বড়/ছোট ইংরেজি অক্ষর এবং সংখ্যার সমন্বয়ে গঠিত হতে হবে (শুধুমাত্র সংখ্যা নয়)",
"resetLoginPassword": "লগইন পাসওয়ার্ড রিসেট করুন",
"resetLoginPasswordtTips1": "আপনার ব্যবহারকারী ID বা কাস্টম ID দিয়ে লগইন করুন। আজী অ্যাকাউন্ট দিয়ে লগইন করা আরও নিরাপদ।",
"resetLoginPasswordtTips1": "আপনার ব্যবহারকারী ID বা কাস্টম ID দিয়ে লগইন করুন। yumi অ্যাকাউন্ট দিয়ে লগইন করা আরও নিরাপদ।",
"localMusic": "লোকাল মিউজিক",
"setLoginPassword": "লগইন পাসওয়ার্ড সেট করুন",
"confirmSwitchMicThemeTips": "আপনি কি চেয়ার স্টাইল পরিবর্তন করতে নিশ্চিত করছেন?",
@ -390,7 +390,7 @@
"acceptedYour": "{1} আপনার আমন্ত্রণ গ্রহণ করেছে",
"youAccepted": "আপনি {1} এর আমন্ত্রণ গ্রহণ করেছেন",
"openRedPackDialogTip": "লাল খাম",
"micManagement": "মাইক্রো ম্যানেজমেন্ট",
"micManagement": "মাইক ব্যবস্থাপনা",
"bdCenter": "BD সেন্টার",
"rechargeAgency": "রিচার্জ এজেন্সি",
"adminCenter": "অ্যাডমিন সেন্টার",
@ -400,25 +400,25 @@
"daily": "দৈনন্দিন",
"female": "মহিলা",
"male": "পুরুষ",
"identity": "আইডেন্টিটি",
"identity": "পরিচয়",
"adjust": "সামঞ্জস্য করুন",
"warning": "সতর্কতা",
"screenshotTips": "স্ক্রিনশট (সর্বাধিক 3)",
"roomNotice": "রুম নোটিশ",
"roomTheme": "রুম থিম",
"description": "বর্ণনা:",
"inputDesHint": "সমস্যাটি বুঝতে এবং সমাধান করতে আমাদের সাহায্য করার জন্য কृপয়া সমস্যাটি যতটা সম্ভব বিস্তারিতভাবে বর্ণনা করুন।",
"inputDesHint": "সমস্যাটি বুঝতে এবং সমাধান করতে আমাদের সাহায্য করার জন্য অনুগ্রহ করে সমস্যাটি যতটা সম্ভব বিস্তারিতভাবে বর্ণনা করুন।",
"roomProfilePicture": "রুম প্রোফাইল ছবি",
"userProfilePicture": "ব্যবহারকারী প্রোফাইল ছবি",
"userName": "ব্যবহারকারী নাম",
"pleaseSelectTheTypeToProcess": "কৃপয়া প্রক্রিয়াকরণের টাইপ নির্বাচন করুন:",
"pleaseSelectTheTypeToProcess": "অনুগ্রহ করে প্রক্রিয়াকরণের ধরন নির্বাচন করুন:",
"roomEditing": "রুম সম্পাদনা",
"setAccount": "অ্যাকাউন্ট সেট করুন",
"userEditing": "ব্যবহারকারী সম্পাদনা",
"enterTheUserId": "ব্যবহারকারী ID লিখুন",
"enterTheRoomId": "রুম ID লিখুন",
"deleteAccount": "অ্যাকাউন্ট মুছে ফেলুন",
"becomeAgent": "এজেন্ট बनুন",
"becomeAgent": "এজেন্ট ন",
"enterNickname": "উপনাম লিখুন",
"selectYourCountry": "আপনার দেশ নির্বাচন করুন",
"inviteCode": "আমন্ত্রণ কোড",
@ -426,9 +426,9 @@
"luckGiftSpecialEffects": "ভাগ্যশালী উপহার অ্যানিমেশন প্রভাব",
"theVideoSizeCannotExceed": "ভিডিও আকার 50M অতিক্রম করতে পারবেন না",
"weekly": "সাপ্তাহিক",
"customizedGiftRulesContent": "আমি কীভাবে কাস্টমাইজড গিফট পেতে পারি:\n1.বর্তমান সম্পদ স্তর অনুসারে ব্যবহারকারীর কাস্টমাইজড গিফট পাওয়ার যোগ্যতা নির্ধারণ করুন.\n(1) ব্যবহারকারীর সম্পদ স্তর ≥35 হলে: \nব্যবহারকারী কাস্টমাইজড গিফটের জন্য একবার ভিডিও আপলোড করতে পারেন। আমরা ব্যবহারকারীর বর্তমান প্রোফাইল ছবিকে গিফট ইমেজ হিসেবে এবং প্রদত্ত ভিডিওকে \"কাস্টম\" এর উপর গিফট প্রভাব হিসেবে ব্যবহার করব। প্রDUCTION কিছুটা সময় নেবে এবং স্টোরে উপলব্ধ হওয়ার সাথে সাথে আপনাকে অবহিত করব।\n(2) ব্যবহারকারীর সম্পদ স্তর ≥45 হলে: \nব্যবহারকারী কাস্টমাইজড গিফটের জন্য একবার ভিডিও আপলোড করতে পারেন। আমরা ব্যবহারকারীর বর্তমান প্রোফাইল ছবিকে গিফট ইমেজ হিসেবে এবং প্রদত্ত ভিডিওকে \"কাস্টম\" এর উপর গিফট প্রভাব হিসেবে ব্যবহার করব। প্রDUCTION কিছুটা সময় নেবে এবং স্টোরে উপলব্ধ হওয়ার সাথে সাথে আপনাকে অবহিত করব।\n2.অ্যাপের নির্দিষ্ট কার্যকলাপে অংশ নিতে পারেন এবং মানদণ্ড পূরণ করার পর \"মেসেজ\" → \"আমাদের সাথে যোগাযোগ করুন\" বিভাগ থেকে আমাদের সাথে যোগাযোগ করতে পারেন। কার্যকলাপের স্ক্রিনশট এবং কাস্টমাইজড গিফটের জন্য ব্যবহার করতে চান এমন ভিডিও প্রদান করুন। আমরা আপনার বর্তমান প্রোফাইল ছবিকে গিফট ইমেজ হিসেবে এবং প্রদত্ত ভিডিওকে গিফট প্রভাব হিসেবে ব্যবহার করব, তারপর \"কাস্টম\" এর অধীনে তালিকাভুক্ত করা হবে। প্রDUCTION কিছুটা সময় নেবে এবং স্টোরে উপলব্ধ হওয়ার সাথে সাথে আপনাকে অবহিত করব।\nকাস্টমাইজড গিফটের মেয়াদী সময় & কীভাবে সম্প্রসারিত করব:\nকাস্টমাইজড কাস্টম গিফটগুলি র্যাকে 30 দিনের মেয়াদী সময়সহ থাকবে। কার্যকর এবং অনুপ্রেরণামূলক ব্যবহারকারীদের এই নতুন অভিজ্ঞতা চালিয়ে যেতে এবং তাদের ব্যক্তিগত স্টাইল প্রদর্শন করতে সাহায্য করার জন্য, কাস্টমাইজড গিফট ধারণকারী ব্যবহারকারীরা যেকোনো মাসে 500 মার্কিন ডলার রিচার্জ করে তাদের সমস্ত কাস্টমাইজড গিফটের র্যাক সময় 30 দিন বাড়াতে পারেন।",
"customizedGiftRulesContent": "আমি কীভাবে আমার কাস্টমাইজড গিফট পেতে পারি:\n1. ব্যবহারকারীর বর্তমান সম্পদ স্তরের ভিত্তিতে কাস্টমাইজড গিফট পাওয়ার যোগ্যতা নির্ধারণ করা হবে।\n(1) ব্যবহারকারীর সম্পদ স্তর ≥35 হলে:\nব্যবহারকারী একবার একটি ভিডিও আপলোড করতে পারেন। আমরা ব্যবহারকারীর বর্তমান প্রোফাইল ছবিকে গিফটের ছবি হিসেবে এবং আপলোড করা ভিডিওটিকে \"কাস্টম\" বিভাগের গিফট ইফেক্ট হিসেবে ব্যবহার করব। এটি তৈরি হতে কিছুটা সময় লাগবে; স্টোরে উপলব্ধ হলে আপনাকে জানানো হবে।\n(2) ব্যবহারকারীর সম্পদ স্তর ≥45 হলে:\nব্যবহারকারী একবার একটি ভিডিও আপলোড করতে পারেন। আমরা ব্যবহারকারীর বর্তমান প্রোফাইল ছবিকে গিফটের ছবি হিসেবে এবং আপলোড করা ভিডিওটিকে \"কাস্টম\" বিভাগের গিফট ইফেক্ট হিসেবে ব্যবহার করব। এটি তৈরি হতে কিছুটা সময় লাগবে; স্টোরে উপলব্ধ হলে আপনাকে জানানো হবে।\n2. আপনি অ্যাপের নির্দিষ্ট কিছু কার্যক্রমে অংশ নিতে পারেন। শর্ত পূরণ হলে \"মেসেজ\" → \"আমাদের সাথে যোগাযোগ করুন\" বিভাগ থেকে আমাদের সঙ্গে যোগাযোগ করুন। কার্যক্রমের স্ক্রিনশট এবং কাস্টমাইজড গিফটের জন্য যে ভিডিওটি ব্যবহার করতে চান তা পাঠান। আমরা আপনার বর্তমান প্রোফাইল ছবিকে গিফটের ছবি হিসেবে এবং ভিডিওটিকে গিফট ইফেক্ট হিসেবে ব্যবহার করব, এরপর সেটি \"কাস্টম\" বিভাগের অধীনে যুক্ত করা হবে। এটি তৈরি হতে কিছুটা সময় লাগবে; স্টোরে উপলব্ধ হলে আপনাকে জানানো হবে।\nকাস্টমাইজড গিফটের মেয়াদ ও বাড়ানোর উপায়:\nএক্সক্লুসিভ কাস্টমাইজড গিফট 30 দিনের জন্য স্টোরে উপলব্ধ থাকবে। প্রভাবশালী ও অনুপ্রেরণাদায়ক ব্যবহারকারীরা যাতে এই অভিজ্ঞতা আরও দীর্ঘ সময় উপভোগ করতে পারেন, সে জন্য কাস্টমাইজড গিফটধারী ব্যবহারকারীরা যেকোনো মাসে 500 মার্কিন ডলার রিচার্জ করে তাদের স কাস্টমাইজড গিফটের ময়াদ আরও 30 দিন বাড়াতে পারেন।",
"customizedGiftRules": "কাস্টমাইজড গিফট নিয়ম",
"rulesUpload": "নিয়ম&আপলোড",
"rulesUpload": "নিয়মআপলোড",
"monthly": "মাসিক",
"message": "মেসেজ",
"clearCache": "ক্যাশ মুছে ফেলুন",
@ -438,10 +438,10 @@
"joinRoomTips": "রুমে যোগদান করেছেন !",
"roomSetting": "রুম সেটিংস",
"roomDetails": "রুম বিবরণ",
"systemRoomTips": "শিষ্টাচার এবং সম্মানজনক হোন। আজীতে কোনো পর্নোগ্রাফিক বা অনুপযুক্ত কন্টেন্ট একেবারে নিষিদ্ধ। সনাক্ত হলে, অ্যাকাউন্ট স্থায়ীভাবে ব্লক করা হবে। কृপয়া আজী প্ল্যাটফর্মের নিয়মাবলী সচেতনভাবে অনুসরণ করুন।",
"systemRoomTips": "ভদ্র ও সম্মানজনক থাকুন। yumi-তে যেকোনো পর্নোগ্রাফিক বা অশালীন কনটেন্ট কঠোরভাবে নিষিদ্ধ। এ ধরনের কিছু ধরা পড়লে অ্যাকাউন্ট স্থায়ীভাবে ব্লক করা হবে। অনুগ্রহ করে yumi প্ল্যাটফর্মের নিয়ম মেনে চলুন।",
"copiedToClipboard": "ক্লিপবোর্ডে কপি করা হয়েছে",
"recharge": "রিচার্জ করুন",
"receivedFromALuckyGift": "ভাগ্যশালী/জাদुई গিফট থেকে প্রাপ্ত হয়েছে।",
"receivedFromALuckyGift": "ভাগ্যবান/জাদুকরী গিফট থেকে প্রাপ্ত হয়েছে।",
"followedYou": "আপনাকে ফলো করেছেন",
"agentCenter": "এজেন্ট সেন্টার",
"areYouSureYouWantToClearLocalCache": "আপনি কি লোকাল ক্যাশ মুছে ফেলতে চান?",
@ -454,21 +454,21 @@
"importantReminder": "গুরুত্বপূর্ণ স্মারক",
"entryVehicleAnimation": "প্রবেশ যান অ্যানিমেশন",
"floatingAnimationInGlobal": "গ্লোবালে ভাসমান অ্যানিমেশন",
"entryVehicleAnimation2": "VIP4 বা তার বেশি অধিকার ધারণকারী ব্যবহারকারীরা ফাংশন ব্যবহার করে গাড়ির অ্যানিমেশন বন্ধ করতে পারেন।",
"entryVehicleAnimation2": "VIP4 বা তার বেশি অধিকারধারী ব্যবহারকারীরা এই ফিচার ব্যবহার করে গাড়ির অ্যানিমেশন বন্ধ করতে পারেন।",
"dailyTasks": "দৈনন্দিন টাস্ক",
"enterRoomConfirmTips": "আপনি কি রুমে যেতে চান?",
"followSucc": "সফলভাবে ফলো করা হয়েছে",
"goldListort": "সোনা তালিকা",
"rechargeList": "রিচার্জ তালিকা",
"edit": "সম্পাদনা করুন",
"swipeLeftOnTheFloatingScreenAreaToQuicklyCloseIt": "*টিপস: ভাসমান স্ক্রিন এলাকায় বামে সвайপ করে দ্রুত বন্ধ করুন।",
"swipeLeftOnTheFloatingScreenAreaToQuicklyCloseIt": "*টিপস: ভাসমান স্ক্রিন এলাকায় বামে সোয়াইপ করে দ্রুত বন্ধ করুন।",
"enterThisVoiceChatRoom": "আপনি কি এই ভয়েস চ্যাট রুমে যেতে চান?",
"go": "যান",
"done": "সম্পন্ন",
"improvementTasks": "সুশোধন টাস্ক",
"improvementTasks": "উন্নয়ন টাস্ক",
"save": "সংরক্ষণ করুন",
"kickPrevention": "কিক প্রতিরোধ",
"freeChatSpeak": "বিনামূল্যে চ্যাট & কথা বলুন",
"freeChatSpeak": "বিনামূল্যে চ্যাট কথা বলুন",
"nickName": "উপনাম",
"gender": "লিঙ্গ",
"unFollow": "আনফলো করুন",
@ -487,9 +487,9 @@
"exclusiveEmojiWillBeReleasedAfterBecoming": "এক্সক্লুসিভ ইমোজি হওয়ার পরে মুক্তি পাবে",
"preventBeingBlocked": "ব্লক হওয়া প্রতিরোধ করুন",
"enableRankIncognitoMode": "র‌্যাঙ্ক ইনকগনিটো মোড সক্ষম করুন",
"avoidBeingKicked": "পেটানো থেকে বিরত থাকুন",
"avoidBeingKicked": "রুম থেকে বের হয়ে যাওয়া এড়ান",
"privileges": "{1} সুবিধাসমূহ",
"andAboveUsers": "{1} এবং উপরের ব্যবহারকারীরা",
"andAboveUsers": "{1} এবং তার ঊর্ধ্বের ব্যবহারকারীরা",
"basicPermissions": "মূল অনুমতিসমূহ",
"mysteriousInvisibility": "রহস্যময় অদৃশ্যতা",
"antiBlock": "ব্লক-বিরোধী",
@ -500,20 +500,20 @@
"membershipFreeChatSpeak": "সদস্যতা ছাড়াই চ্যাট ও কথা বলা",
"startVoiceParty": "ভয়েস পার্টি শুরু করুন!",
"enterRoomTips": "{1} রুমে প্রবেশ করেছেন",
"roomName": "রুম নাম",
"roomName": "রুমের নাম",
"roomMember": "রুম সদস্য",
"priorityRoomSorting": "প্রাথমিক কক্ষ শ্রেণীবিন্যাস",
"userColoredID": "ব্যবহারকারী রঙিন পরিচয়পত্র",
"pleaseSelectYourCountry": "কৃপয়া আপনার দেশ নির্বাচন করুন।",
"pleaseSelectYourGender": "কৃপয়া আপনার লিঙ্গ নির্বাচন করুন।",
"pleaseEnterNickname": "কৃপয়া একটি উপনাম লিখুন।",
"countryRegion": "দেশ&অঞ্চল",
"priorityRoomSorting": "অগ্রাধিকারভিত্তিক রুম সাজানো",
"userColoredID": "রঙিন ব্যবহারকারী আইডি",
"pleaseSelectYourCountry": "অনুগ্রহ করে আপনার দেশ নির্বাচন করুন।",
"pleaseSelectYourGender": "অনুগ্রহ করে আপনার লিঙ্গ নির্বাচন করুন।",
"pleaseEnterNickname": "অনুগ্রহ করে একটি উপনাম লিখুন।",
"countryRegion": "দেশঅঞ্চল",
"dateOfBirth": "জন্ম তারিখ",
"mute": "মিউট করুন",
"exit": "প্রস্থান",
"pleaseSelectaItem": "কৃপয়া একটি আইটেম নির্বাচন করুন",
"areYouRureRoRecharge": "আপনি কি রিচার্জ করতে চান?",
"mInimize": "রাখো",
"pleaseSelectaItem": "অনুগ্রহ করে একটি আইটেম নির্বাচন করুন",
"areYouRureRoRecharge": "আপনি কি নিশ্চিত যে রিচার্জ করতে চান?",
"mInimize": "ছোট করুন",
"roomOwner": "রুমের মালিক",
"hostCenter": "হোস্ট সেন্টার",
"allOnMicrophone": "সবাই মাইক্রোফোনে",
@ -522,16 +522,16 @@
"send": "পাঠান",
"crop": "ক্রপ করুন",
"finish": "শেষ করুন",
"takeTheMic": "মাইক্রো নিন",
"openTheMic": "মাইক্রো খুলুন",
"takeTheMic": "মাইকে উঠুন",
"openTheMic": "মাইক চালু করুন",
"muteTheMic": "মাইক্রো মিউট করুন",
"unlockTheMic": "মাইক্রো আনলক করুন",
"unlockTheMic": "মাইক আনলক করুন",
"leavelTheMic": "মাইক্রো ছেড়ে দিন",
"lockTheMic": "মাইক্রো লক করুন",
"removeTheMic": "মাইক্রো সরান",
"inviteToTheMicrophone": "মাইক্রোফোনে আমন্ত্রণ দিন",
"openUserProfleCard": "ব্যবহারকারী প্রোফাইল কার্ড খুলুন",
"obtain": "প্রপ্ত করুন",
"obtain": "পান",
"win2": "{1} বিজয়",
"backTheRoom": "রুমে ফিরে যান",
"toConsume": "খরচ করার জন্য",
@ -548,16 +548,16 @@
"guest": "অতিথি",
"submit": "জমা দিন",
"membershipFee": "সদস্যপদ ফি",
"membershipFeeTips1": "কৃপয়া আপনার রুমের জন্য সদস্যপদ ফি সেট করুন। ব্যবহারকারীরা ফি পরিশোধ করে আপনার রুমে যোগদান করতে পারেন।",
"membershipFeeTips1": "অনুগ্রহ করে আপনার রুমের জন্য সদস্যপদ ফি সেট করুন। ব্যবহারকারীরা ফি পরিশোধ করে আপনার রুমে যোগদান করতে পারেন।",
"membershipFeeTips2": "রুম সদস্য হওয়ার জন্য ব্যবহারকারীর প্রয়োজনীয় সোনা।রুম মালিক সোনার 50% পাবেন।",
"freePrice": "ফি:0-10000",
"touristsSendText": "পর্যটক টেক্সট পাঠায়",
"touristsTakeToTheMic": "পর্যটক মাইক্রো নেয়",
"touristsSendText": "পর্যটকরা টেক্সট পাঠাতে পারে",
"touristsTakeToTheMic": "পর্যটকরা মাইকে উঠতে পারে",
"theMembershipFee": "সদস্যপদ ফি",
"theModificationsMade": "এবার করা পরিবর্তনগুলি প্রস্থানের পর সংরক্ষণ করা হবে না",
"viewFrame": "ফ্রেম দেখুন",
"enterRoomName": "রুম নাম লিখুন",
"headdress": "হেডড্রেস",
"headdress": "ফ্রেম",
"mountains": "গাড়ি",
"purchaseIsSuccessful": "ক্রয় সফল",
"buy": "কিনুন",
@ -585,12 +585,12 @@
"logIn": "লগইন করুন",
"saySomething": "কিছু বলুন...",
"sayHi": "হাই..",
"pleaseChatFfriendly": "কৃপয়া বন্ধুত্বপূর্ণভাবে চ্যাট করুন",
"pleaseChatFfriendly": "অনুগ্রহ করে বন্ধুত্বপূর্ণভাবে চ্যাট করুন",
"unLockTheRoom": "রুম আনলক করুন",
"operationSuccessful": "অপারেশন সফল হয়েছে।",
"adminByHomeowner": "হোম ওনার দ্বারা অ্যাডমিন হিসেবে নিযুক্ত করা হয়েছে।",
"memberByHomeowner": "হোম ওনার দ্বারা সদস্য হিসেবে নিযুক্ত করা হয়েছে।",
"touristByHomeowner": "হোম ওনার দ্বারা পর্যটক হিসেবে নিযুক্ত করা হয়েছে।",
"adminByHomeowner": "রুমের মালিক আপনাকে অ্যাডমিন করেছেন।",
"memberByHomeowner": "রুমের মালিক আপনাকে সদস্য করেছেন।",
"touristByHomeowner": "রুমের মালিক আপনাকে পর্যটক করেছেন।",
"becomeHost": "হোস্ট হতে আবেদন করুন",
"superFans": " সুপার ফ্যান:",
"setUpAnIdentity": "আইডেন্টিটি সেট আপ করুন",
@ -609,7 +609,7 @@
"special": "বিশেষ",
"visitorList": "ভিজিটর তালিকা",
"successfulWear": "সফলভাবে পরা হয়েছে",
"confirmUnUseTips": "আপনি কি অপসারণ করতে নিশ্চিত করছেন?",
"confirmUnUseTips": "আপনি কি এটি খুলে ফেলতে চান?",
"custom": "কাস্টম",
"myItems": "আমার আইটেম",
"use": "ব্যবহার করুন",
@ -623,12 +623,12 @@
"country2": "দেশ:",
"sendTo": "পাঠানো হবে",
"credits": "ক্রেডিট: {1}",
"successfullyUnloaded": "সফলভাবে আনলোড করা হয়েছে",
"successfullyUnloaded": "সফলভাবে সরানো হয়েছে",
"expired": "মেয়াদ শেষ",
"day": "দিন",
"inUse": "ব্যবহারে",
"confirmUseTips": "আপনি কি ব্যবহার করতে নিশ্চিত করছেন?",
"pleaseUploadUserAvatar": "কৃপয়া একটি প্রোফাইল ছবি আপলোড করুন।",
"pleaseUploadUserAvatar": "অনুগ্রহ করে একটি প্রোফাইল ছবি আপলোড করুন।",
"joinMemberTips": "আপনি যদি রুমে পর্যটক হন, তবে আপনি মাইক্রোফোন নিতে পারবেন না।",
"giftGivingSuccessful": "গিফট দেওয়া সফল।",
"theAccountPasswordCannotBeEmpty": "অ্যাকাউন্ট বা পাসওয়ার্ড খালি হতে পারে না।",
@ -639,6 +639,6 @@
"darkMode": "ডার্ক মোড",
"lightMode": "লাইট মোড",
"systemDefault": "সিস্টেম ডিফল্ট",
"pleaseGetOnTheMicFirst": "কৃপয়া প্রথমে মাইক্রোফোনে যান।",
"pleaseGetOnTheMicFirst": "অনুগ্রহ করে আগে মাইকে উঠুন।",
"duration2": "সময়:{1}"
}

View File

@ -5,9 +5,9 @@
"signInWithApple": "Sign in with Apple",
"loginRepresentsAgreementTo": "Login represents agreement to",
"termsofService": "Terms of service",
"privaceyPolicy": "Privacey Policy",
"privaceyPolicy": "Privacy Policy",
"tips": "Tips",
"searchNoDataTips": "Enter the room or user lD you want to search.",
"searchNoDataTips": "Enter the room or user ID you want to search for.",
"games": "Games",
"mine": "Mine",
"party": "Party",
@ -43,13 +43,13 @@
"recent": "Recent",
"popularEvents": "Popular Events",
"inviteGoRoomTips": "Always here for you, rain or shine. Drop in and say hi!",
"confirmInviteThisUserToTheRoom": "Confirm invite this user(ID:{1}) to the room?",
"confirmInviteThisUserToTheRoom": "Confirm inviting this user (ID:{1}) to the room?",
"clearCacheSuccessfully": "Clear cache successfully",
"sent": "Sent",
"keep": "Keep",
"open": "Open",
"deleteAccountTips2": "*lf you change your mind, you can log back into your current account with in seven days, and we will automatically restore your account. lf no restoration occurs within seven days, the account will be permanently deleted",
"deleteAccountTips": "You have full administrative rights to this account. lf you intend to delete the account, please be aware of the following risks associated with this operation:\n1.Once the account is successfully deleted, you will no longer be able to login to your current account. Account deletion is a permanent action.\n2. After the account is successfully deleted, you will not be able to recover any account data. All information (including rooms, friends), virtual currency, gifts, and virtual items will be permanently deleted and cannot be restored.\n3. Cooling-off period: lf you do not restore the account, you will be unable to access the purchase page, withdrawal page, or any other pages on the app.\n4.During the cooling-off period or after the account has been deleted, the profile page will indicate that it has been deleted. To protect your account from being searched or accessed by others, your personal information will be removed from systems related to daily functions. When account deletion involves national security, civil or criminal proceedings, or the protection of the legitimate rights and interests of third parties, the official reserves the right to reject the user's account deletion request.\nIf you are certain that you want to delete all personal data from your current account, please click \"Delete Account.\"",
"deleteAccountTips2": "*If you change your mind, you can log back into your current account within seven days, and we will automatically restore your account. If no restoration occurs within seven days, the account will be permanently deleted.",
"deleteAccountTips": "You have full administrative rights to this account. If you intend to delete the account, please be aware of the following risks associated with this operation:\n1. Once the account is successfully deleted, you will no longer be able to log in to your current account. Account deletion is a permanent action.\n2. After the account is successfully deleted, you will not be able to recover any account data. All information (including rooms and friends), virtual currency, gifts, and virtual items will be permanently deleted and cannot be restored.\n3. Cooling-off period: If you do not restore the account, you will be unable to access the purchase page, withdrawal page, or any other pages in the app.\n4. During the cooling-off period or after the account has been deleted, the profile page will indicate that it has been deleted. To protect your account from being searched or accessed by others, your personal information will be removed from systems related to daily functions. When account deletion involves national security, civil or criminal proceedings, or the protection of the legitimate rights and interests of third parties, the official team reserves the right to reject the user's account deletion request.\nIf you are certain that you want to delete all personal data from your current account, please click \"Delete Account.\"",
"accountDeletionNotice": "Account Deletion Notice:",
"thisUserHasBeenBlacklisted": "This user has been blacklisted.",
"trend": "Trend",
@ -71,7 +71,7 @@
"specialEffectsManagement": "Special effects management",
"wishingYouHappinessEveryDay": "Wishing you happiness every day.",
"newMessage": "New message",
"createRoomSuccsess": "Create room succsess!",
"createRoomSuccsess": "Room created successfully!",
"contactUs": "Contact Us",
"systemAnnouncementTips1": "Guard against fraud:",
"systemAnnouncementTips": "Verify information solely through official channels. Never download third-party software, share personal data, or transfer money based on external requests. Official staff IDs are only 10000, 10003, and 10086. For any suspicion, stop and report via",
@ -93,14 +93,14 @@
"memberList": "Member List",
"treasureChest": "Treasure Chest",
"applicationRecord": "Application Record",
"appUpdateTip": "The app has a new version ({1}), please go and download it?",
"ownerIncomeCoins": "Owner's income:{1} coins",
"appUpdateTip": "The app has a new version ({1}). Would you like to download it now?",
"ownerIncomeCoins": "Owner's income: {1} coins",
"game": "Game",
"skip2": "Skip",
"coins4": "Coins",
"weekStart": "Week-Start",
"forMoreRewardsPleaseCheckTheTaskCenter": "For more rewards,please check the task center",
"kingQuuen": "King-Quuen",
"forMoreRewardsPleaseCheckTheTaskCenter": "For more rewards, please check the task center",
"kingQuuen": "King-Queen",
"ramadan": "Ramadan",
"updateNow": "Update Now",
"allGames": "All Games",
@ -128,16 +128,16 @@
"roomReward2": "Room Reward:{1}",
"roomReward": "Room Reward",
"expirationTime": "Expiration time",
"ownerSendTheRedEnvelope": "Owner send the Reward coins.",
"ownerSendTheRedEnvelope": "The owner sent reward coins.",
"rewardCoins": "Reward coins:{1} coins",
"lastWeekProgress": "Last week's progress",
"redEnvelopeTips2": "*If the red envelope is not claimed within the time limit, the remaining coins will be returned to the user who sent the red envelope.",
"goToRecharge": "Go to recharge",
"deleteAccount2": " Delete Account({1}s)",
"deleteAccount2": " Delete Account ({1}s)",
"areYouSureYouWantToDeleteYourAccount": " Are you sure you want to delete your account?",
"insufhcientGoldsGoToRecharge": "Insufhcient golds,recharge now!",
"coins2": "{1}Coins",
"remainingNumberTips": "Remaining number of available:({1}/{2})",
"insufhcientGoldsGoToRecharge": "Insufficient gold. Recharge now!",
"coins2": "{1} Coins",
"remainingNumberTips": "Remaining available: ({1}/{2})",
"collectionTimeTips": "Collection time:{1}({2}/{3})",
"sendARedEnvelope": "Send a red envelope",
"sendRedPackConfirmTips": "Are you sure you want to send the red packet?",
@ -152,11 +152,11 @@
"entertainment": "Entertainment:",
"reportSucc": "Report successful",
"pornography": "Pornography",
"reportInputTips": "Please describe the problem in as much detail as possible sothat we can understand and solve it.",
"reportInputTips": "Please describe the problem in as much detail as possible so that we can understand and solve it.",
"cancel": "Cancel",
"join": "Join",
"items": "Items",
"vistors": "Vistors",
"vistors": "Visitors",
"fans": "Fans",
"balanceNotEnough": "Insufficient gold coin balance. Do you want to go to top up?",
"skip": "Skip {1}",
@ -199,19 +199,19 @@
"logout": "Logout",
"luck": "Luck",
"level": "Level",
"themeGoToUploadTips": "1.Review within24 hours after the upload is successful.\n2.All coins will be returned if the review fails.",
"themeGoToUploadTips": "1. Review will be completed within 24 hours after the upload succeeds.\n2. All coins will be returned if the review fails.",
"home": "Home",
"explore": "Explore",
"me": "Me",
"socialPrivilege": "Social privilege",
"information": "Information",
"myPhoto": "My Photo",
"areYouSureYouWantToSpend3": "*lf the other party declines the CP invitation, your coins willbe returned to your wallet.",
"areYouSureYouWantToSpend3": "*If the other party declines the CP invitation, your coins will be returned to your wallet.",
"areYouSureYouWantToSpend": "Are you sure you want to spend",
"areYouSureYouWantToSpend2": "to send a CP invitation to this user?",
"underReview": "Under review",
"doYouWantToDeleteIt": "Do you want to delete it?",
"chooseFromAblum": "Choose from Ablum",
"chooseFromAblum": "Choose from Album",
"spaceBackground": "Space Background",
"editProfile": "Edit Profile",
"sendTheCpRequest": "Send the CP request",
@ -220,11 +220,11 @@
"reconcile": "Reconcile",
"separated": "Separated",
"areYouSureYouWantToSpend5": "{1} confessed the feeling to you; if you accept, you will become a couple.",
"areYouSureYouWantToSpend6": "{1} wants to get back together with you. lf you decide to reconcile, all of your previous data will be restored.",
"reconcileInvitationTips": "*lf the other party declines the CP invitation, your coins willbe returned to your wallet.",
"areYouSureYouWantToSpend6": "{1} wants to get back together with you. If you decide to reconcile, all of your previous data will be restored.",
"reconcileInvitationTips": "*If the other party declines the CP invitation, your coins will be returned to your wallet.",
"reconcileInvitation": "Reconcile Invitation",
"areYouSureYouWantToSpend4": "to send a reconciliation invitation to this user?",
"partWaysTips": "*lf one partner in a couple chooses to part ways, there willbe a 7-day cooling-off period. During this time, both partiescan choose to reconcile, and all data will be restored uponreconciliation. lf no reconciliation is chosen by the end ofthe 7-day period, the couple's data will be cleared.",
"partWaysTips": "*If one partner in a couple chooses to part ways, there will be a 7-day cooling-off period. During this time, both parties can choose to reconcile, and all data will be restored upon reconciliation. If no reconciliation is chosen by the end of the 7-day period, the couple's data will be cleared.",
"areYouSureYouWantToPartWaysWithYourCP": "Are you sure you want to part ways with your CP?",
"timeSpentTogether": "Time spent together: {1} days",
"firstDay": "First day:{1}",
@ -233,8 +233,8 @@
"win": "Win",
"dice": "Dice",
"rps": "RPS",
"operationFail": "The operation was fail.",
"likedYourComment": "Liked your Comment.",
"operationFail": "The operation failed.",
"likedYourComment": "Liked your comment.",
"doYouWantToKeepTheDraft": "Do you want to keep the draft?",
"operationsAreTooFrequent": "Operations are too frequent",
"luckNumber": "Luck Number",
@ -247,7 +247,7 @@
"inviteYouToBecomeBD": "Invite you to become a BD.",
"adminInviteRechargeAgent": "Invite you to become a Recharge agent.",
"confirmAcceptTheInvitation": "Confirm to accept the invitation?",
"confirmDeclineTheInvitation": "Confirm decline of the invitation?",
"confirmDeclineTheInvitation": "Confirm declining the invitation?",
"host": "Host",
"following": "Following",
"agent": "Agency",
@ -263,13 +263,13 @@
"roomAnnouncement": "Room Announcement",
"help": "Help",
"rejected": "Rejected",
"boxContributeTips": "Investment has already been made today, please do not invest again",
"boxContributeTips": "Investment has already been made today. Please do not invest again.",
"bd": "BD",
"coupon": "Coupon",
"search": "Search",
"get": "Get",
"inRocket": "In the rocket",
"roomRocketHelpTips": "1. Sending gifts in the room increases rocket energy. *1 gold coin gift = 1 rocket energy point; lucky gifts increase rocket energy by 4% of the gift's gold coin value.\n2. Once the rocket energy is fully charged, the room can launch the rocket. Rewards will be automatically distributed after launch.\n3. Different rocket levels offer different rewards.\n4. When the rocket launches, all users in the room can claim the rocket reward.5. Rocket energy is reset at 00:00 every day.",
"roomRocketHelpTips": "1. Sending gifts in the room increases rocket energy. *1 gold coin gift = 1 rocket energy point; lucky gifts increase rocket energy by 4% of the gift's gold coin value.\n2. Once the rocket energy is fully charged, the room can launch the rocket. Rewards will be automatically distributed after launch.\n3. Different rocket levels offer different rewards.\n4. When the rocket launches, all users in the room can claim the rocket reward.\n5. Rocket energy is reset at 00:00 every day.",
"couponRecord": "Coupon usage record",
"inRoom": "In Room",
"searchCouponHint": "Search Coupon",
@ -281,10 +281,10 @@
"deleteConversationTips": "Are you sure you want to delete the chat history with this user?",
"propMessagePrompt": "Prop message prompt",
"inputUserId": "Enter User ID",
"fromLuckyGifts": "from lucky/magic gifts",
"fromLuckyGifts": "From lucky/magic gifts",
"receive": "Receive",
"checkInSuccessful": "Check-in successful",
"sginTips": "You will get reward at the frst time you log in eachday. lf you interrupt your login, the reward will becalculated from the frst day when you log in again.",
"sginTips": "You will get a reward the first time you log in each day. If you interrupt your login streak, the reward will be recalculated from the first day when you log in again.",
"popular": "Popular",
"recommend": "Recommend",
"follow": "Follow",
@ -308,7 +308,7 @@
"album": "Album",
"camera": "Camera",
"system": "System",
"notifcation": "Notice",
"notifcation": "Notification",
"inviteYouToBecomeAgent": "Invite you to become a agency.",
"myMusic": "My Music",
"add": "Add",
@ -335,16 +335,16 @@
"joinRequest": "Join Request",
"scrollToTheBottom": "Scroll to the bottom",
"gameRules": "Game Rules:",
"charmGameRulesTips": "Turn on the dashboard to show received gift coin of all users on mic,1 coin = 1 score (Lucky gift 1 coin = 0.04 score).",
"charmGameRulesTips": "Turn on the dashboard to show the received gift coins of all users on mic. 1 coin = 1 score (Lucky gift: 1 coin = 0.04 score).",
"inputYourOldPassword": "Input your old password",
"enterYourOldPassword": "Enter your old password",
"setYourPassword": "Set your password",
"enterYourNewPassword": "Enter your new password",
"confirmYourPassword": "Confirm your password",
"theTwoPasswordsDoNotMatch": "The two passwords do not match.",
"resetLoginPasswordtTips2": "The password must be 8-16 characters long and must be a combination ofuppercase and lowercase English letters and numbers (not just numbers)",
"resetLoginPasswordtTips2": "The password must be 8-16 characters long and must be a combination of uppercase and lowercase English letters and numbers (not just numbers).",
"resetLoginPassword": "Reset Login Password",
"resetLoginPasswordtTips1": "Log in with your user ID or vanity ID. lt is safer to log in with a yumi account.",
"resetLoginPasswordtTips1": "Log in with your user ID or vanity ID. It is safer to log in with a yumi account.",
"localMusic": "Local Music",
"setLoginPassword": "Set Login Password",
"confirmSwitchMicThemeTips": "Do you confirm the switch of seat style?",
@ -378,7 +378,7 @@
"roomNotice": "Room notice",
"roomTheme": "Room theme",
"description": "Description:",
"inputDesHint": "Please describe the problem in as much detail as possible sothat we can understand and solve it.",
"inputDesHint": "Please describe the problem in as much detail as possible so that we can understand and solve it.",
"roomProfilePicture": "Room profile picture",
"userProfilePicture": "User profile picture",
"userName": "User name",
@ -389,12 +389,12 @@
"enterTheUserId": "Enter the userId",
"enterTheRoomId": "Enter the roomId",
"deleteAccount": "Delete Account",
"becomeAgent": "Become a agent",
"becomeAgent": "Become an agent",
"enterNickname": "Enter Nickname",
"selectYourCountry": "Select your country",
"inviteCode": "Invite Code",
"magic": "Magic",
"luckGiftSpecialEffects": "Lucky gift animation effets",
"luckGiftSpecialEffects": "Lucky gift animation effects",
"theVideoSizeCannotExceed": "The video size cannot exceed 50M",
"weekly": "Weekly",
"customizedGiftRulesContent": "How to get my customized gift:\n1.Determine whether the user is eligible to receive a customized gift based on their current wealth level.\n(1) When the user's wealth level is ≥35: The user can upload a video for the customized gift once. We will use the user's current profile picture as the gift image and the provided video as the gift effect on \"Customized.\" Production will take some time, and we will notify you as soon as it is available in the store.\n(2) When the user's wealth level is ≥45: The user can upload a video for the customized gift once. We will use the user's current profile picture as the gift image and the provided video as the gift effect on \"Customized.\" Production will take some time, and we will notify you as soon as it is available in the store.\n2.You can participate in specific activities on app and, after meeting the criteria, contact us through the \"Message\" → \"Contact us\" section. Provide screenshots of the activity and the video you wish to use for the customized gift. We will use your current profile picture as the gift image and the provided video as the gift effect, then list it under \"Customized.\" Production will take some time, and we will notify you as soon as it is available in the store.\nCustomized Gift Validity Period & How to Extend It:\nThe exclusive customized gifts will be available on the shelf for a validity period of 30 days. To enable influential and inspiring users to continue enjoying this new experience and showcase their personal style, users who own customized gifts can extend the shelf time of all their customized gifts by 30 days by recharging $500 in any given month.",
@ -406,7 +406,7 @@
"customized": "Customized",
"searchInputHint": "Enter account/room number",
"kickRoomTips": "You have been kicked out of the room.",
"joinRoomTips": "joined room !",
"joinRoomTips": "Joined the room!",
"roomSetting": "Room Setting",
"roomDetails": "Room Details",
"systemRoomTips": "Be polite and respectful. Any pornographic or vulgar content is strictly prohibited in yumi. Once discovered, the account will be banned permanently. Please consciously abide by the regulations of the yumi platform.",
@ -425,7 +425,7 @@
"importantReminder": "Important Reminder",
"entryVehicleAnimation": "Entry vehicle animation",
"floatingAnimationInGlobal": "Floating animation in global",
"entryVehicleAnimation2": "Users with VlP4 or higher privileges can use the functionto disable vehicle animations.",
"entryVehicleAnimation2": "Users with VIP4 or higher privileges can use this function to disable vehicle animations.",
"dailyTasks": "Daily Tasks",
"enterRoomConfirmTips": "Are you sure you want to enter the room?",
"followSucc": "Followed successfully",
@ -469,8 +469,8 @@
"membershipFreeChatSpeak": "Membership-free Chat & Speak",
"priorityRoomSorting": "Priority Room Sorting",
"userColoredID": "User Colored ID",
"pleaseSelectaItem": "Please select a item",
"areYouRureRoRecharge": "Are you sure to recharge?",
"pleaseSelectaItem": "Please select an item",
"areYouRureRoRecharge": "Are you sure you want to recharge?",
"mInimize": "Keep",
"everyone": "Everyone",
"shop": "Shop",
@ -496,11 +496,11 @@
"openTheMic": "Open the mic",
"muteTheMic": "Mute the mic",
"unlockTheMic": "Unlock the mic",
"leavelTheMic": "Leavel the mic",
"leavelTheMic": "Leave the mic",
"lockTheMic": "Lock the mic",
"removeTheMic": "Remove the mic",
"inviteToTheMicrophone": "Invite to the microphone",
"openUserProfleCard": "Open user profle card",
"openUserProfleCard": "Open user profile card",
"obtain": "obtain",
"win2": "Win {1}",
"backTheRoom": "Back room",
@ -545,7 +545,7 @@
"dailyCoinBonanzaRules": "Daily Coin Bonanza Rules",
"roomOwnerTasks": "Room Owner Tasks",
"personalTasks": "Personal Tasks",
"noPromptsToday": "No prompts today.",
"noPromptsToday": "No tasks today.",
"getPaidToRefer": "Get Paid to Refer",
"membershipFee": "Membership Fee",
"membershipFeeTips1": "Please set the membership fee for your room. Users can join your room by paying the fee.",
@ -564,9 +564,9 @@
"followed": "Followed",
"follow2": "Follow:{1}",
"fans2": "Fans:{1}",
"vistors2": "Vistors:{1}",
"vistors2": "Visitors:{1}",
"personal2": "Personal:",
"conntinue": "Conntinue",
"conntinue": "Continue",
"confirmBuyTips": "Are you sure you want to buy?",
"purchase": "Purchase",
"setRoomPassword": "Set room password",
@ -585,7 +585,7 @@
"logIn": "Log In",
"saySomething": "Say something...",
"sayHi": "Say Hi..",
"pleaseChatFfriendly": "Please chat friendly",
"pleaseChatFfriendly": "Please chat kindly",
"unLockTheRoom": "Unlock The Room",
"operationSuccessful": "The operation was successful.",
"adminByHomeowner": "is set as an administrator by the homeowner.",
@ -601,8 +601,8 @@
"theImageSizeCannotExceed": "The image size cannot exceed 4M",
"activity": "Activity",
"alreadyAnAdministrator": "Already an administrator",
"alreadyAnMember": "Already an member",
"alreadyAnTourist": "Already an tourist",
"alreadyAnMember": "Already a member",
"alreadyAnTourist": "Already a tourist",
"touristsCannotSendMessages": "Tourists cannot send messages",
"touristsAreNotAllowedToGoOnTheMic": "Tourists are not allowed to go on the mic",
"lockTheRoom": "Lock The Room",
@ -613,7 +613,7 @@
"custom": "Custom",
"myItems": "My items",
"use": "Use",
"unUse": "Un use",
"unUse": "Unequip",
"renewal": "Renewal",
"wallet": "Wallet",
"profile": "Profile",

View File

@ -8,7 +8,7 @@
"privaceyPolicy": "Gizlilik Politikası",
"tips": "İpuçları",
"searchNoDataTips": "Aramak istediğiniz oda veya kullanıcı kimliğini girin.",
"mine": "Benimki",
"mine": "Benim",
"party": "Parti",
"myRoom": "Odam",
"other": "Diğer",
@ -27,7 +27,7 @@
"blockedList2": "Engellenen Liste",
"roomTheme2": "Oda Teması",
"roomPassword": "Oda Şifresi",
"noHistoricalRecordsAvailable": "Mevcut tarihi kayıt yok.",
"noHistoricalRecordsAvailable": "Geçmiş kayıt bulunamadı.",
"inviteNewUsersToEarnCoins": "Yeni kullanıcıları davet ederek coin kazanın",
"crateMyRoom": "KENDİ ODANIZI OLUŞTURUN.",
"event": "Etkinlik",
@ -45,7 +45,7 @@
"trend": "Trend",
"like": "Beğen",
"more": "Daha Fazla",
"discard": "Vur",
"discard": "Vazgeç",
"catchFirstComment": "İlk Yorumu Yakala",
"reply": "Cevapla",
"posting": "Gönderiliyor",
@ -66,9 +66,9 @@
"systemAnnouncementTips1": "Sahtekarlığa karşı dikkat:",
"systemAnnouncementTips": "Bilgileri yalnızca resmi kanallar aracılığıyla doğrulayın. Hiçbir zaman üçüncü taraf yazılımı indirme, kişisel verileri paylaşma veya dış istekler üzerine para transferi yapmayın. Resmi personel kimlik numaraları yalnızca 10000, 10003 ve 10086'dır. Herhangi bir şüpheniz olursa, işlemi durdurun ve üzerinden bildirin",
"systemAnnouncement": "Sistem Duyurusu",
"doNotClickUnfamiliarTips": "Tanımadığınız bağlantılara tıklayın, çünkü bunlar kişisel bilgilerinizi ifşa edebilir. Kimlik numaranızı veya banka kartı detaylarınızı asla kimseyle paylaşmayın.",
"doNotClickUnfamiliarTips": "Tanımadığınız bağlantılara tıklamayın; bunlar kişisel bilgilerinizi açığa çıkarabilir. Kimlik numaranızı veya banka kartı bilgilerinizi asla kimseyle paylaşmayın.",
"atTag": "@Etiket",
"sayHi2": "Merhaba De",
"sayHi2": "Merhaba",
"roomBottomGreeting": "Merhaba...",
"canSendMsgTips": "Özel mesaj göndermek için her iki tarafın da birbirini takip etmesi gerekir.",
"msgSendRedEnvelopeTips": "*Kırmızı zarflar üzerinde %10 hizmet ücreti kesilecektir ve alıcılar yalnızca kırmızı zarfın değerinin %90'ını alacaktır. Göndericinin servet seviyesi 10. Seviyeden yüksek olmalıdır.",
@ -83,7 +83,7 @@
"memberList": "Üye Listesi",
"treasureChest": "Hazine Sandığı",
"applicationRecord": "Başvuru Kaydı",
"appUpdateTip": "Uygulamanın yeni bir sürümü var ({1}), lütfen indirin mi?",
"appUpdateTip": "Uygulamanın yeni bir sürümü ({1}) var, şimdi indirmek ister misiniz?",
"ownerIncomeCoins": "Sahibin Geliri:{1} jetton",
"game": "Oyun",
"skip2": "Atla",
@ -104,7 +104,7 @@
"termsOfServicePrivacyPolicyTips": "Devam ederek Hizmet Şartları'nı ve Gizlilik Politikası'nı kabul ediyorsunuz",
"and": " ve ",
"pleaseSelectTheTypeContent": "Lütfen ihlalci içeriğin türünü seçin.",
"illegalInformation": "Yasaksız Bilgi",
"illegalInformation": "Yasa Dışı Bilgi",
"inappropriateContent": "Uygunsuz İçerik",
"personalAttack": "Kişisel Saldırı",
"confirm": "Onayla",
@ -122,14 +122,14 @@
"lastWeekProgress": "Geçen Haftanın İlerlemesi",
"redEnvelopeTips2": "*Kırmızı zarf zaman sınırı içinde talep edilmezse, kalan jettonlar gönderen kullanıcıya iade edilecektir.",
"goToRecharge": "Yüklemeye Git",
"deleteAccount2": " Hesabı Sil({1}s)",
"deleteAccount2": " Hesabı Sil ({1} sn)",
"areYouSureYouWantToDeleteYourAccount": " Hesabınızı silmek istediğinizden emin misiniz?",
"insufhcientGoldsGoToRecharge": "Altın yetersiz, hemen yükle!",
"coins2": "{1}Jetton",
"coins2": "{1} Jetton",
"remainingNumberTips": "Kalan Kullanılabilir Sayı:({1}/{2})",
"collectionTimeTips": "Toplama Zamanı:{1}({2}/{3})",
"sendARedEnvelope": "Kırmızı Zarf Gönder",
"sendRedPackConfirmTips": "Kırmızı paket göndermek istediğinizden emin misiniz?",
"sendRedPackConfirmTips": "Kırmızı zarfı göndermek istediğinizden emin misiniz?",
"redEnvelopeSendingRecords": "Kırmızı zarf gönderim kayıtları:",
"redEnvelope": "Kırmızı Zarf",
"redEnvelopeRecTips2": "Kırmızı zarfların hepsi talep edildi.",
@ -139,7 +139,7 @@
"redEnvelopeTips1": "Jettonlar:",
"roomTools": "Oda Araçları:",
"entertainment": "Eğlence:",
"reportSucc": "Bildirim başarılı",
"reportSucc": "Bildirim başarıyla gönderildi",
"pornography": "Pornografi",
"reportInputTips": "Sorunu anlayabilmemiz ve çözebilmemiz için lütfen sorunu mümkün olduğunca detaylı anlatın.",
"cancel": "İptal",
@ -173,7 +173,7 @@
"youHaventFollowed": "Hiç oda takip etmediniz",
"deleteFromMyDevice": "Cihazımdan Sil",
"deleteOnAllDevices": "Tüm Cihazlarda Sil",
"messageHasBeenRecalled": "Bu mesaj geri çırıldı",
"messageHasBeenRecalled": "Bu mesaj geri çekildi",
"recallThisMessage": "Bu mesajı geri çağırmak ister misiniz?",
"language": "Dil",
"feedback": "Geri Bildirim",
@ -188,7 +188,7 @@
"logout": ıkış Yap",
"luck": "Şans",
"level": "Seviye",
"themeGoToUploadTips": "1.Yükleme başarılı olduktan sonra 24 saat içinde inceleme yapılacaktır.\n2.Inceleme başarısız olursa tüm jettonlar iade edilecektir.",
"themeGoToUploadTips": "1. Yükleme başarılı olduktan sonra 24 saat içinde inceleme yapılacaktır.\n2. İnceleme başarısız olursa tüm jettonlar iade edilecektir.",
"home": "Anasayfa",
"explore": "Keşfet",
"me": "Ben",
@ -210,14 +210,14 @@
"areYouSureYouWantToSpend2": "bu kullanıcıya CP daveti göndermek için?",
"underReview": "İnceleniyor",
"doYouWantToDeleteIt": "Silmek ister misiniz?",
"chooseFromAblum": "Albümdan Seç",
"chooseFromAblum": "Albümden Seç",
"spaceBackground": "Mekan Arka Planı",
"editProfile": "Profili Düzenle",
"sendTheCpRequest": "CP İsteğini Gönder",
"addCp": "CP Ekle",
"partWays": "Yollarını Ayırmak",
"partWays": "Yolları Ayır",
"reconcile": "Uzlaşmak",
"separated": "Ayırılmış",
"separated": "Ayrıldı",
"areYouSureYouWantToSpend5": "{1} size hislerini ifade etti; kabul ederseniz çift olacaksınız.",
"areYouSureYouWantToSpend6": "{1} sizinle tekrar bir araya gelmek istiyor. Uzlaşmaya karar verirseniz, tüm önceki verileriniz geri yüklenecektir.",
"reconcileInvitationTips": "*Diğer taraf CP davetini reddederse, jettonlarınız cüzdanınıza iade edilecektir.",
@ -231,7 +231,7 @@
"props": "Özellikler",
"win": "Kazanan",
"dice": "Zar",
"rps": "Kağıt-Kaçak-Makas",
"rps": "Taş-Kağıt-Makas",
"operationFail": "İşlem başarısız oldu.",
"likedYourComment": "Yorumunuzu beğendi.",
"doYouWantToKeepTheDraft": "Taslağı saklamak ister misiniz?",
@ -262,19 +262,19 @@
"roomAnnouncement": "Oda Duyurusu",
"help": "Yardım",
"rejected": "Reddedildi",
"boxContributeTips": "Bugün zaten yatırım yapıldı, lütfen tekrar yatırım yapmayın",
"boxContributeTips": "Bugün zaten yatırım yapıldı, lütfen tekrar yatırım yapmayın.",
"bd": "BD",
"coupon": "Kupon",
"search": "Ara",
"get": "Al",
"inRocket": "Rokette",
"roomRocketHelpTips": "1. Odada hediye göndermek roket enerjisini artırır. *1 altın jetton hediyesi = 1 roket enerji puanı; şanslı hediyeler roket enerjisini hediyenin altın jetton değerinin %4'ü kadar artırır.\n2. Roket enerjisi tamamen dolduğunda, oda roketi fırlatabilir. Fırlatmadan sonra ödüller otomatik olarak dağıtılacaktır.\n3. Farklı roket seviyeleri farklı ödüller sunar.\n4. Roket fırlatıldığında, odadaki tüm kullanıcılar roket ödülünü talep edebilir.5. Roket enerjisi her gün 00:00'da sıfırlanır.",
"roomRocketHelpTips": "1. Odada hediye göndermek roket enerjisini artırır. *1 altın jetton hediyesi = 1 roket enerji puanı; şanslı hediyeler roket enerjisini hediyenin altın jetton değerinin %4'ü kadar artırır.\n2. Roket enerjisi tamamen dolduğunda, oda roketi fırlatabilir. Fırlatmadan sonra ödüller otomatik olarak dağıtılacaktır.\n3. Farklı roket seviyeleri farklı ödüller sunar.\n4. Roket fırlatıldığında, odadaki tüm kullanıcılar roket ödülünü talep edebilir.\n5. Roket enerjisi her gün 00:00'da sıfırlanır.",
"couponRecord": "Kupon Kullanım Kaydı",
"inRoom": "Odada",
"searchCouponHint": "Kupon Ara",
"giftCounter": "Hediye Sayacı",
"bDLeaderInviteYouToBecomeBDLeader": "Sizi BD Lideri yapmaya davet ediyoruz",
"wins": "kazanmalar",
"wins": "kazandı",
"inviteYouToBecomeHost": "Sizi sunucu yapmaya davet ediyoruz.",
"friends": "Arkadaşlar",
"deleteConversationTips": "Bu kullanıcıyla olan sohbet geçmişini silmek istediğinizden emin misiniz?",
@ -285,7 +285,7 @@
"checkInSuccessful": "Giriş başarılı",
"sginTips": "Her gün ilk defa giriş yaptığınızda ödül alacaksınız. Girişi keserseniz, tekrar giriş yaptığınızda ödül ilk günden itibaren hesaplanacaktır.",
"popular": "Popüler",
"recommend": "Öner",
"recommend": "Önerilen",
"follow": "Takip Et",
"history": "Tarihçe",
"hotRooms": "Popüler Odalar",
@ -347,7 +347,7 @@
"localMusic": "Yerel Müzik",
"setLoginPassword": "Giriş Şifresi Ayarlayın",
"confirmSwitchMicThemeTips": "Koltuk stili değiştirmeyi onaylıyor musunuz?",
"micTheme": "Mikro Tema",
"micTheme": "Mikrofon Teması",
"classicMic": "Klasik {1} Mikro",
"yesterday": "Dün {1}",
"monday": "Pazartesi {1}",
@ -375,7 +375,7 @@
"warning": "Uyarı",
"screenshotTips": "Ekran Görüntüsü (En Fazla 3)",
"roomNotice": "Oda Bildirimi",
"roomTheme": "Oda Tema",
"roomTheme": "Oda Teması",
"description": "Açıklama:",
"inputDesHint": "Sorunu anlayabilmemiz ve çözebilmemiz için lütfen sorunu mümkün olduğunca detaylı anlatın.",
"roomProfilePicture": "Oda Profil Fotoğrafı",
@ -408,7 +408,7 @@
"joinRoomTips": "odaya katıldı !",
"roomSetting": "Oda Ayarları",
"roomDetails": "Oda Detayları",
"systemRoomTips": "Neysevi ve saygılı olun. yumi'de herhangi bir pornografik veya uygunsuz içerik kesinlikle yasaktır. Keşfedilirse, hesap kalıcı olarak engellenecektir. Lütfen yumi platformunun düzenlemelerini bilinçli olarak takip edin.",
"systemRoomTips": "Nezaketli ve saygılı olun. yumi'de pornografik veya uygunsuz içerik kesinlikle yasaktır. Tespit edilmesi halinde hesap kalıcı olarak engellenecektir. Lütfen yumi platform kurallarına bilinçli şekilde uyun.",
"copiedToClipboard": "Panoya kopyalandı",
"recharge": "Yükle",
"receivedFromALuckyGift": "Şanslı/sihirli bir hediyeden alındı.",
@ -423,7 +423,7 @@
"task": "Görev",
"importantReminder": "Önemli Hatırlatma",
"entryVehicleAnimation": "Giriş Aracı Animasyonu",
"floatingAnimationInGlobal": "Küreselde Süzme Animasyon",
"floatingAnimationInGlobal": "Genel Ekranda Yüzen Animasyon",
"entryVehicleAnimation2": "VIP4 veya daha yüksek haklara sahip kullanıcılar araç animasyonlarını devre dışı bırakmak için fonksiyonu kullanabilir.",
"dailyTasks": "Günlük Görevler",
"enterRoomConfirmTips": "Odaya girmek istediğinizden emin misiniz?",
@ -431,7 +431,7 @@
"goldListort": "Altın Listesi",
"rechargeList": "Yükleme Listesi",
"edit": "Düzenle",
"swipeLeftOnTheFloatingScreenAreaToQuicklyCloseIt": "*İpucu: Süzme ekran alanına sola kaydırarak hızlıca kapatın.",
"swipeLeftOnTheFloatingScreenAreaToQuicklyCloseIt": "*İpucu: Hızlıca kapatmak için yüzen ekran alanında sola kaydırın.",
"enterThisVoiceChatRoom": "Bu sesli sohbet odasına girmek ister misiniz?",
"go": "Git",
"done": "Bitti",
@ -453,14 +453,14 @@
"userLevelXPBoost": "Kullanıcı Seviyesi XP Artışı({1} XP)",
"google": "Google",
"mysteriousInvisibility": "Gizemli görünmezlik",
"antiBlock": "Tıkanmayı Önleyici",
"antiBlock": "Engellenme Koruması",
"privateChat": "Özel Sohbet",
"everyone": "Herkes",
"goToUpgrade": "Yükseltmeye git",
"exclusiveEmojiWillBeReleasedAfterBecoming": "Özel emoji olunduktan sonra yayınlanacak",
"preventBeingBlocked": "Engellenmekten Kaçının",
"enableRankIncognitoMode": "Rütbe Gizli Modunu Etkinleştir",
"avoidBeingKicked": "Tekme Yemekten Kaçının",
"avoidBeingKicked": "Odadan Atılmayı Önleme",
"privileges": "{1} Ayrıcalıklar",
"andAboveUsers": "{1} ve üzeri kullanıcılar",
"basicPermissions": "Temel izinler",
@ -481,7 +481,7 @@
"exit": ıkış",
"pleaseSelectaItem": "Lütfen bir öğe seçin",
"areYouRureRoRecharge": "Yüklemek istediğinizden emin misiniz?",
"mInimize": "Tutmak",
"mInimize": "Küçült",
"shop": "Mağaza",
"expirationTime": "Son kullanma süresi",
"roomOwner": "Oda Sahibi",
@ -495,13 +495,13 @@
"takeTheMic": "Mikroyu Al",
"openTheMic": "Mikroyu Aç",
"muteTheMic": "Mikronun Sesini Kapat",
"unlockTheMic": "Mikroyu Kilidini Aç",
"unlockTheMic": "Mikrofon Kilidini Aç",
"leavelTheMic": "Mikroyu Bırak",
"lockTheMic": "Mikroyu Kilitle",
"removeTheMic": "Mikroyu Kaldır",
"inviteToTheMicrophone": "Mikroya Davet Et",
"openUserProfleCard": "Kullanıcı Profili Kartını Aç",
"obtain": "elde etmek",
"obtain": "Al",
"win2": "{1} Kazan",
"backTheRoom": "Odaya Dön",
"toConsume": "Tüketmek İçin",
@ -519,10 +519,10 @@
"submit": "Gönder",
"membershipFee": "Üyelik Ücreti",
"membershipFeeTips1": "Lütfen odanız için üyelik ücretini ayarlayın. Kullanıcılar ücreti ödeyerek odanıza katılabilir.",
"membershipFeeTips2": "Kullanıcı'nın oda üyesi olması için gerekli altınlar.Oda sahibi altınların %50'sini alacaktır.",
"membershipFeeTips2": "Kullanıcının oda üyesi olması için gereken altın miktarıdır. Oda sahibi altınların %50'sini alacaktır.",
"freePrice": "Ücret:0-10000",
"touristsSendText": "Turist metin gönderir",
"touristsTakeToTheMic": "Turist mikro alır",
"touristsSendText": "Ziyaretçi metin gönderebilir",
"touristsTakeToTheMic": "Ziyaretçi mikrofona geçebilir",
"theMembershipFee": "Üyelik Ücreti",
"theModificationsMade": "Bu sefer yapılan değişiklikler çıkıştan sonra kaydedilmeyecektir",
"viewFrame": "Çerçeveyi Gör",
@ -556,7 +556,7 @@
"saySomething": "Bir şey söyle...",
"sayHi": "Merhaba..",
"pleaseChatFfriendly": "Lütfen arkadaşça sohbet edin",
"unLockTheRoom": "Odayı Kilidini Aç",
"unLockTheRoom": "Odanın Kilidini Aç",
"operationSuccessful": "İşlem başarılı oldu.",
"adminByHomeowner": "ev sahibi tarafından yönetici olarak atandı.",
"memberByHomeowner": "ev sahibi tarafından üye olarak atandı.",
@ -568,7 +568,7 @@
"knapsack": "Sırt Çantası",
"bdLeader": "BD Lideri",
"picture": "Resim",
"claim": "İddia",
"claim": "Talep Et",
"taskNameRoomNewMember": "Yeni Oda Üyeleri",
"taskNameRoomOwnerSendRedPacket": "Oda Sahibi bir kırmızı paket gönderiyor",
"taskNameRoomOwnerSendGiftUser": "Oda Sahibi Hediye Gönderir",
@ -585,7 +585,7 @@
"taskNameRoomOwnerMicTime": "Oda Sahibi odada mikrofona geçer",
"taskNamePersonalActiveInRoom": "Başkalarının Odalarında Aktif Ol",
"taskNamePersonalGameConsume": "Oyun Harcaması",
"taskNamePersonalMicInRoom": "Mikrofonu Aç",
"taskNamePersonalMicInRoom": "Mikrofona Çık",
"complete": "Tamamla",
"shareTo": "Paylaş",
"faceBook": "Facebook",
@ -596,7 +596,7 @@
"dailyCoinBonanzaRules": "Günlük Jeton Çılgınlığı Kuralları",
"roomOwnerTasks": "Oda Sahibi Görevleri",
"personalTasks": "Kişisel Görevler",
"noPromptsToday": "Bugün hiçbir istem yok.",
"noPromptsToday": "Bugün görev yok.",
"getPaidToRefer": "Tavsiye Ederek Para Kazanın",
"theImageSizeCannotExceed": "Görsel boyutu 4M'yi geçemez",
"activity": "Etkinlik",
@ -630,7 +630,7 @@
"confirmUseTips": "Kullanmak için onaylıyor musunuz?",
"pleaseUploadUserAvatar": "Lütfen bir profil fotoğrafı yükleyin.",
"joinMemberTips": "Eğer odada turist iseniz, mikroyu alamazsınız.",
"giftGivingSuccessful": "Hediye verme başarılı.",
"giftGivingSuccessful": "Hediye başarıyla gönderildi.",
"theAccountPasswordCannotBeEmpty": "Hesap veya şifre boş olamaz.",
"invitesYouToTheMicrophone": "{1} seni mikroya davet ediyor",
"english": "İngilizce",

View File

@ -1,3 +1,5 @@
import 'dart:async';
import 'dart:collection';
import 'dart:convert';
import 'dart:ui' as ui;
@ -32,6 +34,7 @@ import 'package:yumi/services/audio/rtc_manager.dart';
import 'package:yumi/services/audio/rtm_manager.dart';
import 'package:yumi/services/auth/user_profile_manager.dart';
import 'package:yumi/ui_kit/widgets/countdown_timer.dart';
import 'package:yumi/ui_kit/widgets/gift/sc_gift_combo_send_button.dart';
import 'package:yumi/ui_kit/widgets/room/room_msg_item.dart';
import 'package:yumi/modules/wallet/wallet_route.dart';
import 'package:yumi/modules/gift/gift_tab_page.dart';
@ -47,16 +50,18 @@ class _GiftPageTabItem {
}
class GiftPage extends StatefulWidget {
SocialChatUserProfile? toUser;
final SocialChatUserProfile? toUser;
GiftPage({super.key, this.toUser});
const GiftPage({super.key, this.toUser});
@override
_GiftPageState createState() => _GiftPageState();
State<GiftPage> createState() => _GiftPageState();
}
class _GiftPageState extends State<GiftPage>
with SingleTickerProviderStateMixin {
class _GiftPageState extends State<GiftPage> with TickerProviderStateMixin {
static const Duration _comboFeedbackDuration = Duration(seconds: 3);
static const Duration _comboSendBatchWindow = Duration(milliseconds: 200);
static const List<String> _preferredGiftTabOrder = <String>[
"ALL",
"ACTIVITY",
@ -97,6 +102,12 @@ class _GiftPageState extends State<GiftPage>
int giftType = 0;
Debouncer debouncer = Debouncer();
late final AnimationController _comboFeedbackController;
final ListQueue<_PendingGiftSendBatch> _comboSendBatchQueue =
ListQueue<_PendingGiftSendBatch>();
Timer? _comboSendBatchTimer;
bool _isComboSendBatchInFlight = false;
bool _showComboFeedback = false;
void _giftFxLog(String message) {
debugPrint('[GiftFX][Send] $message');
@ -200,6 +211,16 @@ class _GiftPageState extends State<GiftPage>
@override
void initState() {
super.initState();
_comboFeedbackController = AnimationController(
vsync: this,
duration: _comboFeedbackDuration,
)..addStatusListener((status) {
if (status == AnimationStatus.completed && mounted) {
setState(() {
_showComboFeedback = false;
});
}
});
rtcProvider = Provider.of<RtcProvider>(context, listen: false);
Provider.of<SCAppGeneralManager>(context, listen: false).giftList();
Provider.of<SCAppGeneralManager>(context, listen: false).giftActivityList();
@ -224,8 +245,13 @@ class _GiftPageState extends State<GiftPage>
@override
void dispose() {
_comboSendBatchTimer?.cancel();
if (_comboSendBatchQueue.isNotEmpty) {
unawaited(_flushAllPendingComboGiftSends());
}
_tabController?.removeListener(_handleTabChanged);
_tabController?.dispose();
_comboFeedbackController.dispose();
super.dispose();
}
@ -781,29 +807,7 @@ class _GiftPageState extends State<GiftPage>
size: 20.w,
),
SizedBox(width: 5.w),
GestureDetector(
onTap: () {
giveGifts();
},
child: Container(
padding: EdgeInsets.symmetric(
vertical: 8.w,
horizontal: 20.w,
),
decoration: BoxDecoration(
color:
SocialChatTheme.primaryLight,
borderRadius:
BorderRadius.circular(5),
),
child: text(
SCAppLocalizations.of(
context,
)!.send,
fontSize: 14.sp,
),
),
),
_buildSendButton(),
],
),
),
@ -1068,8 +1072,7 @@ class _GiftPageState extends State<GiftPage>
}
}
///
void giveGifts() async {
_GiftSendRequest? _buildGiftSendRequest() {
List<String> acceptUserIds = [];
List<MicRes> acceptUsers = [];
@ -1102,7 +1105,7 @@ class _GiftPageState extends State<GiftPage>
'giveType=$giveType',
);
SCTts.show(SCAppLocalizations.of(context)!.pleaseSelectTheRecipient);
return;
return null;
}
final selectedGift = checkedGift;
if (selectedGift == null) {
@ -1111,41 +1114,18 @@ class _GiftPageState extends State<GiftPage>
'acceptUserIds=${acceptUserIds.join(",")} '
'giveType=$giveType',
);
return;
return null;
}
final selectedNumber = number;
final roomId = rtcProvider?.currenRoom?.roomProfile?.roomProfile?.id ?? "";
final roomAccount =
rtcProvider?.currenRoom?.roomProfile?.roomProfile?.roomAccount ?? "";
final isLuckyGiftRequest = _usesLuckyGiftEndpoint(selectedGift);
final requestName = isLuckyGiftRequest ? 'giveLuckyGift' : 'giveGift';
final senderId = AccountStorage().getCurrentUser()?.userProfile?.id ?? "";
final senderName =
AccountStorage().getCurrentUser()?.userProfile?.userNickname ?? "";
final stopwatch = Stopwatch()..start();
_giftFxLog(
'tap send start request=$requestName '
'senderId=$senderId '
'senderName=$senderName '
'giftId=${selectedGift.id} '
'giftName=${selectedGift.giftName} '
'giftTab=${selectedGift.giftTab} '
'special=${selectedGift.special} '
'standardId=${selectedGift.standardId} '
'giftCandy=${selectedGift.giftCandy} '
'number=$selectedNumber '
'acceptCount=${acceptUserIds.length} '
'acceptUserIds=${acceptUserIds.join(",")} '
'roomId=$roomId '
'roomAccount=$roomAccount '
'giveType=$giveType '
'giftType=$giftType',
);
if (isLuckyGiftRequest && !_hasValidLuckyGiftStandardId(selectedGift)) {
const configError =
'Gift configuration unavailable, please try another gift.';
final requestName = isLuckyGiftRequest ? 'giveLuckyGift' : 'giveGift';
_giftFxLog(
'$requestName skipped giftId=${selectedGift.id} '
'giftName=${selectedGift.giftName} '
@ -1154,86 +1134,250 @@ class _GiftPageState extends State<GiftPage>
'reason=invalid_standard_id',
);
SCTts.show(configError);
return null;
}
return _GiftSendRequest(
acceptUserIds: acceptUserIds,
acceptUsers: acceptUsers,
gift: selectedGift,
quantity: selectedNumber,
roomId: roomId,
roomAccount: roomAccount,
isLuckyGiftRequest: isLuckyGiftRequest,
);
}
///
void giveGifts() async {
final request = _buildGiftSendRequest();
if (request == null) {
return;
}
_activateComboFeedback(
gift: request.gift,
quantity: request.quantity,
acceptUserIds: request.acceptUserIds,
);
if (_supportsComboRequestBatching(request.gift)) {
_enqueueComboGiftSendRequest(request);
return;
}
await _performGiftSend(request, trigger: 'direct');
}
bool _supportsComboRequestBatching(SocialChatGiftRes gift) {
return _supportsComboFeedback(gift);
}
void _enqueueComboGiftSendRequest(_GiftSendRequest request) {
final now = DateTime.now();
_PendingGiftSendBatch? existingBatch;
for (final batch in _comboSendBatchQueue) {
if (batch.batchKey == request.batchKey) {
existingBatch = batch;
break;
}
}
if (existingBatch != null) {
existingBatch.quantity += request.quantity;
existingBatch.readyAt = now.add(_comboSendBatchWindow);
_giftFxLog(
'aggregate combo send update '
'batchKey=${existingBatch.batchKey} '
'giftId=${request.gift.id} '
'quantity=${existingBatch.quantity} '
'acceptUserIds=${request.acceptUserIds.join(",")}',
);
} else {
final batch = _PendingGiftSendBatch.fromRequest(
request,
readyAt: now.add(_comboSendBatchWindow),
);
_comboSendBatchQueue.add(batch);
_giftFxLog(
'aggregate combo send enqueue '
'batchKey=${batch.batchKey} '
'giftId=${request.gift.id} '
'quantity=${batch.quantity} '
'acceptUserIds=${request.acceptUserIds.join(",")}',
);
}
_scheduleNextComboGiftSendFlush();
}
void _scheduleNextComboGiftSendFlush() {
_comboSendBatchTimer?.cancel();
_comboSendBatchTimer = null;
if (_isComboSendBatchInFlight || _comboSendBatchQueue.isEmpty) {
return;
}
final headBatch = _comboSendBatchQueue.first;
final delay = headBatch.readyAt.difference(DateTime.now());
if (delay <= Duration.zero) {
unawaited(_flushNextComboGiftSendBatch());
return;
}
_comboSendBatchTimer = Timer(delay, () {
unawaited(_flushNextComboGiftSendBatch());
});
}
Future<void> _flushNextComboGiftSendBatch() async {
_comboSendBatchTimer?.cancel();
_comboSendBatchTimer = null;
if (_isComboSendBatchInFlight || _comboSendBatchQueue.isEmpty) {
return;
}
final headBatch = _comboSendBatchQueue.first;
if (headBatch.readyAt.isAfter(DateTime.now())) {
_scheduleNextComboGiftSendFlush();
return;
}
_comboSendBatchQueue.removeFirst();
_isComboSendBatchInFlight = true;
try {
await _performGiftSend(headBatch.toRequest(), trigger: 'batched');
} finally {
_isComboSendBatchInFlight = false;
_scheduleNextComboGiftSendFlush();
}
}
Future<void> _flushAllPendingComboGiftSends() async {
_comboSendBatchTimer?.cancel();
_comboSendBatchTimer = null;
while (_comboSendBatchQueue.isNotEmpty) {
if (_isComboSendBatchInFlight) {
await Future<void>.delayed(const Duration(milliseconds: 50));
continue;
}
_comboSendBatchQueue.first.readyAt = DateTime.now();
await _flushNextComboGiftSendBatch();
}
}
Future<void> _performGiftSend(
_GiftSendRequest request, {
required String trigger,
}) async {
final requestName = request.requestName;
final profileManager =
navigatorKey.currentState == null
? null
: Provider.of<SocialChatUserProfileManager>(
navigatorKey.currentState!.context,
listen: false,
);
final senderId = AccountStorage().getCurrentUser()?.userProfile?.id ?? "";
final senderName =
AccountStorage().getCurrentUser()?.userProfile?.userNickname ?? "";
final stopwatch = Stopwatch()..start();
_giftFxLog(
'send start trigger=$trigger request=$requestName '
'senderId=$senderId '
'senderName=$senderName '
'giftId=${request.gift.id} '
'giftName=${request.gift.giftName} '
'giftTab=${request.gift.giftTab} '
'special=${request.gift.special} '
'standardId=${request.gift.standardId} '
'giftCandy=${request.gift.giftCandy} '
'number=${request.quantity} '
'acceptCount=${request.acceptUserIds.length} '
'acceptUserIds=${request.acceptUserIds.join(",")} '
'roomId=${request.roomId} '
'roomAccount=${request.roomAccount} '
'giveType=$giveType '
'giftType=$giftType',
);
try {
final repository = SCChatRoomRepository();
_giftFxLog(
'calling repository.$requestName '
'giftId=${selectedGift.id} '
'roomId=$roomId '
'acceptUserIds=${acceptUserIds.join(",")} '
'quantity=$selectedNumber',
'trigger=$trigger '
'giftId=${request.gift.id} '
'roomId=${request.roomId} '
'acceptUserIds=${request.acceptUserIds.join(",")} '
'quantity=${request.quantity}',
);
final result =
isLuckyGiftRequest
request.isLuckyGiftRequest
? await repository.giveLuckyGift(
acceptUserIds,
selectedGift.id ?? "",
selectedNumber,
request.acceptUserIds,
request.gift.id ?? "",
request.quantity,
false,
roomId: roomId,
roomId: request.roomId,
)
: await repository.giveGift(
acceptUserIds,
selectedGift.id ?? "",
selectedNumber,
request.acceptUserIds,
request.gift.id ?? "",
request.quantity,
false,
roomId: roomId,
roomId: request.roomId,
);
_giftFxLog(
'$requestName success giftId=${selectedGift.id} '
'giftName=${selectedGift.giftName} '
'giftSourceUrl=${selectedGift.giftSourceUrl} '
'special=${selectedGift.special} '
'giftTab=${selectedGift.giftTab} '
'standardId=${selectedGift.standardId} '
'number=$selectedNumber '
'acceptUserIds=${acceptUserIds.join(",")} '
'roomId=$roomId '
'$requestName success trigger=$trigger '
'giftId=${request.gift.id} '
'giftName=${request.gift.giftName} '
'giftSourceUrl=${request.gift.giftSourceUrl} '
'special=${request.gift.special} '
'giftTab=${request.gift.giftTab} '
'standardId=${request.gift.standardId} '
'number=${request.quantity} '
'acceptUserIds=${request.acceptUserIds.join(",")} '
'roomId=${request.roomId} '
'balance=$result '
'elapsedMs=${stopwatch.elapsedMilliseconds}',
);
// SCTts.show(SCAppLocalizations.of(context)!.giftGivingSuccessful);
if (isLuckyGiftRequest) {
if (request.isLuckyGiftRequest) {
_showLocalLuckyGiftFeedback(
acceptUsers,
gift: selectedGift,
quantity: selectedNumber,
request.acceptUsers,
gift: request.gift,
quantity: request.quantity,
);
await sendLuckGiftAnimOtherMsg(
acceptUsers,
gift: selectedGift,
quantity: selectedNumber,
request.acceptUsers,
gift: request.gift,
quantity: request.quantity,
);
} else {
sendGiftMsg(acceptUsers, gift: selectedGift, quantity: selectedNumber);
}
if (mounted) {
Provider.of<SocialChatUserProfileManager>(
context,
listen: false,
).updateBalance(result);
sendGiftMsg(
request.acceptUsers,
gift: request.gift,
quantity: request.quantity,
);
}
profileManager?.updateBalance(result);
} catch (e) {
final errorMessage = _resolveGiftSendErrorMessage(e);
final errorDetails = _describeGiftSendError(e);
_giftFxLog(
'$requestName failed giftId=${selectedGift.id} '
'giftName=${selectedGift.giftName} '
'giftTab=${selectedGift.giftTab} '
'standardId=${selectedGift.standardId} '
'$requestName failed trigger=$trigger '
'giftId=${request.gift.id} '
'giftName=${request.gift.giftName} '
'giftTab=${request.gift.giftTab} '
'standardId=${request.gift.standardId} '
'error=$e '
'resolvedError=$errorMessage '
'details={$errorDetails} '
'elapsedMs=${stopwatch.elapsedMilliseconds}',
);
if (mounted) {
SCTts.show(errorMessage);
}
}
}
void sendGiftMsg(
List<MicRes> acceptUsers, {
@ -1347,6 +1491,39 @@ class _GiftPageState extends State<GiftPage>
}
}
void _activateComboFeedback({
required SocialChatGiftRes gift,
required int quantity,
required List<String> acceptUserIds,
}) {
if (!_supportsComboFeedback(gift)) {
return;
}
setState(() {
_showComboFeedback = true;
});
_comboFeedbackController.forward(from: 0);
}
bool _supportsComboFeedback(SocialChatGiftRes gift) {
final giftTab = (gift.giftTab ?? '').trim();
return giftTab == "LUCK" ||
giftTab == SCGiftType.LUCKY_GIFT.name ||
giftTab == SCGiftType.CP.name ||
giftTab == SCGiftType.MAGIC.name;
}
Widget _buildSendButton() {
return SCGiftComboSendButton(
label: SCAppLocalizations.of(context)!.send,
onPressed: giveGifts,
showCountdown: _showComboFeedback,
countdownAnimation: _comboFeedbackController,
width: 96.w,
);
}
/// giftType转换为字符串类型
String _giftTypeToString(int giftType) {
switch (giftType) {
@ -1364,7 +1541,11 @@ class _GiftPageState extends State<GiftPage>
}
_buildGiftHead() {
if (giftType == 1 || giftType == 2 || giftType == 3 || giftType == 5) {
if (giftType == 2 || giftType == 3) {
return Container();
}
if (giftType == 1 || giftType == 5) {
//
String basePath = _strategy.getGiftPageActivityGiftHeadBackground(
_giftTypeToString(giftType),
@ -1375,15 +1556,15 @@ class _GiftPageState extends State<GiftPage>
if (SCGlobalConfig.lang == "ar") {
// _ar
if (basePath.endsWith('.png')) {
imagePath = basePath.substring(0, basePath.length - 4) + '_ar.png';
imagePath = '${basePath.substring(0, basePath.length - 4)}_ar.png';
} else {
imagePath = basePath + '_ar';
imagePath = '${basePath}_ar';
}
} else {
if (basePath.endsWith('.png')) {
imagePath = basePath.substring(0, basePath.length - 4) + '_en.png';
imagePath = '${basePath.substring(0, basePath.length - 4)}_en.png';
} else {
imagePath = basePath + '_en';
imagePath = '${basePath}_en';
}
}
@ -1446,14 +1627,12 @@ class _GiftPageState extends State<GiftPage>
}
class CheckNumber extends StatelessWidget {
final Function(int) onNumberChanged;
late BuildContext context;
final ValueChanged<int> onNumberChanged;
CheckNumber({super.key, required this.onNumberChanged});
const CheckNumber({super.key, required this.onNumberChanged});
@override
Widget build(BuildContext context) {
this.context = context;
return Container(
alignment: AlignmentDirectional.topEnd,
margin: EdgeInsets.only(right: width(22)),
@ -1516,6 +1695,89 @@ class CheckNumber extends StatelessWidget {
}
}
class _GiftSendRequest {
const _GiftSendRequest({
required this.acceptUserIds,
required this.acceptUsers,
required this.gift,
required this.quantity,
required this.roomId,
required this.roomAccount,
required this.isLuckyGiftRequest,
});
final List<String> acceptUserIds;
final List<MicRes> acceptUsers;
final SocialChatGiftRes gift;
final int quantity;
final String roomId;
final String roomAccount;
final bool isLuckyGiftRequest;
String get requestName => isLuckyGiftRequest ? 'giveLuckyGift' : 'giveGift';
String get batchKey {
final sortedAcceptUserIds = List<String>.from(acceptUserIds)..sort();
return '${isLuckyGiftRequest ? "lucky" : "gift"}'
'|${gift.id ?? ""}'
'|$roomId'
'|${sortedAcceptUserIds.join(",")}';
}
}
class _PendingGiftSendBatch {
_PendingGiftSendBatch({
required this.batchKey,
required this.acceptUserIds,
required this.acceptUsers,
required this.gift,
required this.quantity,
required this.roomId,
required this.roomAccount,
required this.isLuckyGiftRequest,
required this.readyAt,
});
factory _PendingGiftSendBatch.fromRequest(
_GiftSendRequest request, {
required DateTime readyAt,
}) {
return _PendingGiftSendBatch(
batchKey: request.batchKey,
acceptUserIds: List<String>.from(request.acceptUserIds),
acceptUsers: List<MicRes>.from(request.acceptUsers),
gift: request.gift,
quantity: request.quantity,
roomId: request.roomId,
roomAccount: request.roomAccount,
isLuckyGiftRequest: request.isLuckyGiftRequest,
readyAt: readyAt,
);
}
final String batchKey;
final List<String> acceptUserIds;
final List<MicRes> acceptUsers;
final SocialChatGiftRes gift;
int quantity;
final String roomId;
final String roomAccount;
final bool isLuckyGiftRequest;
DateTime readyAt;
_GiftSendRequest toRequest() {
return _GiftSendRequest(
acceptUserIds: List<String>.from(acceptUserIds),
acceptUsers: List<MicRes>.from(acceptUsers),
gift: gift,
quantity: quantity,
roomId: roomId,
roomAccount: roomAccount,
isLuckyGiftRequest: isLuckyGiftRequest,
);
}
}
class HeadSelect {
bool isSelect = false;
MicRes? mic;

View File

@ -1,4 +1,3 @@
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:yumi/app_localizations.dart';
@ -10,15 +9,17 @@ import 'package:yumi/ui_kit/widgets/room/room_msg_item.dart';
import 'package:yumi/services/audio/rtm_manager.dart';
class AllChatPage extends StatefulWidget {
const AllChatPage({super.key});
@override
_AllChatPageState createState() => _AllChatPageState();
State<AllChatPage> createState() => _AllChatPageState();
}
class _AllChatPageState extends State<AllChatPage> {
ScrollController _controller = ScrollController();
final ScrollController _controller = ScrollController();
bool showGoBottom = true;
bool _isDisposed = false;
List<Msg> _msgList = [];
final List<Msg> _msgList = [];
late RtmProvider provider;
@override
@ -26,9 +27,9 @@ class _AllChatPageState extends State<AllChatPage> {
super.initState();
_controller.addListener(_scrollListener);
provider = Provider.of<RtmProvider>(context, listen: false);
var msgList = provider.roomAllMsgList;
final msgList = provider.roomAllMsgList;
provider.msgAllListener = _onNewMsg;
_msgList.addAll(msgList ??= []);
_msgList.addAll(msgList);
// 使
_initScrollPosition();
}
@ -68,13 +69,14 @@ class _AllChatPageState extends State<AllChatPage> {
setState(() {});
return;
}
if (!_msgList.contains(msg)) {
setState(() {
if (_msgList.contains(msg)) {
_msgList.remove(msg);
}
_msgList.insert(0, msg);
});
_controller.jumpTo(0.0);
}
}
@override
void dispose() {

View File

@ -1,4 +1,3 @@
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:yumi/shared/business_logic/models/res/login_res.dart';
@ -10,15 +9,17 @@ import 'package:yumi/services/audio/rtm_manager.dart';
import 'package:yumi/ui_kit/widgets/room/room_msg_item.dart';
class GiftChatPage extends StatefulWidget {
const GiftChatPage({super.key});
@override
_GiftChatPageState createState() => _GiftChatPageState();
State<GiftChatPage> createState() => _GiftChatPageState();
}
class _GiftChatPageState extends State<GiftChatPage> {
ScrollController _controller = ScrollController();
final ScrollController _controller = ScrollController();
bool showGoBottom = true;
bool _isDisposed = false;
List<Msg> _msgList = [];
final List<Msg> _msgList = [];
late RtmProvider provider;
@override
@ -26,9 +27,9 @@ class _GiftChatPageState extends State<GiftChatPage> {
super.initState();
_controller.addListener(_scrollListener);
provider = Provider.of<RtmProvider>(context, listen: false);
var msgList = provider.roomGiftMsgList;
final msgList = provider.roomGiftMsgList;
provider.msgGiftListener = _onNewMsg;
_msgList.addAll(msgList ??= []);
_msgList.addAll(msgList);
// 使
_initScrollPosition();
}
@ -68,13 +69,14 @@ class _GiftChatPageState extends State<GiftChatPage> {
setState(() {});
return;
}
if (!_msgList.contains(msg)) {
setState(() {
if (_msgList.contains(msg)) {
_msgList.remove(msg);
}
_msgList.insert(0, msg);
});
_controller.jumpTo(0.0);
}
}
@override
void dispose() {

View File

@ -13,6 +13,7 @@ import 'package:yumi/shared/business_logic/models/res/join_room_res.dart';
import 'package:yumi/services/gift/gift_animation_manager.dart';
import 'package:yumi/services/gift/gift_system_manager.dart';
import 'package:yumi/services/audio/rtm_manager.dart';
import 'package:yumi/shared/tools/sc_gift_vap_svga_manager.dart';
import 'package:yumi/shared/tools/sc_path_utils.dart';
import 'package:yumi/ui_kit/widgets/room/anim/l_gift_animal_view.dart';
import 'package:yumi/ui_kit/widgets/room/anim/room_gift_seat_flight_overlay.dart';
@ -40,12 +41,16 @@ class VoiceRoomPage extends StatefulWidget {
class _VoiceRoomPageState extends State<VoiceRoomPage>
with SingleTickerProviderStateMixin {
static const Duration _luckyGiftComboWindow = Duration(seconds: 3);
late TabController _tabController;
final List<Widget> _pages = [AllChatPage(), ChatPage(), GiftChatPage()];
final List<Widget> _tabs = [];
late StreamSubscription _subscription;
final RoomGiftSeatFlightController _giftSeatFlightController =
RoomGiftSeatFlightController();
final Map<String, _LuckyGiftComboSession> _luckyGiftComboSessions =
<String, _LuckyGiftComboSession>{};
@override
void initState() {
@ -64,6 +69,7 @@ class _VoiceRoomPageState extends State<VoiceRoomPage>
context,
listen: false,
).toggleGiftAnimationVisibility(false);
_clearLuckyGiftComboSessions();
_giftSeatFlightController.clear();
}
});
@ -75,6 +81,7 @@ class _VoiceRoomPageState extends State<VoiceRoomPage>
if (rtmProvider.msgFloatingGiftListener == _floatingGiftListener) {
rtmProvider.msgFloatingGiftListener = null;
}
_clearLuckyGiftComboSessions();
_giftSeatFlightController.clear();
_tabController.dispose(); //
_subscription.cancel();
@ -281,6 +288,11 @@ class _VoiceRoomPageState extends State<VoiceRoomPage>
final giftPhoto = (msg.gift?.giftPhoto ?? "").trim();
final targetUserId = _resolveGiftTargetUserId(msg);
final isLuckyGift = _isLuckyGiftMessage(msg);
if (isLuckyGift) {
_handleLuckyGiftComboVisuals(msg, giftPhoto, targetUserId);
return;
}
if (_shouldPlaySeatFlightGiftAnimation(msg) && targetUserId != null) {
_giftSeatFlightController.enqueue(
RoomGiftSeatFlightRequest(
@ -293,6 +305,82 @@ class _VoiceRoomPageState extends State<VoiceRoomPage>
}
}
bool _isLuckyGiftMessage(Msg msg) {
final giftTab = (msg.gift?.giftTab ?? '').trim();
return giftTab == "LUCK" || giftTab == SCGiftType.LUCKY_GIFT.name;
}
void _handleLuckyGiftComboVisuals(
Msg msg,
String giftPhoto,
String? targetUserId,
) {
final quantity = (msg.number ?? 0).floor();
if (quantity <= 0) {
return;
}
final sessionKey = _buildLuckyGiftComboSessionKey(msg, targetUserId);
final session = _luckyGiftComboSessions.putIfAbsent(
sessionKey,
() => _LuckyGiftComboSession(),
);
session.totalCount += quantity;
final highestMilestone =
SocialChatGiftSystemManager.resolveHighestReachedLuckGiftMilestone(
session.totalCount,
);
if (highestMilestone != null &&
highestMilestone > session.highestPlayedMilestone &&
SCGlobalConfig.isLuckGiftSpecialEffects) {
final effectPath =
SocialChatGiftSystemManager.resolveLuckGiftComboEffectPath(
highestMilestone,
);
if (effectPath != null && effectPath.isNotEmpty) {
SCGiftVapSvgaManager().play(effectPath, priority: 200);
session.highestPlayedMilestone = highestMilestone;
}
}
if (_shouldPlaySeatFlightGiftAnimation(msg) &&
targetUserId != null &&
giftPhoto.isNotEmpty) {
session.pendingFlightRequest = RoomGiftSeatFlightRequest(
imagePath: giftPhoto,
targetUserId: targetUserId,
beginSize: 96.w,
endSize: 28.w,
);
}
session.flushTimer?.cancel();
session.flushTimer = Timer(_luckyGiftComboWindow, () {
if (!mounted) {
return;
}
final activeSession = _luckyGiftComboSessions.remove(sessionKey);
final pendingFlightRequest = activeSession?.pendingFlightRequest;
activeSession?.dispose();
if (pendingFlightRequest != null) {
_giftSeatFlightController.enqueue(pendingFlightRequest);
}
});
}
String _buildLuckyGiftComboSessionKey(Msg msg, String? targetUserId) {
final senderId = (msg.user?.id ?? '').trim();
final giftId = (msg.gift?.id ?? '').trim();
return '$giftId|$senderId|${targetUserId ?? ""}';
}
void _clearLuckyGiftComboSessions() {
for (final session in _luckyGiftComboSessions.values) {
session.dispose();
}
_luckyGiftComboSessions.clear();
}
bool _shouldPlaySeatFlightGiftAnimation(Msg msg) {
final gift = msg.gift;
if (gift == null) {
@ -355,3 +443,14 @@ class _VoiceRoomPageState extends State<VoiceRoomPage>
return null;
}
}
class _LuckyGiftComboSession {
Timer? flushTimer;
int totalCount = 0;
int highestPlayedMilestone = 0;
RoomGiftSeatFlightRequest? pendingFlightRequest;
void dispose() {
flushTimer?.cancel();
}
}

View File

@ -69,6 +69,8 @@ typedef OnMessageRecvC2CReadListener = Function(List<String> messageIDList);
typedef RtmProvider = RealTimeMessagingManager;
class RealTimeMessagingManager extends ChangeNotifier {
static const int _giftComboMergeWindowMs = 3000;
BuildContext? context;
void _giftFxLog(String message) {
@ -856,6 +858,17 @@ class RealTimeMessagingManager extends ChangeNotifier {
///
addMsg(Msg msg) {
final mergedGiftMsg = _mergeGiftMessageIfNeeded(msg);
if (mergedGiftMsg != null) {
msgAllListener?.call(mergedGiftMsg);
msgGiftListener?.call(mergedGiftMsg);
if (msg.type == SCRoomMsgType.gift) {
msgFloatingGiftListener?.call(msg);
}
notifyListeners();
return;
}
roomAllMsgList.insert(0, msg);
if (roomAllMsgList.length > 250) {
print('大于200条消息');
@ -891,6 +904,59 @@ class RealTimeMessagingManager extends ChangeNotifier {
}
}
Msg? _mergeGiftMessageIfNeeded(Msg incoming) {
if (incoming.type != SCRoomMsgType.gift &&
incoming.type != SCRoomMsgType.luckGiftAnimOther) {
return null;
}
final mergeTarget = _findMergeableGiftMessage(incoming);
if (mergeTarget == null) {
return null;
}
mergeTarget.number = (mergeTarget.number ?? 0) + (incoming.number ?? 0);
mergeTarget.time = DateTime.now().millisecondsSinceEpoch;
if ((incoming.msg ?? "").trim().isNotEmpty) {
mergeTarget.msg = incoming.msg;
}
_moveMessageToFront(roomGiftMsgList, mergeTarget);
_moveMessageToFront(roomAllMsgList, mergeTarget);
return mergeTarget;
}
Msg? _findMergeableGiftMessage(Msg incoming) {
final now = DateTime.now().millisecondsSinceEpoch;
for (final existing in roomGiftMsgList) {
if ((existing.time ?? 0) <= 0 ||
now - (existing.time ?? 0) > _giftComboMergeWindowMs) {
continue;
}
if (_isSameGiftComboMessage(existing, incoming)) {
return existing;
}
}
return null;
}
bool _isSameGiftComboMessage(Msg existing, Msg incoming) {
return existing.type == incoming.type &&
existing.groupId == incoming.groupId &&
existing.user?.id == incoming.user?.id &&
existing.toUser?.id == incoming.toUser?.id &&
existing.gift?.id == incoming.gift?.id;
}
void _moveMessageToFront(List<Msg> messages, Msg target) {
final index = messages.indexOf(target);
if (index <= 0) {
return;
}
messages.removeAt(index);
messages.insert(0, target);
}
bool isLogout = false;
logout() async {

View File

@ -8,6 +8,65 @@ import 'package:yumi/shared/business_logic/models/res/gift_res.dart';
typedef GiftProvider = SocialChatGiftSystemManager;
class SocialChatGiftSystemManager extends ChangeNotifier {
static const Map<int, String> _luckGiftComboEffectAssets = {
10: "sc_images/room/anim/luck_gift/luck_gift_combo_count_10.svga",
30: "sc_images/room/anim/luck_gift/luck_gift_combo_count_30.svga",
50: "sc_images/room/anim/luck_gift/luck_gift_combo_count_50.svga",
66: "sc_images/room/anim/luck_gift/luck_gift_combo_count_66.svga",
100: "sc_images/room/anim/luck_gift/luck_gift_combo_count_100.svga",
300: "sc_images/room/anim/luck_gift/luck_gift_combo_count_300.svga",
400: "sc_images/room/anim/luck_gift/luck_gift_combo_count_400.svga",
666: "sc_images/room/anim/luck_gift/luck_gift_combo_count_666.svga",
777: "sc_images/room/anim/luck_gift/luck_gift_combo_count_777.svga",
2000: "sc_images/room/anim/luck_gift/luck_gift_combo_count_2000.svga",
3000: "sc_images/room/anim/luck_gift/luck_gift_combo_count_3000.svga",
5000: "sc_images/room/anim/luck_gift/luck_gift_combo_count_5000.svga",
6000: "sc_images/room/anim/luck_gift/luck_gift_combo_count_6000.svga",
7000: "sc_images/room/anim/luck_gift/luck_gift_combo_count_7000.svga",
8000: "sc_images/room/anim/luck_gift/luck_gift_combo_count_8000.svga",
10000: "sc_images/room/anim/luck_gift/luck_gift_combo_count_10000.svga",
};
static const List<int> _luckGiftMilestones = <int>[
10,
20,
30,
50,
66,
88,
100,
200,
300,
400,
500,
666,
777,
888,
1000,
1500,
2000,
3000,
5000,
10000,
15000,
20000,
25000,
30000,
35000,
40000,
45000,
50000,
55000,
60000,
65000,
70000,
75000,
80000,
85000,
90000,
95000,
100000,
];
///
bool hideLGiftAnimal = false;
@ -129,51 +188,81 @@ class SocialChatGiftSystemManager extends ChangeNotifier {
void modifyLuckyGiftCount(
num n,
bool isManyPeople,
bool manyPeople,
MicRes first,
SocialChatGiftRes? checkedGift,
) {
this.number = number + n;
this.isManyPeople = isManyPeople;
this.toUser = first;
this.gift = checkedGift;
number = number + n;
isManyPeople = manyPeople;
toUser = first;
gift = checkedGift;
giftAnimSize = 1.4;
notifyListeners();
startGiftAnimation();
}
void updateLuckyRewardAmount(num n) {
this.awardAmount = n;
this.luckGiftObtainCoins = luckGiftObtainCoins + n;
this.obtainCoinsAnimSize = 1.4;
this.awardAmountAnimSize = 1.4;
awardAmount = n;
luckGiftObtainCoins = luckGiftObtainCoins + n;
obtainCoinsAnimSize = 1.4;
awardAmountAnimSize = 1.4;
notifyListeners();
}
void startGiftAnimation() {
isPlayed.forEach((k, v) {
if (k < number + 1 && !v) {
playVisualEffect(k);
final milestone = resolveHighestReachedLuckGiftMilestone(number);
if (milestone == null || (isPlayed[milestone] ?? false)) {
return;
}
});
playVisualEffect(milestone);
_markMilestonesPlayedUpTo(milestone);
}
void playVisualEffect(num n) {
if (!(isPlayed[n] ?? false)) {
if (SCGlobalConfig.isLuckGiftSpecialEffects) {
if (n > 9999) {
SCGiftVapSvgaManager().play(
"sc_images/room/anim/luck_gift_count_5000_mor.mp4",
priority: 200,
);
} else {
SCGiftVapSvgaManager().play(
"sc_images/room/anim/luck_gift_count_$n.mp4",
priority: 200,
);
final comboEffectPath = resolveLuckGiftComboEffectPath(n);
if (comboEffectPath != null) {
SCGiftVapSvgaManager().play(comboEffectPath, priority: 200);
}
}
}
isPlayed[n] = true;
}
void _markMilestonesPlayedUpTo(int milestone) {
for (final threshold in _luckGiftMilestones) {
if (threshold > milestone) {
break;
}
isPlayed[threshold] = true;
}
}
static int? resolveHighestReachedLuckGiftMilestone(num count) {
final normalizedCount = count.floor();
int? highest;
for (final milestone in _luckGiftMilestones) {
if (milestone > normalizedCount) {
break;
}
highest = milestone;
}
return highest;
}
static String? resolveLuckGiftComboEffectPath(num count) {
if (count % 1 != 0) {
return null;
}
final normalizedCount = count.toInt();
final comboEffectPath = _luckGiftComboEffectAssets[normalizedCount];
if (comboEffectPath != null) {
return comboEffectPath;
}
if (normalizedCount > 9999) {
return "sc_images/room/anim/luck_gift_count_5000_mor.mp4";
}
return "sc_images/room/anim/luck_gift_count_$normalizedCount.mp4";
}
}

View File

@ -0,0 +1,130 @@
import 'package:flutter/material.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:yumi/ui_kit/theme/socialchat_theme.dart';
class SCGiftComboSendButton extends StatefulWidget {
const SCGiftComboSendButton({
super.key,
required this.label,
required this.onPressed,
required this.showCountdown,
this.countdownAnimation,
this.width = 96,
});
final String label;
final VoidCallback onPressed;
final bool showCountdown;
final Animation<double>? countdownAnimation;
final double width;
@override
State<SCGiftComboSendButton> createState() => _SCGiftComboSendButtonState();
}
class _SCGiftComboSendButtonState extends State<SCGiftComboSendButton> {
static const Duration _pressScaleDuration = Duration(milliseconds: 90);
static const double _pressedScale = 0.96;
bool _pressed = false;
void _setPressed(bool value) {
if (_pressed == value) {
return;
}
setState(() {
_pressed = value;
});
}
@override
Widget build(BuildContext context) {
final animation =
widget.countdownAnimation ?? const AlwaysStoppedAnimation<double>(1);
final baseColor = SocialChatTheme.primaryLight;
final countdownLightColor = Color.lerp(baseColor, Colors.white, 0.18)!;
final countdownDeepColor = Color.lerp(baseColor, Colors.white, 0.04)!;
final borderRadius = BorderRadius.circular(5);
return GestureDetector(
behavior: HitTestBehavior.opaque,
onTapDown: (_) => _setPressed(true),
onTapUp: (_) => _setPressed(false),
onTapCancel: () => _setPressed(false),
onTap: widget.onPressed,
child: AnimatedScale(
scale: _pressed ? _pressedScale : 1,
duration: _pressScaleDuration,
curve: Curves.easeOutCubic,
child: AnimatedBuilder(
animation: animation,
builder: (context, child) {
final progress =
widget.showCountdown
? (1 - animation.value).clamp(0.0, 1.0)
: 0.0;
return SizedBox(
width: widget.width,
child: ClipRRect(
borderRadius: borderRadius,
child: DecoratedBox(
decoration: BoxDecoration(
color: baseColor,
borderRadius: borderRadius,
),
child: LayoutBuilder(
builder: (context, constraints) {
final countdownWidth = constraints.maxWidth * progress;
return Stack(
alignment: Alignment.center,
children: [
if (countdownWidth > 0)
Positioned(
left: 0,
top: 0,
bottom: 0,
width: countdownWidth,
child: DecoratedBox(
decoration: BoxDecoration(
gradient: LinearGradient(
begin: Alignment.centerRight,
end: Alignment.centerLeft,
colors: [
countdownLightColor,
countdownDeepColor,
],
),
),
),
),
Padding(
padding: EdgeInsets.symmetric(
vertical: 8.w,
horizontal: 20.w,
),
child: Text(
widget.label,
maxLines: 1,
overflow: TextOverflow.ellipsis,
style: TextStyle(
fontSize: 14.sp,
color: Colors.white,
fontWeight: FontWeight.w400,
),
),
),
],
);
},
),
),
),
);
},
),
),
);
}
}

View File

@ -1,5 +1,3 @@
import 'dart:async';
import 'package:flutter/cupertino.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:yumi/app/constants/sc_global_config.dart';
@ -7,10 +5,18 @@ import 'package:provider/provider.dart';
import 'package:yumi/ui_kit/components/sc_compontent.dart';
import 'package:yumi/services/audio/rtm_manager.dart';
import 'package:yumi/ui_kit/widgets/svga/sc_svga_asset_widget.dart';
class LuckGiftNomorAnimWidget extends StatefulWidget {
static const String _rewardFrameAssetPath =
"sc_images/room/anim/luck_gift/luck_gift_reward_frame.svga";
static const String _rewardFrameFallbackAssetPath =
"sc_images/room/sc_icon_luck_gift_nomore.webp";
const LuckGiftNomorAnimWidget({super.key});
@override
_LuckGiftNomorAnimWidgetState createState() =>
State<LuckGiftNomorAnimWidget> createState() =>
_LuckGiftNomorAnimWidgetState();
}
@ -21,7 +27,8 @@ class _LuckGiftNomorAnimWidgetState extends State<LuckGiftNomorAnimWidget> {
Provider.of<RtmProvider>(context, listen: false).showLuckGiftBigHead = true;
}
dispose() {
@override
void dispose() {
super.dispose();
}
@ -36,11 +43,25 @@ class _LuckGiftNomorAnimWidgetState extends State<LuckGiftNomorAnimWidget> {
margin: EdgeInsets.only(top: 10.w),
child: Stack(
children: [
Image.asset(
"sc_images/room/sc_icon_luck_gift_nomore.webp",
SCSvgaAssetWidget(
key: ValueKey<String>(
'${provider.currentPlayingLuckGift?.data?.sendUserId ?? ""}'
'|${provider.currentPlayingLuckGift?.data?.acceptUserId ?? ""}'
'|${provider.currentPlayingLuckGift?.data?.awardAmount ?? 0}'
'|${provider.currentPlayingLuckGift?.data?.multiple ?? 0}',
),
assetPath: LuckGiftNomorAnimWidget._rewardFrameAssetPath,
width: ScreenUtil().screenWidth,
height: 380.w,
fit: BoxFit.fitWidth,
allowDrawingOverflow: true,
fallback: Image.asset(
LuckGiftNomorAnimWidget._rewardFrameFallbackAssetPath,
fit: BoxFit.fitWidth,
),
provider.showLuckGiftBigHead?Column(
),
provider.showLuckGiftBigHead
? Column(
mainAxisSize: MainAxisSize.min,
children: [
SizedBox(height: 125.w),
@ -96,14 +117,17 @@ class _LuckGiftNomorAnimWidgetState extends State<LuckGiftNomorAnimWidget> {
Transform.translate(
offset: Offset(-3, 3),
child: Image.asset(
SCGlobalConfig.lang=="ar"? "sc_images/room/sc_icon_times_text_ar.png":"sc_images/room/sc_icon_times_text_en.png",
SCGlobalConfig.lang == "ar"
? "sc_images/room/sc_icon_times_text_ar.png"
: "sc_images/room/sc_icon_times_text_en.png",
height: 12.w,
),
),
],
),
],
):Container(),
)
: Container(),
],
),
)

View File

@ -3,6 +3,7 @@
from __future__ import annotations
import argparse
from contextlib import contextmanager
import datetime as dt
import hashlib
import json
@ -10,6 +11,7 @@ import re
import shutil
import subprocess
import sys
import time
from pathlib import Path
@ -54,14 +56,16 @@ def ensure_clean_dir(path: Path) -> None:
path.mkdir(parents=True, exist_ok=True)
def copy_file(src: Path, dest: Path) -> dict[str, object]:
def copy_file(src: Path, dest: Path, *, include_sha256: bool = True) -> dict[str, object]:
dest.parent.mkdir(parents=True, exist_ok=True)
shutil.copy2(src, dest)
return {
result: dict[str, object] = {
"path": str(dest.relative_to(ROOT)),
"sizeBytes": dest.stat().st_size,
"sha256": sha256_of(dest),
}
if include_sha256:
result["sha256"] = sha256_of(dest)
return result
def copy_tree(src: Path, dest: Path) -> None:
@ -69,8 +73,54 @@ def copy_tree(src: Path, dest: Path) -> None:
shutil.copytree(src, dest, dirs_exist_ok=True)
def append_common_flutter_args(command: list[str], args: argparse.Namespace) -> None:
command.extend(["--release", f"--target={args.target}"])
def first_existing_path(*candidates: Path) -> Path:
for candidate in candidates:
if candidate.exists():
return candidate
raise FileNotFoundError("No build output found in: " + ", ".join(str(candidate) for candidate in candidates))
def timings_bucket(manifest: dict[str, object]) -> dict[str, object]:
timings = manifest.get("timings")
if not isinstance(timings, dict):
timings = {"stages": []}
manifest["timings"] = timings
stages = timings.get("stages")
if not isinstance(stages, list):
timings["stages"] = []
return timings
@contextmanager
def timed_stage(manifest: dict[str, object], key: str, label: str) -> dict[str, object]:
stage_started_at = dt.datetime.now()
stage_started_perf = time.perf_counter()
stage: dict[str, object] = {
"key": key,
"label": label,
"startedAt": stage_started_at.isoformat(timespec="seconds"),
}
timings_bucket(manifest)["stages"].append(stage)
print(f"[stage:start] {label}", flush=True)
try:
yield stage
except Exception as exc:
stage["status"] = "failed"
stage["error"] = str(exc)
raise
else:
stage["status"] = "succeeded"
finally:
duration_seconds = round(time.perf_counter() - stage_started_perf, 3)
stage["endedAt"] = dt.datetime.now().isoformat(timespec="seconds")
stage["durationSeconds"] = duration_seconds
print(f"[stage:end] {label} ({duration_seconds:.1f}s)", flush=True)
def append_common_flutter_args(command: list[str], args: argparse.Namespace, *, build_mode: str = "release") -> None:
command.extend([f"--{build_mode}", f"--target={args.target}"])
if args.flavor:
command.extend(["--flavor", args.flavor])
@ -110,6 +160,7 @@ def build_android(args: argparse.Namespace, manifest: dict[str, object]) -> None
appbundle_cmd = ["flutter", "build", "appbundle"]
append_common_flutter_args(appbundle_cmd, args)
appbundle_cmd.append(f"--split-debug-info={android_symbols_dir.relative_to(ROOT)}")
with timed_stage(manifest, "android.googlePlayAab", "Android 谷歌发布包AAB"):
run_command(appbundle_cmd)
if profile == "full":
@ -123,18 +174,18 @@ def build_android(args: argparse.Namespace, manifest: dict[str, object]) -> None
]
append_common_flutter_args(apk_cmd, args)
apk_cmd.append(f"--split-debug-info={android_symbols_dir.relative_to(ROOT)}")
with timed_stage(manifest, "android.releaseApks", "Android 多 ABI 正式 APK"):
run_command(apk_cmd)
elif profile == "local-arm64":
apk_cmd = [
"flutter",
"build",
"apk",
"--split-per-abi",
"--target-platform",
"android-arm64",
]
append_common_flutter_args(apk_cmd, args)
apk_cmd.append(f"--split-debug-info={android_symbols_dir.relative_to(ROOT)}")
append_common_flutter_args(apk_cmd, args, build_mode="debug")
with timed_stage(manifest, "android.localDebugApk", "Android 极速测试包Debug / ARM64"):
run_command(apk_cmd)
google_play_dir = android_output_dir / "google-play"
@ -144,14 +195,24 @@ def build_android(args: argparse.Namespace, manifest: dict[str, object]) -> None
artifact_prefix = f"{args.package_name}-v{args.build_name}-b{args.build_number}"
artifacts: dict[str, object] = {}
with timed_stage(manifest, "android.collectArtifacts", "整理 Android 产物"):
if profile in {"full", "google-play"}:
aab_src = ROOT / "build" / "app" / "outputs" / "bundle" / "release" / "app-release.aab"
artifacts["googlePlayAab"] = copy_file(aab_src, google_play_dir / f"{artifact_prefix}-google-play.aab")
if profile in {"full", "local-arm64"}:
if profile == "full":
arm64_src = ROOT / "build" / "app" / "outputs" / "flutter-apk" / "app-arm64-v8a-release.apk"
artifacts["localArm64Apk"] = copy_file(arm64_src, local_dir / f"{artifact_prefix}-arm64-v8a.apk")
elif profile == "local-arm64":
arm64_src = first_existing_path(
ROOT / "build" / "app" / "outputs" / "flutter-apk" / "app-arm64-v8a-debug.apk",
ROOT / "build" / "app" / "outputs" / "flutter-apk" / "app-debug.apk",
)
artifacts["localArm64Apk"] = copy_file(
arm64_src,
local_dir / f"{artifact_prefix}-arm64-v8a-debug.apk",
include_sha256=False,
)
if profile == "full":
armv7_src = ROOT / "build" / "app" / "outputs" / "flutter-apk" / "app-armeabi-v7a-release.apk"
@ -159,7 +220,7 @@ def build_android(args: argparse.Namespace, manifest: dict[str, object]) -> None
artifacts["localArmeabiV7aApk"] = copy_file(armv7_src, local_dir / f"{artifact_prefix}-armeabi-v7a.apk")
artifacts["testingX64Apk"] = copy_file(x64_src, testing_dir / f"{artifact_prefix}-x86_64-test.apk")
if android_symbols_dir.exists():
if android_symbols_dir.exists() and profile in {"full", "google-play"}:
symbols_parent_dir = google_play_dir if profile in {"full", "google-play"} else local_dir
copy_tree(android_symbols_dir, symbols_parent_dir / "symbols")
artifacts["dartSymbolsDir"] = {
@ -185,6 +246,7 @@ def build_ios(args: argparse.Namespace, manifest: dict[str, object]) -> None:
else:
command.append("--no-codesign")
with timed_stage(manifest, "ios.buildIpa", "iOS 构建与导出"):
run_command(command)
artifact_prefix = f"{args.package_name}-v{args.build_name}-b{args.build_number}"
@ -193,6 +255,7 @@ def build_ios(args: argparse.Namespace, manifest: dict[str, object]) -> None:
archive_src = ROOT / "build" / "ios" / "archive" / "Runner.xcarchive"
ipa_candidates = sorted((ROOT / "build" / "ios" / "ipa").glob("*.ipa"))
with timed_stage(manifest, "ios.collectArtifacts", "整理 iOS 产物"):
if archive_src.exists():
copy_tree(archive_src, ios_output_dir / "archive" / f"{artifact_prefix}.xcarchive")
artifacts["archiveDir"] = {
@ -276,30 +339,48 @@ def main() -> int:
parser = create_argument_parser()
args = parser.parse_args()
args.output_dir = args.output_dir.resolve()
build_started_at = dt.datetime.now()
build_started_perf = time.perf_counter()
manifest_path = args.output_dir / "build_manifest.json"
args.output_dir.mkdir(parents=True, exist_ok=True)
manifest: dict[str, object] = {
"generatedAt": dt.datetime.now().isoformat(timespec="seconds"),
"packageName": args.package_name,
"platform": args.platform,
"buildName": args.build_name,
"buildNumber": args.build_number,
"target": args.target,
"flavor": args.flavor,
"outputDir": str(args.output_dir.relative_to(ROOT)),
"timings": {
"startedAt": build_started_at.isoformat(timespec="seconds"),
"stages": [],
},
}
exit_code = 0
try:
if should_build_android(args.platform):
build_android(args, manifest)
if should_build_ios(args.platform):
build_ios(args, manifest)
manifest_path = args.output_dir / "build_manifest.json"
manifest_path.write_text(json.dumps(manifest, indent=2, ensure_ascii=False) + "\n", encoding="utf-8")
manifest["status"] = "succeeded"
print(f"Artifacts copied to: {args.output_dir}")
print(f"Manifest written to: {manifest_path}")
return 0
except Exception as exc:
manifest["status"] = "failed"
manifest["error"] = str(exc)
exit_code = 1
raise
finally:
timings = timings_bucket(manifest)
timings["endedAt"] = dt.datetime.now().isoformat(timespec="seconds")
timings["totalSeconds"] = round(time.perf_counter() - build_started_perf, 3)
manifest_path.write_text(json.dumps(manifest, indent=2, ensure_ascii=False) + "\n", encoding="utf-8")
print(f"Total build time: {timings['totalSeconds']:.1f}s", flush=True)
print(f"Manifest written to: {manifest_path}", flush=True)
return exit_code
if __name__ == "__main__":

View File

@ -0,0 +1,126 @@
import 'package:flutter/material.dart';
import 'package:flutter_localizations/flutter_localizations.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:provider/provider.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:yumi/app/config/app_config.dart';
import 'package:yumi/app/constants/sc_screen.dart';
import 'package:yumi/app_localizations.dart';
import 'package:yumi/modules/auth/account/sc_login_with_account_page.dart';
import 'package:yumi/modules/settings/language/language_page.dart';
import 'package:yumi/services/localization/localization_manager.dart';
import 'package:yumi/shared/data_sources/sources/local/data_persistence.dart';
void main() {
TestWidgetsFlutterBinding.ensureInitialized();
AppConfig.initialize();
tearDown(() async {
DataPersistence.reset();
});
const locales = <Locale>[
Locale('en'),
Locale('ar'),
Locale('tr'),
Locale('bn'),
];
for (final locale in locales) {
group('Locale ${locale.languageCode}', () {
testWidgets('LanguagePage renders cleanly', (tester) async {
await _pumpLocalizedPage(
tester: tester,
locale: locale,
child: LanguagePage(),
);
final exceptions = _drainExceptions(tester);
expect(exceptions, isEmpty, reason: exceptions.join('\n\n'));
expect(
tester
.widget<MaterialApp>(find.byType(MaterialApp))
.locale
?.languageCode,
locale.languageCode,
);
});
testWidgets('SCLoginWithAccountPage renders cleanly', (tester) async {
await _pumpLocalizedPage(
tester: tester,
locale: locale,
child: const SCLoginWithAccountPage(),
);
final exceptions = _drainExceptions(tester);
expect(exceptions, isEmpty, reason: exceptions.join('\n\n'));
expect(
tester
.widget<MaterialApp>(find.byType(MaterialApp))
.locale
?.languageCode,
locale.languageCode,
);
});
});
}
}
Future<void> _pumpLocalizedPage({
required WidgetTester tester,
required Locale locale,
required Widget child,
}) async {
SharedPreferences.setMockInitialValues({'lang': locale.languageCode});
await DataPersistence.initialize();
await tester.binding.setSurfaceSize(const Size(390, 844));
await tester.pumpWidget(
ChangeNotifierProvider(
create: (_) => LocalizationManager(),
child: ScreenUtilInit(
designSize: Size(SCScreen.designWidth, SCScreen.designHeight),
splitScreenMode: false,
minTextAdapt: true,
builder: (context, _) {
return MaterialApp(
debugShowCheckedModeBanner: false,
locale: locale,
localizationsDelegates: const [
SCAppLocalizations.delegate,
GlobalMaterialLocalizations.delegate,
GlobalCupertinoLocalizations.delegate,
GlobalWidgetsLocalizations.delegate,
],
supportedLocales: const [
Locale('en'),
Locale('ar'),
Locale('tr'),
Locale('bn'),
],
home: RepaintBoundary(
key: const ValueKey('capture_boundary'),
child: child,
),
);
},
),
),
);
await tester.pump();
await tester.pump(const Duration(milliseconds: 200));
await tester.pump(const Duration(milliseconds: 200));
await tester.pump(const Duration(milliseconds: 200));
}
List<Object> _drainExceptions(WidgetTester tester) {
final exceptions = <Object>[];
Object? exception;
while ((exception = tester.takeException()) != null) {
exceptions.add(exception!);
}
return exceptions;
}

View File

@ -13,6 +13,11 @@
- 本轮按需求暂未处理网络链路上的启动等待,例如审核态检查或远端启动页配置请求。
## 已完成模块
- 已继续优化幸运/CP 礼物连击体验:房间 `Gift/All` 消息面板现在会对短时间内同一发送者、同一目标、同一礼物的连续赠送做聚合更新,不再每点一次就追加一条新消息,而是复用同一条礼物播报并持续刷新成 `xN`同时礼物页底部发送按钮已补上本地连击反馈Lucky/CP/Magic 类礼物连续点击时会显示一条从右向左收缩的浅色倒计时渐变条,并同步累加当前连击数量,用户能更直观看到连击窗口是否还在持续。
- 已继续给发送端补齐连击请求聚合:礼物页当前会对 Lucky/CP/Magic 这类连击型礼物启用约 `200ms` 的本地批量窗口,用户在短时间内连续点击 `Send` 时,前端会先把同一礼物、同一目标集合、同一房间的点击数量累加到同一批次里,再统一发一次接口和一次房间 RTM 消息;这样高连击时不再按点击次数直冲 `/gift/batch``/gift/give/lucky-gift`,同时也避免本地回显和房间消息量被线性放大。
- 已继续收敛幸运礼物高连击时的播放策略:房间内幸运礼物现在按 3 秒连击会话聚合,连击期间只更新房内上飘与总次数,不再每次都立刻飞向麦位;同一轮连击结束后才会向目标麦位补播一次飞行动画,避免 `1000` 连击把静态礼物飞行动画排成超长队列;同时幸运礼物的档位特效已改为只命中当前会话累计数量对应的最高有效档位,不再把中间跨过的 `10/20/30/...` 全部补播一遍。
- 已定位到幸运礼物“中奖通知”使用的是房间页顶层 `LuckGiftNomorAnimWidget`,此前背景一直是静态 `sc_icon_luck_gift_nomore.webp`;当前已改为优先播放本地 `sc_images/room/anim/luck_gift/luck_gift_reward_frame.svga`,并保留原 `webp` 作为失败兜底,这样幸运礼物中奖弹层会直接复用新的奖励边框动效资源。
- 已开始接入幸运礼物连击档位的新动效资源:桌面“幸运礼物相关”目录下的 SVGA 已统一导入到 `sc_images/room/anim/luck_gift/`,并按规范重命名为 `luck_gift_combo_count_10.svga / luck_gift_combo_count_666.svga / luck_gift_combo_count_10000.svga` 这一类统一英文命名;当前连击阈值触发仍复用 `GiftSystemManager.playVisualEffect()`,命中已提供素材的档位时优先播放新的本地 SVGA未提供素材的档位继续保留旧兜底逻辑避免影响现有幸运礼物连击链路。
- 已将语言房送礼链路接入新的“中心停留后飞向目标麦位”组件,但只对无自带特效的静态 PNG 礼物生效:当前带自身 `SVGA/MP4/VAP` 动画或被识别为全屏礼物特效的礼物保持原有播放逻辑不变;只有普通 PNG 礼物会额外触发“屏幕中央停留 -> 三连残影飞向被赠送麦位”的补充动效,避免和自带礼物特效重复叠播。
- 已继续收敛语言房送礼飞行动效的命中条件:上一版对普通礼物的过滤过严,既依赖 `giftPhoto` 必须显式以 `.png` 结尾,也会被部分礼物的 `special` 标记误伤,导致不少实际没有自带动画的礼物被提前跳过;当前已改为只排除真实带 `SVGA/MP4/VAP` 动画源的礼物,普通静态封面礼物即使是带 query 的图片 URL、或不是严格 `.png` 后缀,也会正常触发“中心停留 -> 飞向目标麦位”的补充动画。
- 已将语言房送礼飞行动画从房间页内部 `Stack` 提升到应用根层,挂载方式对齐现有 `SVGA/VAP` 礼物特效层:当前该动画会和 `VapPlusSvgaPlayer` 一样在 `main.dart` 的顶层 builder 中全屏绘制,因此不会再被房间内部聊天区、局部动效或页面层级压住,视觉上更靠前、更容易被用户看到。