commit ff0a034d6caf9eb616c20bda5c5634435719a10a
Author: ZuoZuo <68836346+Mrz-sakura@users.noreply.github.com>
Date: Thu Apr 9 21:32:23 2026 +0800
Initial commit
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..e3dafe1
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,45 @@
+# Miscellaneous
+*.class
+*.log
+*.pyc
+*.swp
+.DS_Store
+.atom/
+.build/
+.buildlog/
+.history
+.svn/
+.swiftpm/
+migrate_working_dir/
+
+# IntelliJ related
+*.iml
+*.ipr
+*.iws
+.idea/
+
+# The .vscode folder contains launch configuration and tasks you configure in
+# VS Code which you may wish to be included in version control, so this line
+# is commented out by default.
+#.vscode/
+
+# Flutter/Dart/Pub related
+**/doc/api/
+**/ios/Flutter/.last_build_id
+.dart_tool/
+.flutter-plugins
+.flutter-plugins-dependencies
+.pub-cache/
+.pub/
+/build/
+
+# Symbolication related
+app.*.symbols
+
+# Obfuscation related
+app.*.map.json
+
+# Android Studio will place build artifacts here
+/android/app/debug
+/android/app/profile
+/android/app/release
diff --git a/.metadata b/.metadata
new file mode 100644
index 0000000..f70d82d
--- /dev/null
+++ b/.metadata
@@ -0,0 +1,33 @@
+# This file tracks properties of this Flutter project.
+# Used by Flutter tool to assess capabilities and perform upgrades etc.
+#
+# This file should be version controlled and should not be manually edited.
+
+version:
+ revision: "ea121f8859e4b13e47a8f845e4586164519588bc"
+ channel: "stable"
+
+project_type: app
+
+# Tracks metadata for the flutter migrate command
+migration:
+ platforms:
+ - platform: root
+ create_revision: ea121f8859e4b13e47a8f845e4586164519588bc
+ base_revision: ea121f8859e4b13e47a8f845e4586164519588bc
+ - platform: android
+ create_revision: ea121f8859e4b13e47a8f845e4586164519588bc
+ base_revision: ea121f8859e4b13e47a8f845e4586164519588bc
+ - platform: ios
+ create_revision: ea121f8859e4b13e47a8f845e4586164519588bc
+ base_revision: ea121f8859e4b13e47a8f845e4586164519588bc
+
+ # User provided section
+
+ # List of Local paths (relative to this file) that should be
+ # ignored by the migrate tool.
+ #
+ # Files that are not part of the templates will be ignored by default.
+ unmanaged_files:
+ - 'lib/main.dart'
+ - 'ios/Runner.xcodeproj/project.pbxproj'
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..4435dd3
--- /dev/null
+++ b/README.md
@@ -0,0 +1,16 @@
+# Aslan
+
+Aslan
+
+## Getting Started
+
+This project is a starting point for a Flutter application.
+
+A few resources to get you started if this is your first Flutter project:
+
+- [Lab: Write your first Flutter app](https://docs.flutter.dev/get-started/codelab)
+- [Cookbook: Useful Flutter samples](https://docs.flutter.dev/cookbook)
+
+For help getting started with Flutter development, view the
+[online documentation](https://docs.flutter.dev/), which offers tutorials,
+samples, guidance on mobile development, and a full API reference.
diff --git a/analysis_options.yaml b/analysis_options.yaml
new file mode 100644
index 0000000..d4e0f0c
--- /dev/null
+++ b/analysis_options.yaml
@@ -0,0 +1,28 @@
+# This file configures the analyzer, which statically analyzes Dart code to
+# check for errors, warnings, and lints.
+#
+# The issues identified by the analyzer are surfaced in the UI of Dart-enabled
+# IDEs (https://dart.dev/tools#ides-and-editors). The analyzer can also be
+# invoked from the command line by running `flutter analyze`.
+
+# The following line activates a set of recommended lints for Flutter apps,
+# packages, and plugins designed to encourage good coding practices.
+include: package:flutter_lints/flutter.yaml
+
+linter:
+ # The lint rules applied to this project can be customized in the
+ # section below to disable rules from the `package:flutter_lints/flutter.yaml`
+ # included above or to enable additional rules. A list of all available lints
+ # and their documentation is published at https://dart.dev/lints.
+ #
+ # Instead of disabling a lint rule for the entire project in the
+ # section below, it can also be suppressed for a single line of code
+ # or a specific dart file by using the `// ignore: name_of_lint` and
+ # `// ignore_for_file: name_of_lint` syntax on the line or in the file
+ # producing the lint.
+ rules:
+ # avoid_print: false # Uncomment to disable the `avoid_print` rule
+ # prefer_single_quotes: true # Uncomment to enable the `prefer_single_quotes` rule
+
+# Additional information about this file can be found at
+# https://dart.dev/guides/language/analysis-options
diff --git a/android/.gitignore b/android/.gitignore
new file mode 100644
index 0000000..c908258
--- /dev/null
+++ b/android/.gitignore
@@ -0,0 +1,14 @@
+gradle-wrapper.jar
+/.gradle
+/captures/
+/gradlew
+/gradlew.bat
+/local.properties
+GeneratedPluginRegistrant.java
+.cxx/
+
+# Remember to never publicly share your keystore.
+# See https://flutter.dev/to/reference-keystore
+key.properties
+**/*.keystore
+**/*.jks
diff --git a/android/aliyun-repos.init.gradle.kts b/android/aliyun-repos.init.gradle.kts
new file mode 100644
index 0000000..92763c7
--- /dev/null
+++ b/android/aliyun-repos.init.gradle.kts
@@ -0,0 +1,28 @@
+val mirrorRepos = listOf(
+ "https://maven.aliyun.com/repository/google",
+ "https://maven.aliyun.com/repository/public",
+ "https://maven.aliyun.com/repository/gradle-plugin",
+)
+
+fun org.gradle.api.artifacts.dsl.RepositoryHandler.addMirrorRepos() {
+ mirrorRepos.forEach { url ->
+ maven(url)
+ }
+}
+
+settingsEvaluated {
+ pluginManagement.repositories.apply {
+ addMirrorRepos()
+ mavenCentral()
+ gradlePluginPortal()
+ google()
+ }
+}
+
+gradle.beforeProject {
+ buildscript.repositories.apply {
+ addMirrorRepos()
+ mavenCentral()
+ google()
+ }
+}
diff --git a/android/app/build.gradle.kts b/android/app/build.gradle.kts
new file mode 100644
index 0000000..27d3e42
--- /dev/null
+++ b/android/app/build.gradle.kts
@@ -0,0 +1,90 @@
+plugins {
+ id("com.android.application")
+ id("kotlin-android")
+ // The Flutter Gradle Plugin must be applied after the Android and Kotlin Gradle plugins.
+ id("dev.flutter.flutter-gradle-plugin")
+ id("com.google.gms.google-services")
+}
+
+android {
+ namespace = "com.org.yumi"
+ compileSdk = 36
+ ndkVersion = "28.2.13676358"
+
+ signingConfigs {
+ create("release") {
+ storeFile = file("./yumi.jks")
+ storePassword = "2025abc"
+ keyAlias = "yumi"
+ keyPassword = "2025abc"
+ }
+
+ getByName("debug") {
+ storeFile = file("./yumi_debug.jks")
+ storePassword = "2025abc"
+ keyAlias = "yumi"
+ keyPassword = "2025abc"
+ }
+ }
+
+ compileOptions {
+ sourceCompatibility = JavaVersion.VERSION_11
+ targetCompatibility = JavaVersion.VERSION_11
+ }
+
+ kotlinOptions {
+ jvmTarget = JavaVersion.VERSION_11.toString()
+ }
+
+
+ defaultConfig {
+ multiDexEnabled = true
+ manifestPlaceholders["appName"] = "Yumi"
+ manifestPlaceholders["appIcon"] = "@mipmap/ic_launcher"
+ manifestPlaceholders["appIconRound"] = "@mipmap/icon_logo_round"
+ applicationId = "com.org.yumi"
+ // You can update the following values to match your application needs.
+ // For more information, see: https://flutter.dev/to/review-gradle-config.
+ minSdk = flutter.minSdkVersion
+ targetSdk = flutter.targetSdkVersion
+ versionCode = flutter.versionCode
+ versionName = flutter.versionName
+
+ ndk {
+ // 指定支持的 ABI 架构
+ abiFilters.add("arm64-v8a")
+ abiFilters.add("armeabi-v7a")
+ abiFilters.add("x86_64")
+ // 如果需要支持 x86 模拟器,可以添加 'x86', 'x86_64'
+ }
+ }
+
+ buildTypes {
+ getByName("release") {
+ isMinifyEnabled = false
+ isShrinkResources = false
+ isZipAlignEnabled = false
+ proguardFiles(
+ getDefaultProguardFile("proguard-android-optimize.txt"),
+ "proguard-rules.pro"
+ )
+ signingConfig = signingConfigs["release"]
+ }
+ getByName("debug") {
+ isMinifyEnabled = false
+ signingConfig = signingConfigs["release"]
+ }
+ }
+}
+dependencies {
+ implementation("androidx.multidex:multidex:2.0.1")
+// implementation(platform("com.google.firebase:firebase-bom:34.0.0"))
+// implementation("com.google.firebase:firebase-auth")
+// implementation("com.google.firebase:firebase-core:16.0.8")
+// implementation("com.google.android.gms:play-services-auth:21.1.1")
+}
+
+
+flutter {
+ source = "../.."
+}
diff --git a/android/app/google-services.json b/android/app/google-services.json
new file mode 100644
index 0000000..bc69a4e
--- /dev/null
+++ b/android/app/google-services.json
@@ -0,0 +1,47 @@
+{
+ "project_info": {
+ "project_number": "980005024266",
+ "project_id": "yumi-c3b30",
+ "storage_bucket": "yumi-c3b30.firebasestorage.app"
+ },
+ "client": [
+ {
+ "client_info": {
+ "mobilesdk_app_id": "1:980005024266:android:581aa38059aa318d9c65f3",
+ "android_client_info": {
+ "package_name": "com.org.yumi"
+ }
+ },
+ "oauth_client": [
+ {
+ "client_id": "980005024266-sl5h466pe90jsjmoi4jcd7bqhmckieec.apps.googleusercontent.com",
+ "client_type": 1,
+ "android_info": {
+ "package_name": "com.org.yumi",
+ "certificate_hash": "9ab21924bfbe2c56555860ebabf23c4099fd7412"
+ }
+ },
+ {
+ "client_id": "980005024266-dgtthe3q98k8tk873rfdrsnu5ot61p09.apps.googleusercontent.com",
+ "client_type": 3
+ }
+ ],
+ "api_key": [
+ {
+ "current_key": "AIzaSyAbxU9QpbnC5PrrhUjDSK1camiotDlF3qE"
+ }
+ ],
+ "services": {
+ "appinvite_service": {
+ "other_platform_oauth_client": [
+ {
+ "client_id": "980005024266-dgtthe3q98k8tk873rfdrsnu5ot61p09.apps.googleusercontent.com",
+ "client_type": 3
+ }
+ ]
+ }
+ }
+ }
+ ],
+ "configuration_version": "1"
+}
diff --git a/android/app/info.txt b/android/app/info.txt
new file mode 100644
index 0000000..9a39b54
--- /dev/null
+++ b/android/app/info.txt
@@ -0,0 +1,3 @@
+yumi.jks签名信息:
+pwd:2025abc
+Alias:yumi
\ No newline at end of file
diff --git a/android/app/proguard-rules.pro b/android/app/proguard-rules.pro
new file mode 100644
index 0000000..fbecac5
--- /dev/null
+++ b/android/app/proguard-rules.pro
@@ -0,0 +1,39 @@
+# Flutter 基础
+-keep class io.flutter.** { *; }
+-keep class io.flutter.app.** { *; }
+-keep class io.flutter.plugin.** { *; }
+-keep class io.flutter.util.** { *; }
+
+# Play Core 保留
+-keep class com.google.android.play.core.** { *; }
+-keep interface com.google.android.play.core.** { *; }
+
+# 根据 missing_rules.txt 添加的规则
+-dontwarn com.google.android.play.core.splitcompat.SplitCompatApplication
+-dontwarn com.google.android.play.core.splitinstall.SplitInstallException
+-dontwarn com.google.android.play.core.splitinstall.SplitInstallManager
+-dontwarn com.google.android.play.core.splitinstall.SplitInstallManagerFactory
+-dontwarn com.google.android.play.core.splitinstall.SplitInstallRequest$Builder
+-dontwarn com.google.android.play.core.splitinstall.SplitInstallRequest
+-dontwarn com.google.android.play.core.splitinstall.SplitInstallSessionState
+-dontwarn com.google.android.play.core.splitinstall.SplitInstallStateUpdatedListener
+-dontwarn com.google.android.play.core.tasks.OnFailureListener
+-dontwarn com.google.android.play.core.tasks.OnSuccessListener
+-dontwarn com.google.android.play.core.tasks.Task
+
+# 保留这些类以确保功能正常
+-keep class com.google.android.play.core.splitcompat.** { *; }
+-keep class com.google.android.play.core.splitinstall.** { *; }
+-keep class com.google.android.play.core.tasks.** { *; }
+-keep class io.flutter.embedding.engine.deferredcomponents.** { *; }
+
+# 应用特定
+-keep class com.org.yumi.** { *; }
+
+# Provider
+-keep class * extends ChangeNotifier { *; }
+-keep class * implements Listenable { *; }
+
+# 其他保留
+-keepattributes *Annotation*
+-keepattributes Signature
\ No newline at end of file
diff --git a/android/app/src/debug/AndroidManifest.xml b/android/app/src/debug/AndroidManifest.xml
new file mode 100644
index 0000000..8ffe024
--- /dev/null
+++ b/android/app/src/debug/AndroidManifest.xml
@@ -0,0 +1,7 @@
+
+
+
+
diff --git a/android/app/src/main/AndroidManifest.xml b/android/app/src/main/AndroidManifest.xml
new file mode 100644
index 0000000..09a35e3
--- /dev/null
+++ b/android/app/src/main/AndroidManifest.xml
@@ -0,0 +1,144 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/android/app/src/main/kotlin/com/tkm/likei/variant1/MainActivity.kt b/android/app/src/main/kotlin/com/tkm/likei/variant1/MainActivity.kt
new file mode 100644
index 0000000..e3fe890
--- /dev/null
+++ b/android/app/src/main/kotlin/com/tkm/likei/variant1/MainActivity.kt
@@ -0,0 +1,13 @@
+package com.org.yumi
+
+import android.content.Intent
+import android.net.Uri
+import io.flutter.embedding.android.FlutterActivity
+import io.flutter.embedding.engine.FlutterEngine
+import io.flutter.plugin.common.MethodChannel
+
+class MainActivity: FlutterActivity() {
+ override fun configureFlutterEngine(flutterEngine: FlutterEngine) {
+ super.configureFlutterEngine(flutterEngine) // 这行必须存在!
+ }
+}
diff --git a/android/app/src/main/res/drawable-v21/launch_background.xml b/android/app/src/main/res/drawable-v21/launch_background.xml
new file mode 100644
index 0000000..1cb7aa2
--- /dev/null
+++ b/android/app/src/main/res/drawable-v21/launch_background.xml
@@ -0,0 +1,12 @@
+
+
+
+
+
+
+
+
diff --git a/android/app/src/main/res/drawable/launch_background.xml b/android/app/src/main/res/drawable/launch_background.xml
new file mode 100644
index 0000000..8403758
--- /dev/null
+++ b/android/app/src/main/res/drawable/launch_background.xml
@@ -0,0 +1,12 @@
+
+
+
+
+
+
+
+
diff --git a/android/app/src/main/res/mipmap-hdpi/ic_launcher.png b/android/app/src/main/res/mipmap-hdpi/ic_launcher.png
new file mode 100644
index 0000000..bab4549
Binary files /dev/null and b/android/app/src/main/res/mipmap-hdpi/ic_launcher.png differ
diff --git a/android/app/src/main/res/mipmap-mdpi/ic_launcher.png b/android/app/src/main/res/mipmap-mdpi/ic_launcher.png
new file mode 100644
index 0000000..6f8ffa1
Binary files /dev/null and b/android/app/src/main/res/mipmap-mdpi/ic_launcher.png differ
diff --git a/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png b/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png
new file mode 100644
index 0000000..97304cd
Binary files /dev/null and b/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png differ
diff --git a/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png b/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png
new file mode 100644
index 0000000..1a5b3c6
Binary files /dev/null and b/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png differ
diff --git a/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png b/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png
new file mode 100644
index 0000000..181965c
Binary files /dev/null and b/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png differ
diff --git a/android/app/src/main/res/values-night/styles.xml b/android/app/src/main/res/values-night/styles.xml
new file mode 100644
index 0000000..360a160
--- /dev/null
+++ b/android/app/src/main/res/values-night/styles.xml
@@ -0,0 +1,18 @@
+
+
+
+
+
+
+
diff --git a/android/app/src/main/res/values/colors.xml b/android/app/src/main/res/values/colors.xml
new file mode 100644
index 0000000..954cc8c
--- /dev/null
+++ b/android/app/src/main/res/values/colors.xml
@@ -0,0 +1,21 @@
+
+
+
+ #FF5722
+ #D84315
+ #FF9800
+
+
+ #FFFFFF
+ #000000
+ #00000000
+
+
+ #F5F5F5
+ #FFFFFF
+
+
+ #212121
+ #757575
+ #BDBDBD
+
diff --git a/android/app/src/main/res/values/strings.xml b/android/app/src/main/res/values/strings.xml
new file mode 100644
index 0000000..a1746ad
--- /dev/null
+++ b/android/app/src/main/res/values/strings.xml
@@ -0,0 +1,4 @@
+
+
+ Yumi
+
\ No newline at end of file
diff --git a/android/app/src/main/res/values/styles.xml b/android/app/src/main/res/values/styles.xml
new file mode 100644
index 0000000..308ea4f
--- /dev/null
+++ b/android/app/src/main/res/values/styles.xml
@@ -0,0 +1,19 @@
+
+
+
+
+
+
+
+
diff --git a/android/app/src/main/res/xml/file_paths.xml b/android/app/src/main/res/xml/file_paths.xml
new file mode 100644
index 0000000..68ea404
--- /dev/null
+++ b/android/app/src/main/res/xml/file_paths.xml
@@ -0,0 +1,18 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/android/app/src/profile/AndroidManifest.xml b/android/app/src/profile/AndroidManifest.xml
new file mode 100644
index 0000000..8ffe024
--- /dev/null
+++ b/android/app/src/profile/AndroidManifest.xml
@@ -0,0 +1,7 @@
+
+
+
+
diff --git a/android/build.gradle.kts b/android/build.gradle.kts
new file mode 100644
index 0000000..aef8ba5
--- /dev/null
+++ b/android/build.gradle.kts
@@ -0,0 +1,43 @@
+plugins {
+ id("com.google.gms.google-services") version "4.4.3" apply false
+}
+buildscript {
+ repositories {
+ google()
+ mavenCentral()
+ // 使用阿里云镜像加速
+ maven { url = uri("https://maven.aliyun.com/repository/google") }
+ maven { url = uri("https://maven.aliyun.com/repository/public") }
+ maven { url = uri("https://maven.aliyun.com/repository/gradle-plugin") }
+ }
+}
+
+
+allprojects {
+ repositories {
+ // 使用阿里云镜像加速
+ maven { url = uri("https://maven.aliyun.com/repository/google") }
+ maven { url = uri("https://maven.aliyun.com/repository/public") }
+ maven { url = uri("https://maven.aliyun.com/repository/gradle-plugin") }
+ // 备用官方仓库
+ google()
+ mavenCentral()
+ }
+}
+
+// 以下是你的现有配置
+val newBuildDir: Directory = rootProject.layout.buildDirectory.dir("../../build").get()
+rootProject.layout.buildDirectory.value(newBuildDir)
+
+subprojects {
+ val newSubprojectBuildDir: Directory = newBuildDir.dir(project.name)
+ project.layout.buildDirectory.value(newSubprojectBuildDir)
+}
+
+subprojects {
+ project.evaluationDependsOn(":app")
+}
+
+tasks.register("clean") {
+ delete(rootProject.layout.buildDirectory)
+}
\ No newline at end of file
diff --git a/android/gradle.properties b/android/gradle.properties
new file mode 100644
index 0000000..b7cda7b
--- /dev/null
+++ b/android/gradle.properties
@@ -0,0 +1,3 @@
+org.gradle.jvmargs=-Xmx8G -XX:MaxMetaspaceSize=4G -XX:ReservedCodeCacheSize=512m -XX:+HeapDumpOnOutOfMemoryError
+android.useAndroidX=true
+android.enableJetifier=true
diff --git a/android/gradle/wrapper/gradle-wrapper.properties b/android/gradle/wrapper/gradle-wrapper.properties
new file mode 100644
index 0000000..6e36e2c
--- /dev/null
+++ b/android/gradle/wrapper/gradle-wrapper.properties
@@ -0,0 +1,5 @@
+distributionBase=GRADLE_USER_HOME
+distributionPath=wrapper/dists
+zipStoreBase=GRADLE_USER_HOME
+zipStorePath=wrapper/dists
+distributionUrl=https\://services.gradle.org/distributions/gradle-8.11.1-all.zip
diff --git a/android/settings.gradle.kts b/android/settings.gradle.kts
new file mode 100644
index 0000000..04bc745
--- /dev/null
+++ b/android/settings.gradle.kts
@@ -0,0 +1,28 @@
+pluginManagement {
+ val flutterSdkPath = run {
+ val properties = java.util.Properties()
+ file("local.properties").inputStream().use { properties.load(it) }
+ val flutterSdkPath = properties.getProperty("flutter.sdk")
+ require(flutterSdkPath != null) { "flutter.sdk not set in local.properties" }
+ flutterSdkPath
+ }
+
+ includeBuild("$flutterSdkPath/packages/flutter_tools/gradle")
+
+ repositories {
+ google()
+ mavenCentral()
+ gradlePluginPortal()
+ maven { url = uri("https://maven.aliyun.com/repository/google") }
+ maven { url = uri("https://maven.aliyun.com/repository/public") }
+ maven { url = uri("https://maven.aliyun.com/repository/gradle-plugin") }
+ }
+}
+
+plugins {
+ id("dev.flutter.flutter-plugin-loader") version "1.0.0"
+ id("com.android.application") version "8.9.1" apply false
+ id("org.jetbrains.kotlin.android") version "2.1.0" apply false
+}
+
+include(":app")
diff --git a/assets/l10n/intl_ar.json b/assets/l10n/intl_ar.json
new file mode 100644
index 0000000..b279e2f
--- /dev/null
+++ b/assets/l10n/intl_ar.json
@@ -0,0 +1,640 @@
+{
+ "signInWithGoogle": "سيج إنويسجوغل",
+ "or": "اور",
+ "signInWithYourAccount": "سيج ، إن ، فايس ، ويوا كونتي",
+ "signInWithApple": "سيج إنويس أبل",
+ "loginRepresentsAgreementTo": "تسجيل الدخول يمثل الموافقة على",
+ "termsofService": "تيمز بنسيفيتش",
+ "privaceyPolicy": "بريفاسيبوليس",
+ "tips": "تيبس",
+ "mine": "خاصتي",
+ "searchNoDataTips": "أدخل معرف الغرفة أو المستخدم الذي تريد البحث عنه.",
+ "party": "حفلة",
+ "event": "حدث",
+ "yes": "نعم",
+ "sound2": "صوت",
+ "games": "ألعاب",
+ "myRoom": "غرفتي",
+ "other": "آخر",
+ "startYourBrandNewJourney": "ابدأ رحلتك الجديدة تمامًا",
+ "maliciousHarassment": "التحرش الخبيث",
+ "aboutMe": "عنّي",
+ "bag": "حقيبة",
+ "roomEdit": "تحرير الغرفة",
+ "cancelRoomPassword": "هل أنت متأكد أنك تريد حذف كلمة مرور الغرفة؟",
+ "roomMemberFee": "رسوم عضو الغرفة",
+ "blockedList2": "قائمة المحظورين",
+ "roomTheme2": "موضوع الغرفة",
+ "roomPassword": "كلمة مرور الغرفة",
+ "numberOfMic": "عدد الميكروفونات",
+ "pleaseEnterContent": "يرجى إدخال المحتوى",
+ "profilePhoto": "صورة الملف الشخصي",
+ "noHistoricalRecordsAvailable": "لا توجد سجلات تاريخية متاحة.",
+ "inviteNewUsersToEarnCoins": "ادعُ مستخدمين جدد لكسب العملات",
+ "crateMyRoom": "أنشئ غرفتك الخاصة.",
+ "casualInteraction": "التفاعل العفوي",
+ "haveGamePlayingTips": "لديك لعبة جارية، يرجى الخروج من اللعبة الحالية أولاً، هل أنت متأكد من الخروج؟",
+ "historicalTour": "جولة تاريخية",
+ "gameCenter": "مركز الألعاب",
+ "returnToVoiceChat": "العودة إلى الدردشة الصوتية؟",
+ "game": "لعبة",
+ "invite": "يدعو",
+ "claim": "مطالبة",
+ "recent": "حديث",
+ "popularEvents": "الأحداث الشهيرة",
+ "exitGameMode": "الخروج من وضع اللعبة",
+ "enterTheRoom": "ادخل الغرفة",
+ "inviteGoRoomTips": "دائمًا هنا من أجلك، في المطر أو الشمس. تعال وقل مرحبًا!",
+ "confirmInviteThisUserToTheRoom": "هل تؤكد دعوة هذا المستخدم (المعرف: {1}) إلى الغرفة؟",
+ "complete": "مكتمل",
+ "copyLink": "نسخ الرابط",
+ "shareTo": "مشاركة إلى",
+ "faceBook": "فيسبوك",
+ "whatsApp": "واتساب",
+ "snapChat": "سناب شات",
+ "taskNameRoomOwnerSendRedPacket": "مالك الغرفة يرسل مظروفًا أحمر",
+ "taskNameRoomNewMember": "أعضاء جدد في الغرفة",
+ "taskNameRoomOwnerSendGiftUser": "مالك الغرفة يرسل هدية",
+ "taskNameRoomMicUser120Min": "الأعضاء بقضاء 120+ دقيقة على الميكروفون",
+ "taskNameRoomMicUser60Min": "الأعضاء بقضاء 60+ دقيقة على الميكروفون",
+ "taskNameRoomMicUser30Min": "الأعضاء بقضاء 30+ دقيقة على الميكروفون",
+ "taskNamePersonalSendGift": "أرسل هدية لمستخدم",
+ "taskNameRoomOnlineUserCount": "الأعضاء المتصلون في الغرفة",
+ "taskNameRoomOwnerInviteMic": "دعوة عضو إلى الميكروفون",
+ "taskNameRoomUserSendGiftGold": "العملات المهداة من الأعضاء",
+ "taskNameRoomOwnerSendGiftGold": "العملات المهداة من مالك الغرفة",
+ "taskNamePersonalMagicGiftGold": "العملات المكتسبة من إرسال هدايا سحرية",
+ "taskNamePersonalLuckyGiftGold": "العملات المكتسبة من إرسال هدايا الحظ",
+ "taskNameRoomOwnerMicTime": "مالك الغرفة يتحدث عبر الميكروفون في الغرفة",
+ "taskNamePersonalActiveInRoom": "كن نشطًا في غرف الآخرين",
+ "taskNamePersonalGameConsume": "إنفاق في اللعبة",
+ "taskNamePersonalMicInRoom": "اذهب إلى المايك",
+ "dailyCoinBonanzaRules": "قواعد مهرجان العملات اليومي",
+ "magic": "سحر",
+ "dailyCoinBonanzaRulesDetail": "1. يمكن إكمال المهام الشخصية اليومية ومهام صاحب الغرفة اليومية مرة واحدة لكل مستخدم يوميًا. يتم إعادة تعيين المهام عند الساعة 00:00:00 بتوقيت السعودية.\n2. يمكن إكمال المهام الشخصية اليومية فقط في غرف الآخرين؛ ويمكن إكمال مهام صاحب الغرفة فقط في غرفتك الخاصة.\n3. يتم احتساب مهام تقديم الهدايا فقط على الهدايا المرسلة في الغرف، وليس الهدايا المرسلة في الخلاصات.\n4. إذا تم إنشاء عدة حسابات باستخدام نفس الجهاز أو نفس بطاقة SIM بأي شكل من الأشكال، يمكن المطالبة بالمكافآت لجميع المهام مرة واحدة فقط.",
+ "roomOwnerTasks": "مهام صاحب الغرفة",
+ "personalTasks": "المهام الشخصية",
+ "noPromptsToday": "لا توجد مطالبات اليوم.",
+ "coins4": "عملات",
+ "getPaidToRefer": "احصل على أجر عن الإحالة",
+ "forMoreRewardsPleaseCheckTheTaskCenter": "لمزيد من المكافآت، يرجى التحقق من مركز المهام",
+ "weekStart": "بداية الأسبوع",
+ "kingQuuen": "ملك-ملكة",
+ "ramadan": "رمضان",
+ "like": "مثل",
+ "updateNow": "تحديث الآن",
+ "skip2": "تخطي",
+ "importantReminder": "تذكير مهم",
+ "discard": "تخلص",
+ "deleteCommentTips": "هل أنت متأكد أنك تريد حذف هذا التعليق؟",
+ "deleteSuccessful": "تم الحذف بنجاح!",
+ "itemsLeft": "الأصناف المتبقية",
+ "replySucc": "تم الرد بنجاح",
+ "showLess": "عرض أقل",
+ "showMore": "عرض المزيد",
+ "comment": "تعليق",
+ "more": "أكثر",
+ "swipeLeftOnTheFloatingScreenAreaToQuicklyCloseIt": "*نصيحة: اسحب إلى اليسار على منطقة الشاشة العائمة لإغلاقها بسرعة.",
+ "enterThisVoiceChatRoom": "هل تريد دخول هذه الغرفة الصوتية؟",
+ "roomAnnouncement": "إعلان الغرفة",
+ "saySomething": "قل شيئاً...",
+ "catchFirstComment": "التقط التعليق الأول",
+ "posting": "نشر",
+ "trend": "اتجاه",
+ "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": "مسح الكاش",
+ "multiple": "متعدد",
+ "areYouSureYouWantToClearLocalCache": "هل أنت متأكد أنك تريد مسح الذاكرة المؤقتة المحلية؟",
+ "luckGiftSpecialEffects": "تأثيرات الرسوم المتحركة للهدية السعيدة",
+ "receivedFromALuckyGift": "تم الاستلام من هدية محظوظة/سحرية",
+ "successfullyRemovedFromTheBlacklist": "تمت الإزالة من القائمة السوداء بنجاح!",
+ "successfullyAddedToTheBlacklist": "تمت الإضافة إلى القائمة السوداء بنجاح!",
+ "youAreCurrentlyCPRelationshipPleaseDissolve": "أنت حاليا في علاقة CP. الرجاء حلها أولا.",
+ "areYouSureToCancelBlacklist": "هل أنت متأكد من إلغاء القائمة السوداء؟",
+ "areYouSureYouWantToBlockThisUser": "هل أنت متأكد أنك تريد حظر هذا المستخدم؟",
+ "removeFromBlacklist": "إزالة من القائمة السوداء",
+ "moveToBlacklist": "نقل إلى القائمة السوداء",
+ "userBlacklist": "قائمة الحظر للمستخدمين",
+ "redEnvelopeNotYetClaimed": "المظروف الأحمر لم يُستلم بعد",
+ "redEnvelopeAmount": "مبلغ الظرف الأحمر: {1} عملات",
+ "followed": "تبع",
+ "newMessage": "رسالة جديدة",
+ "keep": "يحفظ",
+ "open": "فتح",
+ "clearCacheSuccessfully": "تم مسح ذاكرة التخزين المؤقت بنجاح",
+ "thisUserHasBeenBlacklisted": "تم إدراج هذا المستخدم في القائمة السوداء.",
+ "thisFeatureIsCurrentlyUnavailable": "هذه الخاصية غير متوفرة حاليا.",
+ "pleaseSelectTheRecipient": "المرجو اختيار المستلم",
+ "searchMemberIdHint": "يرجى إدخال رقم هوية العضو",
+ "unclaimedRedEnvelopes": "الأظرفة الحمراء غير المطالب بها يتم استردادها خلال 24 ساعة.",
+ "sentARedEnvelope": "أرسل ظرف أحمر.",
+ "theRedEnvelopeHasExpired": "الظرف الأحمر منتهي الصلاحية",
+ "acceptedYour": "{1} قبل طلبك",
+ "youAccepted": "لقد قبلت {1} ",
+ "openRedPackDialogTip": "الظرف الأحمر",
+ "wishingYouHappinessEveryDay": "أتمنى لك السعادة كل يوم.",
+ "createRoomSuccsess": "تم إنشاء الغرفة بنجاح!",
+ "contactUs": "اتصل بنا",
+ "specialEffectsManagement": "إدارة المؤثرات الخاصة",
+ "canSendMsgTips": "كلا الطرفين يجب أن يتابع بعضهما البعض قبل أن يتمكنا من إرسال رسائل خاصة.",
+ "systemAnnouncementTips1": "احذر الاحتيال:",
+ "systemAnnouncementTips": "تحقق من المعلومات عن طريق القنوات الرسمية فقط. لا تقم بتنزيل برامج من طرف ثالث، ولا تشارك البيانات الشخصية، ولا تحول المال بناءً على طلبات خارجية. بطاقات هوية الموظفين الرسمية هي فقط 10000 و10003 و10086. في حالة أي شك، توقف وقدم التقرير عبر",
+ "systemAnnouncement": "إعلان النظام",
+ "doNotClickUnfamiliarTips": "ماتضغطش على الروابط الغير معروفة، حيث قد تكشف معلوماتك الشخصية. متشاركش أبدا بطاقة الهوية أو معلومات البطاقة البنكية ديالك مع أي واحد.",
+ "atTag": "@تاغ",
+ "sayHi2": "قل مرحبا",
+ "msgSendRedEnvelopeTips": "سيتم فرض رسوم خدمة بنسبة 10% على المظاريف الحمراء، ولن يحصل المستلمون إلا على 90% من قيمة المظروف. يجب أن يكون مستوى ثروة المرسل أعلى من المستوى 10.",
+ "reapply": "أعد التقديم",
+ "cancelRequest": "إلغاء الطلب",
+ "supporter": "مشجع",
+ "numberOfSign": "عدد العلامة: {1}",
+ "hostWeeklyRank": "تصنيف المضيف الأسبوعي",
+ "supporterWeeklyRank": "ترتيب الأسبوعي للمشجعين",
+ "memberList": "قائمة الأعضاء",
+ "treasureChest": "صندوق الكنز",
+ "applicationRecord": "سجل الطلبات",
+ "pending": "قيد الانتظار",
+ "appUpdateTip": "التطبيق لديه نسخة جديدة ({1})، هل تود الذهاب وتحميلها؟",
+ "reconcile": "يصالح",
+ "separated": "منفصل",
+ "areYouSureYouWantToSpend5": "{1} اعترف بالمشاعر ليك؛ إذا قبلتي، غادي توليو ثنائي.",
+ "areYouSureYouWantToSpend6": "{1} يريد العودة للتقارب معك. إذا قررت المصالحة، سيتم استعادة جميع بياناتك السابقة.",
+ "reconcileInvitationTips": "إذا الطرف الآخر رفض دعوة CP، غتترجع العملات ديالك للمحفظة ديالك.",
+ "reconcileInvitation": "دعوة للمصالحة",
+ "areYouSureYouWantToSpend4": "إرسال دعوة للمصالحة لهدا المستخدم؟",
+ "partWaysTips": "إذا قرر أحد الشريكين في العلاقة الانفصال، سيكون هناك فترة تهدئة لمدة 7 أيام. خلال هذه الفترة، يمكن للطرفين اختيار المصالحة، وسيتم استعادة كل البيانات عند المصالحة. إذا لم يتم اختيار المصالحة بنهاية فترة السبعة أيام، سيتم مسح بيانات الزوجين.",
+ "areYouSureYouWantToPartWaysWithYourCP": "هل أنت متأكد أنك تريد الانفصال عن شريكك؟",
+ "partWays": "افترقوا",
+ "firstDay": "اليوم الأول:{1}",
+ "timeSpentTogether": "الوقت المشترك: {1} أيام",
+ "areYouSureYouWantToSpend3": "إذا الطرف الآخر رفض دعوة CP، غتترجع العملات ديالك للمحفظة ديالك.",
+ "areYouSureYouWantToSpend2": "هل تريد إرسال دعوة CP لهذا المستخدم؟",
+ "areYouSureYouWantToSpend": "هل أنت متأكد أنك تريد أن تنفق",
+ "underReview": "قيد المراجعة",
+ "doYouWantToDeleteIt": "هل تريد حذفه؟",
+ "myPhoto": "صورتي",
+ "balanceNotEnough": "رصيد العملات الذهبية غير كافي. واش بغيت تزود الرصيد؟",
+ "skip": "تخطي {1}",
+ "chooseFromAblum": "اختر من الألبوم",
+ "information": "معلومات",
+ "spaceBackground": "خلفية الفضاء",
+ "editProfile": "تعديل الملف الشخصي",
+ "sendTheCpRequest": "أرسل طلب CP",
+ "addCp": "أضف CP",
+ "numberOfMyCPs": "عدد نقاط السيطرة ديالي:({1}/{2})",
+ "relationShip": "علاقة",
+ "props": "الدعائم",
+ "couple2": "زوج",
+ "dice": "نرد",
+ "operationsAreTooFrequent": "العمليات متكررة بشكل مفرط",
+ "luckNumber": "رقم الحظ",
+ "rps": "حجر ورقة مقص",
+ "couple": "زوج {1}:",
+ "noMatchedCP": "لا يوجد CP مطابق",
+ "adminInviteRechargeAgent": "ندعوك لتصبح وكيلا لإعادة الشحن.",
+ "ownerIncomeCoins": "دخل المالك: {1} عملة",
+ "allGames": "كل الألعاب",
+ "fishClass": "فئة الأسماك",
+ "raceSeries": "سلسلة السباق",
+ "others": "آخرون",
+ "slotsClass": "فئة السلوتس",
+ "greedyClass": "الفئة الجشعة",
+ "hotGames": "الألعاب الرائجة",
+ "sent": "أُرسل",
+ "termsOfServicePrivacyPolicyTips": "بمتابعتك، أنت توافق على شروط الخدمة و سياسة الخصوصية",
+ "and": " اندر ",
+ "chatBox": "صندوق الشات",
+ "confirm": "تأكيد",
+ "cancel": "إلغاء",
+ "join": "انضم",
+ "vistors": "زوار",
+ "fans": "المعجبون",
+ "items": "عناصر",
+ "letGoToWatch": "هيا نذهب للمشاهدة!",
+ "launchedARocket": "أطلق صاروخ",
+ "sendUserId": "أرسل معرف المستخدم:{1}",
+ "giveUpIdentity": "تخلى عن الهوية",
+ "leaveRoomIdentityTips": "هل أنت متأكد من أنك تريد التخلي عن هوية الغرفة؟",
+ "joinMemberTips2": "هل تريد تأكيد انضمامك إلى الغرفة كعضو؟",
+ "sureUnfollowThisRoom": "متأكد بغيتي تحيد المتابعة لهاذ الغرفة؟",
+ "settings": "الإعدادات",
+ "alreadyAnTourist": "أنت بالفعل سائح",
+ "deleteConversationTips": "هل أنت متأكد أنك تريد حذف سجل المحادثة مع هذا المستخدم؟",
+ "account": "أكونتي",
+ "youHaventFollowed": "أنت لم تتابع أي غرفة",
+ "messageHasBeenRecalled": "تم استرجاع هذه الرسالة",
+ "propMessagePrompt": "موجه رسالة دعائية",
+ "deleteFromMyDevice": "احذف من جهازي",
+ "deleteOnAllDevices": "حذف على جميع الأجهزة",
+ "inputUserId": "أدخل معرف المستخدم",
+ "common": "شائع",
+ "useCoupontips": "هل أنت متأكد أنك تريد استخدام القسيمة؟",
+ "searchUserId": "ابحث عن معرف المستخدم",
+ "receiveSucc": "تم المطالبة بنجاح",
+ "reject": "رفض",
+ "sendUser": "إرسال المستخدم",
+ "bio": "معلومات شخصية",
+ "delete": "حذف",
+ "sendCoupontips": "هل أنت متأكد أنك تريد إرسال هذه القسيمة لهذا المستخدم؟",
+ "recallThisMessage": "تذكر هذه الرسالة؟",
+ "copy": "نسخ",
+ "youDontHaveAnyCouponsYet": "ليس لديك أي كوبونات بعد",
+ "hobby": "هواية",
+ "recall": "استدعاء",
+ "accept": "اقبل",
+ "signedin": "تم التوقيع",
+ "following": "التالي",
+ "inviteYouToBecomeBD": "ندعوك لتصبح BD",
+ "confirmAcceptTheInvitation": "هل تريد تأكيد قبول الدعوة؟",
+ "confirmDeclineTheInvitation": "تأكيد رفض الدعوة؟",
+ "friends": "أصدقاء",
+ "language": "اللغة",
+ "feedback": "تعليق",
+ "coupon": "قسيمة",
+ "get": "احصل",
+ "couponRecord": "سجل استخدام القسيمة",
+ "inRoom": "في الغرفة",
+ "inRocket": "في الصاروخ",
+ "roomRocketHelpTips": "1. إرسال الهدايا في الغرفة يزيد من طاقة الصاروخ. *هدية واحدة من العملات الذهبية = نقطة طاقة صاروخية واحدة؛ الهدايا المحظوظة تزيد من طاقة الصاروخ بنسبة 4% من قيمة العملة الذهبية للهدية.\n2. بعد اكتمال شحن الطاقة، يمكنك إطلاق الصاروخ. سيتم توزيع المكافآت تلقائيًا بعد إطلاق الصاروخ.\n3. تقدم فئات الصواريخ المختلفة مكافآت مختلفة.\n4. عند إطلاق الصاروخ، يمكن لجميع المستخدمين في الغرفة المطالبة بمكافأة الصاروخ.\n5. سيتم تحديث طاقة الصاروخ في الساعة 0:00 كل يوم.",
+ "searchCouponHint": "ابحث عن كوبون",
+ "search": "بحث",
+ "checkInSuccessful": "تسجيل الوصول ناجح",
+ "about": "حوالي",
+ "inviteYouToBecomeHost": "ندعوك لتصبح مضيفًا",
+ "receive": "استقبل",
+ "sginTips": "ستحصل على المكافأة في أول مرة تسجل دخولك فيها كل يوم. إذا قمت بقطع تسجيل دخولك، ستُحسب المكافأة من أول يوم تسجل فيه دخولك مرة أخرى.",
+ "aboutUs": "حولنا",
+ "theme": "موضوع",
+ "home": "المنزل",
+ "luck": "حظ",
+ "bDLeaderInviteYouToBecomeBDLeader": "ندعوك لتصبح قائد تطوير الأعمال",
+ "win2": "فوز {1}",
+ "level": "مستوى",
+ "wealthLevel": "مستوى الثروة",
+ "userLevel": "مستوى المستخدم",
+ "themeGoToUploadTips": "1.سيتم مراجعة التحميل خلال 24 ساعة بعد نجاحه. 2.\n سيتم إرجاع جميع العملات إذا فشلت المراجعة.",
+ "goToUpload": "اذهب لتحميل",
+ "rechargeAgency": "وكالة الشحن",
+ "logout": "تسجيل الخروج",
+ "adminCenter": "مركز الإدارة",
+ "explore": "استكشاف",
+ "micManagement": "إدارة الميكروفون",
+ "followList": "قائمة المتابعة",
+ "fansList": "قائمة المعجبين",
+ "pleaseSelectTheTypeContent": "يرجى اختيار نوع المحتوى المخالف",
+ "me": "أنا",
+ "socialPrivilege": "امتياز اجتماعي",
+ "spam": "بريد مزعج",
+ "inappropriateContent": "محتوى غير لائق",
+ "illegalInformation": "معلومات غير قانونية",
+ "personalAttack": "هجوم شخصي",
+ "identity": "الهوية",
+ "adjust": "تعديل",
+ "roomReward": "مكافأة الغرفة",
+ "insufhcientGoldsGoToRecharge": "الذهب غير كافي، عاود الشحن دابا!",
+ "received": "تم الاستلام",
+ "goToRecharge": "اذهب لإعادة الشحن",
+ "warning": "تحذير",
+ "ownerSendTheRedEnvelope": "المالك أرسل عملات المكافأة",
+ "rewardCoins": "عملات المكافأة:{1} عملة",
+ "lastWeekProgress": "تقدم الأسبوع الماضي",
+ "currentProgress": "التقدم الحالي",
+ "coins2": "{1} عملات",
+ "roomReward2": "مكافأة الغرفة:{1}",
+ "currentStage": "المرحلة الحالية:{1}",
+ "fraud": "احتيال",
+ "redEnvelopeTips2": "إذا لم يتم المطالبة بالمظروف الأحمر ضمن الفترة المحددة، ستُعاد العملات المتبقية إلى المستخدم الذي أرسل المظروف الأحمر.",
+ "remainingNumberTips": "العدد المتبقي المتاح: ({1}/{2})",
+ "collectionTimeTips": "وقت الجمع:{1}({2}/{3})",
+ "sendARedEnvelope": "أرسل ظرفاً أحمر",
+ "sendRedPackConfirmTips": "هل أنت متأكد أنك تريد إرسال الحزمة الحمراء؟",
+ "redEnvelopeSendingRecords": "سجلات إرسال الظرف الأحمر:",
+ "countdownMinutes": "دقائق العد التنازلي:",
+ "number2": "رقم:",
+ "redEnvelopeRecTips2": "تم المطالبة بجميع المظاريف الحمراء.",
+ "redEnvelopeRecTips3": "انتهى وقت جمع الظرف الأحمر!",
+ "openTheTreasureChest": "افتح صندوق الكنز",
+ "redEnvelopeRecTips1": "تم إيداع العملات المكتسبة في محفظتك.",
+ "redEnvelope": "ظرف أحمر",
+ "redEnvelopeTips1": "عملات:",
+ "roomTools": "أدوات الغرفة:",
+ "entertainment": "الترفيه:",
+ "reportSucc": "تم الإبلاغ بنجاح",
+ "reportInputTips": "من فضلك وصف المشكل بأكبر قدر ممكن من التفاصيل باش نقدر نفهموه ونحلوه.",
+ "pornography": "الاباحية",
+ "screenshotTips": "لقطة شاشة (حتى 3)",
+ "roomEditing": "تحرير الغرفة",
+ "picture": "صورة",
+ "inputDesHint": "من فضلك وصف المشكلة بأكبر قدر ممكن من التفاصيل باش نقدر نفهموها ونحلها.",
+ "description": "الوصف:",
+ "roomNotice": "إشعار الغرفة",
+ "roomTheme": "موضوع الغرفة",
+ "roomProfilePicture": "صورة الملف الشخصي للغرفة",
+ "userProfilePicture": "صورة ملف المستخدم",
+ "userName": "اسم المستخدم",
+ "pleaseSelectTheTypeToProcess": "يرجى تحديد النوع لمعالجته:",
+ "userEditing": "تعديل المستخدم",
+ "enterTheUserId": "أدخل معرف المستخدم",
+ "enterTheRoomId": "أدخل رقم الغرفة",
+ "theImageSizeCannotExceed": "حجم الصورة لا يمكن أن يتجاوز 4 ميغابايت",
+ "bdLeader": "زعيم بنك التنمية",
+ "kickedOutOfRoom": "تم طرده من الغرفة",
+ "lockTheMic": "اقفل الميكروفون",
+ "openTheMic": "افتح الميكروفون",
+ "finish": "أنهى",
+ "removeTheMic": "أزل الميكروفون",
+ "leavelTheMic": "اترك الميكروفون",
+ "unlockTheMic": "افتح الميكروفون",
+ "muteTheMic": "كتم الميكروفون",
+ "inviteToTheMicrophone": "دعوة للتحدث في الميكروفون",
+ "takeTheMic": "خذ الميكروفون",
+ "openUserProfleCard": "افتح بطاقة ملف المستخدم",
+ "crop": "محصول",
+ "host": "مضيف",
+ "agent": "وكالة",
+ "ra": "را",
+ "bd": "بي دي",
+ "unread": "غير مقروء",
+ "read": "اقرأ",
+ "image": "[صورة]",
+ "video": "[فيديو]",
+ "sound": "[صوت]",
+ "gift2": "[هدية]",
+ "clickHereToStartChatting": "قل شيئًا.....",
+ "receivedAMessage": "[تلقى رسالة]",
+ "giftCounter": "عداد الهدايا",
+ "wins": "يفوز",
+ "deleteAccount": "حذف الحساب",
+ "becomeAgent": "أصبح وكيلا",
+ "male": "ذكر",
+ "setAccount": "تعيين الحساب",
+ "female": "أنثى",
+ "album": "ألبوم",
+ "loadingFailedClickToRetry": "فشل التحميل، انقر لإعادة المحاولة",
+ "releaseToLoadMore": "حرر للتحميل المزيد",
+ "haveMyLimits": "---لدي حدودي.---",
+ "pullToLoadMore": "اسحب للتحميل المزيد",
+ "enterNickname": "أدخل الاسم المستعار",
+ "camera": "كاميرا",
+ "system": "نظام",
+ "selectYourCountry": "اختر دولتك",
+ "inviteCode": "رمز الدعوة",
+ "yesterday": "أمس {1}",
+ "monday": "الاثنين {1}",
+ "tuesday": "الثلاثاء {1}",
+ "wednesday": "الأربعاء {1}",
+ "thursday": "الخميس {1}",
+ "friday": "الجمعة {1}",
+ "saturday": "السبت {1}",
+ "sunday": "الأحد {1}",
+ "notifcation": "إشعار",
+ "inviteYouToBecomeAgent": "ندعوك لتصبح وكالة",
+ "theVideoSizeCannotExceed": "لا يمكن أن يتجاوز حجم الفيديو 50 ميغابايت",
+ "fromLuckyGifts": "من الهدايا المحظوظة",
+ "confirmSwitchMicModelTips": "هل تؤكد تغيير وضعية الجلوس؟",
+ "classicMic": "ميكروفون كلاسيكي {1}",
+ "number": "رقم",
+ "micTheme": "ثيم المايك",
+ "chat": "دردشة",
+ "rejected": "مرفوض",
+ "refuse": "رفض",
+ "boxContributeTips": "لقد تم الاستثمار بالفعل اليوم، رجاءً لا تستثمر مرة أخرى",
+ "help": "مساعدة",
+ "approved": "معتمد",
+ "onlineUsers": "المستخدمون عبر الإنترنت ({1}/{2}):",
+ "applyToJoin": "قدّم للانضمام",
+ "hostList": "قائمة المضيف",
+ "supporterList": "قائمة الداعمين",
+ "upToMembers": "حتى {1} أعضاء",
+ "upToAdmins": "حتى {1} مسؤولين",
+ "levelPrivileges": "امتيازات المستوى",
+ "agree": "موافق",
+ "joinRequest": "طلب الانضمام",
+ "gameRules": "قوانين اللعبة:",
+ "gift": "هدية",
+ "charmGameRulesTips": "قم بتشغيل لوحة التحكم لعرض العملات الهدايا المستلمة لجميع المستخدمين على الميكروفون، 1 عملة = 1 نقطة (هدية محظوظة 1 عملة = 0.04 نقطة).",
+ "charm": "تعويذة هدية",
+ "chats": "الدردشات",
+ "myMusic": "موسيقاي",
+ "membershipFeeTips1": "من فضلك حدد رسوم الانضمام لغرفتك. يمكن للمستخدمين الانضمام إلى غرفتك من خلال دفع الرسوم.",
+ "membershipFeeTips2": "الذهب المطلوب للعضو في الغرفة. صاحب الغرفة سيحصل على 50٪ من الذهب.",
+ "membershipFee": "رسوم العضوية",
+ "touristsSendText": "السائح يرسل نص",
+ "freePrice": "الرسوم: 0-10000",
+ "pleaseChatFfriendly": "رجاءً تحدث بطريقة ودية",
+ "kickPrevention": "الوقاية من الركلات",
+ "daily": "يوميًا",
+ "start": "ابدأ",
+ "win": "فوز",
+ "stop": "توقف",
+ "add": "أضف",
+ "scrollToTheBottom": "قم بالتمرير إلى الأسفل",
+ "apple": "تفاحة",
+ "music": "موسيقى",
+ "free": "مجاناً",
+ "goToUpgrade": "اذهب إلى الترقية",
+ "google": "جوجل",
+ "exclusiveEmojiWillBeReleasedAfterBecoming": "سيتم إصدار الرموز التعبيرية الحصرية بعد أن تصبح",
+ "preventBeingBlocked": "منع الحظر",
+ "enableRankIncognitoMode": "تمكين وضع الترتيب الخفي",
+ "avoidBeingKicked": "تجنب الركل",
+ "privileges": "{1} الامتيازات",
+ "andAboveUsers": "{1} والمستخدمون أعلاه",
+ "everyone": "الجميع",
+ "basicPermissions": "الأذونات الأساسية",
+ "mysteriousInvisibility": "الاختفاء الغامض",
+ "antiBlock": "مضاد للانسداد",
+ "privateChat": "دردشة خاصة",
+ "storeDiscount": "خصم المتجر {1}",
+ "membershipFreeChatSpeak": "دردشة وتحدث بدون عضوية",
+ "priorityRoomSorting": "فرز الغرف حسب الأولوية",
+ "userColoredID": "معرّف المستخدم الملون",
+ "setLoginPassword": "حدد كلمة مرور تسجيل الدخول",
+ "theTwoPasswordsDoNotMatch": "كلمتا المرور لا تتطابقتان.",
+ "resetLoginPasswordtTips2": "كلمة المرور يجب أن تكون بطول 8-16 حرف ويجب أن تكون مزيج من الأحرف الإنجليزية الكبيرة والصغيرة والأرقام (ليس فقط أرقام)",
+ "confirmYourPassword": "أكد كلمة المرور الخاصة بك",
+ "enterYourNewPassword": "أدخل كلمة مرورك الجديدة",
+ "setYourPassword": "عيّن كلمة المرور ديالك",
+ "enterYourOldPassword": "أدخل كلمة السر القديمة الخاصة بك",
+ "inputYourOldPassword": "أدخل كلمة المرور القديمة الخاصة بك",
+ "resetLoginPasswordtTips1": "سجل الدخول باستخدام معرف المستخدم أو معرف النمط. من الآمن أكثر تسجيل الدخول باستخدام حساب لايكي.",
+ "resetLoginPassword": "إعادة تعيين كلمة مرور تسجيل الدخول",
+ "localMusic": "الموسيقى المحلية",
+ "confirmSwitchMicThemeTips": "هل تؤكد تغيير نمط المقعد؟",
+ "follow2": "اتبع:{1}",
+ "fans2": "المعجبون:{1}",
+ "vistors2": "الزوار:{1}",
+ "personal2": "شخصي:",
+ "dailyTaskRewardBonus": "مكافأة مهمة يومية ({1} نقطة خبرة)",
+ "userLevelXPBoost": "زيادة خبرة مستوى المستخدم ({1} XP)",
+ "enterRoomName": "أدخل اسم الغرفة",
+ "theMembershipFee": "رسوم العضوية",
+ "theModificationsMade": "التعديلات التي تمت هذه المرة لن يتم حفظها بعد الخروج.",
+ "touristsTakeToTheMic": "السياح ياخذو الميكروفون.",
+ "weekly": "أسبوعي",
+ "conntinue": "استمر",
+ "logIn": "تسجيل الدخول",
+ "sayHi": "قُل مرحبا..",
+ "password": "كلمة السر",
+ "enterAccount": "دخول الحساب",
+ "enterPassword": "أدخل كلمة المرور",
+ "roomName": "اسم الغرفة",
+ "enterRoomTips": "{1} ادخل الغرفة",
+ "startVoiceParty": "ابدأ حفلة صوتية!",
+ "freeChatSpeak": "دردش بحرية وتحدث",
+ "roomMember": "عضو الغرفة",
+ "popular": "مشهور",
+ "coinsReceived": "العملات المستلمة",
+ "hotRooms": "غرف حارة",
+ "viewMore": "عرض المزيد",
+ "noData": "لا توجد بيانات",
+ "recommend": "يوصي",
+ "follow": "تابع",
+ "monthly": "شهريًا",
+ "message": "رسالة",
+ "bdCenter": "مركز BD",
+ "history": "تاريخ",
+ "users": "المستخدمون",
+ "rooms": "غرف",
+ "days": "أيام",
+ "permanent": "دائم",
+ "unFollow": "إلغاء المتابعة",
+ "searchInputHint": "أدخل رقم الحساب / الغرفة",
+ "kickRoomTips": "لقد تم طردك من الغرفة",
+ "joinRoomTips": "غرفة متضامة!",
+ "roomSetting": "تجهيز الغرفة",
+ "roomDetails": "تفاصيل الغرفة",
+ "systemRoomTips": "كن مهذبا ومحترما. يُمنع منعاً باتاً أي محتوى إباحي أو مبتذل في yumi. بمجرد اكتشافه، سيتم حظر الحساب بشكل دائم. يرجى الالتزام بوعي بلوائح منصة yumi.",
+ "copiedToClipboard": "تم النسخ إلى الحافظة",
+ "recharge": "إعادة الشحن",
+ "agentCenter": "مركز الوكالة",
+ "report": "تقرير",
+ "done": "تمّ",
+ "improvementTasks": "مهام التحسين",
+ "followedYou": "تابعتك",
+ "followSucc": "تمت المتابعة بنجاح",
+ "edit": "تحرير",
+ "task": "مهمة",
+ "save": "احفظ",
+ "go": "اذهب",
+ "deleteAccount2": "حذف الحساب({1}s)",
+ "areYouSureYouWantToDeleteYourAccount": "هل أنت متأكد أنك تريد حذف حسابك؟",
+ "enterRoomConfirmTips": "هل أنت متأكد أنك تريد دخول الغرفة؟",
+ "dailyTasks": "المهام اليومية",
+ "nickName": "لقب",
+ "giftSpecialEffects": "هدية المؤثرات الخاصة",
+ "country": "دولة",
+ "basicFeatures": "الميزات الأساسية",
+ "floatingAnimationInGlobal": "الرسوم المتحركة العائمة في العالم",
+ "joinMemberTips": "إذا كنت زائرًا في الغرفة، لا يمكنك أخذ الميكروفون.",
+ "countryRegion": "البلد والمنطقة",
+ "gender": "جنس",
+ "likedYourComment": "أعجبتني طاقتك.",
+ "deleteAccountTips2": "*إذا غيرت رأيك، يمكنك تسجيل الدخول مرة أخرى إلى حسابك الحالي خلال سبعة أيام، وسنقوم تلقائيًا باستعادة حسابك. إذا لم تتم عملية الاستعادة خلال سبعة أيام، فسيتم حذف الحساب نهائيًا",
+ "deleteAccountTips": "لديك صلاحيات إدارية كاملة على هذا الحساب. إذا كنت تنوي حذف الحساب، يُرجى الانتباه إلى المخاطر التالية المرتبطة بهذه العملية:\n\n1. بمجرد حذف الحساب بنجاح، لن تتمكن من تسجيل الدخول إليه. حذف الحساب إجراء نهائي.\n\n2. بعد حذف الحساب بنجاح، لن تتمكن من استعادة أي بيانات. سيتم حذف جميع المعلومات (بما في ذلك الغرف، والأصدقاء)، والعملة الافتراضية، والهدايا، والعناصر الافتراضية نهائيًا ولن يكون بالإمكان استعادتها.\n\n3. فترة السماح: إذا لم تقم باستعادة الحساب، فلن تتمكن من الوصول إلى صفحة الشراء، أو صفحة السحب، أو أي صفحات أخرى في التطبيق.\n\n4. خلال فترة السماح أو بعد حذف الحساب، ستشير صفحة الملف الشخصي إلى أنه قد تم حذفه. لحماية حسابك من البحث أو الوصول إليه من قِبل الآخرين، سيتم حذف معلوماتك الشخصية من الأنظمة المتعلقة بالوظائف اليومية. عندما يتعلق حذف الحساب بالأمن القومي، أو الإجراءات المدنية أو الجنائية، أو حماية الحقوق والمصالح المشروعة لأطراف ثالثة، يحتفظ المسؤول بحقه في رفض طلب حذف حساب المستخدم.\n\nإذا كنت متأكدًا من رغبتك في حذف جميع بياناتك الشخصية من حسابك الحالي، يُرجى النقر على \"حذف الحساب\".",
+ "accountDeletionNotice": "إشعار حذف الحساب:",
+ "entryVehicleAnimation2": "يمكن للمستخدمين الحاصلين على صلاحيات VlP4 أو أعلى استخدام هذه الوظيفة لتعطيل رسوميات المركبات المتحركة.",
+ "entryVehicleAnimation": "الرسوم المتحركة لدخول السيارة",
+ "man": "رجل",
+ "woman": "امرأة",
+ "all": "الكل",
+ "activity": "نشاط",
+ "knapsack": "حقيبه",
+ "areYouRureRoRecharge": "هل أنت متأكد من شحن ؟",
+ "clearMessage": "مسح رسائل الشاشة",
+ "pleaseSelectaItem": "يرجى اختيار البند",
+ "birthday": "عيد ميلاد",
+ "pleaseEnterNickname": "يرجى إدخال لقب.",
+ "pleaseSelectYourCountry": "يرجى تحديد بلدك.",
+ "pleaseSelectYourGender": "يرجى تحديد جنسك.",
+ "dateOfBirth": "تاريخ الميلاد",
+ "mute": "صامت",
+ "exit": "خروج",
+ "send": "أرسل",
+ "goldList": "القائمة الذهبية",
+ "coins": "النقود المعدنية",
+ "lockTheRoom": "أغلق الغرفة",
+ "giftGivingSuccessful": "إن تقديم الهدايا كان ناجحًا.",
+ "hostCenter": "مركز الاستضافة",
+ "allOnMicrophone": "الجميع على الميكروفون",
+ "usersOnMicrophone": "المستخدمون على الميكروفون",
+ "mInimize": "احتفظ",
+ "shop": "متجر",
+ "expirationTime": "وقت الانتهاء",
+ "roomOwner": "مالك الغرفة",
+ "owner": "مالك",
+ "admin": "المشرف",
+ "member": "عضو",
+ "guest": "ضيف",
+ "submit": "تقديم",
+ "enter": "دخل",
+ "unLockTheRoom": "افتح الغرفة",
+ "setRoomPassword": "تعيين كلمة مرور الغرفة",
+ "inputRoomPassword": "إدخال كلمة مرور الغرفة",
+ "operationSuccessful": "كانت العملية ناجحة.",
+ "adminByHomeowner": "يتم تعيين كمسؤول من قبل مالك المنزل.",
+ "memberByHomeowner": "يتم تعيين كأعضاء من قبل صاحب المنزل.",
+ "touristByHomeowner": "تم تعيين كسائح من قبل صاحب المنزل.",
+ "setUpAnIdentity": "أعد إعداد هوية.",
+ "allInTheRoom": "كل شيء في الغرفة.",
+ "theAccountPasswordCannotBeEmpty": "لا يمكن أن يكون الحساب أو كلمة المرور خالية.",
+ "goldListort": "القائمة الذهبية",
+ "rechargeList": "قائمة إعادة الشحن",
+ "becomeHost": "قدّم لتصبح مضيفًاً",
+ "alreadyAnAdministrator": "مسؤول بالفعل.ً",
+ "alreadyAnMember": "أنت بالفعل عضو.ً",
+ "touristsCannotSendMessages": "لا يستطيع السائحون إرسال الرسائل",
+ "touristsAreNotAllowedToGoOnTheMic": "لا يسمح للسياح بالدخول إلى الميكروفون",
+ "superFans": "المشجعين الخارقين:ً",
+ "special": "خاص",
+ "custom": "مخصص",
+ "store": "دكان",
+ "viewFrame": "عرض الإطار",
+ "headdress": "إطارات",
+ "mountains": "مركبات",
+ "buy": "ابتاع",
+ "visitorList": "قائمة الزوار",
+ "spendCoinsToGainExperiencePoints": "اصرف العملات لكسب نقاط الخبرة",
+ "howToUpgrade": "كيف يمكن الترقية؟",
+ "higherLevelFancierAvatarFrame": "مستوى أعلى، شارات/إطار صور أفخم.",
+ "use": "استخدم",
+ "expired": "منتهي",
+ "day": "يوم",
+ "obtain": "الحصول على",
+ "backTheRoom": "الغرفة الخلفية",
+ "toConsume": "الاستهلاك",
+ "profile": "بروفايل",
+ "wallet": "محفظة",
+ "giftwall": "جيفت وول",
+ "announcement": "إعلان",
+ "blockedList": "قائمة محظورة",
+ "renewal": "تجديد",
+ "country2": "بلد:",
+ "sendTo": "أرسل إلى",
+ "credits": "الاعتمادات: {1}",
+ "successfullyUnloaded": "تم تفريغها بنجاح",
+ "unUse": "استخدام واحد",
+ "successfulWear": "ملابس ناجحة",
+ "confirmUnUseTips": "هل تؤكد على إزالته؟",
+ "inUse": "قيد الاستخدام",
+ "confirmUseTips": "هل تريد التأكيد على استخدامه؟",
+ "pleaseUploadUserAvatar": "يرجى رفع صورة شخصية.",
+ "myItems": "أشيائي",
+ "confirmBuyTips": "هل أنت متأكد من أنك تريد الشراء؟",
+ "purchaseIsSuccessful": "الشراء ناجح",
+ "purchase": "ابتاع",
+ "invitesYouToTheMicrophone": "{1} يدعوك إلى الميكروفون",
+ "english": "الإنجليزية",
+ "chinese": "الصينية",
+ "arabic": "العربية",
+ "darkMode": "الوضع الداكن",
+ "lightMode": "الوضع الفاتح",
+ "systemDefault": "النظام الافتراضي",
+ "pleaseGetOnTheMicFirst": "من فضلك استخدم الميكروفون أولاً.",
+ "duration2": "المدة:{1}"
+}
diff --git a/assets/l10n/intl_bn.json b/assets/l10n/intl_bn.json
new file mode 100644
index 0000000..e2790f3
--- /dev/null
+++ b/assets/l10n/intl_bn.json
@@ -0,0 +1,643 @@
+{
+ "signInWithGoogle": "Google দিয়ে লগইন করুন",
+ "or": "অথবা",
+ "signInWithYourAccount": "আপনার অ্যাকাউন্ট দিয়ে লগইন করুন",
+ "signInWithApple": "Apple দিয়ে লগইন করুন",
+ "loginRepresentsAgreementTo": "লগইন করলে আপনি নিম্নলিখিতগুলি স্বীকার করছেন:",
+ "termsofService": "সেবা শর্তাবলী",
+ "privaceyPolicy": "গোপনীয়তা নীতি",
+ "tips": "টিপস",
+ "mine": "আমার",
+ "games": "খেলাধুলা",
+ "party": "পার্টি",
+ "yes": "হ্যাঁ",
+ "bag": "ব্যাগ",
+ "sound2": "শব্দ",
+ "startYourBrandNewJourney": "আপনার সম্পূর্ণ নতুন যাত্রা শুরু করুন",
+ "searchNoDataTips": "আপনি যে রুম বা ব্যবহারকারীর আইডি অনুসন্ধান করতে চান তা লিখুন।",
+ "event": "ইভেন্ট",
+ "other": "অন্য",
+ "maliciousHarassment": "দূরাচার হয়রানি",
+ "roomEdit": "রুম এডিট",
+ "cancelRoomPassword": "আপনি কি নিশ্চিত যে আপনি রুমের পাসওয়ার্ডটি মুছে ফেলতে চান?",
+ "roomMemberFee": "রুম সদস্য ফি",
+ "blockedList2": "ব্লক করা তালিকা",
+ "roomTheme2": "রুম থিম",
+ "roomPassword": "রুম পাসওয়ার্ড",
+ "numberOfMic": "মাইকের সংখ্যা",
+ "pleaseEnterContent": "অনুগ্রহ করে বিষয়বস্তু লিখুন",
+ "profilePhoto": "প্রোফাইল ছবি",
+ "aboutMe": "আমার সম্পর্কে",
+ "noHistoricalRecordsAvailable": "কোনও ঐতিহাসিক রেকর্ড পাওয়া যায়নি।",
+ "inviteNewUsersToEarnCoins": "নতুন ব্যবহারকারীকে আমন্ত্রণ করুন কয়েন উপার্জনের জন্য",
+ "crateMyRoom": "নিজের রুম তৈরি করুন।",
+ "myRoom": "আমার ঘর",
+ "recent": "সাম্প্রতিক",
+ "popularEvents": "জনপ্রিয় ইভেন্ট",
+ "casualInteraction": "সাধারণ আলোচনাচিত্র",
+ "haveGamePlayingTips": "আপনার গেমটি চলমান আছে, দয়া করে প্রথমে বর্তমান গেমটি ছাড়ুন, আপনি কি নিশ্চিতভাবে বের হতে চান?",
+ "historicalTour": "ঐতিহাসিক ভ্রমণ",
+ "gameCenter": "গেম সেন্টার",
+ "returnToVoiceChat": "ভয়েস চ্যাটে ফিরে যেতে চাই?",
+ "exitGameMode": "গেম মোড থেকে বের হন",
+ "enterTheRoom": "ঘরে প্রবেশ করো",
+ "inviteGoRoomTips": "সব সময় তোমার জন্য এখানে আছি, বৃষ্টি হোক বা রোদ। এসে সালাম জানাও!",
+ "invite": "আমন্ত্রণ করা",
+ "confirmInviteThisUserToTheRoom": "এই ব্যবহারকারী (ID:{1}) কে রুমে নিমন্ত্রণ নিশ্চিত করবেন?",
+ "clearCacheSuccessfully": "ক্যাশ সফলভাবে মুছে ফেলা হয়েছে",
+ "sent": "পাঠানো হয়েছে",
+ "keep": "রাখুন",
+ "open": "খুলুন",
+ "deleteAccountTips2": "*আপনি যদি মন পরিবর্তন করেন, তবে সাত দিনের মধ্যে আপনার বর্তমান অ্যাকাউন্টে আবার লগইন করতে পারবেন এবং আপনার অ্যাকাউন্ট স্বয়ংক্রিয়ভাবে পুনরুদ্ধার করা হবে। সাত দিনের মধ্যে পুনরুদ্ধার না করলে, অ্যাকাউন্ট স্থায়ীভাবে মুছে ফেলা হবে",
+ "deleteAccountTips": "আপনার এই অ্যাকাউন্টে সম্পূর্ণ প্রশাসনিক অধিকার রয়েছে। আপনি যদি অ্যাকাউন্ট মুছে ফেলতে চান, তবে এই ক্রিয়াটির সাথে সম্পর্কিত নিম্নলিখিত ঝুঁকিগুলি কृপয়া ভুলবেন না:\n1.অ্যাকাউন্ট সফলভাবে মুছে ফেলা হলে, আপনি আর আপনার বর্তমান অ্যাকাউন্টে লগইন করতে পারবেন না। অ্যাকাউন্ট মুছে ফেলা একটি স্থায়ী ক্রিয়া।\n2. অ্যাকাউন্ট সফলভাবে মুছে ফেলা হলে, আপনি অ্যাকাউন্টের কোনো ডেটা পুনরুদ্ধার করতে পারবেন না। সমস্ত তথ্য (রুম, বন্ধু সহ), ভার্চুয়াল মুদ্রা, উপহার এবং ভার্চুয়াল আইটেম স্থায়ীভাবে মুছে ফেলা হবে এবং পুনরুদ্ধার করা যাবে না।\n3. কুলডাউন সময়: আপনি যদি অ্যাকাউন্ট পুনরুদ্ধার না করেন, তবে আপনি অ্যাপের ক্রয় পৃষ্ঠা, পেমেন্ট উত্তোলন পৃষ্ঠা বা অন্য কোনো পৃষ্ঠায় অ্যাক্সেস করতে পারবেন না।\n4.কুলডাউন সময়কালীন বা অ্যাকাউন্ট মুছে ফেলার পর, প্রোফাইল পৃষ্ঠা এটি মুছে ফেলা হয়েছে বলে দেখাবে। আপনার অ্যাকাউন্ট অন্যদের দ্বারা সনাক্ত বা অ্যাক্সেস করা থেকে বাধা দেওয়ার জন্য, আপনার ব্যক্তিগত তথ্য দৈনন্দিন ফাংশন সম্পর্কিত সিস্টেম থেকে মুছে ফেলা হবে। অ্যাকাউন্ট মুছে ফেলা জাতীয় নিরাপত্তা, নাগরিক বা দণ্ডী মামলা বা তৃতীয় পক্ষের বৈধ অধিকার ও সুবিধার রক্ষণসংস্কারকে অন্তর্ভুক্ত করলে, সরকারি প্রশাসন ব্যবহারকারীর অ্যাকাউন্ট মুছে ফেলার অনুরোধ প্রত্যাখ্যান করার অধিকার সংরক্ষণ করে।\nআপনি যদি আপনার বর্তমান অ্যাকাউন্টের সমস্ত ব্যক্তিগত ডেটা মুছে ফেলতে নিশ্চিত হন, তবে কृপয়া \"অ্যাকাউন্ট মুছে ফেলুন\" বোতামে ক্লিক করুন।",
+ "accountDeletionNotice": "অ্যাকাউন্ট মুছে ফেলার নোটিশ:",
+ "thisUserHasBeenBlacklisted": "এই ব্যবহারকারী ব্ল্যাকলিস্টে যুক্ত করা হয়েছে।",
+ "trend": "ট্রেন্ড",
+ "like": "পছন্দ করুন",
+ "more": "আরও",
+ "discard": "বাতিল করুন",
+ "catchFirstComment": "প্রথম মন্তব্য ক্যাচ করুন",
+ "reply": "উত্তর দিন",
+ "posting": "পোস্ট করা হচ্ছে",
+ "multiple": "একাধিক",
+ "successfullyRemovedFromTheBlacklist": "ব্ল্যাকলিস্ট থেকে সফলভাবে সরানো হয়েছে!",
+ "successfullyAddedToTheBlacklist": "ব্ল্যাকলিস্টে সফলভাবে যুক্ত করা হয়েছে!",
+ "youAreCurrentlyCPRelationshipPleaseDissolve": "আপনি বর্তমানে একটি CP সম্পর্কে আছেন।\nকृপয়া প্রথমে সম্পর্কটি সমাধান করুন।",
+ "areYouSureToCancelBlacklist": "আপনি কি ব্ল্যাকলিস্ট বাতিল করতে চান?",
+ "areYouSureYouWantToBlockThisUser": "আপনি কি এই ব্যবহারকারীকে ব্লক করতে চান?",
+ "removeFromBlacklist": "ব্ল্যাকলিস্ট থেকে সরান",
+ "moveToBlacklist": "ব্ল্যাকলিস্টে যুক্ত করুন",
+ "userBlacklist": "ব্যবহারকারী ব্ল্যাকলিস্ট",
+ "specialEffectsManagement": "বিশেষ প্রভাব ব্যবস্থাপনা",
+ "wishingYouHappinessEveryDay": "আপনাকে প্রতিদিন সুখের কামনা করছি।",
+ "newMessage": "নতুন বার্তা",
+ "createRoomSuccsess": "রুম সফলভাবে তৈরি হয়েছে!",
+ "contactUs": "আমাদের সাথে যোগাযোগ করুন",
+ "systemAnnouncementTips1": "ধোঁকাধন্ডা থেকে সতর্ক:",
+ "systemAnnouncementTips": "শুধুমাত্র অফিসিয়াল চ্যানেলের মাধ্যমে তথ্য যাচাই করুন। কখনওই তৃতীয় পক্ষের সফটওয়্যার ডাউনলোড করবেন না, ব্যক্তিগত তথ্য শেয়ার করবেন না বা বাহ্যিক অনুরোধের উপর অর্থ ট্রান্সফার করবেন না। অফিসিয়াল কর্মী আইডি শুধুমাত্র 10000, 10003 এবং 10086। আপনার কোনো সন্দেহ থাকলে, ক্রিয়াটি বন্ধ করুন এবং এর মাধ্যমে রিপোর্ট করুন",
+ "systemAnnouncement": "সিস্টেম ঘোষণা",
+ "doNotClickUnfamiliarTips": "অপরিচিত লিঙ্কে ক্লিক করবেন না, কারণ এগুলি আপনার ব্যক্তিগত তথ্য প্রকাশ করতে পারে। আপনার আইডি নম্বর বা ব্যাংক কার্ডের বিবরণ কখনওই কারো সাথে শেয়ার করবেন না।",
+ "atTag": "@ট্যাগ",
+ "sayHi2": "হাই",
+ "canSendMsgTips": "ব্যক্তিগত বার্তা পাঠানোর জন্য উভয় পক্ষকে একে অপরকে ফলো করতে হবে।",
+ "msgSendRedEnvelopeTips": "*লাল খাম之上 10% সেবা ফি কেটে নেওয়া হবে এবং প্রাপক শুধুমাত্র লাল খামের মানের 90% পাবেন। প্রেরকের সম্পদ স্তর 10 তম স্তরের থেকে বেশি হতে হবে।",
+ "reapply": "আবার আবেদন করুন",
+ "cancelRequest": "অনুরোধ বাতিল করুন",
+ "pending": "পেন্ডিং",
+ "supporter": "সমর্থক",
+ "coinsReceived": "কয়েন প্রাপ্ত হয়েছে",
+ "numberOfSign": "সাইন ইন সংখ্যা: {1}",
+ "hostWeeklyRank": "হোস্ট সাপ্তাহিক র্যাঙ্ক",
+ "supporterWeeklyRank": "সমর্থক সাপ্তাহিক র্যাঙ্ক",
+ "memberList": "সদস্য তালিকা",
+ "treasureChest": "সম্পদ বাক্স",
+ "applicationRecord": "আবেদন রেকর্ড",
+ "appUpdateTip": "অ্যাপের একটি নতুন সংস্করণ আছে ({1}), কি ডাউনলোড করবেন?",
+ "ownerIncomeCoins": "মালিকের আয়:{1} কয়েন",
+ "game": "গেম",
+ "skip2": "স্কিপ করুন",
+ "coins4": "কয়েন",
+ "claim": "দাবি",
+ "complete": "সম্পূর্ণ",
+ "shareTo": "শেয়ার করুন",
+ "copyLink": "লিঙ্ক কপি করুন",
+ "weekStart": "সপ্তাহের শুরু",
+ "faceBook": "ফেসবুক",
+ "whatsApp": "হোয়াটসঅ্যাপ",
+ "snapChat": "স্ন্যাপচ্যাট",
+ "taskNameRoomNewMember": "রুমে নতুন সদস্যের সংখ্যা",
+ "taskNameRoomOwnerSendRedPacket": "রুম মালিক একটি লাল লিফলেট পাঠান",
+ "taskNameRoomOwnerSendGiftUser": "রুম মালিক উপহার পাঠান",
+ "taskNameRoomMicUser120Min": "১২০+ মিনিট মাইকে কাটানো সদস্য",
+ "taskNameRoomMicUser60Min": "৬০+ মিনিট মাইকে কাটানো সদস্য",
+ "taskNameRoomMicUser30Min": "৩০+ মিনিট মাইকে কাটানো সদস্য",
+ "taskNamePersonalSendGift": "অন্যের রুমে মাইক্রোফোনে আসুন",
+ "taskNameRoomOnlineUserCount": "রুমের অনলাইন সদস্যরা",
+ "taskNameRoomOwnerInviteMic": "সদস্যকে মাইকে আমন্ত্রণ করুন",
+ "taskNameRoomUserSendGiftGold": "সদস্যদের দেওয়া উপহার কয়েন",
+ "taskNameRoomOwnerSendGiftGold": "রুম মালিকের দেওয়া উপহার কয়েন",
+ "taskNamePersonalMagicGiftGold": "যাদুকরী উপহার পাঠিয়ে জয় করা কয়েন",
+ "taskNamePersonalLuckyGiftGold": "ভাগ্যবান উপহার পাঠিয়ে জয় করা কয়েন",
+ "taskNameRoomOwnerMicTime": "রুমের মালিক রুমে মাইকে কথা বলেন",
+ "taskNamePersonalActiveInRoom": "অন্যের রুমে সক্রিয় হোন",
+ "taskNamePersonalGameConsume": "গেম ব্যয়",
+ "taskNamePersonalMicInRoom": "মাইকে যান",
+ "forMoreRewardsPleaseCheckTheTaskCenter": "আরও পুরস্কারের জন্য কृপয়া টাস্ক সেন্টার চেক করুন",
+ "kingQuuen": "রাজা-রানী",
+ "dailyCoinBonanzaRulesDetail": "১. দৈনিক ব্যক্তিগত কাজ এবং দৈনিক রুম মালিকের কাজ প্রতিটি ব্যবহারকারীর জন্য দিনে একবার সম্পন্ন করা যেতে পারে। কাজগুলি সৌদি সময় ০০:০০:০০ এ রিসেট হয়।\n২. দৈনিক ব্যক্তিগত কাজ কেবল অন্যের রুমে সম্পন্ন করা যায়; রুম মালিকের কাজ কেবল আপনার নিজের রুমে সম্পন্ন করা যায়।\n৩. উপহার দেওয়ার কাজগুলিতে কেবল রুমে পাঠানো উপহারগুলি গণ্য হবে, ফিডে পাঠানো উপহার নয়।\n৪. যদি একই ডিভাইস বা একই সিম কার্ড ব্যবহার করে একাধিক অ্যাকাউন্ট তৈরি করা হয়, সমস্ত কাজের পুরস্কার কেবল একবারই দাবি করা যেতে পারে।",
+ "dailyCoinBonanzaRules": "দৈনিক কয়েন বোনাঞ্জার নিয়ম",
+ "roomOwnerTasks": "রুম মালিকের কাজ",
+ "personalTasks": "ব্যক্তিগত কাজ",
+ "getPaidToRefer": "প্রস্তাব দেওয়ার জন্য অর্থ উপার্জন করুন",
+ "ramadan": "রমজান",
+ "noPromptsToday": "আজ কোনো প্রম্পট নেই।",
+ "updateNow": "এখন update করুন",
+ "allGames": "সমস্ত গেম",
+ "fishClass": "মাছ শ্রেণী",
+ "greedyClass": "লোভী শ্রেণী",
+ "raceSeries": "রেস সিরিজ",
+ "slotsClass": "স্লট শ্রেণী",
+ "others": "অন্যান্য",
+ "hotGames": "হট গেমস",
+ "chatBox": "চ্যাট বক্স",
+ "termsOfServicePrivacyPolicyTips": "এগিয়ে যাওয়ার মাধ্যমে আপনি সেবা শর্তাবলী এবং গোপনীয়তা নীতি স্বীকার করছেন",
+ "and": " এবং ",
+ "pleaseSelectTheTypeContent": "কृপয়া লঙ্ঘনকারী কন্টেন্টের টাইপ নির্বাচন করুন।",
+ "illegalInformation": "বেআইনি তথ্য",
+ "inappropriateContent": "অনুপযুক্ত কন্টেন্ট",
+ "personalAttack": "ব্যক্তিগত আক্রমণ",
+ "confirm": "নিশ্চিত করুন",
+ "spam": "স্প্যাম",
+ "countdownMinutes": "কাউন্টডাউন মিনিট :",
+ "number2": "নম্বর:",
+ "fraud": "ধোঁকাধন্ডা",
+ "received": "প্রাপ্ত হয়েছে",
+ "currentProgress": "বর্তমান অগ্রগতি",
+ "currentStage": "বর্তমান স্টেজ:{1}",
+ "roomReward2": "রুম পুরস্কার:{1}",
+ "roomReward": "রুম পুরস্কার",
+ "ownerSendTheRedEnvelope": "মালিক পুরস্কার কয়েন পাঠিয়েছেন।",
+ "rewardCoins": "পুরস্কার কয়েন:{1} কয়েন",
+ "lastWeekProgress": "গত সপ্তাহের অগ্রগতি",
+ "redEnvelopeTips2": "*লাল খাম সময়সীমার মধ্যে দাবি না করলে, বাকি কয়েন প্রেরক ব্যবহারকারীকে ফেরত দেওয়া হবে।",
+ "goToRecharge": "রিচার্জ করতে যান",
+ "deleteAccount2": " অ্যাকাউন্ট মুছে ফেলুন({1}সেকেন্ড)",
+ "areYouSureYouWantToDeleteYourAccount": " আপনি কি আপনার অ্যাকাউন্ট মুছে ফেলতে চান?",
+ "insufhcientGoldsGoToRecharge": "সোনা অপর্যাপ্ত, দ্রুত রিচার্জ করুন!",
+ "coins2": "{1}কয়েন",
+ "remainingNumberTips": "বাকি ব্যবহারযোগ্য সংখ্যা:({1}/{2})",
+ "collectionTimeTips": "সংগ্রহের সময়:{1}({2}/{3})",
+ "sendARedEnvelope": "লাল খাম পাঠান",
+ "sendRedPackConfirmTips": "আপনি কি লাল প্যাক পাঠাতে চান?",
+ "redEnvelopeSendingRecords": "লাল খাম প্রেরণ রেকর্ড:",
+ "redEnvelope": "লাল খাম",
+ "redEnvelopeRecTips2": "সব লাল খাম দাবি করা হয়েছে।",
+ "redEnvelopeRecTips3": "লাল খাম সংগ্রহের সময় শেষ হয়ে গেছে!",
+ "openTheTreasureChest": "সম্পদ বাক্স খুলুন",
+ "redEnvelopeRecTips1": "বিজয়ী কয়েন আপনার ওয়ালেটে জমা হয়েছে।",
+ "redEnvelopeTips1": "কয়েন:",
+ "roomTools": "রুম টুলস:",
+ "entertainment": "বিনোদন:",
+ "reportSucc": "রিপোর্ট সফল",
+ "pornography": "পর্নোগ্রাফি",
+ "reportInputTips": "সমস্যাটি বুঝতে এবং সমাধান করতে আমাদের সাহায্য করার জন্য কृপয়া সমস্যাটি যতটা সম্ভব বিস্তারিতভাবে বর্ণনা করুন।",
+ "cancel": "বাতিল করুন",
+ "join": "যোগদান করুন",
+ "items": "আইটেম",
+ "vistors": "ভিজিটর",
+ "fans": "ফ্যান",
+ "balanceNotEnough": "সোনা কয়েন ব্যালেন্স অপর্যাপ্ত। আপনি কি রিচার্জ করতে চান?",
+ "skip": "{1} স্কিপ করুন",
+ "letGoToWatch": "চলুন দেখতে যাই!",
+ "launchedARocket": "রকেট চালু করেছে",
+ "sendUserId": "ব্যবহারকারী ID পাঠান:{1}",
+ "giveUpIdentity": "আইডেন্টিটি ছেড়ে দিন",
+ "leaveRoomIdentityTips": "আপনি কি রুম আইডেন্টিটি ছেড়ে দিতে চান?",
+ "joinMemberTips2": "আপনি কি সদস্য হিসেবে রুমে যোগদান করতে নিশ্চিত করছেন?",
+ "sureUnfollowThisRoom": "আপনি কি এই রুমকে আনফলো করতে চান?",
+ "welcomeMessage": "আমাদের অ্যাপে স্বাগতম, {name}!",
+ "settings": "সেটিংস",
+ "account": "অ্যাকাউন্ট",
+ "common": "সাধারণ",
+ "delete": "মুছে ফেলুন",
+ "copy": "কপি করুন",
+ "bio": "জীবনী",
+ "useCoupontips": "আপনি কি কুপন ব্যবহার করতে চান?",
+ "searchUserId": "ব্যবহারকারী ID সার্চ করুন",
+ "sendUser": "ব্যবহারকারীকে পাঠান",
+ "hobby": "শখ",
+ "sendCoupontips": "আপনি কি এই কুপনটি এই ব্যবহারকারীকে পাঠাতে চান?",
+ "youDontHaveAnyCouponsYet": "আপনার এখনও কোনো কুপন নেই।",
+ "recall": "ফিরে ডাকুন",
+ "youHaventFollowed": "আপনি কোনো রুম ফলো করেন না",
+ "deleteFromMyDevice": "আমার ডিভাইস থেকে মুছে ফেলুন",
+ "deleteOnAllDevices": "সমস্ত ডিভাইসে মুছে ফেলুন",
+ "messageHasBeenRecalled": "এই বার্তা ফিরে ডাকা হয়েছে",
+ "recallThisMessage": "আপনি কি এই বার্তা ফিরে ডাকতে চান?",
+ "language": "ভাষা",
+ "feedback": "ফিডব্যাক",
+ "signedin": "সাইন ইন করা হয়েছে",
+ "receiveSucc": "সফলভাবে দাবি করা হয়েছে",
+ "about": "সম্পর্কে",
+ "aboutUs": "আমাদের সম্পর্কে",
+ "theme": "থিম",
+ "wealthLevel": "সম্পদ স্তর",
+ "userLevel": "ব্যবহারকারী স্তর",
+ "goToUpload": "আপলোড করতে যান",
+ "logout": "লগআউট",
+ "luck": "ভাগ্য",
+ "level": "স্তর",
+ "themeGoToUploadTips": "1.আপলোড সফল হলে 24 ঘন্টার মধ্যে রিভিউ করা হবে।\n2.রিভিউ ব্যর্থ হলে সমস্ত কয়েন ফেরত দেওয়া হবে।",
+ "home": "হোম",
+ "explore": "অন্বেষণ",
+ "me": "আমি",
+ "socialPrivilege": "সামাজিক সুবিধা",
+ "information": "তথ্য",
+ "myPhoto": "আমার ফটো",
+ "areYouSureYouWantToSpend3": "*অন্য পক্ষ CP আমন্ত্রণ প্রত্যাখ্যান করলে, আপনার কয়েন আপনার ওয়ালেটে ফেরত দেওয়া হবে।",
+ "areYouSureYouWantToSpend": "আপনি কি খরচ করতে চান",
+ "areYouSureYouWantToSpend2": "এই ব্যবহারকারীকে CP আমন্ত্রণ পাঠাতে?",
+ "underReview": "রিভিউ চলছে",
+ "doYouWantToDeleteIt": "আপনি কি এটি মুছে ফেলতে চান?",
+ "chooseFromAblum": "অ্যালবাম থেকে নির্বাচন করুন",
+ "spaceBackground": "স্পেস ব্যাকগ্রাউন্ড",
+ "editProfile": "প্রোফাইল সম্পাদনা করুন",
+ "sendTheCpRequest": "CP অনুরোধ পাঠান",
+ "addCp": "CP যোগ করুন",
+ "partWays": "পথ ভেদ করুন",
+ "reconcile": "মিলন করুন",
+ "separated": "বিচ্ছিন্ন",
+ "areYouSureYouWantToSpend5": "{1} আপনাকে তার অনুভূতি প্রকাশ করেছে; আপনি যদি গ্রহণ করেন তবে আপনি জোড়া হবেন।",
+ "areYouSureYouWantToSpend6": "{1} আপনার সাথে আবার মিলিত হতে চান। আপনি যদি মিলনের সিদ্ধান্ত নেন, তবে আপনার সমস্ত পূর্বের ডেটা পুনরুদ্ধার করা হবে।",
+ "reconcileInvitationTips": "*অন্য পক্ষ CP আমন্ত্রণ প্রত্যাখ্যান করলে, আপনার কয়েন আপনার ওয়ালেটে ফেরত দেওয়া হবে।",
+ "reconcileInvitation": "মিলন আমন্ত্রণ",
+ "areYouSureYouWantToSpend4": "এই ব্যবহারকারীকে মিলন আমন্ত্রণ পাঠাতে?",
+ "partWaysTips": "*জোড়ার একজন পার্টনার পথ ভেদ করার সিদ্ধান্ত নিলে, 7 দিনের কুলডাউন সময় থাকবে। এই সময়কালীন উভয় পক্ষই মিলনের সিদ্ধান্ত নিতে পারে এবং মিলনের ক্ষেত্রে সমস্ত ডেটা পুনরুদ্ধার করা হবে। 7 দিনের সময় শেষ হলে মিলন না করলে, জোড়া ডেটা মুছে ফেলা হবে।",
+ "areYouSureYouWantToPartWaysWithYourCP": "আপনি কি আপনার CP와 পথ ভেদ করতে চান?",
+ "timeSpentTogether": "একসাথে কাটানো সময়: {1} দিন",
+ "firstDay": "প্রথম দিন:{1}",
+ "numberOfMyCPs": "আমার CP সংখ্যা:({1}/{2})",
+ "props": "প্রপস",
+ "win": "বিজয়ী",
+ "dice": "ডাইস",
+ "rps": "কাগজ-কাঁচা-কামড়া",
+ "operationFail": "অপারেশন ব্যর্থ হয়েছে।",
+ "likedYourComment": "আপনার মন্তব্য পছন্দ করেছেন।",
+ "doYouWantToKeepTheDraft": "আপনি কি ড্রাফট রাখতে চান?",
+ "operationsAreTooFrequent": "অপারেশন খুব ঘন ঘন",
+ "luckNumber": "ভাগ্য নম্বর",
+ "relationShip": "সম্পর্ক",
+ "couple": "জোড়া {1}:",
+ "couple2": "জোড়া",
+ "reject": "প্রত্যাখ্যান করুন",
+ "accept": "গ্রহণ করুন",
+ "noMatchedCP": "মিলে যাওয়া CP নেই",
+ "inviteYouToBecomeBD": "আপনাকে BD बनতে আমন্ত্রণ জানাচ্ছি।",
+ "adminInviteRechargeAgent": "আপনাকে রিচার্জ এজেন্ট बनতে আমন্ত্রণ জানাচ্ছি।",
+ "confirmAcceptTheInvitation": "আপনি কি আমন্ত্রণ গ্রহণ করতে নিশ্চিত করছেন?",
+ "confirmDeclineTheInvitation": "আপনি কি আমন্ত্রণ প্রত্যাখ্যান করতে নিশ্চিত করছেন?",
+ "host": "হোস্ট",
+ "following": "ফলো করা হচ্ছে",
+ "agent": "এজেন্ট",
+ "approved": "অনুমোদিত",
+ "onlineUsers": "অনলাইন ব্যবহারকারী({1}/{2}):",
+ "applyToJoin": "যোগদানের জন্য আবেদন করুন",
+ "supporterList": "সমর্থক তালিকা",
+ "hostList": "হোস্ট তালিকা",
+ "upToAdmins": "সর্বাধিক {1} অ্যাডমিন",
+ "upToMembers": "সর্বাধিক {1} সদস্য",
+ "levelPrivileges": "স্তরের অধিকার",
+ "ra": "RA",
+ "roomAnnouncement": "রুম ঘোষণা",
+ "help": "সহায়তা",
+ "rejected": "প্রত্যাখ্যান করা হয়েছে",
+ "boxContributeTips": "আজ ইতিমধ্যে অবদান রাখা হয়েছে, কृপয়া আবার অবদান না রাখুন",
+ "bd": "BD",
+ "coupon": "কুপন",
+ "search": "সার্চ",
+ "get": "পান করুন",
+ "inRocket": "রকেটে",
+ "roomRocketHelpTips": "1. রুমে উপহার পাঠান রকেট শক্তি বাড়ায়। *1 সোনা কয়েন উপহার = 1 রকেট শক্তি পয়েন্ট; ভাগ্যশালী উপহার রকেট শক্তি উপহারের সোনা কয়েন মানের 4% পরিমাণে বাড়ায়।\n2. রকেট শক্তি সম্পূর্ণভাবে পূর্ণ হলে, রুম রকেট চালু করতে পারে। চালু করার পর পুরস্কার স্বয়ংক্রিয়ভাবে বিতরণ করা হবে।\n3. বিভিন্ন রকেট স্তর বিভিন্ন পুরস্কার প্রদান করে।\n4. রকেট চালু হলে, রুমের সমস্ত ব্যবহারকারী রকেট পুরস্কার দাবি করতে পারে।5. রকেট শক্তি প্রতিদিন 00:00 এ শূন্য হয়ে যায়।",
+ "couponRecord": "কুপন ব্যবহার রেকর্ড",
+ "inRoom": "রুমে",
+ "searchCouponHint": "কুপন সার্চ করুন",
+ "giftCounter": "উপহার কাউন্টার",
+ "bDLeaderInviteYouToBecomeBDLeader": "আপনাকে BD লিডার बनতে আমন্ত্রণ জানাচ্ছি",
+ "wins": "বিজয়",
+ "inviteYouToBecomeHost": "আপনাকে হোস্ট बनতে আমন্ত্রণ জানাচ্ছি।",
+ "friends": "বন্ধু",
+ "deleteConversationTips": "আপনি কি এই ব্যবহারকারীর সাথে চ্যাট ইতিহাস মুছে ফেলতে চান?",
+ "propMessagePrompt": "প্রপ মেসেজ টিপস",
+ "inputUserId": "ব্যবহারকারী ID লিখুন",
+ "fromLuckyGifts": "ভাগ্যশালী/জাদुई উপহার থেকে",
+ "receive": "প্রাপ্ত করুন",
+ "checkInSuccessful": "সাইন ইন সফল",
+ "sginTips": "আপনি প্রতিদিন প্রথমবার সাইন ইন করলে পুরস্কার পাবেন। আপনি যদি সাইন ইন বন্ধ করেন, তবে আবার সাইন ইন করলে পুরস্কার প্রথম দিন থেকে গণনা করা হবে।",
+ "popular": "জনপ্রিয়",
+ "recommend": "সুপারিশ",
+ "follow": "ফলো করুন",
+ "history": "ইতিহাস",
+ "hotRooms": "হট রুম",
+ "viewMore": "আরও দেখুন",
+ "noData": "ডেটা নেই",
+ "users": "ব্যবহারকারী",
+ "rooms": "রুম",
+ "coins": "কয়েন",
+ "unread": "অপঠিত",
+ "read": "পঠিত",
+ "image": "[ছবি]",
+ "video": "[ভিডিও]",
+ "sound": "[সাউন্ড]",
+ "gift2": "[উপহার]",
+ "clickHereToStartChatting": "কিছু বলুন.....",
+ "receivedAMessage": "[মেসেজ প্রাপ্ত]",
+ "confirmSwitchMicModelTips": "আপনি কি চেয়ার মোড পরিবর্তন করতে নিশ্চিত করছেন?",
+ "number": "নম্বর",
+ "album": "অ্যালবাম",
+ "camera": "ক্যামেরা",
+ "system": "সিস্টেম",
+ "notifcation": "নোটিফিকেশন",
+ "inviteYouToBecomeAgent": "আপনাকে এজেন্ট बनতে আমন্ত্রণ জানাচ্ছি।",
+ "myMusic": "আমার মিউজিক",
+ "add": "যোগ করুন",
+ "pullToLoadMore": "লোড করার জন্য টানুন",
+ "loadingFailedClickToRetry": "লোড ব্যর্থ, পুনরায় চেষ্টা করার জন্য ক্লিক করুন",
+ "releaseToLoadMore": "লোড করার জন্য ছেড়ে দিন",
+ "haveMyLimits": "---আমার নিজস্ব সীমা আছে।---",
+ "music": "মিউজিক",
+ "free": "বিনামূল্যে",
+ "charm": "আকর্ষণ",
+ "start": "শুরু করুন",
+ "stop": "বন্ধ করুন",
+ "chats": "চ্যাট",
+ "refuse": "প্রত্যাখ্যান করুন",
+ "agree": "সম্মত হন",
+ "thisFeatureIsCurrentlyUnavailable": "এই ফিচারটি বর্তমানে অনুপলব্ধ।",
+ "pleaseSelectTheRecipient": "কृপয়া প্রাপক নির্বাচন করুন।",
+ "searchMemberIdHint": "কৃপয়া সদস্যের আইডি নম্বর লিখুন",
+ "unclaimedRedEnvelopes": "দাবি না করা লাল খাম 24 ঘন্টার মধ্যে ফেরত দেওয়া হবে।",
+ "redEnvelopeNotYetClaimed": "লাল খাম এখনও দাবি করা হয়নি।",
+ "redEnvelopeAmount": "লাল খামের পরিমাণ: {1} কয়েন",
+ "sentARedEnvelope": "লাল খাম পাঠিয়েছে।",
+ "theRedEnvelopeHasExpired": "লাল খামের মেয়াদ শেষ হয়ে গেছে।",
+ "joinRequest": "যোগদানের অনুরোধ",
+ "scrollToTheBottom": "নিচে স্ক্রোল করুন",
+ "gameRules": "গেম নিয়ম:",
+ "charmGameRulesTips": "মিটার প্যানেল খুলুন, মাইক্রোফোনে সমস্ত ব্যবহারকারী প্রাপ্ত উপহার কয়েন দেখান,1 কয়েন উপহার = 1 পয়েন্ট (ভাগ্যশালী উপহার 0.04 পয়েন্ট)।",
+ "inputYourOldPassword": "আপনার পুরানো পাসওয়ার্ড লিখুন",
+ "enterYourOldPassword": "আপনার পুরানো পাসওয়ার্ড লিখুন",
+ "setYourPassword": "আপনার পাসওয়ার্ড সেট করুন",
+ "enterYourNewPassword": "আপনার নতুন পাসওয়ার্ড লিখুন",
+ "confirmYourPassword": "আপনার পাসওয়ার্ড নিশ্চিত করুন",
+ "theTwoPasswordsDoNotMatch": "দুটি পাসওয়ার্ড মিলছে না।",
+ "resetLoginPasswordtTips2": "পাসওয়ার্ড 8-16 অক্ষরের দৈর্ঘ্যের হতে হবে এবং বড়/ছোট ইংরেজি অক্ষর এবং সংখ্যার সমন্বয়ে গঠিত হতে হবে (শুধুমাত্র সংখ্যা নয়)",
+ "resetLoginPassword": "লগইন পাসওয়ার্ড রিসেট করুন",
+ "resetLoginPasswordtTips1": "আপনার ব্যবহারকারী ID বা কাস্টম ID দিয়ে লগইন করুন। আজী অ্যাকাউন্ট দিয়ে লগইন করা আরও নিরাপদ।",
+ "localMusic": "লোকাল মিউজিক",
+ "setLoginPassword": "লগইন পাসওয়ার্ড সেট করুন",
+ "confirmSwitchMicThemeTips": "আপনি কি চেয়ার স্টাইল পরিবর্তন করতে নিশ্চিত করছেন?",
+ "micTheme": "মাইক্রো থিম",
+ "classicMic": "ক্লাসিক {1} মাইক্রো",
+ "yesterday": "গতকাল {1}",
+ "monday": "সোমবার {1}",
+ "tuesday": "মঙ্গলবার {1}",
+ "wednesday": "বুধবার {1}",
+ "thursday": "বৃহস্পতিবার {1}",
+ "friday": "শুক্রবার {1}",
+ "saturday": "শনিবার {1}",
+ "sunday": "রবিবার {1}",
+ "acceptedYour": "{1} আপনার আমন্ত্রণ গ্রহণ করেছে",
+ "youAccepted": "আপনি {1} এর আমন্ত্রণ গ্রহণ করেছেন",
+ "openRedPackDialogTip": "লাল খাম",
+ "micManagement": "মাইক্রো ম্যানেজমেন্ট",
+ "bdCenter": "BD সেন্টার",
+ "rechargeAgency": "রিচার্জ এজেন্সি",
+ "adminCenter": "অ্যাডমিন সেন্টার",
+ "goldList": "সোনা তালিকা",
+ "followList": "ফলো তালিকা",
+ "fansList": "ফ্যান তালিকা",
+ "daily": "দৈনন্দিন",
+ "female": "মহিলা",
+ "male": "পুরুষ",
+ "identity": "আইডেন্টিটি",
+ "adjust": "সামঞ্জস্য করুন",
+ "warning": "সতর্কতা",
+ "screenshotTips": "স্ক্রিনশট (সর্বাধিক 3)",
+ "roomNotice": "রুম নোটিশ",
+ "roomTheme": "রুম থিম",
+ "description": "বর্ণনা:",
+ "inputDesHint": "সমস্যাটি বুঝতে এবং সমাধান করতে আমাদের সাহায্য করার জন্য কृপয়া সমস্যাটি যতটা সম্ভব বিস্তারিতভাবে বর্ণনা করুন।",
+ "roomProfilePicture": "রুম প্রোফাইল ছবি",
+ "userProfilePicture": "ব্যবহারকারী প্রোফাইল ছবি",
+ "userName": "ব্যবহারকারী নাম",
+ "pleaseSelectTheTypeToProcess": "কৃপয়া প্রক্রিয়াকরণের টাইপ নির্বাচন করুন:",
+ "roomEditing": "রুম সম্পাদনা",
+ "setAccount": "অ্যাকাউন্ট সেট করুন",
+ "userEditing": "ব্যবহারকারী সম্পাদনা",
+ "enterTheUserId": "ব্যবহারকারী ID লিখুন",
+ "enterTheRoomId": "রুম ID লিখুন",
+ "deleteAccount": "অ্যাকাউন্ট মুছে ফেলুন",
+ "becomeAgent": "এজেন্ট बनুন",
+ "enterNickname": "উপনাম লিখুন",
+ "selectYourCountry": "আপনার দেশ নির্বাচন করুন",
+ "inviteCode": "আমন্ত্রণ কোড",
+ "magic": "জাদু",
+ "luckGiftSpecialEffects": "ভাগ্যশালী উপহার অ্যানিমেশন প্রভাব",
+ "theVideoSizeCannotExceed": "ভিডিও আকার 50M অতিক্রম করতে পারবেন না",
+ "weekly": "সাপ্তাহিক",
+ "customizedGiftRulesContent": "আমি কীভাবে কাস্টমাইজড গিফট পেতে পারি:\n1.বর্তমান সম্পদ স্তর অনুসারে ব্যবহারকারীর কাস্টমাইজড গিফট পাওয়ার যোগ্যতা নির্ধারণ করুন.\n(1) ব্যবহারকারীর সম্পদ স্তর ≥35 হলে: \nব্যবহারকারী কাস্টমাইজড গিফটের জন্য একবার ভিডিও আপলোড করতে পারেন। আমরা ব্যবহারকারীর বর্তমান প্রোফাইল ছবিকে গিফট ইমেজ হিসেবে এবং প্রদত্ত ভিডিওকে \"কাস্টম\" এর উপর গিফট প্রভাব হিসেবে ব্যবহার করব। প্রDUCTION কিছুটা সময় নেবে এবং স্টোরে উপলব্ধ হওয়ার সাথে সাথে আপনাকে অবহিত করব।\n(2) ব্যবহারকারীর সম্পদ স্তর ≥45 হলে: \nব্যবহারকারী কাস্টমাইজড গিফটের জন্য একবার ভিডিও আপলোড করতে পারেন। আমরা ব্যবহারকারীর বর্তমান প্রোফাইল ছবিকে গিফট ইমেজ হিসেবে এবং প্রদত্ত ভিডিওকে \"কাস্টম\" এর উপর গিফট প্রভাব হিসেবে ব্যবহার করব। প্রDUCTION কিছুটা সময় নেবে এবং স্টোরে উপলব্ধ হওয়ার সাথে সাথে আপনাকে অবহিত করব।\n2.অ্যাপের নির্দিষ্ট কার্যকলাপে অংশ নিতে পারেন এবং মানদণ্ড পূরণ করার পর \"মেসেজ\" → \"আমাদের সাথে যোগাযোগ করুন\" বিভাগ থেকে আমাদের সাথে যোগাযোগ করতে পারেন। কার্যকলাপের স্ক্রিনশট এবং কাস্টমাইজড গিফটের জন্য ব্যবহার করতে চান এমন ভিডিও প্রদান করুন। আমরা আপনার বর্তমান প্রোফাইল ছবিকে গিফট ইমেজ হিসেবে এবং প্রদত্ত ভিডিওকে গিফট প্রভাব হিসেবে ব্যবহার করব, তারপর \"কাস্টম\" এর অধীনে তালিকাভুক্ত করা হবে। প্রDUCTION কিছুটা সময় নেবে এবং স্টোরে উপলব্ধ হওয়ার সাথে সাথে আপনাকে অবহিত করব।\nকাস্টমাইজড গিফটের মেয়াদী সময় & কীভাবে সম্প্রসারিত করব:\nকাস্টমাইজড কাস্টম গিফটগুলি র্যাকে 30 দিনের মেয়াদী সময়সহ থাকবে। কার্যকর এবং অনুপ্রেরণামূলক ব্যবহারকারীদের এই নতুন অভিজ্ঞতা চালিয়ে যেতে এবং তাদের ব্যক্তিগত স্টাইল প্রদর্শন করতে সাহায্য করার জন্য, কাস্টমাইজড গিফট ধারণকারী ব্যবহারকারীরা যেকোনো মাসে 500 মার্কিন ডলার রিচার্জ করে তাদের সমস্ত কাস্টমাইজড গিফটের র্যাক সময় 30 দিন বাড়াতে পারেন।",
+ "customizedGiftRules": "কাস্টমাইজড গিফট নিয়ম",
+ "rulesUpload": "নিয়ম&আপলোড",
+ "monthly": "মাসিক",
+ "message": "মেসেজ",
+ "clearCache": "ক্যাশ মুছে ফেলুন",
+ "customized": "কাস্টমাইজড",
+ "searchInputHint": "অ্যাকাউন্ট/রুম নম্বর লিখুন",
+ "kickRoomTips": "আপনাকে রুম থেকে বের করা হয়েছে।",
+ "joinRoomTips": "রুমে যোগদান করেছেন !",
+ "roomSetting": "রুম সেটিংস",
+ "roomDetails": "রুম বিবরণ",
+ "systemRoomTips": "শিষ্টাচার এবং সম্মানজনক হোন। আজীতে কোনো পর্নোগ্রাফিক বা অনুপযুক্ত কন্টেন্ট একেবারে নিষিদ্ধ। সনাক্ত হলে, অ্যাকাউন্ট স্থায়ীভাবে ব্লক করা হবে। কृপয়া আজী প্ল্যাটফর্মের নিয়মাবলী সচেতনভাবে অনুসরণ করুন।",
+ "copiedToClipboard": "ক্লিপবোর্ডে কপি করা হয়েছে",
+ "recharge": "রিচার্জ করুন",
+ "receivedFromALuckyGift": "ভাগ্যশালী/জাদुई গিফট থেকে প্রাপ্ত হয়েছে।",
+ "followedYou": "আপনাকে ফলো করেছেন",
+ "agentCenter": "এজেন্ট সেন্টার",
+ "areYouSureYouWantToClearLocalCache": "আপনি কি লোকাল ক্যাশ মুছে ফেলতে চান?",
+ "clearMessage": "স্ক্রিন মেসেজ মুছে ফেলুন",
+ "report": "রিপোর্ট করুন",
+ "coins3": "কয়েন",
+ "giftSpecialEffects": "গিফট বিশেষ প্রভাব",
+ "basicFeatures": "মৌলিক বৈশিষ্ট্য",
+ "task": "টাস্ক",
+ "importantReminder": "গুরুত্বপূর্ণ স্মারক",
+ "entryVehicleAnimation": "প্রবেশ যান অ্যানিমেশন",
+ "floatingAnimationInGlobal": "গ্লোবালে ভাসমান অ্যানিমেশন",
+ "entryVehicleAnimation2": "VIP4 বা তার বেশি অধিকার ધারণকারী ব্যবহারকারীরা ফাংশন ব্যবহার করে গাড়ির অ্যানিমেশন বন্ধ করতে পারেন।",
+ "dailyTasks": "দৈনন্দিন টাস্ক",
+ "enterRoomConfirmTips": "আপনি কি রুমে যেতে চান?",
+ "followSucc": "সফলভাবে ফলো করা হয়েছে",
+ "goldListort": "সোনা তালিকা",
+ "rechargeList": "রিচার্জ তালিকা",
+ "edit": "সম্পাদনা করুন",
+ "swipeLeftOnTheFloatingScreenAreaToQuicklyCloseIt": "*টিপস: ভাসমান স্ক্রিন এলাকায় বামে সвайপ করে দ্রুত বন্ধ করুন।",
+ "enterThisVoiceChatRoom": "আপনি কি এই ভয়েস চ্যাট রুমে যেতে চান?",
+ "go": "যান",
+ "done": "সম্পন্ন",
+ "improvementTasks": "সুশোধন টাস্ক",
+ "save": "সংরক্ষণ করুন",
+ "kickPrevention": "কিক প্রতিরোধ",
+ "freeChatSpeak": "বিনামূল্যে চ্যাট & কথা বলুন",
+ "nickName": "উপনাম",
+ "gender": "লিঙ্গ",
+ "unFollow": "আনফলো করুন",
+ "days": "দিন",
+ "permanent": "স্থায়ী",
+ "country": "দেশ",
+ "birthday": "জন্মদিন",
+ "man": "পুরুষ",
+ "woman": "মহিলা",
+ "apple": "Apple",
+ "google": "Google",
+ "everyone": "সবার",
+ "dailyTaskRewardBonus": "দৈনন্দিন কাজের পুরস্কার বোনাস({1} XP)",
+ "userLevelXPBoost": "ব্যবহারকারীর স্তরের এক্সপি বৃদ্ধি({1} এক্সপি)",
+ "goToUpgrade": "আপগ্রেড করতে যান",
+ "exclusiveEmojiWillBeReleasedAfterBecoming": "এক্সক্লুসিভ ইমোজি হওয়ার পরে মুক্তি পাবে",
+ "preventBeingBlocked": "ব্লক হওয়া প্রতিরোধ করুন",
+ "enableRankIncognitoMode": "র্যাঙ্ক ইনকগনিটো মোড সক্ষম করুন",
+ "avoidBeingKicked": "পেটানো থেকে বিরত থাকুন",
+ "privileges": "{1} সুবিধাসমূহ",
+ "andAboveUsers": "{1} এবং উপরের ব্যবহারকারীরা",
+ "basicPermissions": "মূল অনুমতিসমূহ",
+ "mysteriousInvisibility": "রহস্যময় অদৃশ্যতা",
+ "antiBlock": "ব্লক-বিরোধী",
+ "shop": "দোকান",
+ "expirationTime": "মেয়াদ শেষ হওয়ার সময়",
+ "privateChat": "ব্যক্তিগত চ্যাট",
+ "storeDiscount": "স্টোর ডিসকাউন্ট {1} ছাড়",
+ "membershipFreeChatSpeak": "সদস্যতা ছাড়াই চ্যাট ও কথা বলা",
+ "startVoiceParty": "ভয়েস পার্টি শুরু করুন!",
+ "enterRoomTips": "{1} রুমে প্রবেশ করেছেন",
+ "roomName": "রুম নাম",
+ "roomMember": "রুম সদস্য",
+ "priorityRoomSorting": "প্রাথমিক কক্ষ শ্রেণীবিন্যাস",
+ "userColoredID": "ব্যবহারকারী রঙিন পরিচয়পত্র",
+ "pleaseSelectYourCountry": "কৃপয়া আপনার দেশ নির্বাচন করুন।",
+ "pleaseSelectYourGender": "কৃপয়া আপনার লিঙ্গ নির্বাচন করুন।",
+ "pleaseEnterNickname": "কৃপয়া একটি উপনাম লিখুন।",
+ "countryRegion": "দেশ&অঞ্চল",
+ "dateOfBirth": "জন্ম তারিখ",
+ "mute": "মিউট করুন",
+ "exit": "প্রস্থান",
+ "pleaseSelectaItem": "কৃপয়া একটি আইটেম নির্বাচন করুন",
+ "areYouRureRoRecharge": "আপনি কি রিচার্জ করতে চান?",
+ "mInimize": "রাখো",
+ "roomOwner": "রুমের মালিক",
+ "hostCenter": "হোস্ট সেন্টার",
+ "allOnMicrophone": "সবাই মাইক্রোফোনে",
+ "usersOnMicrophone": "মাইক্রোফোনে ব্যবহারকারী",
+ "allInTheRoom": "সবাই রুমে",
+ "send": "পাঠান",
+ "crop": "ক্রপ করুন",
+ "finish": "শেষ করুন",
+ "takeTheMic": "মাইক্রো নিন",
+ "openTheMic": "মাইক্রো খুলুন",
+ "muteTheMic": "মাইক্রো মিউট করুন",
+ "unlockTheMic": "মাইক্রো আনলক করুন",
+ "leavelTheMic": "মাইক্রো ছেড়ে দিন",
+ "lockTheMic": "মাইক্রো লক করুন",
+ "removeTheMic": "মাইক্রো সরান",
+ "inviteToTheMicrophone": "মাইক্রোফোনে আমন্ত্রণ দিন",
+ "openUserProfleCard": "ব্যবহারকারী প্রোফাইল কার্ড খুলুন",
+ "obtain": "প্রাপ্ত করুন",
+ "win2": "{1} বিজয়",
+ "backTheRoom": "রুমে ফিরে যান",
+ "toConsume": "খরচ করার জন্য",
+ "howToUpgrade": "কীভাবে উন্নত করব?",
+ "spendCoinsToGainExperiencePoints": "অভিজ্ঞতা পয়েন্ট পাওয়ার জন্য কয়েন খরচ করুন",
+ "higherLevelFancierAvatarFrame": "উচ্চতর স্তর, আরও সুন্দর ব্যাজ/প্রোফাইল ফ্রেম",
+ "all": "সব",
+ "gift": "গিফট",
+ "chat": "চ্যাট",
+ "owner": "মালিক",
+ "store": "স্টোর",
+ "admin": "অ্যাডমিন",
+ "member": "সদস্য",
+ "guest": "অতিথি",
+ "submit": "জমা দিন",
+ "membershipFee": "সদস্যপদ ফি",
+ "membershipFeeTips1": "কৃপয়া আপনার রুমের জন্য সদস্যপদ ফি সেট করুন। ব্যবহারকারীরা ফি পরিশোধ করে আপনার রুমে যোগদান করতে পারেন।",
+ "membershipFeeTips2": "রুম সদস্য হওয়ার জন্য ব্যবহারকারীর প্রয়োজনীয় সোনা।রুম মালিক সোনার 50% পাবেন।",
+ "freePrice": "ফি:0-10000",
+ "touristsSendText": "পর্যটক টেক্সট পাঠায়",
+ "touristsTakeToTheMic": "পর্যটক মাইক্রো নেয়",
+ "theMembershipFee": "সদস্যপদ ফি",
+ "theModificationsMade": "এবার করা পরিবর্তনগুলি প্রস্থানের পর সংরক্ষণ করা হবে না",
+ "viewFrame": "ফ্রেম দেখুন",
+ "enterRoomName": "রুম নাম লিখুন",
+ "headdress": "হেডড্রেস",
+ "mountains": "গাড়ি",
+ "purchaseIsSuccessful": "ক্রয় সফল",
+ "buy": "কিনুন",
+ "followed": "ফলো করা হয়েছে",
+ "follow2": "ফলো:{1}",
+ "fans2": "ফ্যান:{1}",
+ "vistors2": "ভিজিটর:{1}",
+ "personal2": "ব্যক্তিগত:",
+ "conntinue": "চালিয়ে যান",
+ "confirmBuyTips": "আপনি কি কিনতে চান?",
+ "purchase": "ক্রয়",
+ "setRoomPassword": "রুম পাসওয়ার্ড সেট করুন",
+ "inputRoomPassword": "রুম পাসওয়ার্ড লিখুন",
+ "enter": "প্রবেশ করুন",
+ "deleteCommentTips": "আপনি কি এই মন্তব্য মুছে ফেলতে চান?",
+ "deleteSuccessful": "মুছে ফেলা সফল!",
+ "itemsLeft": "বাকি আইটেম",
+ "password": "পাসওয়ার্ড",
+ "replySucc": "উত্তর সফল",
+ "comment": "মন্তব্য",
+ "showMore": "আরও দেখুন",
+ "showLess": "কম দেখুন",
+ "enterPassword": "পাসওয়ার্ড লিখুন",
+ "enterAccount": "অ্যাকাউন্ট লিখুন",
+ "logIn": "লগইন করুন",
+ "saySomething": "কিছু বলুন...",
+ "sayHi": "হাই..",
+ "pleaseChatFfriendly": "কৃপয়া বন্ধুত্বপূর্ণভাবে চ্যাট করুন",
+ "unLockTheRoom": "রুম আনলক করুন",
+ "operationSuccessful": "অপারেশন সফল হয়েছে।",
+ "adminByHomeowner": "হোম ওনার দ্বারা অ্যাডমিন হিসেবে নিযুক্ত করা হয়েছে।",
+ "memberByHomeowner": "হোম ওনার দ্বারা সদস্য হিসেবে নিযুক্ত করা হয়েছে।",
+ "touristByHomeowner": "হোম ওনার দ্বারা পর্যটক হিসেবে নিযুক্ত করা হয়েছে।",
+ "becomeHost": "হোস্ট হতে আবেদন করুন",
+ "superFans": " সুপার ফ্যান:",
+ "setUpAnIdentity": "আইডেন্টিটি সেট আপ করুন",
+ "kickedOutOfRoom": "রুম থেকে বের করা হয়েছে",
+ "knapsack": "ব্যাকপ্যাক",
+ "bdLeader": "BD লিডার",
+ "picture": "ছবি",
+ "theImageSizeCannotExceed": "ছবির আকার 4M অতিক্রম করতে পারবেন না",
+ "activity": "কার্যকলাপ",
+ "alreadyAnAdministrator": "ইতিমধ্যে অ্যাডমিন",
+ "alreadyAnMember": "ইতিমধ্যে সদস্য",
+ "alreadyAnTourist": "ইতিমধ্যে পর্যটক",
+ "touristsCannotSendMessages": "পর্যটক মেসেজ পাঠাতে পারেন না",
+ "touristsAreNotAllowedToGoOnTheMic": "পর্যটকদের মাইক্রোফোনে যাওয়ার অনুমতি নেই",
+ "lockTheRoom": "রুম লক করুন",
+ "special": "বিশেষ",
+ "visitorList": "ভিজিটর তালিকা",
+ "successfulWear": "সফলভাবে পরা হয়েছে",
+ "confirmUnUseTips": "আপনি কি অপসারণ করতে নিশ্চিত করছেন?",
+ "custom": "কাস্টম",
+ "myItems": "আমার আইটেম",
+ "use": "ব্যবহার করুন",
+ "unUse": "ব্যবহার না করুন",
+ "renewal": "পুনর্নবীকরণ",
+ "wallet": "ওয়ালেট",
+ "profile": "প্রোফাইল",
+ "giftwall": "গিফট ওয়াল",
+ "announcement": "ঘোষণা",
+ "blockedList": "ব্লক করা তালিকা",
+ "country2": "দেশ:",
+ "sendTo": "পাঠানো হবে",
+ "credits": "ক্রেডিট: {1}",
+ "successfullyUnloaded": "সফলভাবে আনলোড করা হয়েছে",
+ "expired": "মেয়াদ শেষ",
+ "day": "দিন",
+ "inUse": "ব্যবহারে",
+ "confirmUseTips": "আপনি কি ব্যবহার করতে নিশ্চিত করছেন?",
+ "pleaseUploadUserAvatar": "কৃপয়া একটি প্রোফাইল ছবি আপলোড করুন।",
+ "joinMemberTips": "আপনি যদি রুমে পর্যটক হন, তবে আপনি মাইক্রোফোন নিতে পারবেন না।",
+ "giftGivingSuccessful": "গিফট দেওয়া সফল।",
+ "theAccountPasswordCannotBeEmpty": "অ্যাকাউন্ট বা পাসওয়ার্ড খালি হতে পারে না।",
+ "invitesYouToTheMicrophone": "{1} আপনাকে মাইক্রোফোনে আমন্ত্রণ জানাচ্ছে",
+ "english": "ইংরেজি",
+ "chinese": "চীনা",
+ "arabic": "আরবি",
+ "darkMode": "ডার্ক মোড",
+ "lightMode": "লাইট মোড",
+ "systemDefault": "সিস্টেম ডিফল্ট",
+ "pleaseGetOnTheMicFirst": "কৃপয়া প্রথমে মাইক্রোফোনে যান।",
+ "duration2": "সময়:{1}"
+}
diff --git a/assets/l10n/intl_en.json b/assets/l10n/intl_en.json
new file mode 100644
index 0000000..c624327
--- /dev/null
+++ b/assets/l10n/intl_en.json
@@ -0,0 +1,643 @@
+{
+ "signInWithGoogle": "Sign in with Google",
+ "or": "Or",
+ "signInWithYourAccount": "Sign in with your account",
+ "signInWithApple": "Sign in with Apple",
+ "loginRepresentsAgreementTo": "Login represents agreement to",
+ "termsofService": "Terms of service",
+ "privaceyPolicy": "Privacey Policy",
+ "tips": "Tips",
+ "searchNoDataTips": "Enter the room or user lD you want to search.",
+ "games": "Games",
+ "mine": "Mine",
+ "party": "Party",
+ "other": "Other",
+ "yes": "Yes",
+ "bag": "Bag",
+ "sound2": "Sound",
+ "startYourBrandNewJourney": "Start Your Brand New Journey",
+ "maliciousHarassment": "Malicious harassment",
+ "event": "Event",
+ "roomEdit": "Room Edit",
+ "cancelRoomPassword": "Are you sure you want to delete the room password?",
+ "roomMemberFee": "Room Member Fee",
+ "roomTheme2": "Room Theme",
+ "blockedList2": "Blocked List",
+ "roomPassword": "Room Password",
+ "numberOfMic": "Number of Mic",
+ "pleaseEnterContent": "Please enter content",
+ "profilePhoto": "Profile Photo",
+ "aboutMe": "About me",
+ "myRoom": "My room",
+ "noHistoricalRecordsAvailable": "No historical records available.",
+ "inviteNewUsersToEarnCoins": "Invite new users to earn coins",
+ "crateMyRoom": "CREATE YOUR OWN ROOM.",
+ "casualInteraction": "Casual Interaction",
+ "haveGamePlayingTips": "You have a game in progress. Please exit the current game. Are you sure you want to exit?",
+ "historicalTour": "Historical Tour",
+ "gameCenter": "Game Center",
+ "returnToVoiceChat": "Return to voice chat?",
+ "exitGameMode": "Exit Game Mode",
+ "enterTheRoom": "Enter the room",
+ "invite": "Invite",
+ "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?",
+ "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.\"",
+ "accountDeletionNotice": "Account Deletion Notice:",
+ "thisUserHasBeenBlacklisted": "This user has been blacklisted.",
+ "trend": "Trend",
+ "like": "Like",
+ "more": "More",
+ "discard": "Discard",
+ "catchFirstComment": "Catch first comment",
+ "reply": "Reply",
+ "posting": "Posting",
+ "multiple": "Multiple",
+ "successfullyRemovedFromTheBlacklist": "Successfully removed from the blacklist!",
+ "successfullyAddedToTheBlacklist": "Successfully added to the blacklist!",
+ "youAreCurrentlyCPRelationshipPleaseDissolve": "You are currently in a CP relationship.\nPlease dissolve it first.",
+ "areYouSureToCancelBlacklist": "Are you sure to cancel blacklist?",
+ "areYouSureYouWantToBlockThisUser": "Are you sure you want to block this user?",
+ "removeFromBlacklist": "Remove from blacklist",
+ "moveToBlacklist": "Move to blacklist",
+ "userBlacklist": "User blacklist",
+ "specialEffectsManagement": "Special effects management",
+ "wishingYouHappinessEveryDay": "Wishing you happiness every day.",
+ "newMessage": "New message",
+ "createRoomSuccsess": "Create room succsess!",
+ "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",
+ "systemAnnouncement": "System Announcement",
+ "doNotClickUnfamiliarTips": "Do not click unfamiliar links, as they can expose your personal information. Never share your ID or bank card details with anyone.",
+ "atTag": "@Tag",
+ "sayHi2": "Say Hi",
+ "canSendMsgTips": "Both parties need to follow each other before they can send private messages.",
+ "msgSendRedEnvelopeTips": "*A 10% service fee will be charged on red envelopes, and recipients will only receive 90% of the red envelope's value. The sender's wealth level must be higher than Level 10.",
+ "reapply": "Reapply",
+ "cancelRequest": "Cancel Request",
+ "pending": "Pending",
+ "supporter": "Supporter",
+ "coinsReceived": "Coins Received",
+ "numberOfSign": "Number of sign: {1}",
+ "hostWeeklyRank": "Host Weekly Rank",
+ "supporterWeeklyRank": "Supporter Weekly Rank",
+ "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",
+ "game": "Game",
+ "skip2": "Skip",
+ "coins4": "Coins",
+ "weekStart": "Week-Start",
+ "forMoreRewardsPleaseCheckTheTaskCenter": "For more rewards,please check the task center",
+ "kingQuuen": "King-Quuen",
+ "ramadan": "Ramadan",
+ "updateNow": "Update Now",
+ "allGames": "All Games",
+ "fishClass": "Fish Class",
+ "greedyClass": "Greedy Class",
+ "raceSeries": "Race Series",
+ "slotsClass": "Slots Class",
+ "others": "Others",
+ "hotGames": "Hot Games",
+ "chatBox": "Chat box",
+ "termsOfServicePrivacyPolicyTips": "By continuing you agree to the Terms of Service& Privacy Policy",
+ "and": " and ",
+ "pleaseSelectTheTypeContent": "Please select the type of offending content.",
+ "illegalInformation": "Illegal information",
+ "inappropriateContent": "Inappropriate content",
+ "personalAttack": "Personal attack",
+ "confirm": "Confirm",
+ "spam": "Spam",
+ "countdownMinutes": "Countdown Minutes :",
+ "number2": "Number:",
+ "fraud": "Fraud",
+ "received": "Received",
+ "currentProgress": "Current progress",
+ "currentStage": "Current stage:{1}",
+ "roomReward2": "Room Reward:{1}",
+ "roomReward": "Room Reward",
+ "expirationTime": "Expiration time",
+ "ownerSendTheRedEnvelope": "Owner send the 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)",
+ "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})",
+ "collectionTimeTips": "Collection time:{1}({2}/{3})",
+ "sendARedEnvelope": "Send a red envelope",
+ "sendRedPackConfirmTips": "Are you sure you want to send the red packet?",
+ "redEnvelopeSendingRecords": "Red envelope sending records:",
+ "redEnvelope": "Red Envelope",
+ "redEnvelopeRecTips2": "The red envelopes have all been claimed.",
+ "redEnvelopeRecTips3": "The red envelope collection time has expired!",
+ "openTheTreasureChest": "Open the treasure chest",
+ "redEnvelopeRecTips1": "The earned coins have been deposited into your wallet.",
+ "redEnvelopeTips1": "Coins:",
+ "roomTools": "Room Tools:",
+ "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.",
+ "cancel": "Cancel",
+ "join": "Join",
+ "items": "Items",
+ "vistors": "Vistors",
+ "fans": "Fans",
+ "balanceNotEnough": "Insufficient gold coin balance. Do you want to go to top up?",
+ "skip": "Skip {1}",
+ "letGoToWatch": "Let's go to watch!",
+ "launchedARocket": "launched a rocket",
+ "sendUserId": "Send UserID:{1}",
+ "giveUpIdentity": "Give up identity",
+ "leaveRoomIdentityTips": "Are you sure you want to give up the room identity?",
+ "joinMemberTips2": "Do you want to confirm joining the room as a member?",
+ "sureUnfollowThisRoom": "Sure to unfollow this room?",
+ "welcomeMessage": "Welcome to our application, {name}!",
+ "settings": "Settings",
+ "account": "Account",
+ "common": "Common",
+ "delete": "Delete",
+ "copy": "Copy",
+ "bio": "Bio",
+ "useCoupontips": "Are you sure you want to use the coupon?",
+ "searchUserId": "Search user's ID",
+ "sendUser": "Send User",
+ "hobby": "Hobby",
+ "sendCoupontips": "Are you sure you want to send this coupon to this user?",
+ "youDontHaveAnyCouponsYet": "You don't have any coupons yet.",
+ "recall": "Recall",
+ "youHaventFollowed": "You haven't followed any room",
+ "deleteFromMyDevice": "Delete from my device",
+ "deleteOnAllDevices": "Delete on all devices",
+ "messageHasBeenRecalled": "This message has been recalled",
+ "recallThisMessage": "Recall this message?",
+ "language": "Language",
+ "feedback": "Feedback",
+ "signedin": "Signed in",
+ "receiveSucc": "Successfully claimed",
+ "about": "About",
+ "aboutUs": "About Us",
+ "theme": "Theme",
+ "wealthLevel": "Wealth Level",
+ "userLevel": "User Level",
+ "goToUpload": "Go to upload",
+ "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.",
+ "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.",
+ "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",
+ "spaceBackground": "Space Background",
+ "editProfile": "Edit Profile",
+ "sendTheCpRequest": "Send the CP request",
+ "addCp": "Add CP",
+ "partWays": "Part Ways",
+ "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.",
+ "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.",
+ "areYouSureYouWantToPartWaysWithYourCP": "Are you sure you want to part ways with your CP?",
+ "timeSpentTogether": "Time spent together: {1} days",
+ "firstDay": "First day:{1}",
+ "numberOfMyCPs": "Number of my CPs:({1}/{2})",
+ "props": "Props",
+ "win": "Win",
+ "dice": "Dice",
+ "rps": "RPS",
+ "operationFail": "The operation was fail.",
+ "likedYourComment": "Liked your Comment.",
+ "doYouWantToKeepTheDraft": "Do you want to keep the draft?",
+ "operationsAreTooFrequent": "Operations are too frequent",
+ "luckNumber": "Luck Number",
+ "relationShip": "Relationship",
+ "couple": "Couple {1}:",
+ "couple2": "Couple",
+ "reject": "Reject",
+ "accept": "Accept",
+ "noMatchedCP": "No matched CP",
+ "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?",
+ "host": "Host",
+ "following": "Following",
+ "agent": "Agency",
+ "approved": "Approved",
+ "onlineUsers": "Online Users({1}/{2}):",
+ "applyToJoin": "Apply to join",
+ "supporterList": "Supporter List",
+ "hostList": "Host List",
+ "upToAdmins": "Up to {1} Admins",
+ "upToMembers": "Up to {1} Members",
+ "levelPrivileges": "Level privileges",
+ "ra": "RA",
+ "roomAnnouncement": "Room Announcement",
+ "help": "Help",
+ "rejected": "Rejected",
+ "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.",
+ "couponRecord": "Coupon usage record",
+ "inRoom": "In Room",
+ "searchCouponHint": "Search Coupon",
+ "giftCounter": "Gift counter",
+ "bDLeaderInviteYouToBecomeBDLeader": "Invite you to become a BDLeader",
+ "wins": "wins",
+ "inviteYouToBecomeHost": "Invite you to become a host.",
+ "friends": "Friends",
+ "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",
+ "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.",
+ "popular": "Popular",
+ "recommend": "Recommend",
+ "follow": "Follow",
+ "history": "History",
+ "hotRooms": "Hot Rooms",
+ "viewMore": "View more",
+ "noData": "No data",
+ "users": "Users",
+ "rooms": "Rooms",
+ "coins": "coins",
+ "unread": "Unread",
+ "read": "Read",
+ "image": "[Image]",
+ "video": "[Video]",
+ "sound": "[Sound]",
+ "gift2": "[Gift]",
+ "clickHereToStartChatting": "Say something.....",
+ "receivedAMessage": "[Received a message]",
+ "confirmSwitchMicModelTips": "Do you confirm the switch in seating mode?",
+ "number": "Number",
+ "album": "Album",
+ "camera": "Camera",
+ "system": "System",
+ "notifcation": "Notice",
+ "inviteYouToBecomeAgent": "Invite you to become a agency.",
+ "myMusic": "My Music",
+ "add": "Add",
+ "pullToLoadMore": "Pull to load more",
+ "loadingFailedClickToRetry": "Loading failed, click to retry",
+ "releaseToLoadMore": "Release to load more",
+ "haveMyLimits": "---I have my limits.---",
+ "music": "Music",
+ "free": "Free",
+ "charm": "Gift charm",
+ "start": "Start",
+ "stop": "Stop",
+ "chats": "Chats",
+ "refuse": "Refuse",
+ "agree": "Agree",
+ "thisFeatureIsCurrentlyUnavailable": "This feature is currently unavailable.",
+ "pleaseSelectTheRecipient": "Please select the recipient.",
+ "searchMemberIdHint": "Please enter the member's ID",
+ "unclaimedRedEnvelopes": "Unclaimed red envelopes are refunded in 24 hours.",
+ "redEnvelopeNotYetClaimed": "Red envelope not yet claimed.",
+ "redEnvelopeAmount": "Red envelope amount: {1} coins",
+ "sentARedEnvelope": "sent a red envelope.",
+ "theRedEnvelopeHasExpired": "The red envelope has expired.",
+ "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).",
+ "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)",
+ "resetLoginPassword": "Reset Login Password",
+ "resetLoginPasswordtTips1": "Log in with your user ID or vanity ID. lt 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?",
+ "micTheme": "Mic Theme",
+ "classicMic": "Classic {1} Mic",
+ "yesterday": "Yesterday {1}",
+ "monday": "Monday {1}",
+ "tuesday": "Tuesday {1}",
+ "wednesday": "Wednesday {1}",
+ "thursday": "Thursday {1}",
+ "friday": "Friday {1}",
+ "saturday": "Saturday {1}",
+ "sunday": "Sunday {1}",
+ "acceptedYour": "{1} accepted your ",
+ "youAccepted": "You accepted {1} ",
+ "openRedPackDialogTip": "The red envelope",
+ "micManagement": "Mic Management",
+ "bdCenter": "BD Center",
+ "rechargeAgency": "Recharge Agency",
+ "adminCenter": "Admin Center",
+ "goldList": "Gold List",
+ "followList": "Follow List",
+ "fansList": "Fans List",
+ "daily": "Daily",
+ "female": "Female",
+ "male": "Male",
+ "identity": "Identity",
+ "adjust": "Adjust",
+ "warning": "Warning",
+ "screenshotTips": "Screenshot (Up to 3)",
+ "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.",
+ "roomProfilePicture": "Room profile picture",
+ "userProfilePicture": "User profile picture",
+ "userName": "User name",
+ "pleaseSelectTheTypeToProcess": "Please select the type to process:",
+ "roomEditing": "Room Editing",
+ "setAccount": "Set Account",
+ "userEditing": "User Editing",
+ "enterTheUserId": "Enter the userId",
+ "enterTheRoomId": "Enter the roomId",
+ "deleteAccount": "Delete Account",
+ "becomeAgent": "Become a agent",
+ "enterNickname": "Enter Nickname",
+ "selectYourCountry": "Select your country",
+ "inviteCode": "Invite Code",
+ "magic": "Magic",
+ "luckGiftSpecialEffects": "Lucky gift animation effets",
+ "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.",
+ "customizedGiftRules": "Customized Gift Rules",
+ "rulesUpload": "Rules&Upload",
+ "monthly": "Monthly",
+ "message": "Message",
+ "clearCache": "Clear Cache",
+ "customized": "Customized",
+ "searchInputHint": "Enter account/room number",
+ "kickRoomTips": "You have been kicked out of the room.",
+ "joinRoomTips": "joined 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.",
+ "copiedToClipboard": "Copied to clipboard",
+ "recharge": "Recharge",
+ "receivedFromALuckyGift": "Received from a lucky/magic gift.",
+ "followedYou": "Followed you",
+ "agentCenter": "Agency Center",
+ "areYouSureYouWantToClearLocalCache": "Are you sure you want to clear local cache?",
+ "clearMessage": "Clear screen messages",
+ "report": "Report",
+ "coins3": "Coins",
+ "giftSpecialEffects": "Gift special effects",
+ "basicFeatures": "Basic Features",
+ "task": "Task",
+ "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.",
+ "dailyTasks": "Daily Tasks",
+ "enterRoomConfirmTips": "Are you sure you want to enter the room?",
+ "followSucc": "Followed successfully",
+ "goldListort": "Gold List",
+ "rechargeList": "Recharge List",
+ "edit": "Edit",
+ "swipeLeftOnTheFloatingScreenAreaToQuicklyCloseIt": "*Tip: Swipe left on the floating screen area to quickly close it.",
+ "enterThisVoiceChatRoom": "Enter this voice chat room?",
+ "go": "Go",
+ "done": "Done",
+ "improvementTasks": "Improvement Tasks",
+ "save": "Save",
+ "kickPrevention": "Kick prevention",
+ "freeChatSpeak": "Free Chat & Speak",
+ "nickName": "NickName",
+ "gender": "Gender",
+ "unFollow": "Unfollow",
+ "days": "Days",
+ "permanent": "Permanent",
+ "country": "Country",
+ "birthday": "Birthday",
+ "man": "Man",
+ "woman": "Woman",
+ "apple": "Apple",
+ "google": "Google",
+ "startVoiceParty": "Start a voice party!",
+ "enterRoomTips": "{1} Enter the room",
+ "roomName": "Room Name",
+ "roomMember": "Room Member",
+ "pleaseSelectYourCountry": "Please select your country.",
+ "pleaseSelectYourGender": "Please select your gender.",
+ "pleaseEnterNickname": "Please enter a nickname.",
+ "countryRegion": "Country&Region",
+ "dateOfBirth": "Date of birth",
+ "mute": "Mute",
+ "exit": "Exit",
+ "mysteriousInvisibility": "Mysterious invisibility",
+ "antiBlock": "Anti-Block",
+ "privateChat": "Private Chat",
+ "storeDiscount": "Store Discount {1} Off",
+ "membershipFreeChatSpeak": "Membership-free Chat & Speak",
+ "priorityRoomSorting": "Priority Room Sorting",
+ "userColoredID": "User Colored ID",
+ "pleaseSelectaItem": "Please select a item",
+ "areYouRureRoRecharge": "Are you sure to recharge?",
+ "mInimize": "Keep",
+ "everyone": "Everyone",
+ "shop": "Shop",
+ "roomOwner": "Room Owner",
+ "dailyTaskRewardBonus": "Daily Task Reward Bonus({1} XP)",
+ "userLevelXPBoost": "User Level XP Boost({1} XP)",
+ "andAboveUsers": "{1} And Above Users",
+ "privileges": "{1} Privileges",
+ "basicPermissions": "Basic permissions",
+ "hostCenter": "Host Center",
+ "allOnMicrophone": "All on mic",
+ "usersOnMicrophone": "Users on mic",
+ "allInTheRoom": "All in room",
+ "send": "Send",
+ "crop": "Crop",
+ "goToUpgrade": "Go to upgrade",
+ "exclusiveEmojiWillBeReleasedAfterBecoming": "Exclusive emoji will be released after becoming",
+ "preventBeingBlocked": "Prevent Being Blocked",
+ "enableRankIncognitoMode": "Enable Rank Incognito Mode",
+ "avoidBeingKicked": "Avoid Being Kicked",
+ "finish": "Finish",
+ "takeTheMic": "Take the mic",
+ "openTheMic": "Open the mic",
+ "muteTheMic": "Mute the mic",
+ "unlockTheMic": "Unlock the mic",
+ "leavelTheMic": "Leavel the mic",
+ "lockTheMic": "Lock the mic",
+ "removeTheMic": "Remove the mic",
+ "inviteToTheMicrophone": "Invite to the microphone",
+ "openUserProfleCard": "Open user profle card",
+ "obtain": "obtain",
+ "win2": "Win {1}",
+ "backTheRoom": "Back room",
+ "toConsume": "To consume",
+ "howToUpgrade": "How to upgrade?",
+ "spendCoinsToGainExperiencePoints": "Spend Coins to gain experience points",
+ "higherLevelFancierAvatarFrame": "Higher level, fancier badges/avatar frame",
+ "all": "All",
+ "gift": "Gift",
+ "chat": "Chat",
+ "owner": "Owner",
+ "store": "Store",
+ "admin": "Admin",
+ "member": "Member",
+ "guest": "Guest",
+ "submit": "Submit",
+ "claim": "Claim",
+ "complete": "Complete",
+ "shareTo": "Share to",
+ "copyLink": "Copy Link",
+ "faceBook": "Facebook",
+ "whatsApp": "Whatsapp",
+ "snapChat": "Snapchat",
+ "taskNamePersonalGameConsume": "Game Spending",
+ "taskNameRoomNewMember": "New Room Members",
+ "taskNameRoomOwnerSendRedPacket": "Room Owner sends one red packet",
+ "taskNameRoomOwnerSendGiftUser": "Room Owner Sends Gift",
+ "taskNameRoomMicUser120Min": "Members with 120+ minutes on mic",
+ "taskNameRoomMicUser60Min": "Members with 60+ minutes on mic",
+ "taskNameRoomMicUser30Min": "Members with 30+ minutes on mic",
+ "taskNamePersonalSendGift": "Send Gift to User",
+ "taskNameRoomOnlineUserCount": "Room online members",
+ "taskNameRoomOwnerInviteMic": "Invite member to Mic",
+ "taskNameRoomUserSendGiftGold": "Coins gifted by members",
+ "taskNameRoomOwnerSendGiftGold": "Coins gifted by room owner",
+ "taskNamePersonalMagicGiftGold": "Coins Won by Sending Magic Gifts",
+ "taskNamePersonalLuckyGiftGold": "Coins Won by Sending Lucky Gifts",
+ "taskNameRoomOwnerMicTime": "Room Owner goes on mic in the room",
+ "taskNamePersonalActiveInRoom": "Be Active in Others' Rooms",
+ "taskNamePersonalMicInRoom": "Go on Mic",
+ "dailyCoinBonanzaRulesDetail": "1. Daily Personal Tasks and Daily Room Owner Tasks can be completed once per user per day. Tasks reset at 00:00:00 Saudi time.\n2.Daily personal tasks can only be completed in others' rooms; room owner tasks can only be completed in your own room.\n3. Gift-giving tasks only count gifts sent in rooms, not gifts sent on feeds.\n4. If multiple accounts are created using the same device or the same SIM card in any way, rewards for all tasks can only be claimed once.",
+ "dailyCoinBonanzaRules": "Daily Coin Bonanza Rules",
+ "roomOwnerTasks": "Room Owner Tasks",
+ "personalTasks": "Personal Tasks",
+ "noPromptsToday": "No prompts 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.",
+ "membershipFeeTips2": "The golds required for the user to become the room member.The room owner will get 50% of the golds.",
+ "freePrice": "Fee:0-10000",
+ "touristsSendText": "Tourist send text",
+ "touristsTakeToTheMic": "Tourists take to the mic",
+ "theMembershipFee": "The membership fee",
+ "theModificationsMade": "The modifications made this time will not be saved after exiting",
+ "viewFrame": "View Frame",
+ "enterRoomName": "Enter room name",
+ "headdress": "Frames",
+ "mountains": "Vehicles",
+ "purchaseIsSuccessful": "Purchase is successful",
+ "buy": "Buy",
+ "followed": "Followed",
+ "follow2": "Follow:{1}",
+ "fans2": "Fans:{1}",
+ "vistors2": "Vistors:{1}",
+ "personal2": "Personal:",
+ "conntinue": "Conntinue",
+ "confirmBuyTips": "Are you sure you want to buy?",
+ "purchase": "Purchase",
+ "setRoomPassword": "Set room password",
+ "inputRoomPassword": "Input room password",
+ "enter": "Enter",
+ "deleteCommentTips": "Are you sure you want to delete this comment?",
+ "deleteSuccessful": "Deletion successful!",
+ "itemsLeft": "Items left",
+ "password": "Password",
+ "replySucc": "Reply successful",
+ "comment": "Comment",
+ "showMore": "Show more",
+ "showLess": "Show less",
+ "enterPassword": "Enter Password",
+ "enterAccount": "Enter Account",
+ "logIn": "Log In",
+ "saySomething": "Say something...",
+ "sayHi": "Say Hi..",
+ "pleaseChatFfriendly": "Please chat friendly",
+ "unLockTheRoom": "Unlock The Room",
+ "operationSuccessful": "The operation was successful.",
+ "adminByHomeowner": "is set as an administrator by the homeowner.",
+ "memberByHomeowner": "is set as members by the homeowner.",
+ "touristByHomeowner": "is set as a tourist by the homeowner.",
+ "becomeHost": "Apply To Become A Host",
+ "superFans": "Super fans:",
+ "setUpAnIdentity": "Set up an identity",
+ "kickedOutOfRoom": "Kicked out of room",
+ "knapsack": "Knapsack",
+ "bdLeader": "BD Leader",
+ "picture": "Picture",
+ "theImageSizeCannotExceed": "The image size cannot exceed 4M",
+ "activity": "Activity",
+ "alreadyAnAdministrator": "Already an administrator",
+ "alreadyAnMember": "Already an member",
+ "alreadyAnTourist": "Already an tourist",
+ "touristsCannotSendMessages": "Tourists cannot send messages",
+ "touristsAreNotAllowedToGoOnTheMic": "Tourists are not allowed to go on the mic",
+ "lockTheRoom": "Lock The Room",
+ "special": "Special",
+ "visitorList": "Visitor List",
+ "successfulWear": "Successful wear",
+ "confirmUnUseTips": "Do you confirm to remove it?",
+ "custom": "Custom",
+ "myItems": "My items",
+ "use": "Use",
+ "unUse": "Un use",
+ "renewal": "Renewal",
+ "wallet": "Wallet",
+ "profile": "Profile",
+ "giftwall": "Giftwall",
+ "announcement": "Announcement",
+ "blockedList": "Blocked list",
+ "country2": "Country:",
+ "sendTo": "Send to",
+ "credits": "Credits: {1}",
+ "successfullyUnloaded": "Successfully unloaded",
+ "expired": "Expired",
+ "day": "Day",
+ "inUse": "In use",
+ "confirmUseTips": "Do you want to confirm using it?",
+ "pleaseUploadUserAvatar": "Please upload an avatar.",
+ "joinMemberTips": "If you are a visitor in the room, you cannot take the microphone.",
+ "giftGivingSuccessful": "Gift giving successful.",
+ "theAccountPasswordCannotBeEmpty": "The account or password cannot be empty.",
+ "invitesYouToTheMicrophone": "{1} invites you to the microphone",
+ "english": "English",
+ "chinese": "Chinese",
+ "arabic": "Arabic",
+ "darkMode": "Dark Mode",
+ "lightMode": "Light Mode",
+ "systemDefault": "System Default",
+ "pleaseGetOnTheMicFirst": "Please get on the mic first.",
+ "duration2": "Duration:{1}"
+}
diff --git a/assets/l10n/intl_tr.json b/assets/l10n/intl_tr.json
new file mode 100644
index 0000000..db3e44e
--- /dev/null
+++ b/assets/l10n/intl_tr.json
@@ -0,0 +1,643 @@
+{
+ "signInWithGoogle": "Google ile Giriş Yap",
+ "or": "Veya",
+ "signInWithYourAccount": "Hesabınız ile Giriş Yap",
+ "signInWithApple": "Apple ile Giriş Yap",
+ "loginRepresentsAgreementTo": "Giriş yapmak, aşağıdakilere kabul ettiğiniz anlamına gelir",
+ "termsofService": "Hizmet Şartları",
+ "privaceyPolicy": "Gizlilik Politikası",
+ "tips": "İpuçları",
+ "searchNoDataTips": "Aramak istediğiniz oda veya kullanıcı kimliğini girin.",
+ "mine": "Benimki",
+ "party": "Parti",
+ "myRoom": "Odam",
+ "other": "Diğer",
+ "yes": "Evet",
+ "bag": "Çanta",
+ "sound2": "Ses",
+ "startYourBrandNewJourney": "Yepyeni Yolculuğunuza Başlayın",
+ "maliciousHarassment": "Kötü niyetli taciz",
+ "numberOfMic": "Mikrofon Sayısı",
+ "pleaseEnterContent": "Lütfen içerik girin",
+ "profilePhoto": "Profil Fotoğrafı",
+ "aboutMe": "Hakkımda",
+ "roomEdit": "Oda Düzenle",
+ "cancelRoomPassword": "Oda şifresini silmek istediğinizden emin misiniz?",
+ "roomMemberFee": "Oda Üyelik Ücreti",
+ "blockedList2": "Engellenen Liste",
+ "roomTheme2": "Oda Teması",
+ "roomPassword": "Oda Şifresi",
+ "noHistoricalRecordsAvailable": "Mevcut tarihi kayıt yok.",
+ "inviteNewUsersToEarnCoins": "Yeni kullanıcıları davet ederek coin kazanın",
+ "crateMyRoom": "KENDİ ODANIZI OLUŞTURUN.",
+ "event": "Etkinlik",
+ "clearCacheSuccessfully": "Önbellek başarıyla temizlendi",
+ "sent": "Gönderildi",
+ "keep": "Sakla",
+ "open": "Aç",
+ "recent": "Son",
+ "popularEvents": "Popüler Etkinlikler",
+ "confirmInviteThisUserToTheRoom": "Bu kullanıcıyı (ID:{1}) odaya davet etmeyi onaylıyor musunuz?",
+ "deleteAccountTips2": "*Fikrinizi değiştirirseniz, yedi gün içinde mevcut hesabınıza tekrar giriş yapabilir ve hesapınız otomatik olarak geri yüklenecektir. Yedi gün içinde geri yüklenmezse, hesap kalıcı olarak silinir",
+ "deleteAccountTips": "Bu hesap üzerinde tam yönetim haklarınız bulunur. Hesabı silmek istiyorsanız, bu işlemin ilişkili olduğu aşağıdaki riskleri lütfen unutmayın:\n1.Hesap başarıyla silindikten sonra, mevcut hesabınıza artık giriş yapamazsınız. Hesap silme kalıcı bir eylemdir.\n2. Hesap başarıyla silindikten sonra, hesap verilerinin hiçbirini kurtaramazsınız. Tüm bilgiler (odalar, arkadaşlar dahil), sanal para, hediyeler ve sanal eşyalar kalıcı olarak silinir ve geri yüklenemez.\n3. Soğuma süresi: Hesabı geri yüklemezseniz, uygulamadaki satın alma sayfasına, para çekme sayfasına veya diğer herhangi bir sayfaya erişemezsiniz.\n4.Soğuma süresi boyunca veya hesap silindikten sonra, profil sayfası silindiğini gösterecektir. Hesabınızın başkaları tarafından aranmasını veya erişilmesini engellemek için, kişisel bilgilerinizin günlük işlevlerle ilgili sistemlerden kaldırılacaktır. Hesap silme ulusal güvenliği, siviller veya cezai davaları veya üçüncü tarafların geçerli hak ve menfaatlerinin korunmasını içerdiğinde, resmi yönetim kullanıcının hesap silme isteğini reddetme hakkını saklı tutar.\nEğer mevcut hesabınızdaki tüm kişisel verileri silmekten eminseniz, lütfen \"Hesabı Sil\" butonuna tıklayın.",
+ "accountDeletionNotice": "Hesap Silme Bildirimi:",
+ "thisUserHasBeenBlacklisted": "Bu kullanıcı kara listeye alındı.",
+ "trend": "Trend",
+ "like": "Beğen",
+ "more": "Daha Fazla",
+ "discard": "Vur",
+ "catchFirstComment": "İlk Yorumu Yakala",
+ "reply": "Cevapla",
+ "posting": "Gönderiliyor",
+ "multiple": "Çoklu",
+ "successfullyRemovedFromTheBlacklist": "Kara listeden başarıyla kaldırıldı!",
+ "successfullyAddedToTheBlacklist": "Kara listeye başarıyla eklendi!",
+ "youAreCurrentlyCPRelationshipPleaseDissolve": "Şu anda bir CP ilişkisindesiniz.\nLütfen önce ilişkiyi sonlandırın.",
+ "areYouSureToCancelBlacklist": "Kara listeyi iptal etmek istediğinizden emin misiniz?",
+ "areYouSureYouWantToBlockThisUser": "Bu kullanıcıyı engellemek istediğinizden emin misiniz?",
+ "removeFromBlacklist": "Kara listeden kaldır",
+ "moveToBlacklist": "Kara listeye ekle",
+ "userBlacklist": "Kullanıcı kara listesi",
+ "specialEffectsManagement": "Özel Efekt Yönetimi",
+ "wishingYouHappinessEveryDay": "Her gün mutlu olmanızı dileyiyoruz.",
+ "newMessage": "Yeni mesaj",
+ "createRoomSuccsess": "Oda başarıyla oluşturuldu!",
+ "contactUs": "Bize Ulaşın",
+ "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.",
+ "atTag": "@Etiket",
+ "sayHi2": "Merhaba De",
+ "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.",
+ "reapply": "Tekrar Başvur",
+ "cancelRequest": "İsteği İptal Et",
+ "pending": "Beklemede",
+ "supporter": "Destekçi",
+ "coinsReceived": "Jetton Alındı",
+ "numberOfSign": "Giriş Sayısı: {1}",
+ "hostWeeklyRank": "Sunucu Haftalık Sıralaması",
+ "supporterWeeklyRank": "Destekçi Haftalık Sıralaması",
+ "memberList": "Üye Listesi",
+ "treasureChest": "Hazine Sandığı",
+ "applicationRecord": "Başvuru Kaydı",
+ "appUpdateTip": "Uygulamanın yeni bir sürümü var ({1}), lütfen indirin mi?",
+ "ownerIncomeCoins": "Sahibin Geliri:{1} jetton",
+ "game": "Oyun",
+ "skip2": "Atla",
+ "coins4": "Jetton",
+ "weekStart": "Hafta Başlangıcı",
+ "forMoreRewardsPleaseCheckTheTaskCenter": "Daha fazla ödül için lütfen görev merkezini kontrol edin",
+ "kingQuuen": "Kral-Kraliçe",
+ "ramadan": "Ramazan",
+ "updateNow": "Şimdi Güncelle",
+ "allGames": "Tüm Oyunlar",
+ "fishClass": "Balık Sınıfı",
+ "greedyClass": "Aşırı İstekli Sınıfı",
+ "raceSeries": "Yarış Serisi",
+ "slotsClass": "Slot Sınıfı",
+ "others": "Diğerleri",
+ "hotGames": "Popüler Oyunlar",
+ "chatBox": "Sohbet Kutusu",
+ "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",
+ "inappropriateContent": "Uygunsuz İçerik",
+ "personalAttack": "Kişisel Saldırı",
+ "confirm": "Onayla",
+ "spam": "İstenmeyen Mesaj",
+ "countdownMinutes": "Geri Sayım Dakikaları :",
+ "number2": "Numara:",
+ "fraud": "Sahtekarlık",
+ "received": "Alındı",
+ "currentProgress": "Mevcut İlerleme",
+ "currentStage": "Mevcut Aşama:{1}",
+ "roomReward2": "Oda Ödülü:{1}",
+ "roomReward": "Oda Ödülü",
+ "ownerSendTheRedEnvelope": "Sahip ödül jettonlarını gönderdi.",
+ "rewardCoins": "Ödül jettonları:{1} jetton",
+ "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)",
+ "areYouSureYouWantToDeleteYourAccount": " Hesabınızı silmek istediğinizden emin misiniz?",
+ "insufhcientGoldsGoToRecharge": "Altın yetersiz, hemen yükle!",
+ "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?",
+ "redEnvelopeSendingRecords": "Kırmızı zarf gönderim kayıtları:",
+ "redEnvelope": "Kırmızı Zarf",
+ "redEnvelopeRecTips2": "Kırmızı zarfların hepsi talep edildi.",
+ "redEnvelopeRecTips3": "Kırmızı zarf toplama zamanı doldu!",
+ "openTheTreasureChest": "Hazine Sandığını Aç",
+ "redEnvelopeRecTips1": "Kazanan jettonlar cüzdanınıza yatırıldı.",
+ "redEnvelopeTips1": "Jettonlar:",
+ "roomTools": "Oda Araçları:",
+ "entertainment": "Eğlence:",
+ "reportSucc": "Bildirim başarılı",
+ "pornography": "Pornografi",
+ "reportInputTips": "Sorunu anlayabilmemiz ve çözebilmemiz için lütfen sorunu mümkün olduğunca detaylı anlatın.",
+ "cancel": "İptal",
+ "join": "Katıl",
+ "items": "Eşyalar",
+ "vistors": "Ziyaretçiler",
+ "fans": "Hayranlar",
+ "balanceNotEnough": "Altın jetton bakiyesi yetersiz. Yüklemek ister misiniz?",
+ "skip": "{1} Atla",
+ "letGoToWatch": "Haydi izlemeye gidelim!",
+ "launchedARocket": "roket fırlattı",
+ "sendUserId": "Kullanıcı ID'si Gönder:{1}",
+ "giveUpIdentity": "Kimliği Bırak",
+ "leaveRoomIdentityTips": "Oda kimliğini bırakmak istediğinizden emin misiniz?",
+ "joinMemberTips2": "Üye olarak odaya katılmayı onaylamak ister misiniz?",
+ "sureUnfollowThisRoom": "Bu odayı takipten çıkarmak istediğinizden emin misiniz?",
+ "welcomeMessage": "Uygulamamıza hoş geldiniz, {name}!",
+ "settings": "Ayarlar",
+ "account": "Hesap",
+ "common": "Genel",
+ "delete": "Sil",
+ "copy": "Kopyala",
+ "bio": "Biyografi",
+ "useCoupontips": "Kuponu kullanmak istediğinizden emin misiniz?",
+ "searchUserId": "Kullanıcı ID'sini Ara",
+ "sendUser": "Kullanıcıya Gönder",
+ "hobby": "Hobi",
+ "sendCoupontips": "Bu kuponu bu kullanıcıya göndermek istediğinizden emin misiniz?",
+ "youDontHaveAnyCouponsYet": "Henüz hiç kuponunuz yok.",
+ "recall": "Geri Çağır",
+ "youHaventFollowed": "Hiç oda takip etmediniz",
+ "deleteFromMyDevice": "Cihazımdan Sil",
+ "deleteOnAllDevices": "Tüm Cihazlarda Sil",
+ "messageHasBeenRecalled": "Bu mesaj geri çağırıldı",
+ "recallThisMessage": "Bu mesajı geri çağırmak ister misiniz?",
+ "language": "Dil",
+ "feedback": "Geri Bildirim",
+ "signedin": "Giriş Yapıldı",
+ "receiveSucc": "Başarıyla talep edildi",
+ "about": "Hakkında",
+ "aboutUs": "Hakkımızda",
+ "theme": "Tema",
+ "wealthLevel": "Servet Seviyesi",
+ "userLevel": "Kullanıcı Seviyesi",
+ "goToUpload": "Yüklemeye Git",
+ "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.",
+ "home": "Anasayfa",
+ "explore": "Keşfet",
+ "me": "Ben",
+ "socialPrivilege": "Sosyal ayrıcalık",
+ "games": "Oyunlar",
+ "casualInteraction": "Günlük Etkileşim",
+ "haveGamePlayingTips": "Oynadığınız bir oyun devam ediyor, lütfen önce mevcut oyundan çıkın, çıkmak istediğinizden emin misiniz?",
+ "historicalTour": "Tarihi Tur",
+ "gameCenter": "Oyun Merkezi",
+ "returnToVoiceChat": "Sesli sohbete geri dön?",
+ "exitGameMode": "Oyun Modundan Çık",
+ "enterTheRoom": "Odaya gir",
+ "inviteGoRoomTips": "Her zaman senin için buradayım, yağmurda ya da güneşte. Gel ve merhaba de!",
+ "invite": "Davet et",
+ "information": "Bilgi",
+ "myPhoto": "Fotoğraflarım",
+ "areYouSureYouWantToSpend3": "*Diğer taraf CP davetini reddederse, jettonlarınız cüzdanınıza iade edilecektir.",
+ "areYouSureYouWantToSpend": "Harcamak istediğinizden emin misiniz",
+ "areYouSureYouWantToSpend2": "bu kullanıcıya CP daveti göndermek için?",
+ "underReview": "İnceleniyor",
+ "doYouWantToDeleteIt": "Silmek ister misiniz?",
+ "chooseFromAblum": "Albümdan Seç",
+ "spaceBackground": "Mekan Arka Planı",
+ "editProfile": "Profili Düzenle",
+ "sendTheCpRequest": "CP İsteğini Gönder",
+ "addCp": "CP Ekle",
+ "partWays": "Yollarını Ayırmak",
+ "reconcile": "Uzlaşmak",
+ "separated": "Ayırılmış",
+ "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.",
+ "reconcileInvitation": "Uzlaşma Daveti",
+ "areYouSureYouWantToSpend4": "bu kullanıcıya uzlaşma daveti göndermek için?",
+ "partWaysTips": "*Çiftin bir partneri yollarını ayırmayı seçerse, 7 günlük bir soğuma süresi olacaktır. Bu süre boyunca her iki taraf da uzlaşmayı seçebilir ve uzlaşma durumunda tüm veriler geri yüklenecektir. 7 günlük sürenin sonunda uzlaşma seçilmezse, çift verileri temizlenecektir.",
+ "areYouSureYouWantToPartWaysWithYourCP": "CP'nizle yollarınızı ayırmak istediğinizden emin misiniz?",
+ "timeSpentTogether": "Birlikte Geçirilen Zaman: {1} gün",
+ "firstDay": "İlk Gün:{1}",
+ "numberOfMyCPs": "CP'lerim Sayısı:({1}/{2})",
+ "props": "Özellikler",
+ "win": "Kazanan",
+ "dice": "Zar",
+ "rps": "Kağıt-Kaçak-Makas",
+ "operationFail": "İşlem başarısız oldu.",
+ "likedYourComment": "Yorumunuzu beğendi.",
+ "doYouWantToKeepTheDraft": "Taslağı saklamak ister misiniz?",
+ "operationsAreTooFrequent": "İşlemler çok sık",
+ "luckNumber": "Şans Numarası",
+ "relationShip": "İlişki",
+ "couple": "Çift {1}:",
+ "couple2": "Çift",
+ "reject": "Reddet",
+ "accept": "Kabul Et",
+ "noMatchedCP": "Eşleşen CP yok",
+ "inviteYouToBecomeBD": "Sizi BD yapmaya davet ediyoruz.",
+ "adminInviteRechargeAgent": "Sizi Yükleme temsilcisi yapmaya davet ediyoruz.",
+ "confirmAcceptTheInvitation": "Daveti kabul etmek için onaylıyor musunuz?",
+ "confirmDeclineTheInvitation": "Daveti reddetmek için onaylıyor musunuz?",
+ "host": "Sunucu",
+ "following": "Takip Edilenler",
+ "agent": "Temsilcilik",
+ "approved": "Onaylandı",
+ "onlineUsers": "Çevrimiçi Kullanıcılar({1}/{2}):",
+ "applyToJoin": "Katılmak İçin Başvur",
+ "supporterList": "Destekçi Listesi",
+ "hostList": "Sunucu Listesi",
+ "upToAdmins": "En Fazla {1} Yönetici",
+ "upToMembers": "En Fazla {1} Üye",
+ "levelPrivileges": "Seviye Hakları",
+ "ra": "RA",
+ "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",
+ "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.",
+ "couponRecord": "Kupon Kullanım Kaydı",
+ "inRoom": "Odada",
+ "searchCouponHint": "Kupon Ara",
+ "giftCounter": "Hediye Sayacı",
+ "bDLeaderInviteYouToBecomeBDLeader": "Sizi BD Lideri yapmaya davet ediyoruz",
+ "wins": "kazanmalar",
+ "inviteYouToBecomeHost": "Sizi sunucu yapmaya davet ediyoruz.",
+ "friends": "Arkadaşlar",
+ "deleteConversationTips": "Bu kullanıcıyla olan sohbet geçmişini silmek istediğinizden emin misiniz?",
+ "propMessagePrompt": "Özellik Mesaj İpucu",
+ "inputUserId": "Kullanıcı ID'sini Girin",
+ "fromLuckyGifts": "şanslı/sihirli hediyelerden",
+ "receive": "Al",
+ "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",
+ "follow": "Takip Et",
+ "history": "Tarihçe",
+ "hotRooms": "Popüler Odalar",
+ "viewMore": "Daha Fazlasını Gör",
+ "noData": "Veri yok",
+ "users": "Kullanıcılar",
+ "rooms": "Odalar",
+ "coins": "jetton",
+ "unread": "Okunmadı",
+ "read": "Okundu",
+ "image": "[Görsel]",
+ "video": "[Video]",
+ "sound": "[Ses]",
+ "gift2": "[Hediye]",
+ "clickHereToStartChatting": "Bir şey söyle.....",
+ "receivedAMessage": "[Mesaj alındı]",
+ "confirmSwitchMicModelTips": "Koltuk modunu değiştirmek için onaylıyor musunuz?",
+ "number": "Numara",
+ "album": "Albüm",
+ "camera": "Kamera",
+ "system": "Sistem",
+ "notifcation": "Bildirim",
+ "inviteYouToBecomeAgent": "Sizi temsilcilik yapmaya davet ediyoruz.",
+ "myMusic": "Müziklerim",
+ "add": "Ekle",
+ "pullToLoadMore": "Yüklemek için çekin",
+ "loadingFailedClickToRetry": "Yükleme başarısız, tekrar denemek için tıklayın",
+ "releaseToLoadMore": "Yüklemek için bırakın",
+ "haveMyLimits": "---Kendi sınırlarım var.---",
+ "music": "Müzik",
+ "free": "Ücretsiz",
+ "charm": "Hediye Çekiciliği",
+ "start": "Başlat",
+ "stop": "Durdur",
+ "chats": "Sohbetler",
+ "refuse": "Reddet",
+ "agree": "Kabul Et",
+ "thisFeatureIsCurrentlyUnavailable": "Bu özellik şu anda kullanılamıyor.",
+ "pleaseSelectTheRecipient": "Lütfen alıcıyı seçin.",
+ "searchMemberIdHint": "Lütfen üyenin kimlik numarasını girin",
+ "unclaimedRedEnvelopes": "Talep edilmemiş kırmızı zarflar 24 saat içinde iade edilir.",
+ "redEnvelopeNotYetClaimed": "Kırmızı zarf henüz talep edilmedi.",
+ "redEnvelopeAmount": "Kırmızı zarf miktarı: {1} jetton",
+ "sentARedEnvelope": "kırmızı zarf gönderdi.",
+ "theRedEnvelopeHasExpired": "Kırmızı zarfın süresi doldu.",
+ "joinRequest": "Katılma İsteği",
+ "scrollToTheBottom": "En alta kaydır",
+ "gameRules": "Oyun Kuralları:",
+ "charmGameRulesTips": "Gösterge panelini açın, mikrodaki tüm kullanıcıların aldığı hediye jettonunu gösterin,1 jetton = 1 puan (Şanslı hediye 1 jetton = 0.04 puan).",
+ "inputYourOldPassword": "Eski şifrenizi girin",
+ "enterYourOldPassword": "Eski şifrenizi girin",
+ "setYourPassword": "Şifrenizi ayarlayın",
+ "enterYourNewPassword": "Yeni şifrenizi girin",
+ "confirmYourPassword": "Şifrenizi onaylayın",
+ "theTwoPasswordsDoNotMatch": "İki şifre eşleşmiyor.",
+ "resetLoginPasswordtTips2": "Şifre 8-16 karakter uzunluğunda olmalı ve büyük/küçük harf İngilizce harfleri ile sayılardan oluşan bir kombinasyon olmalıdır (yalnızca sayılar olmamalı)",
+ "resetLoginPassword": "Giriş Şifresini Sıfırla",
+ "resetLoginPasswordtTips1": "Kullanıcı ID'niz veya özel ID'niz ile giriş yapın. yumi hesabı ile giriş yapmak daha güvenlidir.",
+ "localMusic": "Yerel Müzik",
+ "setLoginPassword": "Giriş Şifresi Ayarlayın",
+ "confirmSwitchMicThemeTips": "Koltuk stili değiştirmeyi onaylıyor musunuz?",
+ "micTheme": "Mikro Tema",
+ "classicMic": "Klasik {1} Mikro",
+ "yesterday": "Dün {1}",
+ "monday": "Pazartesi {1}",
+ "tuesday": "Salı {1}",
+ "wednesday": "Çarşamba {1}",
+ "thursday": "Perşembe {1}",
+ "friday": "Cuma {1}",
+ "saturday": "Cumartesi {1}",
+ "sunday": "Pazar {1}",
+ "acceptedYour": "{1} sizin davetinizi kabul etti",
+ "youAccepted": "Sen {1} davetini kabul ettin",
+ "openRedPackDialogTip": "Kırmızı zarf",
+ "micManagement": "Mikro Yönetimi",
+ "bdCenter": "BD Merkezi",
+ "rechargeAgency": "Yükleme Temsilciliği",
+ "adminCenter": "Yönetici Merkezi",
+ "goldList": "Altın Listesi",
+ "followList": "Takip Listesi",
+ "fansList": "Hayran Listesi",
+ "daily": "Günlük",
+ "female": "Kadın",
+ "male": "Erkek",
+ "identity": "Kimlik",
+ "adjust": "Ayarlama",
+ "warning": "Uyarı",
+ "screenshotTips": "Ekran Görüntüsü (En Fazla 3)",
+ "roomNotice": "Oda Bildirimi",
+ "roomTheme": "Oda Tema",
+ "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ı",
+ "userProfilePicture": "Kullanıcı Profil Fotoğrafı",
+ "userName": "Kullanıcı Adı",
+ "pleaseSelectTheTypeToProcess": "Lütfen işlem türünü seçin:",
+ "roomEditing": "Oda Düzenleme",
+ "setAccount": "Hesap Ayarla",
+ "userEditing": "Kullanıcı Düzenleme",
+ "enterTheUserId": "Kullanıcı ID'sini Girin",
+ "enterTheRoomId": "Oda ID'sini Girin",
+ "deleteAccount": "Hesabı Sil",
+ "becomeAgent": "Temsilci Ol",
+ "enterNickname": "Takma Ad Girin",
+ "selectYourCountry": "Ülkenizi Seçin",
+ "inviteCode": "Davet Kodu",
+ "magic": "Sihir",
+ "luckGiftSpecialEffects": "Şanslı hediye animasyon efektleri",
+ "theVideoSizeCannotExceed": "Video boyutu 50M'yi geçemez",
+ "weekly": "Haftalık",
+ "customizedGiftRulesContent": "Özel hediyemi nasıl alabilirim:\n1.Kullanıcının özel hediye almaya haklı olup olmadığını mevcut servet seviyesine göre belirleyin.\n(1) Kullanıcının servet seviyesi ≥35 olduğunda: \nKullanıcı özel hediye için bir kez video yükleyebilir. Kullanıcının mevcut profil fotoğrafını hediye görüntüsü olarak ve sağlanan videoyu \"Özel\" üzerindeki hediye efekti olarak kullanacağız. Üretim biraz zaman alacak ve mağazada kullanılabilir hale gelir gelmez sizi bilgilendireceğiz.\n(2) Kullanıcının servet seviyesi ≥45 olduğunda: \nKullanıcı özel hediye için bir kez video yükleyebilir. Kullanıcının mevcut profil fotoğrafını hediye görüntüsü olarak ve sağlanan videoyu \"Özel\" üzerindeki hediye efekti olarak kullanacağız. Üretim biraz zaman alacak ve mağazada kullanılabilir hale gelir gelmez sizi bilgilendireceğiz.\n2.Uygulamadaki belirli etkinliklere katılabilir ve kriterleri karşıladıktan sonra \"Mesaj\" → \"Bize Ulaşın\" bölümünden bizimle iletişime geçebilirsiniz. Etkinliğin ekran görüntülerini ve özel hediye için kullanmak istediğiniz videoyu sağlayın. Mevcut profil fotoğrafınızı hediye görüntüsü olarak ve sağlanan videoyu hediye efekti olarak kullanacağız, ardından \"Özel\" altında listelenecektir. Üretim biraz zaman alacak ve mağazada kullanılabilir hale gelir gelmez sizi bilgilendireceğiz.\nÖzel Hediye Geçerlilik Süresi & Nasıl Uzatılır:\nÖzel özel hediyeler 30 günlük bir geçerlilik süresiyle raflarda bulunacaktır. Etkili ve ilham verici kullanıcıların bu yeni deneyimi devam ettirmesini ve kişisel tarzlarını sergilemesini sağlamak için, özel hediyelere sahip kullanıcılar herhangi bir ayda 500 ABD doları yükleyerek tüm özel hediyelerinin raf zamanını 30 gün uzatabilir.",
+ "customizedGiftRules": "Özel Hediye Kuralları",
+ "rulesUpload": "Kurallar&Yükleme",
+ "monthly": "Aylık",
+ "message": "Mesaj",
+ "clearCache": "Önbelleği Temizle",
+ "customized": "Özel",
+ "searchInputHint": "Hesap/oda numarasını girin",
+ "kickRoomTips": "Odadan atıldınız.",
+ "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.",
+ "copiedToClipboard": "Panoya kopyalandı",
+ "recharge": "Yükle",
+ "receivedFromALuckyGift": "Şanslı/sihirli bir hediyeden alındı.",
+ "followedYou": "Seni takip etti",
+ "agentCenter": "Temsilci Merkezi",
+ "areYouSureYouWantToClearLocalCache": "Yerel önbelleği temizlemek istediğinizden emin misiniz?",
+ "clearMessage": "Ekran mesajlarını temizle",
+ "report": "Bildir",
+ "coins3": "Jetton",
+ "giftSpecialEffects": "Hediye Özel Efektleri",
+ "basicFeatures": "Temel Özellikler",
+ "task": "Görev",
+ "importantReminder": "Önemli Hatırlatma",
+ "entryVehicleAnimation": "Giriş Aracı Animasyonu",
+ "floatingAnimationInGlobal": "Küreselde Süzme 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?",
+ "followSucc": "Başarıyla takip edildi",
+ "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.",
+ "enterThisVoiceChatRoom": "Bu sesli sohbet odasına girmek ister misiniz?",
+ "go": "Git",
+ "done": "Bitti",
+ "improvementTasks": "Geliştirme Görevleri",
+ "save": "Kaydet",
+ "kickPrevention": "Atma Koruması",
+ "freeChatSpeak": "Ücretsiz Sohbet & Konuşma",
+ "nickName": "Takma Ad",
+ "gender": "Cinsiyet",
+ "unFollow": "Takipten Çık",
+ "days": "Günler",
+ "permanent": "Kalıcı",
+ "country": "Ülke",
+ "birthday": "Doğum Günü",
+ "man": "Erkek",
+ "woman": "Kadın",
+ "apple": "Apple",
+ "dailyTaskRewardBonus": "Günlük Görev Ödül Bonusu ({1} XP)",
+ "userLevelXPBoost": "Kullanıcı Seviyesi XP Artışı({1} XP)",
+ "google": "Google",
+ "mysteriousInvisibility": "Gizemli görünmezlik",
+ "antiBlock": "Tıkanmayı Önleyici",
+ "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",
+ "privileges": "{1} Ayrıcalıklar",
+ "andAboveUsers": "{1} ve üzeri kullanıcılar",
+ "basicPermissions": "Temel izinler",
+ "storeDiscount": "Mağaza İndirimi {1} Tutarında",
+ "membershipFreeChatSpeak": "Üyeliksiz Sohbet ve Konuşma",
+ "priorityRoomSorting": "Öncelikli Oda Sıralaması",
+ "userColoredID": "Kullanıcı Renkli Kimliği",
+ "startVoiceParty": "Sesli parti başlat!",
+ "enterRoomTips": "{1} odaya girdi",
+ "roomName": "Oda Adı",
+ "roomMember": "Oda Üyesi",
+ "pleaseSelectYourCountry": "Lütfen ülkenizi seçin.",
+ "pleaseSelectYourGender": "Lütfen cinsiyetinizi seçin.",
+ "pleaseEnterNickname": "Lütfen bir takma ad girin.",
+ "countryRegion": "Ülke&Bölge",
+ "dateOfBirth": "Doğum Tarihi",
+ "mute": "Sesi Kapat",
+ "exit": "Çıkış",
+ "pleaseSelectaItem": "Lütfen bir öğe seçin",
+ "areYouRureRoRecharge": "Yüklemek istediğinizden emin misiniz?",
+ "mInimize": "Tutmak",
+ "shop": "Mağaza",
+ "expirationTime": "Son kullanma süresi",
+ "roomOwner": "Oda Sahibi",
+ "hostCenter": "Sunucu Merkezi",
+ "allOnMicrophone": "Hepsi Mikrodadır",
+ "usersOnMicrophone": "Mikrodaki Kullanıcılar",
+ "allInTheRoom": "Hepsi Odadadır",
+ "send": "Gönder",
+ "crop": "Kırp",
+ "finish": "Bitir",
+ "takeTheMic": "Mikroyu Al",
+ "openTheMic": "Mikroyu Aç",
+ "muteTheMic": "Mikronun Sesini Kapat",
+ "unlockTheMic": "Mikroyu 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",
+ "win2": "{1} Kazan",
+ "backTheRoom": "Odaya Dön",
+ "toConsume": "Tüketmek İçin",
+ "howToUpgrade": "Nasıl yükseltirim?",
+ "spendCoinsToGainExperiencePoints": "Deneyim puanı kazanmak için jetton harcayın",
+ "higherLevelFancierAvatarFrame": "Daha yüksek seviye, daha şık rozetler/profil çerçevesi",
+ "all": "Tümü",
+ "gift": "Hediye",
+ "chat": "Sohbet",
+ "owner": "Sahip",
+ "store": "Mağaza",
+ "admin": "Yönetici",
+ "member": "Üye",
+ "guest": "Misafir",
+ "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.",
+ "freePrice": "Ücret:0-10000",
+ "touristsSendText": "Turist metin gönderir",
+ "touristsTakeToTheMic": "Turist mikro alır",
+ "theMembershipFee": "Üyelik Ücreti",
+ "theModificationsMade": "Bu sefer yapılan değişiklikler çıkıştan sonra kaydedilmeyecektir",
+ "viewFrame": "Çerçeveyi Gör",
+ "enterRoomName": "Oda adını girin",
+ "headdress": "Çerçeveler",
+ "mountains": "Araçlar",
+ "purchaseIsSuccessful": "Satın alma başarılı",
+ "buy": "Satın Al",
+ "followed": "Takip Edildi",
+ "follow2": "Takip:{1}",
+ "fans2": "Hayranlar:{1}",
+ "vistors2": "Ziyaretçiler:{1}",
+ "personal2": "Kişisel:",
+ "conntinue": "Devam Et",
+ "confirmBuyTips": "Satın almak istediğinizden emin misiniz?",
+ "purchase": "Satın Alma",
+ "setRoomPassword": "Oda Şifresi Ayarlayın",
+ "inputRoomPassword": "Oda şifresini girin",
+ "enter": "Gir",
+ "deleteCommentTips": "Bu yorumu silmek istediğinizden emin misiniz?",
+ "deleteSuccessful": "Silme başarılı!",
+ "itemsLeft": "Kalan Eşyalar",
+ "password": "Şifre",
+ "replySucc": "Cevap başarılı",
+ "comment": "Yorum",
+ "showMore": "Daha Fazlasını Göster",
+ "showLess": "Daha Azını Göster",
+ "enterPassword": "Şifre Girin",
+ "enterAccount": "Hesap Girin",
+ "logIn": "Giriş Yap",
+ "saySomething": "Bir şey söyle...",
+ "sayHi": "Merhaba..",
+ "pleaseChatFfriendly": "Lütfen arkadaşça sohbet edin",
+ "unLockTheRoom": "Odayı 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ı.",
+ "touristByHomeowner": "ev sahibi tarafından turist olarak atandı.",
+ "becomeHost": "Ev Sahibi Olmak İçin Başvur",
+ "superFans": " Süper hayranlar:",
+ "setUpAnIdentity": "Kimlik Kur",
+ "kickedOutOfRoom": "Odadan Atıldı",
+ "knapsack": "Sırt Çantası",
+ "bdLeader": "BD Lideri",
+ "picture": "Resim",
+ "claim": "İddia",
+ "taskNameRoomNewMember": "Yeni Oda Üyeleri",
+ "taskNameRoomOwnerSendRedPacket": "Oda Sahibi bir kırmızı paket gönderiyor",
+ "taskNameRoomOwnerSendGiftUser": "Oda Sahibi Hediye Gönderir",
+ "taskNameRoomMicUser120Min": "Mikrofon süresi 120+ dakika olan üyeler",
+ "taskNameRoomMicUser60Min": "Mikrofon süresi 60+ dakika olan üyeler",
+ "taskNameRoomMicUser30Min": "Mikrofon süresi 30+ dakika olan üyeler",
+ "taskNamePersonalSendGift": "Kullanıcıya Hediye Gönder",
+ "taskNameRoomOnlineUserCount": "Odadaki Çevrimiçi Üyeler",
+ "taskNameRoomOwnerInviteMic": "Üyeyi Mikrofona Davet Et",
+ "taskNameRoomUserSendGiftGold": "Üyelerin hediye ettiği jetonlar",
+ "taskNameRoomOwnerSendGiftGold": "Oda sahibinin hediye ettiği jetonlar",
+ "taskNamePersonalMagicGiftGold": "Büyülü Hediyeler Göndererek Kazanılan Jetonlar",
+ "taskNamePersonalLuckyGiftGold": "Şanslı Hediyeler Göndererek Kazanılan Jetonlar",
+ "taskNameRoomOwnerMicTime": "Oda Sahibi odada mikrofona geçer",
+ "taskNamePersonalActiveInRoom": "Başkalarının Odalarında Aktif Ol",
+ "taskNamePersonalGameConsume": "Oyun Harcaması",
+ "taskNamePersonalMicInRoom": "Mikrofonu Aç",
+ "complete": "Tamamla",
+ "shareTo": "Paylaş",
+ "faceBook": "Facebook",
+ "whatsApp": "Whatsapp",
+ "snapChat": "Snapchat",
+ "dailyCoinBonanzaRulesDetail": "1. Günlük Kişisel Görevler ve Günlük Oda Sahibi Görevleri, kullanıcı başına günde bir kez tamamlanabilir. Görevler, Suudi zamanı ile 00:00:00'da sıfırlanır.\n2. Günlük kişisel görevler yalnızca başkalarının odalarında tamamlanabilir; oda sahibi görevleri yalnızca kendi odanızda tamamlanabilir.\n3. Hediye verme görevleri yalnızca odalarda gönderilen hediyeleri sayar, akışlarda gönderilen hediyeleri saymaz.\n4. Aynı cihaz veya aynı SIM kart kullanılarak birden fazla hesap oluşturulursa, tüm görevlerin ödülleri yalnızca bir kez alınabilir.",
+ "copyLink": "Bağlantıyı Kopyala",
+ "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.",
+ "getPaidToRefer": "Tavsiye Ederek Para Kazanın",
+ "theImageSizeCannotExceed": "Görsel boyutu 4M'yi geçemez",
+ "activity": "Etkinlik",
+ "alreadyAnAdministrator": "Zaten yönetici",
+ "alreadyAnMember": "Zaten üye",
+ "alreadyAnTourist": "Zaten turist",
+ "touristsCannotSendMessages": "Turistler mesaj gönderemez",
+ "touristsAreNotAllowedToGoOnTheMic": "Turistlerin mikroya çıkmasına izin verilmiyor",
+ "lockTheRoom": "Odayı Kilitle",
+ "special": "Özel",
+ "visitorList": "Ziyaretçi Listesi",
+ "successfulWear": "Başarıyla takıldı",
+ "confirmUnUseTips": "Kaldırmak için onaylıyor musunuz?",
+ "custom": "Özel",
+ "myItems": "Eşyalarım",
+ "use": "Kullan",
+ "unUse": "Kullanmama",
+ "renewal": "Yenileme",
+ "wallet": "Cüzdan",
+ "profile": "Profil",
+ "giftwall": "Hediye Duvarı",
+ "announcement": "Duyuru",
+ "blockedList": "Engellenen Liste",
+ "country2": "Ülke:",
+ "sendTo": "Gönderilecek Kişi",
+ "credits": "Krediler: {1}",
+ "successfullyUnloaded": "Başarıyla çıkarıldı",
+ "expired": "Süresi Doldu",
+ "day": "Gün",
+ "inUse": "Kullanımda",
+ "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ı.",
+ "theAccountPasswordCannotBeEmpty": "Hesap veya şifre boş olamaz.",
+ "invitesYouToTheMicrophone": "{1} seni mikroya davet ediyor",
+ "english": "İngilizce",
+ "chinese": "Çince",
+ "arabic": "Arapça",
+ "darkMode": "Karanlık Mod",
+ "lightMode": "Açık Mod",
+ "systemDefault": "Sistem Varsayılanı",
+ "pleaseGetOnTheMicFirst": "Lütfen önce mikroya çıkın.",
+ "duration2": "Süre:{1}"
+}
diff --git a/devtools_options.yaml b/devtools_options.yaml
new file mode 100644
index 0000000..e8f3dda
--- /dev/null
+++ b/devtools_options.yaml
@@ -0,0 +1,3 @@
+description: This file stores settings for Dart & Flutter DevTools.
+documentation: https://docs.flutter.dev/tools/devtools/extensions#configure-extension-enablement-states
+extensions:
diff --git a/fonts/.keep b/fonts/.keep
new file mode 100644
index 0000000..8b13789
--- /dev/null
+++ b/fonts/.keep
@@ -0,0 +1 @@
+
diff --git a/ios/.gitignore b/ios/.gitignore
new file mode 100644
index 0000000..ad322bc
--- /dev/null
+++ b/ios/.gitignore
@@ -0,0 +1,34 @@
+**/dgph
+*.mode1v3
+*.mode2v3
+*.moved-aside
+*.pbxuser
+*.perspectivev3
+**/*sync/
+.sconsign.dblite
+.tags*
+**/.vagrant/
+**/DerivedData/
+Icon?
+**/Pods/
+**/.symlinks/
+profile
+xcuserdata
+**/.generated/
+Flutter/App.framework
+Flutter/Flutter.framework
+Flutter/Flutter.podspec
+Flutter/Generated.xcconfig
+Flutter/ephemeral/
+Flutter/app.flx
+Flutter/app.zip
+Flutter/flutter_assets/
+Flutter/flutter_export_environment.sh
+ServiceDefinitions.json
+Runner/GeneratedPluginRegistrant.*
+
+# Exceptions to above rules.
+!default.mode1v3
+!default.mode2v3
+!default.pbxuser
+!default.perspectivev3
diff --git a/ios/Flutter/AppFrameworkInfo.plist b/ios/Flutter/AppFrameworkInfo.plist
new file mode 100644
index 0000000..391a902
--- /dev/null
+++ b/ios/Flutter/AppFrameworkInfo.plist
@@ -0,0 +1,24 @@
+
+
+
+
+ CFBundleDevelopmentRegion
+ en
+ CFBundleExecutable
+ App
+ CFBundleIdentifier
+ io.flutter.flutter.app
+ CFBundleInfoDictionaryVersion
+ 6.0
+ CFBundleName
+ App
+ CFBundlePackageType
+ FMWK
+ CFBundleShortVersionString
+ 1.0
+ CFBundleSignature
+ ????
+ CFBundleVersion
+ 1.0
+
+
diff --git a/ios/Flutter/Debug.xcconfig b/ios/Flutter/Debug.xcconfig
new file mode 100644
index 0000000..6ed344c
--- /dev/null
+++ b/ios/Flutter/Debug.xcconfig
@@ -0,0 +1,5 @@
+#include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"
+#include "Generated.xcconfig"
+
+APP_DISPLAY_NAME=yumi
+PRODUCT_BUNDLE_IDENTIFIER=com.org.yumi
diff --git a/ios/Flutter/Release.xcconfig b/ios/Flutter/Release.xcconfig
new file mode 100644
index 0000000..e5efcef
--- /dev/null
+++ b/ios/Flutter/Release.xcconfig
@@ -0,0 +1,5 @@
+#include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"
+#include "Generated.xcconfig"
+
+APP_DISPLAY_NAME=yumi
+PRODUCT_BUNDLE_IDENTIFIER=com.org.yumi
diff --git a/ios/Podfile b/ios/Podfile
new file mode 100644
index 0000000..a09ea13
--- /dev/null
+++ b/ios/Podfile
@@ -0,0 +1,84 @@
+# Uncomment this line to define a global platform for your project
+# platform :ios, '13.0'
+
+# CocoaPods analytics sends network stats synchronously affecting flutter build latency.
+ENV['COCOAPODS_DISABLE_STATS'] = 'true'
+
+project 'Runner', {
+ 'Debug' => :debug,
+ 'Profile' => :release,
+ 'Release' => :release,
+}
+
+def flutter_root
+ generated_xcode_build_settings_path = File.expand_path(File.join('..', 'Flutter', 'Generated.xcconfig'), __FILE__)
+ unless File.exist?(generated_xcode_build_settings_path)
+ raise "#{generated_xcode_build_settings_path} must exist. If you're running pod install manually, make sure flutter pub get is executed first"
+ end
+
+ File.foreach(generated_xcode_build_settings_path) do |line|
+ matches = line.match(/FLUTTER_ROOT\=(.*)/)
+ return matches[1].strip if matches
+ end
+ raise "FLUTTER_ROOT not found in #{generated_xcode_build_settings_path}. Try deleting Generated.xcconfig, then run flutter pub get"
+end
+
+require File.expand_path(File.join('packages', 'flutter_tools', 'bin', 'podhelper'), flutter_root)
+
+flutter_ios_podfile_setup
+
+target 'Runner' do
+ use_frameworks!
+
+ flutter_install_all_ios_pods File.dirname(File.realpath(__FILE__))
+ target 'RunnerTests' do
+ inherit! :search_paths
+ end
+end
+
+post_install do |installer|
+ installer.pods_project.targets.each do |target|
+ flutter_additional_ios_build_settings(target)
+
+ target.build_configurations.each do |config|
+ # 这里的配置会告诉编译器在编译时剔除未使用的权限代码
+ config.build_settings['GCC_PREPROCESSOR_DEFINITIONS'] ||= [
+ '$(inherited)',
+
+ ## 1. 禁用 日历 (NSCalendarsUsageDescription)
+ 'PERMISSION_EVENTS=0',
+ 'PERMISSION_EVENTS_FULL_ACCESS=0',
+
+ ## 2. 禁用 提醒事项
+ 'PERMISSION_REMINDERS=0',
+
+ ## 3. 禁用 通讯录 (NSContactsUsageDescription)
+ 'PERMISSION_CONTACTS=0',
+
+ ## 4. 禁用 语音识别 (NSSpeechRecognitionUsageDescription)
+ 'PERMISSION_SPEECH_RECOGNIZER=0',
+
+ ## 5. 禁用 运动与健身 (NSMotionUsageDescription)
+ 'PERMISSION_SENSORS=0',
+
+ ## 6. 禁用 Siri/助手 (NSSiriUsageDescription)
+ 'PERMISSION_ASSISTANT=0',
+
+ ## 7. 禁用 媒体库 (NSAppleMusicUsageDescription)
+ 'PERMISSION_MEDIA_LIBRARY=1',
+
+ ## 8. 禁用 蓝牙 (如果你没用到蓝牙,建议也关掉)
+ 'PERMISSION_BLUETOOTH=0',
+
+ ## --- 以下是建议保留的常见权限 (设为 1),如果你的 App 也没用到,也可以改为 0 ---
+ 'PERMISSION_CAMERA=1',
+ 'PERMISSION_MICROPHONE=1',
+ 'PERMISSION_PHOTOS=1',
+ 'PERMISSION_LOCATION=0',
+ 'PERMISSION_NOTIFICATIONS=1',
+ 'PERMISSION_APP_TRACKING_TRANSPARENCY=0',
+ 'PERMISSION_CRITICAL_ALERTS=0',
+ ]
+ end
+ end
+end
diff --git a/ios/Podfile.lock b/ios/Podfile.lock
new file mode 100644
index 0000000..eae30da
--- /dev/null
+++ b/ios/Podfile.lock
@@ -0,0 +1,498 @@
+PODS:
+ - agora_rtc_engine (6.5.3):
+ - AgoraIrisRTC_iOS (= 4.5.2-build.1)
+ - AgoraRtcEngine_iOS (= 4.5.2)
+ - Flutter
+ - AgoraInfra_iOS (1.2.13.1)
+ - AgoraIrisRTC_iOS (4.5.2-build.1)
+ - AgoraRtcEngine_iOS (4.5.2):
+ - AgoraRtcEngine_iOS/AIAEC (= 4.5.2)
+ - AgoraRtcEngine_iOS/AIAECLL (= 4.5.2)
+ - AgoraRtcEngine_iOS/AINS (= 4.5.2)
+ - AgoraRtcEngine_iOS/AINSLL (= 4.5.2)
+ - AgoraRtcEngine_iOS/AudioBeauty (= 4.5.2)
+ - AgoraRtcEngine_iOS/ClearVision (= 4.5.2)
+ - AgoraRtcEngine_iOS/ContentInspect (= 4.5.2)
+ - AgoraRtcEngine_iOS/FaceCapture (= 4.5.2)
+ - AgoraRtcEngine_iOS/FaceDetection (= 4.5.2)
+ - AgoraRtcEngine_iOS/LipSync (= 4.5.2)
+ - AgoraRtcEngine_iOS/ReplayKit (= 4.5.2)
+ - AgoraRtcEngine_iOS/RtcBasic (= 4.5.2)
+ - AgoraRtcEngine_iOS/SpatialAudio (= 4.5.2)
+ - AgoraRtcEngine_iOS/VideoAv1CodecDec (= 4.5.2)
+ - AgoraRtcEngine_iOS/VideoAv1CodecEnc (= 4.5.2)
+ - AgoraRtcEngine_iOS/VideoCodecDec (= 4.5.2)
+ - AgoraRtcEngine_iOS/VideoCodecEnc (= 4.5.2)
+ - AgoraRtcEngine_iOS/VirtualBackground (= 4.5.2)
+ - AgoraRtcEngine_iOS/VQA (= 4.5.2)
+ - AgoraRtcEngine_iOS/AIAEC (4.5.2)
+ - AgoraRtcEngine_iOS/AIAECLL (4.5.2)
+ - AgoraRtcEngine_iOS/AINS (4.5.2)
+ - AgoraRtcEngine_iOS/AINSLL (4.5.2)
+ - AgoraRtcEngine_iOS/AudioBeauty (4.5.2)
+ - AgoraRtcEngine_iOS/ClearVision (4.5.2)
+ - AgoraRtcEngine_iOS/ContentInspect (4.5.2)
+ - AgoraRtcEngine_iOS/FaceCapture (4.5.2)
+ - AgoraRtcEngine_iOS/FaceDetection (4.5.2)
+ - AgoraRtcEngine_iOS/LipSync (4.5.2)
+ - AgoraRtcEngine_iOS/ReplayKit (4.5.2)
+ - AgoraRtcEngine_iOS/RtcBasic (4.5.2):
+ - AgoraInfra_iOS (= 1.2.13.1)
+ - AgoraRtcEngine_iOS/SpatialAudio (4.5.2)
+ - AgoraRtcEngine_iOS/VideoAv1CodecDec (4.5.2)
+ - AgoraRtcEngine_iOS/VideoAv1CodecEnc (4.5.2)
+ - AgoraRtcEngine_iOS/VideoCodecDec (4.5.2)
+ - AgoraRtcEngine_iOS/VideoCodecEnc (4.5.2)
+ - AgoraRtcEngine_iOS/VirtualBackground (4.5.2)
+ - AgoraRtcEngine_iOS/VQA (4.5.2)
+ - app_links (6.4.1):
+ - Flutter
+ - AppAuth (1.7.6):
+ - AppAuth/Core (= 1.7.6)
+ - AppAuth/ExternalUserAgent (= 1.7.6)
+ - AppAuth/Core (1.7.6)
+ - AppAuth/ExternalUserAgent (1.7.6):
+ - AppAuth/Core
+ - AppCheckCore (11.2.0):
+ - GoogleUtilities/Environment (~> 8.0)
+ - GoogleUtilities/UserDefaults (~> 8.0)
+ - PromisesObjC (~> 2.4)
+ - audioplayers_darwin (0.0.1):
+ - Flutter
+ - FlutterMacOS
+ - device_info_plus (0.0.1):
+ - Flutter
+ - Firebase/Auth (11.15.0):
+ - Firebase/CoreOnly
+ - FirebaseAuth (~> 11.15.0)
+ - Firebase/CoreOnly (11.15.0):
+ - FirebaseCore (~> 11.15.0)
+ - Firebase/Crashlytics (11.15.0):
+ - Firebase/CoreOnly
+ - FirebaseCrashlytics (~> 11.15.0)
+ - firebase_auth (5.7.0):
+ - Firebase/Auth (= 11.15.0)
+ - firebase_core
+ - Flutter
+ - firebase_core (3.15.2):
+ - Firebase/CoreOnly (= 11.15.0)
+ - Flutter
+ - firebase_crashlytics (4.3.10):
+ - Firebase/Crashlytics (= 11.15.0)
+ - firebase_core
+ - Flutter
+ - FirebaseAppCheckInterop (11.15.0)
+ - FirebaseAuth (11.15.0):
+ - FirebaseAppCheckInterop (~> 11.0)
+ - FirebaseAuthInterop (~> 11.0)
+ - FirebaseCore (~> 11.15.0)
+ - FirebaseCoreExtension (~> 11.15.0)
+ - GoogleUtilities/AppDelegateSwizzler (~> 8.1)
+ - GoogleUtilities/Environment (~> 8.1)
+ - GTMSessionFetcher/Core (< 5.0, >= 3.4)
+ - RecaptchaInterop (~> 101.0)
+ - FirebaseAuthInterop (11.15.0)
+ - FirebaseCore (11.15.0):
+ - FirebaseCoreInternal (~> 11.15.0)
+ - GoogleUtilities/Environment (~> 8.1)
+ - GoogleUtilities/Logger (~> 8.1)
+ - FirebaseCoreExtension (11.15.0):
+ - FirebaseCore (~> 11.15.0)
+ - FirebaseCoreInternal (11.15.0):
+ - "GoogleUtilities/NSData+zlib (~> 8.1)"
+ - FirebaseCrashlytics (11.15.0):
+ - FirebaseCore (~> 11.15.0)
+ - FirebaseInstallations (~> 11.0)
+ - FirebaseRemoteConfigInterop (~> 11.0)
+ - FirebaseSessions (~> 11.0)
+ - GoogleDataTransport (~> 10.0)
+ - GoogleUtilities/Environment (~> 8.1)
+ - nanopb (~> 3.30910.0)
+ - PromisesObjC (~> 2.4)
+ - FirebaseInstallations (11.15.0):
+ - FirebaseCore (~> 11.15.0)
+ - GoogleUtilities/Environment (~> 8.1)
+ - GoogleUtilities/UserDefaults (~> 8.1)
+ - PromisesObjC (~> 2.4)
+ - FirebaseRemoteConfigInterop (11.15.0)
+ - FirebaseSessions (11.15.0):
+ - FirebaseCore (~> 11.15.0)
+ - FirebaseCoreExtension (~> 11.15.0)
+ - FirebaseInstallations (~> 11.0)
+ - GoogleDataTransport (~> 10.0)
+ - GoogleUtilities/Environment (~> 8.1)
+ - GoogleUtilities/UserDefaults (~> 8.1)
+ - nanopb (~> 3.30910.0)
+ - PromisesSwift (~> 2.1)
+ - Flutter (1.0.0)
+ - flutter_foreground_task (0.0.1):
+ - Flutter
+ - flutter_image_compress_common (1.0.0):
+ - Flutter
+ - Mantle
+ - SDWebImage
+ - SDWebImageWebPCoder
+ - flutter_inappwebview_ios (0.0.1):
+ - Flutter
+ - flutter_inappwebview_ios/Core (= 0.0.1)
+ - OrderedSet (~> 6.0.3)
+ - flutter_inappwebview_ios/Core (0.0.1):
+ - Flutter
+ - OrderedSet (~> 6.0.3)
+ - fluttertoast (0.0.2):
+ - Flutter
+ - google_sign_in_ios (0.0.1):
+ - AppAuth (>= 1.7.4)
+ - Flutter
+ - FlutterMacOS
+ - GoogleSignIn (~> 8.0)
+ - GTMSessionFetcher (>= 3.4.0)
+ - GoogleDataTransport (10.1.0):
+ - nanopb (~> 3.30910.0)
+ - PromisesObjC (~> 2.4)
+ - GoogleSignIn (8.0.0):
+ - AppAuth (< 2.0, >= 1.7.3)
+ - AppCheckCore (~> 11.0)
+ - GTMAppAuth (< 5.0, >= 4.1.1)
+ - GTMSessionFetcher/Core (~> 3.3)
+ - GoogleUtilities/AppDelegateSwizzler (8.1.0):
+ - GoogleUtilities/Environment
+ - GoogleUtilities/Logger
+ - GoogleUtilities/Network
+ - GoogleUtilities/Privacy
+ - GoogleUtilities/Environment (8.1.0):
+ - GoogleUtilities/Privacy
+ - GoogleUtilities/Logger (8.1.0):
+ - GoogleUtilities/Environment
+ - GoogleUtilities/Privacy
+ - GoogleUtilities/Network (8.1.0):
+ - GoogleUtilities/Logger
+ - "GoogleUtilities/NSData+zlib"
+ - GoogleUtilities/Privacy
+ - GoogleUtilities/Reachability
+ - "GoogleUtilities/NSData+zlib (8.1.0)":
+ - GoogleUtilities/Privacy
+ - GoogleUtilities/Privacy (8.1.0)
+ - GoogleUtilities/Reachability (8.1.0):
+ - GoogleUtilities/Logger
+ - GoogleUtilities/Privacy
+ - GoogleUtilities/UserDefaults (8.1.0):
+ - GoogleUtilities/Logger
+ - GoogleUtilities/Privacy
+ - GTMAppAuth (4.1.1):
+ - AppAuth/Core (~> 1.7)
+ - GTMSessionFetcher/Core (< 4.0, >= 3.3)
+ - GTMSessionFetcher (3.5.0):
+ - GTMSessionFetcher/Full (= 3.5.0)
+ - GTMSessionFetcher/Core (3.5.0)
+ - GTMSessionFetcher/Full (3.5.0):
+ - GTMSessionFetcher/Core
+ - HydraAsync (2.0.6)
+ - image_cropper (0.0.4):
+ - Flutter
+ - TOCropViewController (~> 2.6.1)
+ - image_picker_ios (0.0.1):
+ - Flutter
+ - in_app_purchase_storekit (0.0.1):
+ - Flutter
+ - FlutterMacOS
+ - iris_method_channel (0.0.1):
+ - Flutter
+ - libwebp (1.5.0):
+ - libwebp/demux (= 1.5.0)
+ - libwebp/mux (= 1.5.0)
+ - libwebp/sharpyuv (= 1.5.0)
+ - libwebp/webp (= 1.5.0)
+ - libwebp/demux (1.5.0):
+ - libwebp/webp
+ - libwebp/mux (1.5.0):
+ - libwebp/demux
+ - libwebp/sharpyuv (1.5.0)
+ - libwebp/webp (1.5.0):
+ - libwebp/sharpyuv
+ - loading_indicator_view_plus (0.0.1):
+ - Flutter
+ - Mantle (2.2.0):
+ - Mantle/extobjc (= 2.2.0)
+ - Mantle/extobjc (2.2.0)
+ - nanopb (3.30910.0):
+ - nanopb/decode (= 3.30910.0)
+ - nanopb/encode (= 3.30910.0)
+ - nanopb/decode (3.30910.0)
+ - nanopb/encode (3.30910.0)
+ - on_audio_query_ios (0.0.1):
+ - Flutter
+ - SwiftyBeaver
+ - OrderedSet (6.0.3)
+ - package_info_plus (0.4.5):
+ - Flutter
+ - path_provider_foundation (0.0.1):
+ - Flutter
+ - FlutterMacOS
+ - permission_handler_apple (9.3.0):
+ - Flutter
+ - PromisesObjC (2.4.0)
+ - PromisesSwift (2.4.0):
+ - PromisesObjC (= 2.4.0)
+ - QGVAPlayer (1.0.19)
+ - RecaptchaInterop (101.0.0)
+ - SDWebImage (5.21.7):
+ - SDWebImage/Core (= 5.21.7)
+ - SDWebImage/Core (5.21.7)
+ - SDWebImageWebPCoder (0.15.0):
+ - libwebp (~> 1.0)
+ - SDWebImage/Core (~> 5.17)
+ - shared_preferences_foundation (0.0.1):
+ - Flutter
+ - FlutterMacOS
+ - sign_in_with_apple (0.0.1):
+ - Flutter
+ - social_sharing_plus (0.0.1):
+ - Flutter
+ - sqflite_darwin (0.0.4):
+ - Flutter
+ - FlutterMacOS
+ - store_redirect (0.0.1):
+ - Flutter
+ - SwiftyBeaver (1.9.5)
+ - tancent_vap (0.0.1):
+ - Flutter
+ - QGVAPlayer (= 1.0.19)
+ - tencent_cloud_chat_sdk (8.0.0):
+ - Flutter
+ - HydraAsync
+ - TXIMSDK_Plus_iOS_XCFramework (= 8.3.6498)
+ - TOCropViewController (2.6.1)
+ - TXIMSDK_Plus_iOS_XCFramework (8.3.6498)
+ - url_launcher_ios (0.0.1):
+ - Flutter
+ - video_player_avfoundation (0.0.1):
+ - Flutter
+ - FlutterMacOS
+ - video_thumbnail (0.0.1):
+ - Flutter
+ - libwebp
+ - wakelock_plus (0.0.1):
+ - Flutter
+ - webview_flutter_wkwebview (0.0.1):
+ - Flutter
+ - FlutterMacOS
+
+DEPENDENCIES:
+ - agora_rtc_engine (from `.symlinks/plugins/agora_rtc_engine/ios`)
+ - app_links (from `.symlinks/plugins/app_links/ios`)
+ - audioplayers_darwin (from `.symlinks/plugins/audioplayers_darwin/darwin`)
+ - device_info_plus (from `.symlinks/plugins/device_info_plus/ios`)
+ - firebase_auth (from `.symlinks/plugins/firebase_auth/ios`)
+ - firebase_core (from `.symlinks/plugins/firebase_core/ios`)
+ - firebase_crashlytics (from `.symlinks/plugins/firebase_crashlytics/ios`)
+ - Flutter (from `Flutter`)
+ - flutter_foreground_task (from `.symlinks/plugins/flutter_foreground_task/ios`)
+ - flutter_image_compress_common (from `.symlinks/plugins/flutter_image_compress_common/ios`)
+ - flutter_inappwebview_ios (from `.symlinks/plugins/flutter_inappwebview_ios/ios`)
+ - fluttertoast (from `.symlinks/plugins/fluttertoast/ios`)
+ - google_sign_in_ios (from `.symlinks/plugins/google_sign_in_ios/darwin`)
+ - image_cropper (from `.symlinks/plugins/image_cropper/ios`)
+ - image_picker_ios (from `.symlinks/plugins/image_picker_ios/ios`)
+ - in_app_purchase_storekit (from `.symlinks/plugins/in_app_purchase_storekit/darwin`)
+ - iris_method_channel (from `.symlinks/plugins/iris_method_channel/ios`)
+ - loading_indicator_view_plus (from `.symlinks/plugins/loading_indicator_view_plus/ios`)
+ - on_audio_query_ios (from `.symlinks/plugins/on_audio_query_ios/ios`)
+ - package_info_plus (from `.symlinks/plugins/package_info_plus/ios`)
+ - path_provider_foundation (from `.symlinks/plugins/path_provider_foundation/darwin`)
+ - permission_handler_apple (from `.symlinks/plugins/permission_handler_apple/ios`)
+ - shared_preferences_foundation (from `.symlinks/plugins/shared_preferences_foundation/darwin`)
+ - sign_in_with_apple (from `.symlinks/plugins/sign_in_with_apple/ios`)
+ - social_sharing_plus (from `.symlinks/plugins/social_sharing_plus/ios`)
+ - sqflite_darwin (from `.symlinks/plugins/sqflite_darwin/darwin`)
+ - store_redirect (from `.symlinks/plugins/store_redirect/ios`)
+ - tancent_vap (from `.symlinks/plugins/tancent_vap/ios`)
+ - tencent_cloud_chat_sdk (from `.symlinks/plugins/tencent_cloud_chat_sdk/ios`)
+ - url_launcher_ios (from `.symlinks/plugins/url_launcher_ios/ios`)
+ - video_player_avfoundation (from `.symlinks/plugins/video_player_avfoundation/darwin`)
+ - video_thumbnail (from `.symlinks/plugins/video_thumbnail/ios`)
+ - wakelock_plus (from `.symlinks/plugins/wakelock_plus/ios`)
+ - webview_flutter_wkwebview (from `.symlinks/plugins/webview_flutter_wkwebview/darwin`)
+
+SPEC REPOS:
+ trunk:
+ - AgoraInfra_iOS
+ - AgoraIrisRTC_iOS
+ - AgoraRtcEngine_iOS
+ - AppAuth
+ - AppCheckCore
+ - Firebase
+ - FirebaseAppCheckInterop
+ - FirebaseAuth
+ - FirebaseAuthInterop
+ - FirebaseCore
+ - FirebaseCoreExtension
+ - FirebaseCoreInternal
+ - FirebaseCrashlytics
+ - FirebaseInstallations
+ - FirebaseRemoteConfigInterop
+ - FirebaseSessions
+ - GoogleDataTransport
+ - GoogleSignIn
+ - GoogleUtilities
+ - GTMAppAuth
+ - GTMSessionFetcher
+ - HydraAsync
+ - libwebp
+ - Mantle
+ - nanopb
+ - OrderedSet
+ - PromisesObjC
+ - PromisesSwift
+ - QGVAPlayer
+ - RecaptchaInterop
+ - SDWebImage
+ - SDWebImageWebPCoder
+ - SwiftyBeaver
+ - TOCropViewController
+ - TXIMSDK_Plus_iOS_XCFramework
+
+EXTERNAL SOURCES:
+ agora_rtc_engine:
+ :path: ".symlinks/plugins/agora_rtc_engine/ios"
+ app_links:
+ :path: ".symlinks/plugins/app_links/ios"
+ audioplayers_darwin:
+ :path: ".symlinks/plugins/audioplayers_darwin/darwin"
+ device_info_plus:
+ :path: ".symlinks/plugins/device_info_plus/ios"
+ firebase_auth:
+ :path: ".symlinks/plugins/firebase_auth/ios"
+ firebase_core:
+ :path: ".symlinks/plugins/firebase_core/ios"
+ firebase_crashlytics:
+ :path: ".symlinks/plugins/firebase_crashlytics/ios"
+ Flutter:
+ :path: Flutter
+ flutter_foreground_task:
+ :path: ".symlinks/plugins/flutter_foreground_task/ios"
+ flutter_image_compress_common:
+ :path: ".symlinks/plugins/flutter_image_compress_common/ios"
+ flutter_inappwebview_ios:
+ :path: ".symlinks/plugins/flutter_inappwebview_ios/ios"
+ fluttertoast:
+ :path: ".symlinks/plugins/fluttertoast/ios"
+ google_sign_in_ios:
+ :path: ".symlinks/plugins/google_sign_in_ios/darwin"
+ image_cropper:
+ :path: ".symlinks/plugins/image_cropper/ios"
+ image_picker_ios:
+ :path: ".symlinks/plugins/image_picker_ios/ios"
+ in_app_purchase_storekit:
+ :path: ".symlinks/plugins/in_app_purchase_storekit/darwin"
+ iris_method_channel:
+ :path: ".symlinks/plugins/iris_method_channel/ios"
+ loading_indicator_view_plus:
+ :path: ".symlinks/plugins/loading_indicator_view_plus/ios"
+ on_audio_query_ios:
+ :path: ".symlinks/plugins/on_audio_query_ios/ios"
+ package_info_plus:
+ :path: ".symlinks/plugins/package_info_plus/ios"
+ path_provider_foundation:
+ :path: ".symlinks/plugins/path_provider_foundation/darwin"
+ permission_handler_apple:
+ :path: ".symlinks/plugins/permission_handler_apple/ios"
+ shared_preferences_foundation:
+ :path: ".symlinks/plugins/shared_preferences_foundation/darwin"
+ sign_in_with_apple:
+ :path: ".symlinks/plugins/sign_in_with_apple/ios"
+ social_sharing_plus:
+ :path: ".symlinks/plugins/social_sharing_plus/ios"
+ sqflite_darwin:
+ :path: ".symlinks/plugins/sqflite_darwin/darwin"
+ store_redirect:
+ :path: ".symlinks/plugins/store_redirect/ios"
+ tancent_vap:
+ :path: ".symlinks/plugins/tancent_vap/ios"
+ tencent_cloud_chat_sdk:
+ :path: ".symlinks/plugins/tencent_cloud_chat_sdk/ios"
+ url_launcher_ios:
+ :path: ".symlinks/plugins/url_launcher_ios/ios"
+ video_player_avfoundation:
+ :path: ".symlinks/plugins/video_player_avfoundation/darwin"
+ video_thumbnail:
+ :path: ".symlinks/plugins/video_thumbnail/ios"
+ wakelock_plus:
+ :path: ".symlinks/plugins/wakelock_plus/ios"
+ webview_flutter_wkwebview:
+ :path: ".symlinks/plugins/webview_flutter_wkwebview/darwin"
+
+SPEC CHECKSUMS:
+ agora_rtc_engine: 0c7d50312967c4dc31c3c45e50589ce48f57e08a
+ AgoraInfra_iOS: 3691b2b277a1712a35ae96de25af319de0d73d08
+ AgoraIrisRTC_iOS: eab58c126439adf5ec99632828a558ea216860da
+ AgoraRtcEngine_iOS: 97e2398a2addda9057815a2a583a658e36796ff6
+ app_links: 3dbc685f76b1693c66a6d9dd1e9ab6f73d97dc0a
+ AppAuth: d4f13a8fe0baf391b2108511793e4b479691fb73
+ AppCheckCore: cc8fd0a3a230ddd401f326489c99990b013f0c4f
+ audioplayers_darwin: 835ced6edd4c9fc8ebb0a7cc9e294a91d99917d5
+ device_info_plus: 71ffc6ab7634ade6267c7a93088ed7e4f74e5896
+ Firebase: d99ac19b909cd2c548339c2241ecd0d1599ab02e
+ firebase_auth: 50af8366c87bb88c80ebeae62eb60189c7246b9b
+ firebase_core: 995454a784ff288be5689b796deb9e9fa3601818
+ firebase_crashlytics: 30dcd6dfd2fe895c0848af46722a4227346c19aa
+ FirebaseAppCheckInterop: 06fe5a3799278ae4667e6c432edd86b1030fa3df
+ FirebaseAuth: a6575e5fbf46b046c58dc211a28a5fbdd8d4c83b
+ FirebaseAuthInterop: 7087d7a4ee4bc4de019b2d0c240974ed5d89e2fd
+ FirebaseCore: efb3893e5b94f32b86e331e3bd6dadf18b66568e
+ FirebaseCoreExtension: edbd30474b5ccf04e5f001470bdf6ea616af2435
+ FirebaseCoreInternal: 9afa45b1159304c963da48addb78275ef701c6b4
+ FirebaseCrashlytics: e09d0bc19aa54a51e45b8039c836ef73f32c039a
+ FirebaseInstallations: 317270fec08a5d418fdbc8429282238cab3ac843
+ FirebaseRemoteConfigInterop: 1c6135e8a094cc6368949f5faeeca7ee8948b8aa
+ FirebaseSessions: b9a92c1c51bbb81e78fc3142cda6d925d700f8e7
+ Flutter: cabc95a1d2626b1b06e7179b784ebcf0c0cde467
+ flutter_foreground_task: a159d2c2173b33699ddb3e6c2a067045d7cebb89
+ flutter_image_compress_common: 1697a328fd72bfb335507c6bca1a65fa5ad87df1
+ flutter_inappwebview_ios: b89ba3482b96fb25e00c967aae065701b66e9b99
+ fluttertoast: 2c67e14dce98bbdb200df9e1acf610d7a6264ea1
+ google_sign_in_ios: b48bb9af78576358a168361173155596c845f0b9
+ GoogleDataTransport: aae35b7ea0c09004c3797d53c8c41f66f219d6a7
+ GoogleSignIn: ce8c89bb9b37fb624b92e7514cc67335d1e277e4
+ GoogleUtilities: 00c88b9a86066ef77f0da2fab05f65d7768ed8e1
+ GTMAppAuth: f69bd07d68cd3b766125f7e072c45d7340dea0de
+ GTMSessionFetcher: 5aea5ba6bd522a239e236100971f10cb71b96ab6
+ HydraAsync: 8d589bd725b0224f899afafc9a396327405f8063
+ image_cropper: 655b3ba703c9e15e3111e79151624d6154288774
+ image_picker_ios: 7fe1ff8e34c1790d6fff70a32484959f563a928a
+ in_app_purchase_storekit: d1a48cb0f8b29dbf5f85f782f5dd79b21b90a5e6
+ iris_method_channel: 7d661cf3259b3009ae423508470dbeb9374446ee
+ libwebp: 02b23773aedb6ff1fd38cec7a77b81414c6842a8
+ loading_indicator_view_plus: 33a5d3527e9c6a7b470c79878613d01c4fa1fb65
+ Mantle: c5aa8794a29a022dfbbfc9799af95f477a69b62d
+ nanopb: fad817b59e0457d11a5dfbde799381cd727c1275
+ on_audio_query_ios: 28a780e2d0d85d92d500ba6e12c6c8167022b2fa
+ OrderedSet: e539b66b644ff081c73a262d24ad552a69be3a94
+ package_info_plus: af8e2ca6888548050f16fa2f1938db7b5a5df499
+ path_provider_foundation: 080d55be775b7414fd5a5ef3ac137b97b097e564
+ permission_handler_apple: 4ed2196e43d0651e8ff7ca3483a069d469701f2d
+ PromisesObjC: f5707f49cb48b9636751c5b2e7d227e43fba9f47
+ PromisesSwift: 9d77319bbe72ebf6d872900551f7eeba9bce2851
+ QGVAPlayer: a0bca68c9bd6f1c8de5ac2d10ddf98be6038cce9
+ RecaptchaInterop: 11e0b637842dfb48308d242afc3f448062325aba
+ SDWebImage: e9fc87c1aab89a8ab1bbd74eba378c6f53be8abf
+ SDWebImageWebPCoder: 0e06e365080397465cc73a7a9b472d8a3bd0f377
+ shared_preferences_foundation: 9e1978ff2562383bd5676f64ec4e9aa8fa06a6f7
+ sign_in_with_apple: c5dcc141574c8c54d5ac99dd2163c0c72ad22418
+ social_sharing_plus: e6024862e5a4be59ef8c97a93558cba1043628bf
+ sqflite_darwin: 20b2a3a3b70e43edae938624ce550a3cbf66a3d0
+ store_redirect: 55fd455802ceab09803b2df6e68f19a58815266a
+ SwiftyBeaver: 84069991dd5dca07d7069100985badaca7f0ce82
+ tancent_vap: 4917210cc7e916023fd112655170d8e3d074f482
+ tencent_cloud_chat_sdk: 55e5fffe20f6b7937a26a674ccccb639563a9790
+ TOCropViewController: edfd4f25713d56905ad1e0b9f5be3fbe0f59c863
+ TXIMSDK_Plus_iOS_XCFramework: 5d1933192fb3b7ef2fe933f1623de4a0486a7fe2
+ url_launcher_ios: 694010445543906933d732453a59da0a173ae33d
+ video_player_avfoundation: 2cef49524dd1f16c5300b9cd6efd9611ce03639b
+ video_thumbnail: b637e0ad5f588ca9945f6e2c927f73a69a661140
+ wakelock_plus: e29112ab3ef0b318e58cfa5c32326458be66b556
+ webview_flutter_wkwebview: 1821ceac936eba6f7984d89a9f3bcb4dea99ebb2
+
+PODFILE CHECKSUM: a6f49a93e5f85201a2efdadcd7cf184b0e310894
+
+COCOAPODS: 1.16.2
diff --git a/ios/Runner.xcodeproj/project.pbxproj b/ios/Runner.xcodeproj/project.pbxproj
new file mode 100644
index 0000000..76f33f6
--- /dev/null
+++ b/ios/Runner.xcodeproj/project.pbxproj
@@ -0,0 +1,780 @@
+// !$*UTF8*$!
+{
+ archiveVersion = 1;
+ classes = {
+ };
+ objectVersion = 54;
+ objects = {
+
+/* Begin PBXBuildFile section */
+ 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */; };
+ 331C808B294A63AB00263BE5 /* RunnerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 331C807B294A618700263BE5 /* RunnerTests.swift */; };
+ 3AA5D06ED1878042C8461CFA /* Pods_Runner.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 5787BE1D8BF9BB6960F7B587 /* Pods_Runner.framework */; };
+ 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; };
+ 46D37906416913B201350BFF /* Pods_RunnerTests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D8CD6B2D6477A38E56A72C61 /* Pods_RunnerTests.framework */; };
+ 525B8C722ED013520007B725 /* GoogleService-Info.plist in Resources */ = {isa = PBXBuildFile; fileRef = 525B8C712ED013520007B725 /* GoogleService-Info.plist */; };
+ 52DF38A12F110B0B0086FBE4 /* StoreKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 52DF38A02F110B0B0086FBE4 /* StoreKit.framework */; };
+ 74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 74858FAE1ED2DC5600515810 /* AppDelegate.swift */; };
+ 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FA1CF9000F007C117D /* Main.storyboard */; };
+ 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FD1CF9000F007C117D /* Assets.xcassets */; };
+ 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */; };
+/* End PBXBuildFile section */
+
+/* Begin PBXContainerItemProxy section */
+ 331C8085294A63A400263BE5 /* PBXContainerItemProxy */ = {
+ isa = PBXContainerItemProxy;
+ containerPortal = 97C146E61CF9000F007C117D /* Project object */;
+ proxyType = 1;
+ remoteGlobalIDString = 97C146ED1CF9000F007C117D;
+ remoteInfo = Runner;
+ };
+/* End PBXContainerItemProxy section */
+
+/* Begin PBXCopyFilesBuildPhase section */
+ 9705A1C41CF9048500538489 /* Embed Frameworks */ = {
+ isa = PBXCopyFilesBuildPhase;
+ buildActionMask = 2147483647;
+ dstPath = "";
+ dstSubfolderSpec = 10;
+ files = (
+ );
+ name = "Embed Frameworks";
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXCopyFilesBuildPhase section */
+
+/* Begin PBXFileReference section */
+ 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GeneratedPluginRegistrant.h; sourceTree = ""; };
+ 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = ""; };
+ 2DBA1462EA0F13259D54391C /* Pods-RunnerTests.profile.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RunnerTests.profile.xcconfig"; path = "Target Support Files/Pods-RunnerTests/Pods-RunnerTests.profile.xcconfig"; sourceTree = ""; };
+ 3144A376A151695EA2D1A4FE /* Pods-RunnerTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RunnerTests.debug.xcconfig"; path = "Target Support Files/Pods-RunnerTests/Pods-RunnerTests.debug.xcconfig"; sourceTree = ""; };
+ 331C807B294A618700263BE5 /* RunnerTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RunnerTests.swift; sourceTree = ""; };
+ 331C8081294A63A400263BE5 /* RunnerTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = RunnerTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
+ 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = ""; };
+ 3E47BBEC2076B0DEF3312C28 /* Pods-Runner.profile.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.profile.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.profile.xcconfig"; sourceTree = ""; };
+ 525B8C712ED013520007B725 /* GoogleService-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "GoogleService-Info.plist"; sourceTree = ""; };
+ 52DF389D2F0E79020086FBE4 /* RunnerDebug.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = RunnerDebug.entitlements; sourceTree = ""; };
+ 52DF38A02F110B0B0086FBE4 /* StoreKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = StoreKit.framework; path = System/Library/Frameworks/StoreKit.framework; sourceTree = SDKROOT; };
+ 52DF38A22F110EC10086FBE4 /* RunnerRelease.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = RunnerRelease.entitlements; sourceTree = ""; };
+ 5787BE1D8BF9BB6960F7B587 /* Pods_Runner.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Runner.framework; sourceTree = BUILT_PRODUCTS_DIR; };
+ 628A4C79D49FE8929E845244 /* Pods-RunnerTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RunnerTests.release.xcconfig"; path = "Target Support Files/Pods-RunnerTests/Pods-RunnerTests.release.xcconfig"; sourceTree = ""; };
+ 6FE5DAD7939E244362D1F7DA /* Pods-Runner.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.release.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"; sourceTree = ""; };
+ 7147A3F76DA0C2CFC820ED1C /* Pods-Runner.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.debug.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"; sourceTree = ""; };
+ 74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Runner-Bridging-Header.h"; sourceTree = ""; };
+ 74858FAE1ED2DC5600515810 /* AppDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; };
+ 7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = ""; };
+ 9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Debug.xcconfig; path = Flutter/Debug.xcconfig; sourceTree = ""; };
+ 9740EEB31CF90195004384FC /* Generated.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Generated.xcconfig; path = Flutter/Generated.xcconfig; sourceTree = ""; };
+ 97C146EE1CF9000F007C117D /* Runner.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Runner.app; sourceTree = BUILT_PRODUCTS_DIR; };
+ 97C146FB1CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; };
+ 97C146FD1CF9000F007C117D /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; };
+ 97C147001CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; };
+ 97C147021CF9000F007C117D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; };
+ D8CD6B2D6477A38E56A72C61 /* Pods_RunnerTests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_RunnerTests.framework; sourceTree = BUILT_PRODUCTS_DIR; };
+/* End PBXFileReference section */
+
+/* Begin PBXFrameworksBuildPhase section */
+ 97C146EB1CF9000F007C117D /* Frameworks */ = {
+ isa = PBXFrameworksBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ 52DF38A12F110B0B0086FBE4 /* StoreKit.framework in Frameworks */,
+ 3AA5D06ED1878042C8461CFA /* Pods_Runner.framework in Frameworks */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ A0E84D3ADAE5F6DDD480F35D /* Frameworks */ = {
+ isa = PBXFrameworksBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ 46D37906416913B201350BFF /* Pods_RunnerTests.framework in Frameworks */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXFrameworksBuildPhase section */
+
+/* Begin PBXGroup section */
+ 03AFDC00C5136405689DA84C /* Frameworks */ = {
+ isa = PBXGroup;
+ children = (
+ 52DF38A02F110B0B0086FBE4 /* StoreKit.framework */,
+ 5787BE1D8BF9BB6960F7B587 /* Pods_Runner.framework */,
+ D8CD6B2D6477A38E56A72C61 /* Pods_RunnerTests.framework */,
+ );
+ name = Frameworks;
+ sourceTree = "";
+ };
+ 331C8082294A63A400263BE5 /* RunnerTests */ = {
+ isa = PBXGroup;
+ children = (
+ 331C807B294A618700263BE5 /* RunnerTests.swift */,
+ );
+ path = RunnerTests;
+ sourceTree = "";
+ };
+ 3B8051ED51CBDB3CF1DF0F5B /* Pods */ = {
+ isa = PBXGroup;
+ children = (
+ 7147A3F76DA0C2CFC820ED1C /* Pods-Runner.debug.xcconfig */,
+ 6FE5DAD7939E244362D1F7DA /* Pods-Runner.release.xcconfig */,
+ 3E47BBEC2076B0DEF3312C28 /* Pods-Runner.profile.xcconfig */,
+ 3144A376A151695EA2D1A4FE /* Pods-RunnerTests.debug.xcconfig */,
+ 628A4C79D49FE8929E845244 /* Pods-RunnerTests.release.xcconfig */,
+ 2DBA1462EA0F13259D54391C /* Pods-RunnerTests.profile.xcconfig */,
+ );
+ path = Pods;
+ sourceTree = "";
+ };
+ 9740EEB11CF90186004384FC /* Flutter */ = {
+ isa = PBXGroup;
+ children = (
+ 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */,
+ 9740EEB21CF90195004384FC /* Debug.xcconfig */,
+ 7AFA3C8E1D35360C0083082E /* Release.xcconfig */,
+ 9740EEB31CF90195004384FC /* Generated.xcconfig */,
+ );
+ name = Flutter;
+ sourceTree = "";
+ };
+ 97C146E51CF9000F007C117D = {
+ isa = PBXGroup;
+ children = (
+ 9740EEB11CF90186004384FC /* Flutter */,
+ 97C146F01CF9000F007C117D /* Runner */,
+ 97C146EF1CF9000F007C117D /* Products */,
+ 331C8082294A63A400263BE5 /* RunnerTests */,
+ 3B8051ED51CBDB3CF1DF0F5B /* Pods */,
+ 03AFDC00C5136405689DA84C /* Frameworks */,
+ );
+ sourceTree = "";
+ };
+ 97C146EF1CF9000F007C117D /* Products */ = {
+ isa = PBXGroup;
+ children = (
+ 97C146EE1CF9000F007C117D /* Runner.app */,
+ 331C8081294A63A400263BE5 /* RunnerTests.xctest */,
+ );
+ name = Products;
+ sourceTree = "";
+ };
+ 97C146F01CF9000F007C117D /* Runner */ = {
+ isa = PBXGroup;
+ children = (
+ 52DF38A22F110EC10086FBE4 /* RunnerRelease.entitlements */,
+ 52DF389D2F0E79020086FBE4 /* RunnerDebug.entitlements */,
+ 525B8C712ED013520007B725 /* GoogleService-Info.plist */,
+ 97C146FA1CF9000F007C117D /* Main.storyboard */,
+ 97C146FD1CF9000F007C117D /* Assets.xcassets */,
+ 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */,
+ 97C147021CF9000F007C117D /* Info.plist */,
+ 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */,
+ 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */,
+ 74858FAE1ED2DC5600515810 /* AppDelegate.swift */,
+ 74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */,
+ );
+ path = Runner;
+ sourceTree = "";
+ };
+/* End PBXGroup section */
+
+/* Begin PBXNativeTarget section */
+ 331C8080294A63A400263BE5 /* RunnerTests */ = {
+ isa = PBXNativeTarget;
+ buildConfigurationList = 331C8087294A63A400263BE5 /* Build configuration list for PBXNativeTarget "RunnerTests" */;
+ buildPhases = (
+ CFD1FCCAE92AFBF15E8B607E /* [CP] Check Pods Manifest.lock */,
+ 331C807D294A63A400263BE5 /* Sources */,
+ 331C807F294A63A400263BE5 /* Resources */,
+ A0E84D3ADAE5F6DDD480F35D /* Frameworks */,
+ );
+ buildRules = (
+ );
+ dependencies = (
+ 331C8086294A63A400263BE5 /* PBXTargetDependency */,
+ );
+ name = RunnerTests;
+ productName = RunnerTests;
+ productReference = 331C8081294A63A400263BE5 /* RunnerTests.xctest */;
+ productType = "com.apple.product-type.bundle.unit-test";
+ };
+ 97C146ED1CF9000F007C117D /* Runner */ = {
+ isa = PBXNativeTarget;
+ buildConfigurationList = 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */;
+ buildPhases = (
+ 9AAFF935C9514CBA898ADFC8 /* [CP] Check Pods Manifest.lock */,
+ 9740EEB61CF901F6004384FC /* Run Script */,
+ 97C146EA1CF9000F007C117D /* Sources */,
+ 97C146EB1CF9000F007C117D /* Frameworks */,
+ 97C146EC1CF9000F007C117D /* Resources */,
+ 9705A1C41CF9048500538489 /* Embed Frameworks */,
+ 3B06AD1E1E4923F5004D2608 /* Thin Binary */,
+ F1AFD9E9E8DBA4F1609CE22F /* [CP] Embed Pods Frameworks */,
+ 5DF67264ADC5268AC3021CED /* [CP] Copy Pods Resources */,
+ );
+ buildRules = (
+ );
+ dependencies = (
+ );
+ name = Runner;
+ productName = Runner;
+ productReference = 97C146EE1CF9000F007C117D /* Runner.app */;
+ productType = "com.apple.product-type.application";
+ };
+/* End PBXNativeTarget section */
+
+/* Begin PBXProject section */
+ 97C146E61CF9000F007C117D /* Project object */ = {
+ isa = PBXProject;
+ attributes = {
+ BuildIndependentTargetsInParallel = YES;
+ LastUpgradeCheck = 1510;
+ ORGANIZATIONNAME = "";
+ TargetAttributes = {
+ 331C8080294A63A400263BE5 = {
+ CreatedOnToolsVersion = 14.0;
+ TestTargetID = 97C146ED1CF9000F007C117D;
+ };
+ 97C146ED1CF9000F007C117D = {
+ CreatedOnToolsVersion = 7.3.1;
+ LastSwiftMigration = 1100;
+ };
+ };
+ };
+ buildConfigurationList = 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */;
+ compatibilityVersion = "Xcode 9.3";
+ developmentRegion = en;
+ hasScannedForEncodings = 0;
+ knownRegions = (
+ en,
+ Base,
+ );
+ mainGroup = 97C146E51CF9000F007C117D;
+ productRefGroup = 97C146EF1CF9000F007C117D /* Products */;
+ projectDirPath = "";
+ projectRoot = "";
+ targets = (
+ 97C146ED1CF9000F007C117D /* Runner */,
+ 331C8080294A63A400263BE5 /* RunnerTests */,
+ );
+ };
+/* End PBXProject section */
+
+/* Begin PBXResourcesBuildPhase section */
+ 331C807F294A63A400263BE5 /* Resources */ = {
+ isa = PBXResourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ 97C146EC1CF9000F007C117D /* Resources */ = {
+ isa = PBXResourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */,
+ 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */,
+ 525B8C722ED013520007B725 /* GoogleService-Info.plist in Resources */,
+ 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */,
+ 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXResourcesBuildPhase section */
+
+/* Begin PBXShellScriptBuildPhase section */
+ 3B06AD1E1E4923F5004D2608 /* Thin Binary */ = {
+ isa = PBXShellScriptBuildPhase;
+ alwaysOutOfDate = 1;
+ buildActionMask = 2147483647;
+ files = (
+ );
+ inputPaths = (
+ "${TARGET_BUILD_DIR}/${INFOPLIST_PATH}",
+ );
+ name = "Thin Binary";
+ outputPaths = (
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ shellPath = /bin/sh;
+ shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" embed_and_thin";
+ };
+ 5DF67264ADC5268AC3021CED /* [CP] Copy Pods Resources */ = {
+ isa = PBXShellScriptBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ );
+ inputFileListPaths = (
+ "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-resources-${CONFIGURATION}-input-files.xcfilelist",
+ );
+ name = "[CP] Copy Pods Resources";
+ outputFileListPaths = (
+ "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-resources-${CONFIGURATION}-output-files.xcfilelist",
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ shellPath = /bin/sh;
+ shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-resources.sh\"\n";
+ showEnvVarsInLog = 0;
+ };
+ 9740EEB61CF901F6004384FC /* Run Script */ = {
+ isa = PBXShellScriptBuildPhase;
+ alwaysOutOfDate = 1;
+ buildActionMask = 2147483647;
+ files = (
+ );
+ inputPaths = (
+ );
+ name = "Run Script";
+ outputPaths = (
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ shellPath = /bin/sh;
+ shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" build";
+ };
+ 9AAFF935C9514CBA898ADFC8 /* [CP] Check Pods Manifest.lock */ = {
+ isa = PBXShellScriptBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ );
+ inputFileListPaths = (
+ );
+ inputPaths = (
+ "${PODS_PODFILE_DIR_PATH}/Podfile.lock",
+ "${PODS_ROOT}/Manifest.lock",
+ );
+ name = "[CP] Check Pods Manifest.lock";
+ outputFileListPaths = (
+ );
+ outputPaths = (
+ "$(DERIVED_FILE_DIR)/Pods-Runner-checkManifestLockResult.txt",
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ shellPath = /bin/sh;
+ shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n";
+ showEnvVarsInLog = 0;
+ };
+ CFD1FCCAE92AFBF15E8B607E /* [CP] Check Pods Manifest.lock */ = {
+ isa = PBXShellScriptBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ );
+ inputFileListPaths = (
+ );
+ inputPaths = (
+ "${PODS_PODFILE_DIR_PATH}/Podfile.lock",
+ "${PODS_ROOT}/Manifest.lock",
+ );
+ name = "[CP] Check Pods Manifest.lock";
+ outputFileListPaths = (
+ );
+ outputPaths = (
+ "$(DERIVED_FILE_DIR)/Pods-RunnerTests-checkManifestLockResult.txt",
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ shellPath = /bin/sh;
+ shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n";
+ showEnvVarsInLog = 0;
+ };
+ F1AFD9E9E8DBA4F1609CE22F /* [CP] Embed Pods Frameworks */ = {
+ isa = PBXShellScriptBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ );
+ inputFileListPaths = (
+ "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks-${CONFIGURATION}-input-files.xcfilelist",
+ );
+ name = "[CP] Embed Pods Frameworks";
+ outputFileListPaths = (
+ "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks-${CONFIGURATION}-output-files.xcfilelist",
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ shellPath = /bin/sh;
+ shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh\"\n";
+ showEnvVarsInLog = 0;
+ };
+/* End PBXShellScriptBuildPhase section */
+
+/* Begin PBXSourcesBuildPhase section */
+ 331C807D294A63A400263BE5 /* Sources */ = {
+ isa = PBXSourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ 331C808B294A63AB00263BE5 /* RunnerTests.swift in Sources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+ 97C146EA1CF9000F007C117D /* Sources */ = {
+ isa = PBXSourcesBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ 74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */,
+ 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */,
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ };
+/* End PBXSourcesBuildPhase section */
+
+/* Begin PBXTargetDependency section */
+ 331C8086294A63A400263BE5 /* PBXTargetDependency */ = {
+ isa = PBXTargetDependency;
+ target = 97C146ED1CF9000F007C117D /* Runner */;
+ targetProxy = 331C8085294A63A400263BE5 /* PBXContainerItemProxy */;
+ };
+/* End PBXTargetDependency section */
+
+/* Begin PBXVariantGroup section */
+ 97C146FA1CF9000F007C117D /* Main.storyboard */ = {
+ isa = PBXVariantGroup;
+ children = (
+ 97C146FB1CF9000F007C117D /* Base */,
+ );
+ name = Main.storyboard;
+ sourceTree = "";
+ };
+ 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */ = {
+ isa = PBXVariantGroup;
+ children = (
+ 97C147001CF9000F007C117D /* Base */,
+ );
+ name = LaunchScreen.storyboard;
+ sourceTree = "";
+ };
+/* End PBXVariantGroup section */
+
+/* Begin XCBuildConfiguration section */
+ 249021D3217E4FDB00AE95B9 /* Profile */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ALWAYS_SEARCH_USER_PATHS = NO;
+ ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES;
+ CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES;
+ CLANG_ANALYZER_NONNULL = YES;
+ CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
+ CLANG_CXX_LIBRARY = "libc++";
+ CLANG_ENABLE_MODULES = YES;
+ CLANG_ENABLE_OBJC_ARC = YES;
+ CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
+ CLANG_WARN_BOOL_CONVERSION = YES;
+ CLANG_WARN_COMMA = YES;
+ CLANG_WARN_CONSTANT_CONVERSION = YES;
+ CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
+ CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
+ CLANG_WARN_EMPTY_BODY = YES;
+ CLANG_WARN_ENUM_CONVERSION = YES;
+ CLANG_WARN_INFINITE_RECURSION = YES;
+ CLANG_WARN_INT_CONVERSION = YES;
+ CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
+ CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
+ CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
+ CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
+ CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
+ CLANG_WARN_STRICT_PROTOTYPES = YES;
+ CLANG_WARN_SUSPICIOUS_MOVE = YES;
+ CLANG_WARN_UNREACHABLE_CODE = YES;
+ CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
+ "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
+ COPY_PHASE_STRIP = NO;
+ DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
+ ENABLE_NS_ASSERTIONS = NO;
+ ENABLE_STRICT_OBJC_MSGSEND = YES;
+ ENABLE_USER_SCRIPT_SANDBOXING = NO;
+ GCC_C_LANGUAGE_STANDARD = gnu99;
+ GCC_NO_COMMON_BLOCKS = YES;
+ GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
+ GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
+ GCC_WARN_UNDECLARED_SELECTOR = YES;
+ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
+ GCC_WARN_UNUSED_FUNCTION = YES;
+ GCC_WARN_UNUSED_VARIABLE = YES;
+ IPHONEOS_DEPLOYMENT_TARGET = 13.0;
+ MTL_ENABLE_DEBUG_INFO = NO;
+ SDKROOT = iphoneos;
+ SUPPORTED_PLATFORMS = iphoneos;
+ TARGETED_DEVICE_FAMILY = "1,2";
+ VALIDATE_PRODUCT = YES;
+ };
+ name = Profile;
+ };
+ 249021D4217E4FDB00AE95B9 /* Profile */ = {
+ isa = XCBuildConfiguration;
+ baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */;
+ buildSettings = {
+ ASSETCATALOG_COMPILER_APPat_icon_NAME = AppIcon;
+ CLANG_ENABLE_MODULES = YES;
+ CODE_SIGN_IDENTITY = "Apple Development";
+ CODE_SIGN_STYLE = Automatic;
+ CURRENT_PROJECT_VERSION = 35;
+ DEVELOPMENT_TEAM = S9X2AJ2US9;
+ ENABLE_BITCODE = NO;
+ INFOPLIST_FILE = Runner/Info.plist;
+ IPHONEOS_DEPLOYMENT_TARGET = 13.0;
+ LD_RUNPATH_SEARCH_PATHS = (
+ "$(inherited)",
+ "@executable_path/Frameworks",
+ );
+ MARKETING_VERSION = 1.2.0;
+ PRODUCT_BUNDLE_IDENTIFIER = com.org.yumi;
+ PRODUCT_NAME = "$(TARGET_NAME)";
+ PROVISIONING_PROFILE_SPECIFIER = "";
+ SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
+ SWIFT_VERSION = 5.0;
+ VERSIONING_SYSTEM = "apple-generic";
+ };
+ name = Profile;
+ };
+ 331C8088294A63A400263BE5 /* Debug */ = {
+ isa = XCBuildConfiguration;
+ baseConfigurationReference = 3144A376A151695EA2D1A4FE /* Pods-RunnerTests.debug.xcconfig */;
+ buildSettings = {
+ BUNDLE_LOADER = "$(TEST_HOST)";
+ CODE_SIGN_STYLE = Automatic;
+ CURRENT_PROJECT_VERSION = 1;
+ GENERATE_INFOPLIST_FILE = YES;
+ MARKETING_VERSION = 1.0;
+ PRODUCT_BUNDLE_IDENTIFIER = com.example.yumi.yumi.RunnerTests;
+ PRODUCT_NAME = "$(TARGET_NAME)";
+ SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG;
+ SWIFT_OPTIMIZATION_LEVEL = "-Onone";
+ SWIFT_VERSION = 5.0;
+ TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Runner.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/Runner";
+ };
+ name = Debug;
+ };
+ 331C8089294A63A400263BE5 /* Release */ = {
+ isa = XCBuildConfiguration;
+ baseConfigurationReference = 628A4C79D49FE8929E845244 /* Pods-RunnerTests.release.xcconfig */;
+ buildSettings = {
+ BUNDLE_LOADER = "$(TEST_HOST)";
+ CODE_SIGN_STYLE = Automatic;
+ CURRENT_PROJECT_VERSION = 1;
+ GENERATE_INFOPLIST_FILE = YES;
+ MARKETING_VERSION = 1.0;
+ PRODUCT_BUNDLE_IDENTIFIER = com.example.yumi.yumi.RunnerTests;
+ PRODUCT_NAME = "$(TARGET_NAME)";
+ SWIFT_VERSION = 5.0;
+ TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Runner.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/Runner";
+ };
+ name = Release;
+ };
+ 331C808A294A63A400263BE5 /* Profile */ = {
+ isa = XCBuildConfiguration;
+ baseConfigurationReference = 2DBA1462EA0F13259D54391C /* Pods-RunnerTests.profile.xcconfig */;
+ buildSettings = {
+ BUNDLE_LOADER = "$(TEST_HOST)";
+ CODE_SIGN_STYLE = Automatic;
+ CURRENT_PROJECT_VERSION = 1;
+ GENERATE_INFOPLIST_FILE = YES;
+ MARKETING_VERSION = 1.0;
+ PRODUCT_BUNDLE_IDENTIFIER = com.example.yumi.yumi.RunnerTests;
+ PRODUCT_NAME = "$(TARGET_NAME)";
+ SWIFT_VERSION = 5.0;
+ TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Runner.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/Runner";
+ };
+ name = Profile;
+ };
+ 97C147031CF9000F007C117D /* Debug */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ALWAYS_SEARCH_USER_PATHS = NO;
+ ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = AppIcon;
+ CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES;
+ CLANG_ANALYZER_NONNULL = YES;
+ CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
+ CLANG_CXX_LIBRARY = "libc++";
+ CLANG_ENABLE_MODULES = YES;
+ CLANG_ENABLE_OBJC_ARC = YES;
+ CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
+ CLANG_WARN_BOOL_CONVERSION = YES;
+ CLANG_WARN_COMMA = YES;
+ CLANG_WARN_CONSTANT_CONVERSION = YES;
+ CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
+ CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
+ CLANG_WARN_EMPTY_BODY = YES;
+ CLANG_WARN_ENUM_CONVERSION = YES;
+ CLANG_WARN_INFINITE_RECURSION = YES;
+ CLANG_WARN_INT_CONVERSION = YES;
+ CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
+ CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
+ CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
+ CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
+ CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
+ CLANG_WARN_STRICT_PROTOTYPES = YES;
+ CLANG_WARN_SUSPICIOUS_MOVE = YES;
+ CLANG_WARN_UNREACHABLE_CODE = YES;
+ CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
+ "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
+ COPY_PHASE_STRIP = NO;
+ DEBUG_INFORMATION_FORMAT = dwarf;
+ ENABLE_STRICT_OBJC_MSGSEND = YES;
+ ENABLE_TESTABILITY = YES;
+ ENABLE_USER_SCRIPT_SANDBOXING = NO;
+ GCC_C_LANGUAGE_STANDARD = gnu99;
+ GCC_DYNAMIC_NO_PIC = NO;
+ GCC_NO_COMMON_BLOCKS = YES;
+ GCC_OPTIMIZATION_LEVEL = 0;
+ GCC_PREPROCESSOR_DEFINITIONS = (
+ "DEBUG=1",
+ "$(inherited)",
+ );
+ GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
+ GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
+ GCC_WARN_UNDECLARED_SELECTOR = YES;
+ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
+ GCC_WARN_UNUSED_FUNCTION = YES;
+ GCC_WARN_UNUSED_VARIABLE = YES;
+ IPHONEOS_DEPLOYMENT_TARGET = 13.0;
+ MTL_ENABLE_DEBUG_INFO = YES;
+ ONLY_ACTIVE_ARCH = YES;
+ SDKROOT = iphoneos;
+ TARGETED_DEVICE_FAMILY = "1,2";
+ };
+ name = Debug;
+ };
+ 97C147041CF9000F007C117D /* Release */ = {
+ isa = XCBuildConfiguration;
+ buildSettings = {
+ ALWAYS_SEARCH_USER_PATHS = NO;
+ ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = AppIcon;
+ CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES;
+ CLANG_ANALYZER_NONNULL = YES;
+ CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
+ CLANG_CXX_LIBRARY = "libc++";
+ CLANG_ENABLE_MODULES = YES;
+ CLANG_ENABLE_OBJC_ARC = YES;
+ CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
+ CLANG_WARN_BOOL_CONVERSION = YES;
+ CLANG_WARN_COMMA = YES;
+ CLANG_WARN_CONSTANT_CONVERSION = YES;
+ CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
+ CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
+ CLANG_WARN_EMPTY_BODY = YES;
+ CLANG_WARN_ENUM_CONVERSION = YES;
+ CLANG_WARN_INFINITE_RECURSION = YES;
+ CLANG_WARN_INT_CONVERSION = YES;
+ CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
+ CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
+ CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
+ CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
+ CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
+ CLANG_WARN_STRICT_PROTOTYPES = YES;
+ CLANG_WARN_SUSPICIOUS_MOVE = YES;
+ CLANG_WARN_UNREACHABLE_CODE = YES;
+ CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
+ "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
+ COPY_PHASE_STRIP = NO;
+ DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
+ ENABLE_NS_ASSERTIONS = NO;
+ ENABLE_STRICT_OBJC_MSGSEND = YES;
+ ENABLE_USER_SCRIPT_SANDBOXING = NO;
+ GCC_C_LANGUAGE_STANDARD = gnu99;
+ GCC_NO_COMMON_BLOCKS = YES;
+ GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
+ GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
+ GCC_WARN_UNDECLARED_SELECTOR = YES;
+ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
+ GCC_WARN_UNUSED_FUNCTION = YES;
+ GCC_WARN_UNUSED_VARIABLE = YES;
+ IPHONEOS_DEPLOYMENT_TARGET = 13.0;
+ MTL_ENABLE_DEBUG_INFO = NO;
+ SDKROOT = iphoneos;
+ SUPPORTED_PLATFORMS = iphoneos;
+ SWIFT_COMPILATION_MODE = wholemodule;
+ SWIFT_OPTIMIZATION_LEVEL = "-O";
+ TARGETED_DEVICE_FAMILY = "1,2";
+ VALIDATE_PRODUCT = YES;
+ };
+ name = Release;
+ };
+ 97C147061CF9000F007C117D /* Debug */ = {
+ isa = XCBuildConfiguration;
+ baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */;
+ buildSettings = {
+ ASSETCATALOG_COMPILER_APPat_icon_NAME = AppIcon;
+ CLANG_ENABLE_MODULES = YES;
+ CODE_SIGN_ENTITLEMENTS = Runner/RunnerDebug.entitlements;
+ CODE_SIGN_IDENTITY = "Apple Development";
+ CODE_SIGN_STYLE = Automatic;
+ CURRENT_PROJECT_VERSION = 35;
+ DEVELOPMENT_TEAM = F33K8VUZ62;
+ ENABLE_BITCODE = NO;
+ INFOPLIST_FILE = Runner/Info.plist;
+ IPHONEOS_DEPLOYMENT_TARGET = 13.0;
+ LD_RUNPATH_SEARCH_PATHS = (
+ "$(inherited)",
+ "@executable_path/Frameworks",
+ );
+ MARKETING_VERSION = 1.2.0;
+ PRODUCT_BUNDLE_IDENTIFIER = com.org.yumi;
+ PRODUCT_NAME = "$(TARGET_NAME)";
+ PROVISIONING_PROFILE_SPECIFIER = "";
+ SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
+ SWIFT_OPTIMIZATION_LEVEL = "-Onone";
+ SWIFT_VERSION = 5.0;
+ VERSIONING_SYSTEM = "apple-generic";
+ };
+ name = Debug;
+ };
+ 97C147071CF9000F007C117D /* Release */ = {
+ isa = XCBuildConfiguration;
+ baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */;
+ buildSettings = {
+ ASSETCATALOG_COMPILER_APPat_icon_NAME = AppIcon;
+ CLANG_ENABLE_MODULES = YES;
+ CODE_SIGN_ENTITLEMENTS = Runner/RunnerRelease.entitlements;
+ CODE_SIGN_IDENTITY = "Apple Development";
+ CODE_SIGN_STYLE = Automatic;
+ CURRENT_PROJECT_VERSION = 35;
+ DEVELOPMENT_TEAM = F33K8VUZ62;
+ ENABLE_BITCODE = NO;
+ INFOPLIST_FILE = Runner/Info.plist;
+ IPHONEOS_DEPLOYMENT_TARGET = 13.0;
+ LD_RUNPATH_SEARCH_PATHS = (
+ "$(inherited)",
+ "@executable_path/Frameworks",
+ );
+ MARKETING_VERSION = 1.2.0;
+ PRODUCT_BUNDLE_IDENTIFIER = com.org.yumi;
+ PRODUCT_NAME = "$(TARGET_NAME)";
+ PROVISIONING_PROFILE_SPECIFIER = "";
+ SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
+ SWIFT_VERSION = 5.0;
+ VERSIONING_SYSTEM = "apple-generic";
+ };
+ name = Release;
+ };
+/* End XCBuildConfiguration section */
+
+/* Begin XCConfigurationList section */
+ 331C8087294A63A400263BE5 /* Build configuration list for PBXNativeTarget "RunnerTests" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ 331C8088294A63A400263BE5 /* Debug */,
+ 331C8089294A63A400263BE5 /* Release */,
+ 331C808A294A63A400263BE5 /* Profile */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+ 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ 97C147031CF9000F007C117D /* Debug */,
+ 97C147041CF9000F007C117D /* Release */,
+ 249021D3217E4FDB00AE95B9 /* Profile */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+ 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */ = {
+ isa = XCConfigurationList;
+ buildConfigurations = (
+ 97C147061CF9000F007C117D /* Debug */,
+ 97C147071CF9000F007C117D /* Release */,
+ 249021D4217E4FDB00AE95B9 /* Profile */,
+ );
+ defaultConfigurationIsVisible = 0;
+ defaultConfigurationName = Release;
+ };
+/* End XCConfigurationList section */
+ };
+ rootObject = 97C146E61CF9000F007C117D /* Project object */;
+}
diff --git a/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata
new file mode 100644
index 0000000..c4b79bd
--- /dev/null
+++ b/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata
@@ -0,0 +1,7 @@
+
+
+
+
+
diff --git a/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist
new file mode 100644
index 0000000..fc6bf80
--- /dev/null
+++ b/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist
@@ -0,0 +1,8 @@
+
+
+
+
+ IDEDidComputeMac32BitWarning
+
+
+
diff --git a/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings b/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings
new file mode 100644
index 0000000..af0309c
--- /dev/null
+++ b/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings
@@ -0,0 +1,8 @@
+
+
+
+
+ PreviewsEnabled
+
+
+
diff --git a/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme b/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme
new file mode 100644
index 0000000..bbabc4e
--- /dev/null
+++ b/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme
@@ -0,0 +1,101 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/ios/Runner.xcworkspace/contents.xcworkspacedata b/ios/Runner.xcworkspace/contents.xcworkspacedata
new file mode 100644
index 0000000..17ccc03
--- /dev/null
+++ b/ios/Runner.xcworkspace/contents.xcworkspacedata
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
diff --git a/ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings b/ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings
new file mode 100644
index 0000000..c2cba09
--- /dev/null
+++ b/ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings
@@ -0,0 +1,5 @@
+
+
+
+
+
diff --git a/ios/Runner/AppDelegate.swift b/ios/Runner/AppDelegate.swift
new file mode 100644
index 0000000..8be1cec
--- /dev/null
+++ b/ios/Runner/AppDelegate.swift
@@ -0,0 +1,13 @@
+import Flutter
+import UIKit
+
+@main
+@objc class AppDelegate: FlutterAppDelegate {
+ override func application(
+ _ application: UIApplication,
+ didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
+ ) -> Bool {
+ GeneratedPluginRegistrant.register(with: self)
+ return super.application(application, didFinishLaunchingWithOptions: launchOptions)
+ }
+}
diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json
new file mode 100644
index 0000000..d0d98aa
--- /dev/null
+++ b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json
@@ -0,0 +1 @@
+{"images":[{"size":"20x20","idiom":"iphone","filename":"Icon-App-20x20@2x.png","scale":"2x"},{"size":"20x20","idiom":"iphone","filename":"Icon-App-20x20@3x.png","scale":"3x"},{"size":"29x29","idiom":"iphone","filename":"Icon-App-29x29@1x.png","scale":"1x"},{"size":"29x29","idiom":"iphone","filename":"Icon-App-29x29@2x.png","scale":"2x"},{"size":"29x29","idiom":"iphone","filename":"Icon-App-29x29@3x.png","scale":"3x"},{"size":"40x40","idiom":"iphone","filename":"Icon-App-40x40@2x.png","scale":"2x"},{"size":"40x40","idiom":"iphone","filename":"Icon-App-40x40@3x.png","scale":"3x"},{"size":"57x57","idiom":"iphone","filename":"Icon-App-57x57@1x.png","scale":"1x"},{"size":"57x57","idiom":"iphone","filename":"Icon-App-57x57@2x.png","scale":"2x"},{"size":"60x60","idiom":"iphone","filename":"Icon-App-60x60@2x.png","scale":"2x"},{"size":"60x60","idiom":"iphone","filename":"Icon-App-60x60@3x.png","scale":"3x"},{"size":"20x20","idiom":"ipad","filename":"Icon-App-20x20@1x.png","scale":"1x"},{"size":"20x20","idiom":"ipad","filename":"Icon-App-20x20@2x.png","scale":"2x"},{"size":"29x29","idiom":"ipad","filename":"Icon-App-29x29@1x.png","scale":"1x"},{"size":"29x29","idiom":"ipad","filename":"Icon-App-29x29@2x.png","scale":"2x"},{"size":"40x40","idiom":"ipad","filename":"Icon-App-40x40@1x.png","scale":"1x"},{"size":"40x40","idiom":"ipad","filename":"Icon-App-40x40@2x.png","scale":"2x"},{"size":"50x50","idiom":"ipad","filename":"Icon-App-50x50@1x.png","scale":"1x"},{"size":"50x50","idiom":"ipad","filename":"Icon-App-50x50@2x.png","scale":"2x"},{"size":"72x72","idiom":"ipad","filename":"Icon-App-72x72@1x.png","scale":"1x"},{"size":"72x72","idiom":"ipad","filename":"Icon-App-72x72@2x.png","scale":"2x"},{"size":"76x76","idiom":"ipad","filename":"Icon-App-76x76@1x.png","scale":"1x"},{"size":"76x76","idiom":"ipad","filename":"Icon-App-76x76@2x.png","scale":"2x"},{"size":"83.5x83.5","idiom":"ipad","filename":"Icon-App-83.5x83.5@2x.png","scale":"2x"},{"size":"1024x1024","idiom":"ios-marketing","filename":"Icon-App-1024x1024@1x.png","scale":"1x"}],"info":{"version":1,"author":"xcode"}}
\ No newline at end of file
diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png
new file mode 100644
index 0000000..879503c
Binary files /dev/null and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png differ
diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png
new file mode 100644
index 0000000..e03f697
Binary files /dev/null and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png differ
diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png
new file mode 100644
index 0000000..a4a7cbc
Binary files /dev/null and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png differ
diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png
new file mode 100644
index 0000000..c26b0c5
Binary files /dev/null and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png differ
diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png
new file mode 100644
index 0000000..5d3adbe
Binary files /dev/null and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png differ
diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png
new file mode 100644
index 0000000..3d50c36
Binary files /dev/null and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png differ
diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png
new file mode 100644
index 0000000..8e5585d
Binary files /dev/null and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png differ
diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png
new file mode 100644
index 0000000..a4a7cbc
Binary files /dev/null and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png differ
diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png
new file mode 100644
index 0000000..690398a
Binary files /dev/null and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png differ
diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png
new file mode 100644
index 0000000..40a9548
Binary files /dev/null and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png differ
diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-50x50@1x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-50x50@1x.png
new file mode 100644
index 0000000..7cff2c2
Binary files /dev/null and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-50x50@1x.png differ
diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-50x50@2x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-50x50@2x.png
new file mode 100644
index 0000000..58af325
Binary files /dev/null and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-50x50@2x.png differ
diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-57x57@1x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-57x57@1x.png
new file mode 100644
index 0000000..e8b01af
Binary files /dev/null and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-57x57@1x.png differ
diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-57x57@2x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-57x57@2x.png
new file mode 100644
index 0000000..2f36d02
Binary files /dev/null and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-57x57@2x.png differ
diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png
new file mode 100644
index 0000000..40a9548
Binary files /dev/null and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png differ
diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png
new file mode 100644
index 0000000..33e7037
Binary files /dev/null and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png differ
diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-72x72@1x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-72x72@1x.png
new file mode 100644
index 0000000..bab4549
Binary files /dev/null and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-72x72@1x.png differ
diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-72x72@2x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-72x72@2x.png
new file mode 100644
index 0000000..1a5b3c6
Binary files /dev/null and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-72x72@2x.png differ
diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png
new file mode 100644
index 0000000..b386803
Binary files /dev/null and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png differ
diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png
new file mode 100644
index 0000000..efbff97
Binary files /dev/null and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png differ
diff --git a/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png
new file mode 100644
index 0000000..32f26cb
Binary files /dev/null and b/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png differ
diff --git a/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json b/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json
new file mode 100644
index 0000000..d08a4de
--- /dev/null
+++ b/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json
@@ -0,0 +1,23 @@
+{
+ "images" : [
+ {
+ "idiom" : "universal",
+ "filename" : "LaunchImage.png",
+ "scale" : "1x"
+ },
+ {
+ "idiom" : "universal",
+ "filename" : "LaunchImage@2x.png",
+ "scale" : "2x"
+ },
+ {
+ "idiom" : "universal",
+ "filename" : "LaunchImage@3x.png",
+ "scale" : "3x"
+ }
+ ],
+ "info" : {
+ "version" : 1,
+ "author" : "xcode"
+ }
+}
diff --git a/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png b/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png
new file mode 100644
index 0000000..9da19ea
Binary files /dev/null and b/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png differ
diff --git a/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png b/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png
new file mode 100644
index 0000000..9da19ea
Binary files /dev/null and b/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png differ
diff --git a/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png b/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png
new file mode 100644
index 0000000..9da19ea
Binary files /dev/null and b/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png differ
diff --git a/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md b/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md
new file mode 100644
index 0000000..65a94b5
--- /dev/null
+++ b/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md
@@ -0,0 +1,5 @@
+# Launch Screen Assets
+
+You can customize the launch screen with your own desired assets by replacing the image files in this directory.
+
+You can also do it by opening your Flutter project's Xcode project with `open ios/Runner.xcworkspace`, selecting `Runner/Assets.xcassets` in the Project Navigator and dropping in the desired images.
\ No newline at end of file
diff --git a/ios/Runner/Base.lproj/LaunchScreen.storyboard b/ios/Runner/Base.lproj/LaunchScreen.storyboard
new file mode 100644
index 0000000..497371e
--- /dev/null
+++ b/ios/Runner/Base.lproj/LaunchScreen.storyboard
@@ -0,0 +1,37 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/ios/Runner/Base.lproj/Main.storyboard b/ios/Runner/Base.lproj/Main.storyboard
new file mode 100644
index 0000000..1d74234
--- /dev/null
+++ b/ios/Runner/Base.lproj/Main.storyboard
@@ -0,0 +1,29 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/ios/Runner/GoogleService-Info.plist b/ios/Runner/GoogleService-Info.plist
new file mode 100644
index 0000000..aa092d5
--- /dev/null
+++ b/ios/Runner/GoogleService-Info.plist
@@ -0,0 +1,36 @@
+
+
+
+
+ CLIENT_ID
+ 52796773508-dk441c9e7tdmqv47mbdt2vpbn2clrii8.apps.googleusercontent.com
+ REVERSED_CLIENT_ID
+ com.googleusercontent.apps.52796773508-dk441c9e7tdmqv47mbdt2vpbn2clrii8
+ ANDROID_CLIENT_ID
+ 52796773508-2ruai8tqhp0knuofo02ob1cmheu76u2d.apps.googleusercontent.com
+ API_KEY
+ AIzaSyAeeeuw_zKUQmdUUiOXD4u_BvQqaV3w9Gk
+ GCM_SENDER_ID
+ 52796773508
+ PLIST_VERSION
+ 1
+ BUNDLE_ID
+ com.org.yumi
+ PROJECT_ID
+ yumi-7b503
+ STORAGE_BUCKET
+ yumi-7b503.firebasestorage.app
+ IS_ADS_ENABLED
+
+ IS_ANALYTICS_ENABLED
+
+ IS_APPINVITE_ENABLED
+
+ IS_GCM_ENABLED
+
+ IS_SIGNIN_ENABLED
+
+ GOOGLE_APP_ID
+ 1:52796773508:ios:7dfa56d19e1711ab65ded1
+
+
\ No newline at end of file
diff --git a/ios/Runner/Info.plist b/ios/Runner/Info.plist
new file mode 100644
index 0000000..f9b7b0c
--- /dev/null
+++ b/ios/Runner/Info.plist
@@ -0,0 +1,91 @@
+
+
+
+
+LSApplicationQueriesSchemes
+
+ fb
+ fbapi
+ fb-messenger-api
+ whatsapp
+ snapchat
+
+ CADisableMinimumFrameDurationOnPhone
+
+ NSAppTransportSecurity
+
+ NSAllowsArbitraryLoads
+
+
+ CFBundleDevelopmentRegion
+ $(DEVELOPMENT_LANGUAGE)
+ CFBundleDisplayName
+ yumi
+ CFBundleExecutable
+ $(EXECUTABLE_NAME)
+ CFBundleIdentifier
+ $(PRODUCT_BUNDLE_IDENTIFIER)
+ CFBundleInfoDictionaryVersion
+ 6.0
+ CFBundleName
+ yumi
+ CFBundlePackageType
+ APPL
+ CFBundleShortVersionString
+ $(FLUTTER_BUILD_NAME)
+ CFBundleSignature
+ ????
+ CFBundleURLTypes
+
+
+ CFBundleTypeRole
+ Editor
+
+
+ CFBundleVersion
+ $(FLUTTER_BUILD_NUMBER)
+ LSRequiresIPhoneOS
+
+ NSAppleMusicUsageDescription
+ We need access to the media library so that you can play your favorite local music files in the voice background.
+ NSCameraUsageDescription
+ We need access to your camera so you can take a photo and make it a profile picture, or take and share a picture in real time in a voice chat room.
+ NSMicrophoneUsageDescription
+ We need access to your microphone so that you can make live calls, record, and send voice messages with other users in the voice dating room.
+ NSPhotoLibraryAddUsageDescription
+ We need your permission to save beautiful images you take or edit in the app to your phone album.
+ NSPhotoLibraryUsageDescription
+ We need access to your photo album so you can choose photos from it to update your profile picture or share moments from your life in chat.
+ UIApplicationSupportsIndirectInputEvents
+
+ UILaunchStoryboardName
+ LaunchScreen
+ UIMainStoryboardFile
+ Main
+ UISupportedInterfaceOrientations
+
+ UIInterfaceOrientationPortrait
+
+ UISupportedInterfaceOrientations~ipad
+
+ UIInterfaceOrientationLandscapeLeft
+ UIInterfaceOrientationLandscapeRight
+ UIInterfaceOrientationPortrait
+ UIInterfaceOrientationPortraitUpsideDown
+
+ UIViewControllerBasedStatusBarAppearance
+
+ BGTaskSchedulerPermittedIdentifiers
+
+ com.pravera.flutter_foreground_task.refresh
+
+ UIBackgroundModes
+
+ audio
+
+ com.apple.developer.applesignin
+
+ Default
+
+
+
diff --git a/ios/Runner/Runner-Bridging-Header.h b/ios/Runner/Runner-Bridging-Header.h
new file mode 100644
index 0000000..fae207f
--- /dev/null
+++ b/ios/Runner/Runner-Bridging-Header.h
@@ -0,0 +1 @@
+#import "GeneratedPluginRegistrant.h"
diff --git a/ios/Runner/RunnerDebug.entitlements b/ios/Runner/RunnerDebug.entitlements
new file mode 100644
index 0000000..82e827f
--- /dev/null
+++ b/ios/Runner/RunnerDebug.entitlements
@@ -0,0 +1,10 @@
+
+
+
+
+ com.apple.developer.applesignin
+
+ Default
+
+
+
diff --git a/ios/Runner/RunnerRelease.entitlements b/ios/Runner/RunnerRelease.entitlements
new file mode 100644
index 0000000..82e827f
--- /dev/null
+++ b/ios/Runner/RunnerRelease.entitlements
@@ -0,0 +1,10 @@
+
+
+
+
+ com.apple.developer.applesignin
+
+ Default
+
+
+
diff --git a/ios/RunnerTests/RunnerTests.swift b/ios/RunnerTests/RunnerTests.swift
new file mode 100644
index 0000000..4d206de
--- /dev/null
+++ b/ios/RunnerTests/RunnerTests.swift
@@ -0,0 +1,12 @@
+import Flutter
+import UIKit
+import XCTest
+
+class RunnerTests: XCTestCase {
+
+ func testExample() {
+ // If you add code to the Runner application, consider adding tests here.
+ // See https://developer.apple.com/documentation/xctest for more information about using XCTest.
+ }
+
+}
diff --git a/lib/app/config/app_config.dart b/lib/app/config/app_config.dart
new file mode 100644
index 0000000..76fb85c
--- /dev/null
+++ b/lib/app/config/app_config.dart
@@ -0,0 +1,161 @@
+import 'package:flutter/foundation.dart';
+import 'package:yumi/app/config/configs/sc_variant1_config.dart';
+import 'package:yumi/app/config/business_logic_strategy.dart';
+
+/// 应用配置基类
+/// 定义单一应用配置接口
+abstract class AppConfig {
+ /// 应用显示名称
+ String get appName;
+
+ /// 包名/应用ID
+ String get packageName;
+
+ /// API服务器地址
+ String get apiHost;
+
+ /// 图片服务器地址
+ String get imgHost;
+
+ /// 隐私协议URL
+ String get privacyAgreementUrl;
+
+ /// 用户协议URL
+ String get userAgreementUrl;
+
+ /// 应用下载链接(Google Play)
+ String get appDownloadUrlGoogle;
+
+ /// 应用下载链接(App Store)
+ String get appDownloadUrlApple;
+
+ /// 主播代理URL
+ String get anchorAgentUrl;
+
+ /// 主持人中心URL
+ String get hostCenterUrl;
+
+ /// BD中心URL
+ String get bdCenterUrl;
+
+ /// BD领导中心URL
+ String get bdLeaderUrl;
+
+ /// 代币销售URL
+ String get coinSellerUrl;
+
+ /// 管理员URL
+ String get adminUrl;
+
+ /// 代理中心URL
+ String get agencyCenterUrl;
+
+ /// 游戏国王URL
+ String get gamesKingUrl;
+
+ /// 财富榜URL
+ String get wealthRankUrl;
+
+ /// 魅力榜URL
+ String get charmRankUrl;
+
+ /// 房间榜URL
+ String get roomRankUrl;
+
+ /// 邀请新用户URL
+ String get inviteNewUserUrl;
+
+ /// 主题主颜色
+ int get primaryColor;
+
+ /// 腾讯IM App ID
+ String get tencentImAppid;
+
+ /// Agora RTC App ID
+ String get agoraRtcAppid;
+
+ /// 游戏App ID
+ num get gameAppid;
+
+ /// 游戏渠道
+ String get gameAppChannel;
+
+ /// 全服广播大群ID
+ String get bigBroadcastGroup;
+
+ /// 管理账号
+ String get imAdmin;
+
+ /// 是否审核模式
+ bool get isReview;
+
+ /// 礼物特效开关
+ bool get isGiftSpecialEffects;
+
+ /// 入场秀开关
+ bool get isEntryVehicleAnimation;
+
+ /// 全局飘屏开关
+ bool get isFloatingAnimationInGlobal;
+
+ /// 幸运礼物特效开关
+ bool get isLuckGiftSpecialEffects;
+
+ /// 获取功能开关
+ Map get featureFlags;
+
+ /// 获取业务逻辑策略
+ BusinessLogicStrategy get businessLogicStrategy;
+
+ /// 获取所有配置的Map(用于调试)
+ Map toMap();
+
+ /// 验证配置是否有效
+ /// 检查必要的配置项是否已正确设置
+ /// 如果配置无效,抛出 [StateError]
+ void validate();
+
+ /// 当前应用的配置实例
+ static AppConfig? _current;
+
+ /// 从环境变量获取variant配置
+ /// 支持通过--dart-define=VARIANT=variant2传递参数
+ /// 默认使用variant1
+ static String _getVariant() {
+ const variant = String.fromEnvironment('VARIANT', defaultValue: 'variant1');
+ return variant;
+ }
+
+ /// 获取当前配置实例
+ static AppConfig get current {
+ if (_current == null) {
+ throw StateError(
+ 'AppConfig not initialized. Call AppConfig.initialize() first.',
+ );
+ }
+ return _current!;
+ }
+
+ /// 初始化应用配置
+ /// 支持通过环境变量选择variant(variant1或variant2)
+ /// 使用--dart-define=VARIANT=variant2传递参数
+ static void initialize() {
+ final variant = _getVariant();
+ switch (variant) {
+ case 'variant1':
+ default:
+ _current = SCVariant1Config();
+ debugPrint('AppConfig initialized for variant1 ');
+ }
+
+ // 验证配置是否有效
+ try {
+ _current!.validate();
+ } catch (e) {
+ // validate方法在调试模式下不会抛出异常
+ // 只有在发布模式下验证失败才会抛出异常
+ debugPrint('应用配置验证失败: $e');
+ rethrow;
+ }
+ }
+}
diff --git a/lib/app/config/asset_loader.dart b/lib/app/config/asset_loader.dart
new file mode 100644
index 0000000..fc68e5c
--- /dev/null
+++ b/lib/app/config/asset_loader.dart
@@ -0,0 +1,28 @@
+/// 资源加载器
+class AssetLoader {
+ /// 获取资源路径
+ /// [path] 相对路径,如 'sc_images/icon.png'
+ static String getAssetPath(String path) {
+ return 'assets/$path';
+ }
+
+ /// 获取图片资源路径
+ static String image(String path) {
+ return getAssetPath('sc_images/$path');
+ }
+
+ /// 获取本地化文件路径
+ static String localization(String path) {
+ return getAssetPath('l10n/$path');
+ }
+
+ /// 获取配置文件路径
+ static String config(String path) {
+ return getAssetPath('config/$path');
+ }
+
+ /// 获取共享资源路径
+ static String shared(String path) {
+ return 'assets/shared/$path';
+ }
+}
\ No newline at end of file
diff --git a/lib/app/config/business_logic_strategy.dart b/lib/app/config/business_logic_strategy.dart
new file mode 100644
index 0000000..e7a4c04
--- /dev/null
+++ b/lib/app/config/business_logic_strategy.dart
@@ -0,0 +1,1612 @@
+import 'package:flutter/material.dart';
+
+/// 业务逻辑策略接口
+/// 定义页面类可用的差异化业务逻辑方法
+abstract class BusinessLogicStrategy {
+ /// 获取首页Tab页配置
+ /// 返回: List<Widget> - 首页的页面组件列表
+ List getHomeTabPages(BuildContext context);
+
+ /// 获取首页Tab标签配置
+ /// 返回: List<Widget> - 首页的Tab标签列表
+ List getHomeTabLabels(BuildContext context);
+
+
+ /// 获取首页初始Tab索引
+ /// 返回: int - 初始Tab索引
+ int getHomeInitialTabIndex();
+
+ /// 处理头像点击事件
+ /// 参数: context - BuildContext
+ void onAvatarTap(BuildContext context);
+
+ /// 判断是否显示首充提示
+ /// 返回: bool - 是否显示首充提示
+ bool shouldShowFirstRechargePrompt();
+
+ /// 获取首充提示位置配置
+ /// 返回: Map<String, double?> - 包含top/bottom/start/end位置,未设置的键返回null
+ Map getFirstRechargePosition();
+
+ /// 处理首充提示点击事件
+ /// 参数: context - BuildContext
+ void onFirstRechargeTap(BuildContext context);
+
+ /// === 登录页面差异化方法 ===
+
+ /// 获取登录页面背景图像路径
+ /// 返回: String - 背景图像资源路径
+ String getLoginBackgroundImage();
+
+ /// 获取登录页面应用图标路径
+ /// 返回: String - 应用图标资源路径
+ String getLoginAppIcon();
+
+ /// 获取登录按钮背景颜色
+ /// 返回: Color - 按钮背景颜色
+ Color getLoginButtonColor();
+
+ /// 获取登录按钮渐变颜色(可选)
+ /// 返回: List<Color>? - 渐变颜色列表,null表示使用纯色
+ List? getLoginButtonGradient();
+
+ /// 获取登录按钮文本颜色
+ /// 返回: Color - 按钮文本颜色
+ Color getLoginButtonTextColor();
+
+ /// 获取登录标签文本颜色
+ /// 返回: Color - 标签文本颜色
+ Color getLoginLabelTextColor();
+
+ /// 获取登录输入框装饰
+ /// 返回: BoxDecoration - 输入框装饰样式
+ BoxDecoration getLoginInputDecoration();
+
+ /// 获取登录页面主要内边距
+ /// 返回: EdgeInsets - 页面内边距
+ EdgeInsets getLoginPagePadding();
+
+ /// 是否显示登录页面状态栏
+ /// 返回: bool - 是否显示状态栏
+ bool shouldShowLoginStatusBar();
+
+ /// 获取登录输入框提示文本颜色
+ /// 返回: Color - 提示文本颜色
+ Color getLoginHintTextColor();
+
+ /// 获取登录输入框文本颜色
+ /// 返回: Color - 输入框文本颜色
+ Color getLoginInputTextColor();
+
+
+ /// 是否显示密码房间图标
+ /// 返回: bool - 是否显示密码图标
+ bool shouldShowPasswordRoomIcon();
+
+ /// === 探索页面差异化方法 ===
+
+ /// 获取探索页面房间显示阈值
+ /// 返回: int - 显示在抽屉上方的房间数量阈值
+ int getExploreRoomDisplayThreshold();
+
+ /// 获取探索页面网格视图图标路径
+ /// 返回: String - 网格视图图标资源路径
+ String getExploreGridIcon();
+
+ /// 获取探索页面列表视图图标路径
+ /// 返回: String - 列表视图图标资源路径
+ String getExploreListIcon();
+
+ /// 获取探索页面排名图标路径模式
+ /// 参数: isGrid - 是否为网格视图
+ /// 参数: rank - 排名(1-based)
+ /// 返回: String - 排名图标资源路径
+ String getExploreRankIconPattern(bool isGrid, int rank);
+
+ /// 获取探索页面房间边框颜色
+ /// 返回: Color - 房间边框颜色
+ Color getExploreRoomBorderColor();
+
+ /// 获取探索页面房间边框宽度
+ /// 返回: double - 房间边框宽度
+ double getExploreRoomBorderWidth();
+
+ /// 获取探索页面抽屉内容网格列数
+ /// 返回: int - 网格列数
+ int getExploreDrawerGridCrossAxisCount();
+
+ /// 获取探索页面房间名称滚动阈值
+ /// 返回: int - 房间名称长度超过此值时显示滚动效果
+ int getExploreRoomNameMarqueeThreshold();
+
+ /// 获取探索页面房间描述滚动阈值
+ /// 返回: int - 房间描述长度超过此值时显示滚动效果
+ int getExploreRoomDescMarqueeThreshold();
+
+ /// === 个人主页差异化方法 ===
+
+ /// 获取个人主页默认背景图像路径
+ /// 返回: String - 默认背景图像资源路径
+ String getMePageDefaultBackgroundImage();
+
+ /// 获取个人主页性别背景图像路径
+ /// 参数: isFemale - 是否为女性用户
+ /// 返回: String - 性别背景图像资源路径
+ String getMePageGenderBackgroundImage(bool isFemale);
+
+ /// 获取个人主页CP对话框头像图像路径
+ /// 返回: String - CP对话框头像图像资源路径
+ String getMePageCpDialogHeadImage();
+
+ /// 获取个人主页默认头像图像路径
+ /// 返回: String - 默认头像图像资源路径
+ String getMePageDefaultAvatarImage();
+
+ /// 获取个人主页ID背景图像路径
+ /// 参数: hasSpecialId - 是否有特殊ID
+ /// 返回: String - ID背景图像资源路径
+ String getMePageIdBackgroundImage(bool hasSpecialId);
+
+ /// 获取个人主页复制ID图标路径
+ /// 返回: String - 复制ID图标资源路径
+ String getMePageCopyIdIcon();
+
+ /// 获取个人主页性别年龄背景图像路径
+ /// 参数: isFemale - 是否为女性用户
+ /// 返回: String - 性别年龄背景图像资源路径
+ String getMePageGenderAgeBackgroundImage(bool isFemale);
+
+ /// 获取个人主页访客关注粉丝背景图像路径
+ /// 参数: isFemale - 是否为女性用户
+ /// 返回: String - 访客关注粉丝背景图像资源路径
+ String getMePageVisitorsFollowFansBackgroundImage(bool isFemale);
+
+ /// 获取个人主页编辑用户信息图标路径
+ /// 返回: String - 编辑用户信息图标资源路径
+ String getMePageEditUserInfoIcon();
+
+ /// 获取个人主页闪耀文本颜色
+ /// 返回: Color - 闪耀文本颜色
+ Color getMePageShineColor();
+
+ /// 获取个人主页渐变颜色
+ /// 参数: isFemale - 是否为女性用户
+ /// 返回: List<Color> - 渐变颜色列表
+ List getMePageGradientColors(bool isFemale);
+
+ /// 获取个人主页Tab指示器渐变颜色
+ /// 参数: isFemale - 是否为女性用户
+ /// 返回: List<Color> - Tab指示器渐变颜色列表
+ List getMePageTabIndicatorGradient(bool isFemale);
+
+ /// 获取个人主页访客关注粉丝文本颜色
+ /// 返回: Color - 访客关注粉丝文本颜色
+ Color getMePageVisitorsFollowFansTextColor();
+
+ /// 获取个人主页初始Tab索引
+ /// 返回: int - 初始Tab索引
+ int getMePageInitialTabIndex();
+
+ /// 获取个人主页滚动透明度计算阈值
+ /// 返回: double - 滚动透明度计算阈值
+ double getMePageScrollOpacityThreshold();
+
+ /// 获取个人主页昵称滚动显示阈值
+ /// 返回: int - 昵称长度超过此值时显示滚动效果
+ int getMePageNicknameScrollThreshold();
+
+ /// 获取个人主页年龄显示宽度阈值
+ /// 返回: int - 年龄超过此值时调整显示宽度
+ int getMePageAgeDisplayWidthThreshold();
+
+ /// 获取个人主页头像显示透明度阈值
+ /// 返回: double - 透明度超过此值时显示头像
+ double getMePageOpacityThresholdForAvatarDisplay();
+
+ /// === 热门页面差异化方法 ===
+
+ /// 获取热门页面排行榜背景图像路径
+ /// 参数: leaderboardType - 排行榜类型 ('room', 'wealth', 'charm')
+ /// 返回: String - 背景图像资源路径
+ String getPopularLeaderboardBackgroundImage(String leaderboardType);
+
+ /// === 游戏页面差异化方法 ===
+
+ /// 获取游戏页面排名背景图像路径
+ /// 参数: rank - 排名 (1, 2, 3, 4)
+ /// 返回: String - 排名背景图像资源路径
+ String getGameRankBackgroundImage(int rank);
+
+ /// 获取游戏页面排名图标路径
+ /// 参数: rank - 排名 (1, 2, 3, 4)
+ /// 返回: String - 排名图标资源路径
+ String getGameRankIcon(int rank);
+
+ /// 获取游戏页面主题颜色
+ /// 返回: Color - 游戏页面主题颜色
+ Color getGamePageThemeColor();
+
+ /// 获取游戏页面背景颜色
+ /// 返回: Color - 游戏页面背景颜色
+ Color getGamePageBackgroundColor();
+
+ /// 获取游戏页面列数配置
+ /// 返回: int - 网格列数
+ int getGamePageGridCrossAxisCount();
+
+ /// 获取游戏页面网格高度配置
+ /// 返回: double - 网格高度比例
+ double getGamePageGridChildAspectRatio();
+
+ /// 获取游戏页面排名文本颜色
+ /// 参数: rank - 排名 (1, 2, 3, 4)
+ /// 返回: Color - 排名文本颜色
+ Color getGameRankTextColor(int rank);
+
+ /// 获取游戏页面渐变第二颜色
+ /// 返回: Color - 渐变第二颜色
+ Color getGamePageGradientSecondColor();
+
+ /// 获取游戏页面热门标签背景图像路径
+ /// 返回: String - 热门标签背景图像资源路径
+ String getGameHotTagBackgroundImage();
+
+ /// 获取游戏页面新游戏标签图像路径
+ /// 返回: String - 新游戏标签图像资源路径
+ String getGameNewTagImage();
+
+ /// 获取游戏页面遮罩图像路径
+ /// 返回: String - 游戏页面遮罩图像资源路径
+ String getGamePageMaskImage();
+
+ /// === VIP页面差异化方法 ===
+
+ /// 获取VIP页面背景图像路径
+ /// 参数: vipLevel - VIP等级 (1-9)
+ /// 返回: String - VIP背景图像资源路径
+ String getVipPageBackgroundImage(int vipLevel);
+
+ /// 获取VIP页面图标路径
+ /// 参数: vipLevel - VIP等级 (1-9)
+ /// 返回: String - VIP图标资源路径
+ String getVipPageIcon(int vipLevel);
+
+ /// 获取VIP页面按钮渐变颜色
+ /// 返回: List<Color> - 按钮渐变颜色列表
+ List getVipPageButtonGradient();
+
+ /// 获取VIP页面网格列数配置
+ /// 返回: int - 网格列数
+ int getVipPageGridCrossAxisCount();
+
+ /// 获取VIP页面网格高度配置
+ /// 返回: double - 网格高度比例
+ double getVipPageGridChildAspectRatio();
+
+ /// 获取VIP页面头部背景图像路径
+ /// 参数: vipLevel - VIP等级 (1-9)
+ /// 返回: String - VIP头部背景图像资源路径
+ String getVipPageHeadBackgroundImage(int vipLevel);
+
+ /// 获取VIP页面Tab选中状态图标路径
+ /// 参数: vipLevel - VIP等级 (1-9)
+ /// 返回: String - Tab选中状态图标资源路径
+ String getVipPageTabSelectedIcon(int vipLevel);
+
+ /// 获取VIP页面Tab未选中状态图标路径
+ /// 参数: vipLevel - VIP等级 (1-9)
+ /// 返回: String - Tab未选中状态图标资源路径
+ String getVipPageTabUnselectedIcon(int vipLevel);
+
+ /// 获取VIP页面大图标路径
+ /// 参数: vipLevel - VIP等级 (1-9)
+ /// 返回: String - 大图标资源路径
+ String getVipPageLargeIcon(int vipLevel);
+
+ /// 获取VIP页面标题图像路径
+ /// 参数: vipLevel - VIP等级 (1-9)
+ /// 返回: String - 标题图像资源路径
+ String getVipPageTitleImage(int vipLevel);
+
+ /// 获取VIP页面标签图像路径
+ /// 参数: vipLevel - VIP等级 (1-9)
+ /// 参数: tagIndex - 标签索引 (1或2)
+ /// 返回: String - 标签图像资源路径
+ String getVipPageTagImage(int vipLevel, int tagIndex);
+
+ /// 获取VIP页面功能项背景图像路径
+ /// 参数: vipLevel - VIP等级 (1-9)
+ /// 返回: String - 功能项背景图像资源路径
+ String getVipPageItemBackgroundImage(int vipLevel);
+
+ /// 获取VIP页面特权图标路径
+ /// 参数: vipLevel - VIP等级 (1-9)
+ /// 参数: privilegeIndex - 特权索引 (1-14)
+ /// 返回: String - 特权图标资源路径
+ String getVipPagePrivilegeIcon(int vipLevel, int privilegeIndex);
+
+ /// 获取VIP页面功能图标路径
+ /// 参数: vipLevel - VIP等级 (1-9)
+ /// 参数: featureName - 功能名称 ('badge', 'profile_frame', 'profile_card', 'entrance_effect', 'special_gift_tassel', 'mic_rippl_theme', 'chatbox', 'room_cover_headdress', 'exclusive_vehicles')
+ /// 返回: String - 功能图标资源路径
+ String getVipPageFeatureIcon(int vipLevel, String featureName);
+
+ /// 获取VIP页面预览图像路径
+ /// 参数: vipLevel - VIP等级 (1-9)
+ /// 参数: previewType - 预览类型 ('rev', 'pre')
+ /// 参数: featureName - 功能名称
+ /// 返回: String - 预览图像资源路径
+ String getVipPagePreviewImage(
+ int vipLevel,
+ String previewType,
+ String featureName,
+ );
+
+ /// 获取VIP页面购买背景图像路径
+ /// 参数: vipLevel - VIP等级 (1-9)
+ /// 返回: String - 购买背景图像资源路径
+ String getVipPagePurchaseBackgroundImage(int vipLevel);
+
+ /// 获取VIP页面购买按钮图像路径
+ /// 返回: String - 购买按钮图像资源路径
+ String getVipPagePurchaseButtonImage();
+
+ /// 获取VIP页面文本颜色
+ /// 参数: vipLevel - VIP等级 (1-9)
+ /// 返回: Color - 文本颜色
+ Color getVipPageTextColor(int vipLevel);
+
+ /// === 通用页面差异化方法 ===
+
+ /// 获取通用页面排名背景图像路径模式
+ /// 参数: pageType - 页面类型 ('top', 'local', 'global', 'today')
+ /// 参数: rank - 排名 (1-based)
+ /// 返回: String - 排名背景图像资源路径
+ String getCommonRankBackgroundImage(String pageType, int rank);
+
+ /// 获取通用页面排名图标路径模式
+ /// 参数: pageType - 页面类型 ('top', 'local', 'global', 'today')
+ /// 参数: rank - 排名 (1-based)
+ /// 返回: String - 排名图标资源路径
+ String getCommonRankIcon(String pageType, int rank);
+
+ /// 获取通用页面网格列数配置
+ /// 参数: pageType - 页面类型 ('top', 'local', 'global', 'today')
+ /// 返回: int - 网格列数
+ int getCommonPageGridCrossAxisCount(String pageType);
+
+ /// 获取通用页面网格高度配置
+ /// 参数: pageType - 页面类型 ('top', 'local', 'global', 'today')
+ /// 返回: double - 网格高度比例
+ double getCommonPageGridChildAspectRatio(String pageType);
+
+ /// === 个人主页2 (MePage2) 差异化方法 ===
+
+ /// 获取MePage2钱包区域背景配置
+ /// 返回: Map - 包含渐变颜色、圆角、阴影等配置
+ Map getMePage2WalletBackground();
+
+ /// 获取MePage2统计信息颜色配置
+ /// 返回: Map - 包含数字颜色、标签颜色、分割线颜色
+ Map getMePage2StatisticsColors();
+
+ /// 获取MePage2功能卡片图标路径映射
+ /// 返回: Map - 功能名称到图标路径的映射
+ Map getMePage2FunctionIcons();
+
+ /// 获取MePage2卡片样式配置
+ /// 返回: Map - 包含圆角、阴影、边框等配置
+ Map getMePage2CardStyles();
+
+ /// === Admin编辑页面差异化方法 ===
+
+ /// 获取Admin编辑页面背景图像路径
+ /// 返回: String - 背景图像资源路径
+ String getAdminEditingBackgroundImage();
+
+ /// 获取Admin编辑页面按钮渐变颜色
+ /// 参数: buttonType - 按钮类型 ('warning', 'adjust')
+ /// 返回: List - 渐变颜色列表
+ List getAdminEditingButtonGradient(String buttonType);
+
+ /// 获取Admin编辑页面图标路径
+ /// 参数: iconType - 图标类型 ('specialIdBg', 'normalIdBg', 'copyId', 'addPic', 'closePic', 'checked')
+ /// 返回: String - 图标资源路径
+ String getAdminEditingIcon(String iconType);
+
+ /// 获取Admin编辑页面输入框装饰
+ /// 返回: BoxDecoration - 输入框装饰样式
+ BoxDecoration getAdminEditingInputDecoration();
+
+ /// 获取Admin编辑页面最大图片上传数量
+ /// 返回: int - 最大图片上传数量
+ int getAdminEditingMaxImageUploadCount();
+
+ /// 获取Admin编辑页面描述最大长度
+ /// 返回: int - 描述文本框最大字符数
+ int getAdminEditingDescriptionMaxLength();
+
+ /// 获取Admin编辑页面违规类型映射
+ /// 参数: targetType - 目标类型 ('User', 'Room')
+ /// 返回: Map - 违规类型名称到类型ID的映射
+ Map getAdminEditingViolationTypeMapping(String targetType);
+
+ /// === Admin搜索页面差异化方法 ===
+
+ /// 获取Admin搜索页面背景图像路径
+ /// 参数: pageType - 页面类型 ('userSearch', 'roomSearch')
+ /// 返回: String - 背景图像资源路径
+ String getAdminSearchBackgroundImage(String pageType);
+
+ /// 获取Admin搜索页面搜索按钮渐变颜色
+ /// 参数: pageType - 页面类型 ('userSearch', 'roomSearch')
+ /// 返回: List - 渐变颜色列表
+ List getAdminSearchButtonGradient(String pageType);
+
+ /// 获取Admin搜索页面搜索按钮文本颜色
+ /// 参数: pageType - 页面类型 ('userSearch', 'roomSearch')
+ /// 返回: Color - 文本颜色
+ Color getAdminSearchButtonTextColor(String pageType);
+
+ /// 获取Admin搜索页面编辑图标路径
+ /// 参数: pageType - 页面类型 ('userSearch', 'roomSearch')
+ /// 返回: String - 编辑图标资源路径
+ String getAdminSearchEditIcon(String pageType);
+
+ /// 获取Admin搜索页面搜索框边框颜色
+ /// 参数: pageType - 页面类型 ('userSearch', 'roomSearch')
+ /// 返回: Color - 边框颜色
+ Color getAdminSearchInputBorderColor(String pageType);
+
+ /// 获取Admin搜索页面搜索框文本颜色
+ /// 参数: pageType - 页面类型 ('userSearch', 'roomSearch')
+ /// 返回: Color - 文本颜色
+ Color getAdminSearchInputTextColor(String pageType);
+
+ /// 获取Admin搜索页面用户信息图标路径
+ /// 参数: iconType - 图标类型 ('specialIdBg', 'normalIdBg', 'copyId')
+ /// 返回: String - 图标资源路径
+ String getAdminSearchUserInfoIcon(String iconType);
+
+ /// === Auth页面差异化方法 ===
+
+ /// === 主登录页面 (LoginPage) 方法 ===
+
+ /// 获取主登录页面背景图像路径
+ /// 返回: String - 背景图像资源路径
+ String getLoginMainBackgroundImage();
+
+ /// 获取主登录页面应用图标路径
+ /// 返回: String - 应用图标资源路径
+ String getLoginMainAppIcon();
+
+ /// 获取主登录页面Google登录图标路径
+ /// 返回: String - Google登录图标资源路径
+ String getLoginMainGoogleIcon();
+
+ /// 获取主登录页面Apple登录图标路径
+ /// 返回: String - Apple登录图标资源路径
+ String getLoginMainAppleIcon();
+
+ /// 获取主登录页面账户登录图标路径
+ /// 返回: String - 账户登录图标资源路径
+ String getLoginMainAccountIcon();
+
+ /// 获取主登录页面协议选择图标路径
+ /// 参数: isSelected - 是否选中状态
+ /// 返回: String - 协议选择图标资源路径
+ String getLoginMainAgreementIcon(bool isSelected);
+
+ /// 获取主登录页面分隔线颜色
+ /// 返回: Color - 分隔线颜色
+ Color getLoginMainDividerColor();
+
+ /// 获取主登录页面按钮边框颜色
+ /// 返回: Color - 按钮边框颜色
+ Color getLoginMainButtonBorderColor();
+
+ /// 获取主登录页面按钮背景颜色
+ /// 返回: Color - 按钮背景颜色
+ Color getLoginMainButtonBackgroundColor();
+
+ /// 获取主登录页面链接文本颜色
+ /// 返回: Color - 链接文本颜色
+ Color getLoginMainLinkColor();
+
+ /// 获取主登录页面按钮文本颜色
+ /// 返回: Color - 按钮文本颜色
+ Color getLoginMainButtonTextColor();
+
+ /// === 编辑个人资料页面 (SCEditProfilePage) 方法 ===
+
+ /// 获取编辑个人资料页面背景图像路径
+ /// 返回: String - 背景图像资源路径
+ String getEditProfileBackgroundImage();
+
+ /// 获取编辑个人资料页面默认头像图像路径
+ /// 返回: String - 默认头像图像资源路径
+ String getEditProfileDefaultAvatarImage();
+
+ /// 获取编辑个人资料页面性别图标路径
+ /// 参数: isMale - 是否为男性图标
+ /// 返回: String - 性别图标资源路径
+ String getEditProfileGenderIcon(bool isMale);
+
+ /// 获取编辑个人资料页面性别按钮渐变颜色
+ /// 参数: isMale - 是否为男性按钮
+ /// 参数: isSelected - 是否选中状态
+ /// 返回: List - 渐变颜色列表
+ List getEditProfileGenderButtonGradient(bool isMale, bool isSelected);
+
+ /// 获取编辑个人资料页面输入框背景颜色
+ /// 返回: Color - 输入框背景颜色
+ Color getEditProfileInputBackgroundColor();
+
+ /// 获取编辑个人资料页面日期选择确认按钮颜色
+ /// 返回: Color - 日期选择确认按钮颜色
+ Color getEditProfileDatePickerConfirmColor();
+
+ /// 获取编辑个人资料页面继续按钮颜色
+ /// 返回: Color - 继续按钮颜色
+ Color getEditProfileContinueButtonColor();
+
+ /// === Country页面差异化方法 ===
+
+ /// 获取Country页面选择确认图标路径
+ /// 返回: String - 选择确认图标资源路径
+ String getCountrySelectOkIcon();
+
+ /// 获取Country页面选择未确认图标路径
+ /// 返回: String - 选择未确认图标资源路径
+ String getCountrySelectUnOkIcon();
+
+ /// 获取Country页面单选选中图标路径
+ /// 返回: String - 单选选中图标资源路径
+ String getCountryRadioSelectedIcon();
+
+ /// 获取Country页面单选未选中图标路径
+ /// 返回: String - 单选未选中图标资源路径
+ String getCountryRadioUnselectedIcon();
+
+ /// 获取Country页面国家列表项边框颜色
+ /// 返回: Color - 国家列表项边框颜色
+ Color getCountryItemBorderColor();
+
+ /// 获取Country页面Scaffold背景颜色
+ /// 返回: Color - Scaffold背景颜色
+ Color getCountryPageScaffoldBackgroundColor();
+
+ /// 获取Country页面图标颜色
+ /// 返回: Color - 图标颜色
+ Color getCountryPageIconColor();
+
+ /// 获取Country页面主要文本颜色
+ /// 返回: Color - 主要文本颜色
+ Color getCountryPagePrimaryTextColor();
+
+ /// 获取Country页面次要文本颜色
+ /// 返回: Color - 次要文本颜色
+ Color getCountryPageSecondaryTextColor();
+
+ /// 获取Country页面容器背景颜色
+ /// 返回: Color - 容器背景颜色
+ Color getCountryPageContainerBackgroundColor();
+
+ /// === Chat页面差异化方法 ===
+
+ /// === 消息页面 (SCMessagePage) 方法 ===
+
+ /// 获取消息页面索引遮罩图标路径
+ /// 返回: String - 索引遮罩图标资源路径
+ String getMessagePageIndexMaskIcon();
+
+ /// 获取消息页面公告标签图标路径
+ /// 返回: String - 公告标签图标资源路径
+ String getMessagePageAnnouncementTagIcon();
+
+ /// 获取消息页面活动消息图标路径
+ /// 返回: String - 活动消息图标资源路径
+ String getMessagePageActivityMessageIcon();
+
+ /// 获取消息页面活动消息标题背景图标路径
+ /// 参数: isRtl - 是否为RTL布局(从右到左)
+ /// 返回: String - 活动消息标题背景图标资源路径
+ String getMessagePageActivityTitleBackground(bool isRtl);
+
+ /// 获取消息页面系统消息图标路径
+ /// 返回: String - 系统消息图标资源路径
+ String getMessagePageSystemMessageIcon();
+
+ /// 获取消息页面系统消息标题背景图标路径
+ /// 参数: isRtl - 是否为RTL布局(从右到左)
+ /// 返回: String - 系统消息标题背景图标资源路径
+ String getMessagePageSystemTitleBackground(bool isRtl);
+
+ /// 获取消息页面通知消息图标路径
+ /// 返回: String - 通知消息图标资源路径
+ String getMessagePageNotificationMessageIcon();
+
+ /// 获取消息页面通知消息标题背景图标路径
+ /// 参数: isRtl - 是否为RTL布局(从右到左)
+ /// 返回: String - 通知消息标题背景图标资源路径
+ String getMessagePageNotificationTitleBackground(bool isRtl);
+
+ /// === 聊天页面 (SCMessageChatPage) 方法 ===
+
+ /// 获取聊天页面房间设置背景图像路径
+ /// 返回: String - 房间设置背景图像资源路径
+ String getSCMessageChatPageRoomSettingBackground();
+
+ /// 获取聊天页面表情图标路径
+ /// 返回: String - 表情图标资源路径
+ String getSCMessageChatPageEmojiIcon();
+
+ /// 获取聊天页面聊天键盘图标路径
+ /// 返回: String - 聊天键盘图标资源路径
+ String getSCMessageChatPageChatKeyboardIcon();
+
+ /// 获取聊天页面添加图标路径
+ /// 返回: String - 添加图标资源路径
+ String getSCMessageChatPageAddIcon();
+
+ /// 获取聊天页面发送消息图标路径
+ /// 返回: String - 发送消息图标资源路径
+ String getSCMessageChatPageSendMessageIcon();
+
+ /// 获取聊天页面相机图标路径
+ /// 返回: String - 相机图标资源路径
+ String getSCMessageChatPageCameraIcon();
+
+ /// 获取聊天页面图片图标路径
+ /// 返回: String - 图片图标资源路径
+ String getSCMessageChatPagePictureIcon();
+
+ /// 获取聊天页面红包图标路径
+ /// 返回: String - 红包图标资源路径
+ String getSCMessageChatPageRedEnvelopeIcon();
+
+ /// 获取聊天页面红包消息背景图像路径
+ /// 返回: String - 红包消息背景图像资源路径
+ String getSCMessageChatPageRedEnvelopeMessageBackground();
+
+ /// 获取聊天页面红包配置标签按钮图标路径
+ /// 返回: String - 红包配置标签按钮图标资源路径
+ String getSCMessageChatPageRedEnvelopeConfigTabButtonIcon();
+
+ /// 获取聊天页面红包消息项背景图像路径
+ /// 返回: String - 红包消息项背景图像资源路径
+ String getSCMessageChatPageRedEnvelopeMessageItemBackground();
+
+ /// 获取聊天页面红包接收包图标路径
+ /// 返回: String - 红包接收包图标资源路径
+ String getSCMessageChatPageRedEnvelopeReceivePackageIcon();
+
+ /// 获取聊天页面红包打开背景图像路径
+ /// 返回: String - 红包打开背景图像资源路径
+ String getSCMessageChatPageRedEnvelopeOpenBackground();
+
+ /// 获取聊天页面红包已打开背景图像路径
+ /// 返回: String - 红包已打开背景图像资源路径
+ String getSCMessageChatPageRedEnvelopeOpenedBackground();
+
+ /// 获取聊天页面金币图标路径
+ /// 返回: String - 金币图标资源路径
+ String getSCMessageChatPageGoldCoinIcon();
+
+ /// 获取聊天页面消息菜单删除图标路径
+ /// 返回: String - 消息菜单删除图标资源路径
+ String getSCMessageChatPageMessageMenuDeleteIcon();
+
+ /// 获取聊天页面消息菜单复制图标路径
+ /// 返回: String - 消息菜单复制图标资源路径
+ String getSCMessageChatPageMessageMenuCopyIcon();
+
+ /// 获取聊天页面消息菜单撤回图标路径
+ /// 返回: String - 消息菜单撤回图标资源路径
+ String getSCMessageChatPageMessageMenuRecallIcon();
+
+ /// 获取聊天页面加载图标路径
+ /// 返回: String - 加载图标资源路径
+ String getSCMessageChatPageLoadingIcon();
+
+ /// 获取聊天页面系统头像图像路径
+ /// 返回: String - 系统头像图像资源路径
+ String getSCMessageChatPageSystemHeadImage();
+
+ /// === 通用图标差异化方法 ===
+
+ /// 获取性别背景图像路径
+ /// 参数: isFemale - 是否为女性
+ /// 返回: String - 性别背景图像资源路径
+ String getGenderBackgroundImage(bool isFemale);
+
+ /// 获取通用ID背景图像路径
+ /// 参数: hasSpecialId - 是否有特殊ID
+ /// 返回: String - ID背景图像资源路径
+ String getIdBackgroundImage(bool hasSpecialId);
+
+ /// 获取通用复制ID图标路径
+ /// 返回: String - 复制ID图标资源路径
+ String getCopyIdIcon();
+
+ /// 获取通用选择图标路径
+ /// 返回: String - 选择图标资源路径
+ String getCommonSelectIcon();
+
+ /// 获取通用未选择图标路径
+ /// 返回: String - 未选择图标资源路径
+ String getCommonUnselectIcon();
+
+ /// === Gift页面差异化方法 ===
+
+ /// 获取礼物页面首充房间标签图标路径
+ /// 返回: String - 首充房间标签图标资源路径
+ String getGiftPageFirstRechargeRoomTagIcon();
+
+ /// 获取礼物页面金币图标路径
+ /// 返回: String - 金币图标资源路径
+ String getGiftPageGoldCoinIcon();
+
+ /// 获取礼物页面赠送类型背景图像路径
+ /// 返回: String - 赠送类型背景图像资源路径
+ String getGiftPageGiveTypeBackground();
+
+ /// 获取礼物页面活动礼物头部背景图像路径
+ /// 参数: giftType - 礼物类型 ('ACTIVITY', 'LUCK', 'CP', 'MAGIC')
+ /// 返回: String - 活动礼物头部背景图像资源路径
+ String getGiftPageActivityGiftHeadBackground(String giftType);
+
+ /// 获取礼物页面自定义规则图标路径
+ /// 返回: String - 自定义规则图标资源路径
+ String getGiftPageCustomizedRuleIcon();
+
+ /// 获取礼物页面特效礼物图标路径
+ /// 参数: giftType - 礼物类型标识符
+ /// 返回: String - 特效礼物图标资源路径
+ String getGiftPageGiftEffectIcon(String giftType);
+
+ /// 获取礼物页面音乐礼物图标路径
+ /// 参数: giftType - 礼物类型标识符
+ /// 返回: String - 音乐礼物图标资源路径
+ String getGiftPageGiftMusicIcon(String giftType);
+
+ /// 获取礼物页面幸运礼物图标路径
+ /// 参数: giftType - 礼物类型标识符
+ /// 返回: String - 幸运礼物图标资源路径
+ String getGiftPageGiftLuckIcon(String giftType);
+
+ /// 获取礼物页面CP礼物图标路径
+ /// 参数: giftType - 礼物类型标识符
+ /// 返回: String - CP礼物图标资源路径
+ String getGiftPageGiftCpIcon(String giftType);
+
+ /// 获取礼物页面首充文本图标路径
+ /// 参数: languageCode - 语言代码 ('ar'为阿拉伯语, 'en'为英语)
+ /// 返回: String - 首充文本图标资源路径
+ String getGiftPageFirstRechargeTextIcon(String languageCode);
+
+ /// 获取礼物页面"全开麦"图标路径
+ /// 返回: String - "全开麦"图标资源路径
+ String getGiftPageAllOnMicrophoneIcon();
+
+ /// 获取礼物页面"用户开麦"图标路径
+ /// 返回: String - "用户开麦"图标资源路径
+ String getGiftPageUsersOnMicrophoneIcon();
+
+ /// 获取礼物页面"房间所有人"图标路径
+ /// 返回: String - "房间所有人"图标资源路径
+ String getGiftPageAllInTheRoomIcon();
+
+ /// === Media页面差异化方法 ===
+
+ /// 获取图片预览页面背景颜色
+ /// 返回: Color - 页面背景颜色
+ Color getImagePreviewBackgroundColor();
+
+ /// 获取图片预览画廊背景颜色
+ /// 返回: Color - 画廊背景颜色
+ Color getImagePreviewGalleryBackgroundColor();
+
+ /// 获取图片预览AppBar背景颜色
+ /// 返回: Color - AppBar背景颜色
+ Color getImagePreviewAppBarBackgroundColor();
+
+ /// 获取图片预览返回图标颜色
+ /// 返回: Color - 返回图标颜色
+ Color getImagePreviewBackIconColor();
+
+ /// 获取图片预览文本颜色
+ /// 返回: Color - 文本颜色
+ Color getImagePreviewTextColor();
+
+ /// 获取图片预览加载指示器颜色
+ /// 返回: Color - 加载指示器颜色
+ Color getImagePreviewLoadingIndicatorColor();
+
+ /// 获取图片预览AppBar透明度
+ /// 返回: double - AppBar透明度值
+ double getImagePreviewAppBarOpacity();
+
+ /// 获取视频播放页面背景颜色
+ /// 返回: Color - 页面背景颜色
+ Color getVideoPlayerBackgroundColor();
+
+ /// 获取视频播放控制界面背景颜色
+ /// 返回: Color - 控制界面背景颜色
+ Color getVideoPlayerControlsBackgroundColor();
+
+ /// 获取视频播放图标颜色
+ /// 返回: Color - 图标颜色
+ Color getVideoPlayerIconColor();
+
+ /// 获取视频播放底部控制栏背景颜色
+ /// 返回: Color - 底部控制栏背景颜色
+ Color getVideoPlayerBottomControlsBackgroundColor();
+
+ /// 获取视频播放进度条活动颜色
+ /// 返回: Color - 进度条活动部分颜色
+ Color getVideoPlayerProgressBarActiveColor();
+
+ /// 获取视频播放进度条非活动颜色
+ /// 返回: Color - 进度条非活动部分颜色
+ Color getVideoPlayerProgressBarInactiveColor();
+
+ /// 获取视频播放文本颜色
+ /// 返回: Color - 文本颜色
+ Color getVideoPlayerTextColor();
+
+ /// 获取视频播放加载指示器颜色
+ /// 返回: Color - 加载指示器颜色
+ Color getVideoPlayerLoadingIndicatorColor();
+
+ /// 获取视频播放控制界面透明度
+ /// 返回: double - 控制界面透明度值
+ double getVideoPlayerControlsOpacity();
+
+ /// 获取视频播放底部控制栏透明度
+ /// 返回: double - 底部控制栏透明度值
+ double getVideoPlayerBottomControlsOpacity();
+
+ /// 获取视频播放控制界面显示持续时间(秒)
+ /// 返回: int - 控制界面显示持续时间(秒)
+ int getVideoPlayerControlsDisplayDuration();
+
+ /// === 举报页面差异化方法 ===
+
+ /// 获取举报页面背景图像路径
+ /// 返回: String - 背景图像资源路径
+ String getReportPageBackgroundImage();
+
+ /// 获取举报页面提示文本颜色
+ /// 返回: Color - 提示文本颜色
+ Color getReportPageHintTextColor();
+
+ /// 获取举报页面容器背景颜色
+ /// 返回: Color - 容器背景颜色
+ Color getReportPageContainerBackgroundColor();
+
+ /// 获取举报页面边框颜色
+ /// 返回: Color - 边框颜色
+ Color getReportPageBorderColor();
+
+ /// 获取举报页面主要文本颜色
+ /// 返回: Color - 主要文本颜色
+ Color getReportPagePrimaryTextColor();
+
+ /// 获取举报页面次级提示文本颜色
+ /// 返回: Color - 次级提示文本颜色
+ Color getReportPageSecondaryHintTextColor();
+
+ /// 获取举报页面未选中边框颜色
+ /// 返回: Color - 未选中边框颜色
+ Color getReportPageUnselectedBorderColor();
+
+ /// 获取举报页面提交按钮背景颜色
+ /// 返回: Color - 提交按钮背景颜色
+ Color getReportPageSubmitButtonBackgroundColor();
+
+ /// 获取举报页面提交按钮文本颜色
+ /// 返回: Color - 提交按钮文本颜色
+ Color getReportPageSubmitButtonTextColor();
+
+ /// 获取举报页面图标路径
+ /// 参数: iconType - 图标类型 ('addPic', 'closePic', 'checked')
+ /// 返回: String - 图标资源路径
+ String getReportPageIcon(String iconType);
+
+ /// === 语音房间页面差异化方法 ===
+
+ /// 获取语音房间页面背景颜色
+ /// 返回: Color - 页面背景颜色
+ Color getVoiceRoomBackgroundColor();
+
+ /// 获取语音房间页面Tab标签选中颜色
+ /// 返回: Color - Tab标签选中颜色
+ Color getVoiceRoomTabLabelColor();
+
+ /// 获取语音房间页面Tab标签未选中颜色
+ /// 返回: Color - Tab标签未选中颜色
+ Color getVoiceRoomTabUnselectedLabelColor();
+
+ /// 获取语音房间页面Tab指示器颜色
+ /// 返回: Color - Tab指示器颜色
+ Color getVoiceRoomTabIndicatorColor();
+
+ /// 获取语音房间页面Tab分割线颜色
+ /// 返回: Color - Tab分割线颜色
+ Color getVoiceRoomTabDividerColor();
+
+ /// 获取语音房间页面Tab标签内边距
+ /// 返回: EdgeInsets - Tab标签内边距
+ EdgeInsets getVoiceRoomTabLabelPadding();
+
+ /// 获取语音房间页面聊天容器外边距
+ /// 返回: EdgeInsets - 聊天容器外边距
+ EdgeInsetsDirectional getVoiceRoomChatContainerMargin();
+
+ /// 获取语音房间页面Tab标签选中文本样式
+ /// 返回: TextStyle - Tab标签选中文本样式
+ TextStyle getVoiceRoomTabLabelStyle();
+
+ /// 获取语音房间页面Tab标签未选中文本样式
+ /// 返回: TextStyle - Tab标签未选中文本样式
+ TextStyle getVoiceRoomTabUnselectedLabelStyle();
+
+ /// 获取语音房间默认背景图像路径
+ /// 返回: String - 默认背景图像资源路径
+ String getVoiceRoomDefaultBackgroundImage();
+
+ /// === 钱包页面差异化方法 ===
+
+ /// === 充值页面差异化方法 ===
+
+ /// 获取充值页面背景图像路径
+ /// 返回: String - 背景图像资源路径
+ String getRechargePageBackgroundImage();
+
+ /// 获取充值页面Scaffold背景颜色
+ /// 返回: Color - Scaffold背景颜色
+ Color getRechargePageScaffoldBackgroundColor();
+
+ /// 获取充值页面对话框屏障颜色
+ /// 返回: Color - 对话框屏障颜色
+ Color getRechargePageDialogBarrierColor();
+
+ /// 获取充值页面对话框容器背景颜色
+ /// 返回: Color - 对话框容器背景颜色
+ Color getRechargePageDialogContainerBackgroundColor();
+
+ /// 获取充值页面对话框文本颜色
+ /// 返回: Color - 对话框文本颜色
+ Color getRechargePageDialogTextColor();
+
+ /// 获取充值页面主容器背景颜色
+ /// 返回: Color - 主容器背景颜色
+ Color getRechargePageMainContainerBackgroundColor();
+
+ /// 获取充值页面按钮背景颜色
+ /// 返回: Color - 按钮背景颜色
+ Color getRechargePageButtonBackgroundColor();
+
+ /// 获取充值页面按钮文本颜色
+ /// 返回: Color - 按钮文本颜色
+ Color getRechargePageButtonTextColor();
+
+ /// 获取充值页面钱包背景图像路径
+ /// 返回: String - 钱包背景图像资源路径
+ String getRechargePageWalletBackgroundImage();
+
+ /// 获取充值页面钱包图标路径
+ /// 返回: String - 钱包图标资源路径
+ String getRechargePageWalletIcon();
+
+ /// 获取充值页面钱包文本颜色
+ /// 返回: Color - 钱包文本颜色
+ Color getRechargePageWalletTextColor();
+
+ /// 获取充值页面金币图标路径(默认图标)
+ /// 返回: String - 金币图标资源路径
+ String getRechargePageGoldIcon();
+
+ /// 获取充值页面选中项背景颜色
+ /// 返回: Color - 选中项背景颜色
+ Color getRechargePageSelectedItemBackgroundColor();
+
+ /// 获取充值页面选中项边框颜色
+ /// 返回: Color - 选中项边框颜色
+ Color getRechargePageSelectedItemBorderColor();
+
+ /// 获取充值页面未选中项边框颜色
+ /// 返回: Color - 未选中项边框颜色
+ Color getRechargePageUnselectedItemBorderColor();
+
+ /// 获取充值页面未选中项背景颜色
+ /// 返回: Color - 未选中项背景颜色
+ Color getRechargePageUnselectedItemBackgroundColor();
+
+ /// 获取充值页面项目文本颜色
+ /// 返回: Color - 项目文本颜色
+ Color getRechargePageItemTextColor();
+
+ /// 获取充值页面价格文本颜色
+ /// 返回: Color - 价格文本颜色
+ Color getRechargePageItemPriceTextColor();
+
+ /// 根据索引获取充值页面金币图标路径
+ /// 参数: index - 项目索引 (0, 1, 2)
+ /// 返回: String - 金币图标资源路径
+ String getRechargePageGoldIconByIndex(int index);
+
+ /// 获取充值页面Apple产品项背景颜色
+ /// 返回: Color - Apple产品项背景颜色
+ Color getRechargePageAppleItemBackgroundColor();
+
+ /// === 金币记录页面差异化方法 ===
+
+ /// 获取金币记录页面背景图像路径
+ /// 返回: String - 背景图像资源路径
+ String getGoldRecordPageBackgroundImage();
+
+ /// 获取金币记录页面Scaffold背景颜色
+ /// 返回: Color - Scaffold背景颜色
+ Color getGoldRecordPageScaffoldBackgroundColor();
+
+ /// 获取金币记录页面列表背景颜色
+ /// 返回: Color - 列表背景颜色
+ Color getGoldRecordSCPageListBackgroundColor();
+
+ /// 获取金币记录页面容器背景颜色
+ /// 返回: Color - 容器背景颜色
+ Color getGoldRecordPageContainerBackgroundColor();
+
+ /// 获取金币记录页面边框颜色
+ /// 返回: Color - 边框颜色
+ Color getGoldRecordPageBorderColor();
+
+ /// 获取金币记录页面主要文本颜色
+ /// 返回: Color - 主要文本颜色
+ Color getGoldRecordPagePrimaryTextColor();
+
+ /// 获取金币记录页面次要文本颜色
+ /// 返回: Color - 次要文本颜色
+ Color getGoldRecordPageSecondaryTextColor();
+
+ /// 获取充值页面记录图标路径
+ /// 返回: String - 充值记录图标资源路径
+ String getRechargePageRecordIcon();
+
+ /// === Store页面差异化方法 ===
+
+ /// 获取Store页面背景图像路径
+ /// 返回: String - 背景图像资源路径
+ String getStorePageBackgroundImage();
+
+ /// 获取Store页面购物袋图标路径
+ /// 返回: String - 购物袋图标资源路径
+ String getStorePageShoppingBagIcon();
+
+ /// 获取Store页面购物袋图标外边距
+ /// 返回: EdgeInsetsDirectional - 购物袋图标外边距
+ EdgeInsetsDirectional getStorePageShoppingBagMargin();
+
+ /// 获取Store页面Tab标签内边距
+ /// 返回: EdgeInsets - Tab标签内边距
+ EdgeInsets getStorePageTabLabelPadding();
+
+ /// 获取Store页面Tab标签选中文本样式
+ /// 返回: TextStyle - Tab标签选中文本样式
+ TextStyle getStorePageTabLabelStyle();
+
+ /// 获取Store页面Tab标签未选中文本样式
+ /// 返回: TextStyle - Tab标签未选中文本样式
+ TextStyle getStorePageTabUnselectedLabelStyle();
+
+ /// 获取Store页面Tab指示器颜色
+ /// 返回: Color - Tab指示器颜色
+ Color getStorePageTabIndicatorColor();
+
+ /// 获取Store页面Tab分割线颜色
+ /// 返回: Color - Tab分割线颜色
+ Color getStorePageTabDividerColor();
+
+ /// 获取Store页面底部Divider颜色
+ /// 返回: Color - 底部Divider颜色
+ Color getStorePageBottomDividerColor();
+
+ /// 获取Store页面底部Divider厚度
+ /// 返回: double - 底部Divider厚度
+ double getStorePageBottomDividerThickness();
+
+ /// 获取Store页面底部Divider高度
+ /// 返回: double - 底部Divider高度
+ double getStorePageBottomDividerHeight();
+
+ /// 获取Store页面金币图标路径
+ /// 返回: String - 金币图标资源路径
+ String getStorePageGoldIcon();
+
+ /// 获取Store页面金币文本颜色
+ /// 返回: Color - 金币文本颜色
+ Color getStorePageGoldTextColor();
+
+ /// 获取Store页面金币图标颜色
+ /// 返回: Color - 金币图标颜色
+ Color getStorePageGoldIconColor();
+
+ /// === Store子页面(商品项)差异化方法 ===
+
+ /// 获取Store商品项背景颜色
+ /// 返回: Color - 商品项背景颜色
+ Color getStoreItemBackgroundColor();
+
+ /// 获取Store商品项未选中边框颜色
+ /// 返回: Color - 未选中边框颜色
+ Color getStoreItemUnselectedBorderColor();
+
+ /// 获取Store商品项选中边框颜色
+ /// 返回: Color - 选中边框颜色
+ Color getStoreItemSelectedBorderColor();
+
+ /// 获取Store商品项金币图标路径
+ /// 返回: String - 金币图标资源路径
+ String getStoreItemGoldIcon();
+
+ /// 获取Store商品项价格文本颜色
+ /// 返回: Color - 价格文本颜色
+ Color getStoreItemPriceTextColor();
+
+ /// 获取Store商品项购买按钮背景颜色
+ /// 返回: Color - 购买按钮背景颜色
+ Color getStoreItemBuyButtonColor();
+
+ /// 获取Store商品项购买按钮文本颜色
+ /// 返回: Color - 购买按钮文本颜色
+ Color getStoreItemBuyButtonTextColor();
+
+ /// 获取Store商品项操作图标路径
+ /// 参数: itemType - 商品类型 ('headdress', 'mountains', 'theme', 'chatbox')
+ /// 返回: String - 操作图标资源路径
+ String getStoreItemActionIcon(String itemType);
+
+ /// === 动态页面差异化方法 ===
+
+ /// 获取动态页面背景图像路径
+ /// 返回: String - 背景图像资源路径
+ String getDynamicPageBackgroundImage();
+
+ /// 获取动态页面Scaffold背景颜色
+ /// 返回: Color - Scaffold背景颜色
+ Color getDynamicPageScaffoldBackgroundColor();
+
+ /// 获取动态页面AppBar背景颜色
+ /// 返回: Color - AppBar背景颜色
+ Color getDynamicPageAppBarBackgroundColor();
+
+ /// 获取动态页面Tab标签选中颜色
+ /// 返回: Color - Tab标签选中颜色
+ Color getDynamicPageTabLabelColor();
+
+ /// 获取动态页面Tab标签未选中颜色
+ /// 返回: Color - Tab标签未选中颜色
+ Color getDynamicPageTabUnselectedLabelColor();
+
+ /// 获取动态页面Tab指示器颜色
+ /// 返回: Color - Tab指示器颜色
+ Color getDynamicPageTabIndicatorColor();
+
+ /// 获取动态页面Tab分割线颜色
+ /// 返回: Color - Tab分割线颜色
+ Color getDynamicPageTabDividerColor();
+
+ /// 获取动态页面添加动态按钮图标路径
+ /// 返回: String - 添加动态按钮图标资源路径
+ String getDynamicPageAddButtonIcon();
+
+ /// 是否启用动态页面Tab标签滚动
+ /// 返回: bool - 是否启用Tab标签滚动
+ bool shouldDynamicPageTabScrollable();
+
+ /// 获取动态页面Tab标签选中文本样式
+ /// 返回: TextStyle - Tab标签选中文本样式
+ TextStyle getDynamicPageTabLabelStyle();
+
+ /// 获取动态页面Tab标签未选中文本样式
+ /// 返回: TextStyle - Tab标签未选中文本样式
+ TextStyle getDynamicPageTabUnselectedLabelStyle();
+
+ /// === 启动页面差异化方法 ===
+
+ /// 获取启动页面背景图像路径
+ /// 返回: String - 启动背景图像资源路径
+ String getSplashPageBackgroundImage();
+
+ /// 获取启动页面图标路径
+ /// 返回: String - 启动图标资源路径
+ String getSplashPageIcon();
+
+ /// 获取启动页面跳过按钮背景图像路径
+ /// 返回: String - 跳过按钮背景图像资源路径
+ String getSplashPageSkipButtonBackground();
+
+ /// 获取启动页面跳过按钮文本颜色
+ /// 返回: Color - 跳过按钮文本颜色
+ Color getSplashPageSkipButtonTextColor();
+
+ /// 获取启动页面游戏名称背景图像路径
+ /// 返回: String - 游戏名称背景图像资源路径
+ String getSplashPageKingGamesNameBackground();
+
+ /// 获取启动页面游戏名称文本颜色
+ /// 返回: Color - 游戏名称文本颜色
+ Color getSplashPageKingGamesTextColor();
+
+ /// 获取启动页面CP名称背景图像路径
+ /// 返回: String - CP名称背景图像资源路径
+ String getSplashPageCpNameBackground();
+
+ /// 获取启动页面CP名称文本颜色
+ /// 返回: Color - CP名称文本颜色
+ Color getSplashPageCpTextColor();
+
+ /// === 搜索页面差异化方法 ===
+
+ /// 获取搜索页面Scaffold背景颜色
+ /// 返回: Color - Scaffold背景颜色
+ Color getSearchPageScaffoldBackgroundColor();
+
+ /// 获取搜索页面返回图标颜色
+ /// 返回: Color - 返回图标颜色
+ Color getSearchPageBackIconColor();
+
+ /// 获取搜索页面搜索框边框颜色
+ /// 返回: Color - 搜索框边框颜色
+ Color getSearchPageInputBorderColor();
+
+ /// 获取搜索页面搜索框文本颜色
+ /// 返回: Color - 搜索框文本颜色
+ Color getSearchPageInputTextColor();
+
+ /// 获取搜索页面搜索按钮文本颜色
+ /// 返回: Color - 搜索按钮文本颜色
+ Color getSearchPageButtonTextColor();
+
+ /// 获取搜索页面搜索按钮渐变颜色
+ /// 返回: List - 搜索按钮渐变颜色列表
+ List getSearchPageButtonGradient();
+
+ /// 获取搜索页面历史记录标题文本颜色
+ /// 返回: Color - 历史记录标题文本颜色
+ Color getSearchPageHistoryTitleTextColor();
+
+ /// 获取搜索页面历史项文本颜色
+ /// 返回: Color - 历史项文本颜色
+ Color getSearchPageHistoryItemTextColor();
+
+ /// 获取搜索页面历史项背景颜色
+ /// 返回: Color - 历史项背景颜色
+ Color getSearchPageHistoryItemBackgroundColor();
+
+ /// 获取搜索页面Tab指示器渐变开始颜色
+ /// 返回: Color - Tab指示器渐变开始颜色
+ Color getSearchPageTabIndicatorGradientStartColor();
+
+ /// 获取搜索页面Tab指示器渐变结束颜色
+ /// 返回: Color - Tab指示器渐变结束颜色
+ Color getSearchPageTabIndicatorGradientEndColor();
+
+ /// 获取搜索页面Tab标签选中颜色
+ /// 返回: Color - Tab标签选中颜色
+ Color getSearchPageTabSelectedLabelColor();
+
+ /// 获取搜索页面Tab分割线颜色
+ /// 返回: Color - Tab分割线颜色
+ Color getSearchPageTabDividerColor();
+
+ /// 获取搜索页面Tab标签未选中颜色
+ /// 返回: Color - Tab标签未选中颜色
+ Color getSearchPageTabUnselectedLabelColor();
+
+ /// 获取搜索页面分隔容器背景颜色
+ /// 返回: Color - 分隔容器背景颜色
+ Color getSearchPageDividerContainerBackgroundColor();
+
+ /// 获取搜索页面Tab标签选中文本样式
+ /// 返回: TextStyle - Tab标签选中文本样式
+ TextStyle getSearchPageTabSelectedLabelStyle();
+
+ /// 获取搜索页面Tab标签未选中文本样式
+ /// 返回: TextStyle - Tab标签未选中文本样式
+ TextStyle getSearchPageTabUnselectedLabelStyle();
+
+ /// 获取搜索页面搜索结果Tab标签内边距
+ /// 返回: EdgeInsets - Tab标签内边距
+ EdgeInsets getSearchPageResultTabLabelPadding();
+
+ /// 获取搜索页面搜索结果Tab标签选中颜色
+ /// 返回: Color - Tab标签选中颜色
+ Color getSearchPageResultTabLabelColor();
+
+ /// 获取搜索页面搜索结果Tab标签未选中颜色
+ /// 返回: Color - Tab标签未选中颜色
+ Color getSearchPageResultTabUnselectedLabelColor();
+
+ /// 获取搜索页面搜索结果Tab标签未选中文本样式
+ /// 返回: TextStyle - Tab标签未选中文本样式
+ TextStyle getSearchPageResultTabUnselectedLabelStyle();
+
+ /// 获取搜索页面搜索结果Tab标签选中文本样式
+ /// 返回: TextStyle - Tab标签选中文本样式
+ TextStyle getSearchPageResultTabLabelStyle();
+
+ /// 获取搜索页面搜索结果Tab指示器颜色(渐变)
+ /// 返回: LinearGradient - Tab指示器渐变颜色
+ LinearGradient getSearchPageResultTabIndicatorColor();
+
+ /// 获取搜索页面搜索结果Tab指示器宽度
+ /// 返回: double - Tab指示器宽度
+ double getSearchPageResultTabIndicatorWidth();
+
+ /// 获取搜索页面搜索结果背景颜色
+ /// 返回: Color - 搜索结果背景颜色
+ Color getSearchPageResultBackgroundColor();
+
+ /// 获取搜索页面清除历史记录图标路径
+ /// 返回: String - 清除历史记录图标资源路径
+ String getSearchPageClearHistoryIcon();
+
+ /// 获取搜索页面空数据图标路径
+ /// 返回: String - 空数据图标资源路径
+ String getSearchPageEmptyDataIcon();
+
+ /// === 任务页面差异化方法 ===
+
+ /// 获取任务页面背景图像路径
+ /// 返回: String - 背景图像资源路径
+ String getTaskPageBackgroundImage();
+
+ /// 获取任务页面返回按钮颜色
+ /// 返回: Color - 返回按钮颜色
+ Color getTaskPageBackButtonColor();
+
+ /// 获取任务页面Scaffold背景颜色
+ /// 返回: Color - Scaffold背景颜色
+ Color getTaskPageScaffoldBackgroundColor();
+
+ /// 获取任务页面容器背景颜色
+ /// 返回: Color - 容器背景颜色
+ Color getTaskPageContainerBackgroundColor();
+
+ /// 获取任务页面边框颜色(普通边框)
+ /// 返回: Color - 普通边框颜色
+ Color getTaskPageBorderColor();
+
+ /// 获取任务页面边框颜色(特殊边框,如任务项边框)
+ /// 返回: Color - 特殊边框颜色
+ Color getTaskPageSpecialBorderColor();
+
+ /// 获取任务页面主要文本颜色
+ /// 返回: Color - 主要文本颜色
+ Color getTaskPagePrimaryTextColor();
+
+ /// 获取任务页面金币文本颜色(折扣前价格)
+ /// 返回: Color - 金币文本颜色
+ Color getTaskPageGoldTextColor();
+
+ /// 获取任务页面经验值文本颜色
+ /// 返回: Color - 经验值文本颜色
+ Color getTaskPageExpTextColor();
+
+ /// 获取任务页面主题颜色(用于SocialChatTheme.primaryColor)
+ /// 返回: Color - 主题颜色
+ Color getTaskPageThemeColor();
+
+ /// 获取任务页面主题浅色(用于SocialChatTheme.primaryLight)
+ /// 返回: Color - 主题浅色
+ Color getTaskPageThemeLightColor();
+
+ /// 获取任务页面可领取按钮渐变颜色
+ /// 返回: List - 可领取按钮渐变颜色列表
+ List getTaskPageReceivableButtonGradient();
+
+ /// 获取任务页面已完成按钮渐变颜色
+ /// 返回: List - 已完成按钮渐变颜色列表
+ List getTaskPageCompletedButtonGradient();
+
+ /// 获取任务页面按钮文本颜色
+ /// 返回: Color - 按钮文本颜色
+ Color getTaskPageButtonTextColor();
+
+ /// 获取任务页面遮罩颜色
+ /// 返回: Color - 遮罩颜色
+ Color getTaskPageMaskColor();
+
+ /// 获取任务页面头部背景图像路径
+ /// 返回: String - 头部背景图像资源路径
+ String getTaskPageHeadBackgroundImage();
+
+ /// 获取任务页面金币图标路径
+ /// 返回: String - 金币图标资源路径
+ String getTaskPageGoldIcon();
+
+ /// 获取任务页面经验值图标路径
+ /// 返回: String - 经验值图标资源路径
+ String getTaskPageExpIcon();
+
+ /// 获取任务页面邀请奖励背景图像路径
+ /// 返回: String - 邀请奖励背景图像资源路径
+ String getTaskPageInvitationRewardBackgroundImage();
+
+ /// 获取任务页面礼品袋文本颜色
+ /// 返回: Color - 礼品袋文本颜色
+ Color getTaskPageGiftBagTextColor();
+
+ /// 获取任务页面AppBar背景颜色
+ /// 返回: Color - AppBar背景颜色
+ Color getTaskPageAppBarBackgroundColor();
+
+ /// 获取任务页面透明容器颜色
+ /// 返回: Color - 透明容器颜色
+ Color getTaskPageTransparentContainerColor();
+
+ /// === WebView页面差异化方法 ===
+
+ /// === 普通WebView页面方法 ===
+
+ /// 获取WebView页面AppBar背景颜色
+ /// 返回: Color - AppBar背景颜色
+ Color getWebViewPageAppBarBackgroundColor();
+
+ /// 获取WebView页面标题文本颜色
+ /// 返回: Color - 标题文本颜色
+ Color getWebViewPageTitleTextColor();
+
+ /// 获取WebView页面返回箭头图标颜色
+ /// 返回: Color - 返回箭头图标颜色
+ Color getWebViewPageBackArrowColor();
+
+ /// 获取WebView页面进度条背景颜色
+ /// 返回: Color - 进度条背景颜色
+ Color getWebViewPageProgressBarBackgroundColor();
+
+ /// 获取WebView页面进度条活动颜色
+ /// 返回: Color - 进度条活动颜色
+ Color getWebViewPageProgressBarActiveColor();
+
+ /// === 游戏WebView页面方法 ===
+
+ /// 获取游戏WebView页面关闭图标颜色
+ /// 返回: Color - 关闭图标颜色
+ Color getGameWebViewCloseIconColor();
+
+ /// 获取游戏WebView页面Scaffold背景颜色
+ /// 返回: Color - Scaffold背景颜色
+ Color getGameWebViewScaffoldBackgroundColor();
+
+ /// 获取游戏WebView页面加载指示器颜色
+ /// 返回: Color - 加载指示器颜色
+ Color getGameWebViewLoadingIndicatorColor();
+
+ /// 获取游戏WebView页面进度条背景颜色
+ /// 返回: Color - 进度条背景颜色
+ Color getGameWebViewProgressBarBackgroundColor();
+
+ /// === 设置页面差异化方法 ===
+
+ /// 获取设置页面背景图像路径
+ /// 返回: String - 背景图像资源路径
+ String getSettingsPageBackgroundImage();
+
+ /// 获取设置页面主容器背景颜色
+ /// 返回: Color - 主容器背景颜色
+ Color getSettingsPageMainContainerBackgroundColor();
+
+ /// 获取设置页面主容器边框颜色
+ /// 返回: Color - 主容器边框颜色
+ Color getSettingsPageMainContainerBorderColor();
+
+ /// 获取设置页面主文本颜色
+ /// 返回: Color - 主文本颜色
+ Color getSettingsPagePrimaryTextColor();
+
+ /// 获取设置页面次要文本颜色
+ /// 返回: Color - 次要文本颜色
+ Color getSettingsPageSecondaryTextColor();
+
+ /// 获取设置页面图标颜色
+ /// 返回: Color - 图标颜色
+ Color getSettingsPageIconColor();
+
+ /// 获取设置页面常见文本颜色
+ /// 返回: Color - 常见文本颜色
+ Color getSettingsPageCommonTextColor();
+
+ /// 获取设置页面关于文本颜色
+ /// 返回: Color - 关于文本颜色
+ Color getSettingsPageAboutTextColor();
+
+ /// 获取设置页面容器边框颜色
+ /// 返回: Color - 容器边框颜色
+ Color getSettingsPageContainerBorderColor();
+
+ /// 获取设置页面容器背景颜色
+ /// 返回: Color - 容器背景颜色
+ Color getSettingsPageContainerBackgroundColor();
+
+ /// 获取设置页面按钮背景颜色
+ /// 返回: Color - 按钮背景颜色
+ Color getSettingsPageButtonBackgroundColor();
+
+ /// 获取设置页面按钮文本颜色
+ /// 返回: Color - 按钮文本颜色
+ Color getSettingsPageButtonTextColor();
+
+ /// === 语言页面差异化方法 ===
+
+ /// 获取语言页面背景图像路径
+ /// 返回: String - 背景图像资源路径
+ String getLanguagePageBackgroundImage();
+
+ /// 获取语言页面复选框选中颜色
+ /// 返回: Color - 复选框选中颜色
+ Color getLanguagePageCheckboxActiveColor();
+
+ /// 获取语言页面复选框边框颜色
+ /// 返回: Color - 复选框边框颜色
+ Color getLanguagePageCheckboxBorderColor();
+
+ /// 获取语言页面主文本颜色
+ /// 返回: Color - 主文本颜色
+ Color getLanguagePagePrimaryTextColor();
+
+ /// 获取语言页面复选框对勾颜色
+ /// 返回: Color - 复选框对勾颜色
+ Color getLanguagePageCheckColor();
+
+ /// 获取语言页面复选框边框圆角
+ /// 返回: double - 边框圆角值
+ double getLanguagePageCheckboxBorderRadius();
+
+ /// 获取语言页面复选框边框宽度
+ /// 返回: double - 边框宽度值
+ double getLanguagePageCheckboxBorderWidth();
+
+ /// 获取语言页面Scaffold背景颜色
+ /// 返回: Color - Scaffold背景颜色
+ Color getLanguagePageScaffoldBackgroundColor();
+
+ /// === 账户页面差异化方法 ===
+
+ /// 获取账户页面背景图像路径
+ /// 返回: String - 背景图像资源路径
+ String getAccountPageBackgroundImage();
+
+ /// 获取账户页面主容器背景颜色
+ /// 返回: Color - 主容器背景颜色
+ Color getAccountPageMainContainerBackgroundColor();
+
+ /// 获取账户页面主容器边框颜色
+ /// 返回: Color - 主容器边框颜色
+ Color getAccountPageMainContainerBorderColor();
+
+ /// 获取账户页面主文本颜色
+ /// 返回: Color - 主文本颜色
+ Color getAccountPagePrimaryTextColor();
+
+ /// 获取账户页面次要文本颜色
+ /// 返回: Color - 次要文本颜色
+ Color getAccountPageSecondaryTextColor();
+
+ /// 获取账户页面图标颜色
+ /// 返回: Color - 图标颜色
+ Color getAccountPageIconColor();
+
+ /// 获取账户页面分隔线颜色
+ /// 返回: Color - 分隔线颜色
+ Color getAccountPageDividerColor();
+
+ /// 获取账户页面Scaffold背景颜色
+ /// 返回: Color - Scaffold背景颜色
+ Color getAccountPageScaffoldBackgroundColor();
+
+ Color getGoldRecordPageListBackgroundColor();
+}
diff --git a/lib/app/config/configs/sc_variant1_config.dart b/lib/app/config/configs/sc_variant1_config.dart
new file mode 100644
index 0000000..259d8db
--- /dev/null
+++ b/lib/app/config/configs/sc_variant1_config.dart
@@ -0,0 +1,170 @@
+import 'package:flutter/foundation.dart';
+import 'package:yumi/app/config/app_config.dart';
+import 'package:yumi/app/config/business_logic_strategy.dart';
+import 'package:yumi/app/config/strategies/variant1_business_logic_strategy.dart';
+
+/// 马甲包配置
+class SCVariant1Config implements AppConfig {
+ BusinessLogicStrategy? _businessLogicStrategy;
+
+ @override
+ String get appName => 'yumi'; // 马甲包应用名称
+
+ @override
+ String get packageName => 'com.org.yumi';
+
+ @override
+ String get apiHost => 'http://10.0.2.2:1100/'; // Android 模拟器访问宿主机本地网关
+
+ @override
+ String get imgHost => 'https://img.atuchat.com/'; // 测试图片服务器,上架前需替换为正式域名
+
+ @override
+ String get privacyAgreementUrl => 'https://www.atuchat.com/privacy.html'; // 测试隐私政策页面,上架前需替换
+
+ @override
+ String get userAgreementUrl => 'https://www.atuchat.com/service.html'; // 测试用户协议页面,上架前需替换
+
+ @override
+ String get appDownloadUrlGoogle => 'https://play.google.com/store/apps/details?id=$packageName';
+
+ @override
+ String get appDownloadUrlApple => 'https://apps.apple.com/us/app/atuchat/id1234567890'; // 需要更新为真实App Store ID
+
+ @override
+ String get anchorAgentUrl => 'https://h5.atuchat.com/#/apply'; // 测试H5页面,上架前需替换为正式域名
+
+ @override
+ String get hostCenterUrl => 'https://h5.atuchat.com/#/host-center'; // 测试H5页面,上架前需替换为正式域名
+
+ @override
+ String get bdCenterUrl => 'https://h5.atuchat.com/#/bd-center'; // 测试H5页面,上架前需替换为正式域名
+
+ @override
+ String get bdLeaderUrl => 'http://h5.atuchat.com/#/bd-leader-center'; // 测试H5页面,上架前需替换为正式域名
+
+ @override
+ String get coinSellerUrl => 'https://h5.atuchat.com/#/coin-seller'; // 测试H5页面,上架前需替换为正式域名
+
+ @override
+ String get adminUrl => 'https://h5.atuchat.com/#/admin-center'; // 测试H5页面,上架前需替换为正式域名
+
+ @override
+ String get agencyCenterUrl => 'https://h5.atuchat.com/#/agency-center'; // 测试H5页面,上架前需替换为正式域名
+
+ @override
+ String get gamesKingUrl => 'https://h5.atuchat.com/#/games-king'; // 测试H5页面,上架前需替换为正式域名
+
+ @override
+ String get wealthRankUrl => 'https://h5.atuchat.com/#/ranking?first=Wealth'; // 测试H5页面,上架前需替换为正式域名
+
+ @override
+ String get charmRankUrl => 'https://h5.atuchat.com/#/ranking?first=Charm'; // 测试H5页面,上架前需替换为正式域名
+
+ @override
+ String get roomRankUrl => 'https://h5.atuchat.com/#/ranking?first=Room'; // 测试H5页面,上架前需替换为正式域名
+
+ @override
+ String get inviteNewUserUrl => 'https://h5.atuchat.com/#/invitation/invite-new-user'; // 测试H5页面,上架前需替换为正式域名
+
+ @override
+ int get primaryColor => 0xffFF5722; // 不同主色(橙色)
+
+ @override
+ String get tencentImAppid => '00000000'; // 需要注册新的腾讯云IM账户并获取独立App ID
+
+ @override
+ String get agoraRtcAppid => '00000000'; // 需要创建新的Agora项目并获取独立App ID
+
+ @override
+ num get gameAppid => 9999999999; // 需要注册新的游戏服务账户并获取独立App ID
+
+ @override
+ String get gameAppChannel => 'yumi';
+
+ @override
+ String get bigBroadcastGroup => '@TGS#YUMI_BROADCAST_GROUP_ID'; // 需要创建独立的腾讯IM广播群组
+
+ @override
+ String get imAdmin => 'c2c_atyou-admin'; // 独立的管理账号,需要在实际部署中配置
+
+ @override
+ bool get isReview => true;
+
+ @override
+ bool get isGiftSpecialEffects => true;
+
+ @override
+ bool get isEntryVehicleAnimation => true;
+
+ @override
+ bool get isFloatingAnimationInGlobal => true;
+
+ @override
+ bool get isLuckGiftSpecialEffects => true;
+
+ @override
+ Map get featureFlags => {
+ 'giftSpecialEffects': isGiftSpecialEffects,
+ 'entryVehicleAnimation': isEntryVehicleAnimation,
+ 'floatingAnimationInGlobal': isFloatingAnimationInGlobal,
+ 'luckGiftSpecialEffects': isLuckGiftSpecialEffects,
+ };
+
+ @override
+ BusinessLogicStrategy get businessLogicStrategy {
+ return _businessLogicStrategy ??= Variant1BusinessLogicStrategy();
+ }
+
+ @override
+ Map toMap() {
+ return {
+ 'appName': appName,
+ 'packageName': packageName,
+ 'apiHost': apiHost,
+ 'imgHost': imgHost,
+ 'privacyAgreementUrl': privacyAgreementUrl,
+ 'userAgreementUrl': userAgreementUrl,
+ 'primaryColor': primaryColor,
+ 'tencentImAppid': tencentImAppid,
+ 'agoraRtcAppid': agoraRtcAppid,
+ 'gameAppid': gameAppid,
+ 'gameAppChannel': gameAppChannel,
+ 'bigBroadcastGroup': bigBroadcastGroup,
+ 'imAdmin': imAdmin,
+ 'isReview': isReview,
+ 'isGiftSpecialEffects': isGiftSpecialEffects,
+ 'isEntryVehicleAnimation': isEntryVehicleAnimation,
+ 'isFloatingAnimationInGlobal': isFloatingAnimationInGlobal,
+ 'isLuckGiftSpecialEffects': isLuckGiftSpecialEffects,
+ 'featureFlags': featureFlags,
+ 'businessLogicStrategy': 'Variant1BusinessLogicStrategy',
+ };
+ }
+
+ @override
+ void validate() {
+ final errors = [];
+
+ // 检查API主机地址
+ if (apiHost.isEmpty || !apiHost.startsWith('http')) {
+ errors.add('API主机地址无效或未设置');
+ }
+
+ // 如果有错误,根据模式处理
+ if (errors.isNotEmpty) {
+ final errorMessage = '应用配置验证失败:\n${errors.join('\n')}';
+
+ if (kDebugMode) {
+ // 调试模式下只输出警告,不阻止应用启动(方便开发)
+ debugPrint('⚠️ 警告: $errorMessage');
+ debugPrint('⚠️ 在调试模式下,应用将继续启动,但某些功能可能无法正常工作');
+ } else {
+ // 发布模式下抛出异常,阻止应用启动
+ throw StateError(errorMessage);
+ }
+ } else {
+ debugPrint('应用配置验证通过');
+ }
+ }
+}
diff --git a/lib/app/config/strategies/base_business_logic_strategy.dart b/lib/app/config/strategies/base_business_logic_strategy.dart
new file mode 100644
index 0000000..9e64c71
--- /dev/null
+++ b/lib/app/config/strategies/base_business_logic_strategy.dart
@@ -0,0 +1,2576 @@
+import 'package:flutter/material.dart';
+import 'package:yumi/app/config/business_logic_strategy.dart';
+import 'package:yumi/shared/data_sources/sources/local/user_manager.dart';
+import 'package:yumi/app_localizations.dart';
+import 'package:yumi/services/general/sc_app_general_manager.dart';
+import 'package:yumi/shared/tools/sc_dialog_utils.dart';
+import 'package:yumi/ui_kit/theme/socialchat_theme.dart';
+import 'package:provider/provider.dart';
+
+/// 基础业务逻辑策略实现
+/// 提供原始应用的默认业务逻辑
+class BaseBusinessLogicStrategy implements BusinessLogicStrategy {
+
+ @override
+ List getHomeTabPages(BuildContext context) {
+ final List pages = [];
+ return pages;
+ }
+
+ @override
+ List getHomeTabLabels(BuildContext context) {
+ final List tabs = [];
+ tabs.add(Tab(text: SCAppLocalizations.of(context)!.popular));
+ tabs.add(Tab(text: SCAppLocalizations.of(context)!.explore));
+ return tabs;
+ }
+
+
+ @override
+ int getHomeInitialTabIndex() {
+ return 0;
+ }
+
+ @override
+ void onAvatarTap(BuildContext context) {
+ Provider.of(context, listen: false).openDrawer(context);
+ }
+
+ @override
+ bool shouldShowFirstRechargePrompt() {
+ return UserManager().getCurrentUser()?.userProfile?.firstRecharge ?? false;
+ }
+
+ @override
+ Map getFirstRechargePosition() {
+ return {'bottom': 40.0, 'end': 15.0, 'top': null, 'start': null};
+ }
+
+ @override
+ void onFirstRechargeTap(BuildContext context) {
+ SCDialogUtils.showFirstRechargeDialog(context);
+ }
+
+ /// === 登录页面差异化方法实现 ===
+
+ @override
+ String getLoginBackgroundImage() {
+ // 原始应用默认背景图片
+ return "sc_images/login/login_account.png";
+ }
+
+ @override
+ String getLoginAppIcon() {
+ // 原始应用默认图标
+ return "sc_images/splash/sc_icon_splash_icon.png";
+ }
+
+ @override
+ Color getLoginButtonColor() {
+ // 原始应用默认按钮颜色 - 使用马甲包主题的primaryLight
+ return SocialChatTheme.primaryLight;
+ }
+
+ @override
+ List? getLoginButtonGradient() {
+ // 原始应用默认不使用渐变
+ return null;
+ }
+
+ @override
+ Color getLoginButtonTextColor() {
+ // 原始应用默认按钮文本颜色(白色)
+ return Colors.white;
+ }
+
+ @override
+ Color getLoginLabelTextColor() {
+ // 原始应用默认标签文本颜色(黑色)
+ return Colors.black;
+ }
+
+ @override
+ BoxDecoration getLoginInputDecoration() {
+ // 原始应用输入框装饰:透明背景,黑色边框
+ return BoxDecoration(
+ color: Colors.transparent,
+ borderRadius: BorderRadius.all(Radius.circular(8)),
+ border: Border.all(color: Colors.black45, width: 0.5),
+ );
+ }
+
+ @override
+ EdgeInsets getLoginPagePadding() {
+ // 原始应用默认内边距
+ return const EdgeInsets.only(top: 100);
+ }
+
+ @override
+ bool shouldShowLoginStatusBar() {
+ // 原始应用默认显示状态栏
+ return true;
+ }
+
+ @override
+ Color getLoginHintTextColor() {
+ // 原始应用默认提示文本颜色(黑色45%透明度)
+ return Colors.black45;
+ }
+
+ @override
+ Color getLoginInputTextColor() {
+ // 原始应用默认输入文本颜色(黑色)
+ return Colors.black;
+ }
+
+ /// === 家族页面差异化方法实现 ===
+
+
+
+
+
+
+ @override
+ bool shouldShowPasswordRoomIcon() {
+ // 原始应用:显示密码房间图标
+ return true;
+ }
+
+ /// === 探索页面差异化方法实现 ===
+
+ @override
+ int getExploreRoomDisplayThreshold() {
+ // 原始应用:显示前6个房间在抽屉上方
+ return 6;
+ }
+
+ @override
+ String getExploreGridIcon() {
+ // 原始应用:网格视图图标
+ return "sc_images/index/sc_icon_index_room_model_1.png";
+ }
+
+ @override
+ String getExploreListIcon() {
+ // 原始应用:列表视图图标
+ return "sc_images/index/sc_icon_index_room_model_2.png";
+ }
+
+ @override
+ String getExploreRankIconPattern(bool isGrid, int rank) {
+ // 原始应用:排名图标路径模式
+ if (isGrid) {
+ return "sc_images/index/sc_icon_explore_room_model_1_rank_$rank.png";
+ } else {
+ return "sc_images/index/sc_icon_explore_room_model_2_rank_$rank.png";
+ }
+ }
+
+ @override
+ Color getExploreRoomBorderColor() {
+ // 原始应用:使用主题色作为边框颜色
+ return SocialChatTheme.primaryLight;
+ }
+
+ @override
+ double getExploreRoomBorderWidth() {
+ // 原始应用:边框宽度
+ return 1.3;
+ }
+
+ @override
+ int getExploreDrawerGridCrossAxisCount() {
+ // 原始应用:抽屉内容网格列数
+ return 3;
+ }
+
+ @override
+ int getExploreRoomNameMarqueeThreshold() {
+ // 原始应用:房间名称长度超过10时显示滚动效果
+ return 10;
+ }
+
+ @override
+ int getExploreRoomDescMarqueeThreshold() {
+ // 原始应用:房间描述长度超过12时显示滚动效果
+ return 12;
+ }
+
+ /// === 个人主页差异化方法实现 ===
+
+ @override
+ String getMePageDefaultBackgroundImage() {
+ // 原始应用默认背景图片
+ return "sc_images/person/sc_icon_my_head_bg_defalt.png";
+ }
+
+ @override
+ String getMePageGenderBackgroundImage(bool isFemale) {
+ // 原始应用性别背景图片
+ return isFemale
+ ? "sc_images/person/sc_icon_my_head_bg_woman.png"
+ : "sc_images/person/sc_icon_my_head_bg_man.png";
+ }
+
+ @override
+ String getMePageCpDialogHeadImage() {
+ // 原始应用CP对话框头像图片
+ return "sc_images/person/sc_icon_send_cp_requst_dialog_head.png";
+ }
+
+ @override
+ String getMePageDefaultAvatarImage() {
+ // 原始应用默认头像图片
+ return "sc_images/general/sc_icon_avar_defalt.png";
+ }
+
+ @override
+ String getMePageIdBackgroundImage(bool hasSpecialId) {
+ // 原始应用ID背景图片
+ return hasSpecialId
+ ? "sc_images/general/sc_icon_special_id_bg.png"
+ : "sc_images/general/sc_icon_id_bg.png";
+ }
+
+ @override
+ String getMePageCopyIdIcon() {
+ // 原始应用复制ID图标
+ return "sc_images/room/sc_icon_user_card_copy_id.png";
+ }
+
+ @override
+ String getMePageGenderAgeBackgroundImage(bool isFemale) {
+ // 原始应用性别年龄背景图片
+ return isFemale
+ ? "sc_images/login/sc_icon_sex_woman_bg.png"
+ : "sc_images/login/sc_icon_sex_man_bg.png";
+ }
+
+ @override
+ String getMePageVisitorsFollowFansBackgroundImage(bool isFemale) {
+ // 原始应用访客关注粉丝背景图片
+ return isFemale
+ ? "sc_images/person/sc_icon_vistors_follow_fans_bg_woman.png"
+ : "sc_images/person/sc_icon_vistors_follow_fans_bg_man.png";
+ }
+
+ @override
+ String getMePageEditUserInfoIcon() {
+ // 原始应用编辑用户信息图标
+ return "sc_images/person/sc_icon_edit_user_info2.png";
+ }
+
+ @override
+ Color getMePageShineColor() {
+ // 原始应用闪耀文本颜色
+ return const Color(0xffe6e6e6);
+ }
+
+ @override
+ List getMePageGradientColors(bool isFemale) {
+ // 原始应用渐变颜色
+ if (isFemale) {
+ return [
+ const Color(0xFF3F1016),
+ const Color(0xFF1E0B0E),
+ const Color(0xFF3F0810),
+ ];
+ } else {
+ return [
+ const Color(0xFF666666),
+ const Color(0xFF000000),
+ ];
+ }
+ }
+
+ @override
+ List getMePageTabIndicatorGradient(bool isFemale) {
+ // 原始应用Tab指示器渐变
+ if (isFemale) {
+ return [
+ const Color(0xffC62548),
+ const Color(0xff9C0322),
+ ];
+ } else {
+ return [
+ const Color(0xff141414),
+ const Color(0xffE4E4E4),
+ ];
+ }
+ }
+
+ @override
+ Color getMePageVisitorsFollowFansTextColor() {
+ // 原始应用访客关注粉丝文本颜色
+ return const Color(0xffD0D0D0);
+ }
+
+ @override
+ int getMePageInitialTabIndex() {
+ // 原始应用初始Tab索引
+ return 1; // profile页
+ }
+
+ @override
+ double getMePageScrollOpacityThreshold() {
+ // 原始应用滚动透明度计算阈值
+ return 320.0;
+ }
+
+ @override
+ int getMePageNicknameScrollThreshold() {
+ // 原始应用昵称滚动显示阈值
+ return 13;
+ }
+
+ @override
+ int getMePageAgeDisplayWidthThreshold() {
+ // 原始应用年龄显示宽度阈值
+ return 999;
+ }
+
+ @override
+ double getMePageOpacityThresholdForAvatarDisplay() {
+ // 原始应用头像显示透明度阈值
+ return 0.5;
+ }
+
+ /// === 热门页面差异化方法实现 ===
+
+ @override
+ String getPopularLeaderboardBackgroundImage(String leaderboardType) {
+ // 原始应用:使用现有的图像资源路径
+ switch (leaderboardType) {
+ case 'room':
+ return "sc_images/index/sc_icon_leader_spinner_room_bg.png";
+ case 'wealth':
+ return "sc_images/index/sc_icon_leader_spinner_wealth_bg.png";
+ case 'charm':
+ return "sc_images/index/sc_icon_leader_spinner_charm_bg.png";
+ default:
+ return "sc_images/index/sc_icon_leader_spinner_room_bg.png";
+ }
+ }
+
+ /// === 游戏页面差异化方法实现 ===
+
+ @override
+ String getGameRankBackgroundImage(int rank) {
+ // 原始应用:使用现有的排名背景图像模式
+ return "sc_images/game/sc_icon_game_list_item_bg_$rank.png";
+ }
+
+ @override
+ String getGameRankIcon(int rank) {
+ // 原始应用:使用现有的排名图标模式
+ return "sc_images/game/sc_icon_game_rank_$rank.png";
+ }
+
+ @override
+ Color getGamePageThemeColor() {
+ // 原始应用:默认主题颜色
+ return const Color(0xffFF5722);
+ }
+
+ @override
+ Color getGamePageBackgroundColor() {
+ // 原始应用:默认背景颜色
+ return const Color(0xfff5f5f5);
+ }
+
+ @override
+ int getGamePageGridCrossAxisCount() {
+ // 原始应用:3列网格
+ return 3;
+ }
+
+ @override
+ double getGamePageGridChildAspectRatio() {
+ // 原始应用:默认高度比例
+ return 1.3;
+ }
+
+ @override
+ Color getGameRankTextColor(int rank) {
+ // 原始应用:根据排名返回不同颜色
+ switch (rank) {
+ case 1:
+ return const Color(0xffFFD700); // 金色
+ case 2:
+ return const Color(0xffC0C0C0); // 银色
+ case 3:
+ return const Color(0xffCD7F32); // 铜色
+ default:
+ return Colors.black87;
+ }
+ }
+
+ @override
+ Color getGamePageGradientSecondColor() {
+ // 原始应用:渐变第二颜色
+ return const Color(0xffEAD4FF);
+ }
+
+ @override
+ String getGameHotTagBackgroundImage() {
+ // 原始应用:热门游戏标签背景图片
+ return "sc_images/index/sc_icon_hotgames_tag_bg.png";
+ }
+
+ @override
+ String getGameNewTagImage() {
+ // 原始应用:新游戏标签图片
+ return "sc_images/index/sc_icon_game_new_tag.png";
+ }
+
+ @override
+ String getGamePageMaskImage() {
+ // 原始应用:游戏页面遮罩图片
+ return "sc_images/index/sc_icon_index_mask.png";
+ }
+
+ /// === VIP页面差异化方法实现 ===
+
+ @override
+ String getVipPageBackgroundImage(int vipLevel) {
+ // 原始应用:使用现有的VIP背景图像模式
+ return "sc_images/vip/sc_icon_vip_level_bg_$vipLevel.png";
+ }
+
+ @override
+ String getVipPageIcon(int vipLevel) {
+ // 原始应用:使用现有的VIP图标模式
+ return "sc_images/vip/sc_icon_vip_level_$vipLevel.png";
+ }
+
+ @override
+ List getVipPageButtonGradient() {
+ // 原始应用:VIP按钮渐变颜色
+ return [
+ const Color(0xffFF5722),
+ const Color(0xffFEB219),
+ ];
+ }
+
+ @override
+ int getVipPageGridCrossAxisCount() {
+ // 原始应用:3列网格
+ return 3;
+ }
+
+ @override
+ double getVipPageGridChildAspectRatio() {
+ // 原始应用:默认高度比例
+ return 1.5;
+ }
+
+ @override
+ String getVipPageHeadBackgroundImage(int vipLevel) {
+ // 原始应用:VIP头部背景图像模式
+ return "sc_images/vip/sc_icon_vip_head_bg_v$vipLevel.png";
+ }
+
+ @override
+ String getVipPageTabSelectedIcon(int vipLevel) {
+ // 原始应用:Tab选中状态图标模式
+ return "sc_images/vip/sc_icon_tab_vip_text_on_v$vipLevel.png";
+ }
+
+ @override
+ String getVipPageTabUnselectedIcon(int vipLevel) {
+ // 原始应用:Tab未选中状态图标模式
+ return "sc_images/vip/sc_icon_tab_vip_text_no_v$vipLevel.png";
+ }
+
+ @override
+ String getVipPageLargeIcon(int vipLevel) {
+ // 原始应用:VIP页面大图标路径模式
+ return "sc_images/vip/sc_icon_vip${vipLevel}_ic.webp";
+ }
+
+ @override
+ String getVipPageTitleImage(int vipLevel) {
+ // 原始应用:VIP页面标题图像路径模式
+ return "sc_images/vip/sc_icon_vip${vipLevel}_t1.png";
+ }
+
+ @override
+ String getVipPageTagImage(int vipLevel, int tagIndex) {
+ // 原始应用:VIP页面标签图像路径模式
+ return "sc_images/vip/sc_icon_vip${vipLevel}_tag$tagIndex.png";
+ }
+
+ @override
+ String getVipPageItemBackgroundImage(int vipLevel) {
+ // 原始应用:VIP页面功能项背景图像路径模式
+ return "sc_images/vip/sc_icon_vip${vipLevel}_item_bg.png";
+ }
+
+ @override
+ String getVipPagePrivilegeIcon(int vipLevel, int privilegeIndex) {
+ // 原始应用:VIP页面特权图标路径模式
+ return "sc_images/vip/sc_icon_vip${vipLevel}_privilege$privilegeIndex.png";
+ }
+
+ @override
+ String getVipPageFeatureIcon(int vipLevel, String featureName) {
+ // 原始应用:VIP页面功能图标路径模式
+ return "sc_images/vip/sc_icon_vip${vipLevel}_$featureName.png";
+ }
+
+ @override
+ String getVipPagePreviewImage(int vipLevel, String previewType, String featureName) {
+ // 原始应用:VIP页面预览图像路径模式
+ if (featureName == 'profile_frame') {
+ return "sc_images/vip/sc_icon_vip${vipLevel}_profile_rev.png";
+ } else if (featureName == 'profile_card') {
+ return "sc_images/vip/sc_icon_vip${vipLevel}_profile_card_rev.png";
+ } else if (featureName == 'room_cover_headdress') {
+ return "sc_images/vip/sc_icon_vip${vipLevel}_room_cover_border_rev.png";
+ } else if (featureName == 'mic_rippl_theme') {
+ return "sc_images/vip/sc_icon_vip${vipLevel}_sesc_rev.png";
+ } else if (featureName == 'chatbox') {
+ return "sc_images/vip/sc_icon_vip${vipLevel}_chatbox_pre.png";
+ } else {
+ return "sc_images/vip/sc_icon_vip${vipLevel}_${featureName}_$previewType.png";
+ }
+ }
+
+ @override
+ String getVipPagePurchaseBackgroundImage(int vipLevel) {
+ // 原始应用:VIP页面购买背景图像路径模式
+ return "sc_images/vip/sc_icon_vip${vipLevel}_buy_bg.png";
+ }
+
+ @override
+ String getVipPagePurchaseButtonImage() {
+ // 原始应用:VIP页面购买按钮图像路径
+ return "sc_images/vip/sc_icon_vip_buy_btn.png";
+ }
+
+ @override
+ Color getVipPageTextColor(int vipLevel) {
+ // 原始应用:根据VIP等级返回不同的文本颜色
+ switch (vipLevel) {
+ case 1:
+ return const Color(0xFF71D671);
+ case 2:
+ return const Color(0xFF7179D6);
+ case 3:
+ return const Color(0xFFAA71D6);
+ case 4:
+ return const Color(0xFF71D6B3);
+ case 5:
+ return const Color(0xFFD67171);
+ case 6:
+ return const Color(0xFFFEE5BB);
+ default:
+ return Colors.white;
+ }
+ }
+
+ /// === 通用页面差异化方法实现 ===
+
+ @override
+ String getCommonRankBackgroundImage(String pageType, int rank) {
+ // 原始应用:通用的排名背景图像模式
+ return "sc_images/$pageType/sc_icon_${pageType}_rank_bg_$rank.png";
+ }
+
+ @override
+ String getCommonRankIcon(String pageType, int rank) {
+ // 原始应用:通用的排名图标模式
+ return "sc_images/$pageType/sc_icon_${pageType}_rank_$rank.png";
+ }
+
+ @override
+ int getCommonPageGridCrossAxisCount(String pageType) {
+ // 原始应用:通用的2列网格
+ return 2;
+ }
+
+ @override
+ double getCommonPageGridChildAspectRatio(String pageType) {
+ // 原始应用:通用的高度比例
+ return 1.4;
+ }
+
+ /// === 个人主页2 (MePage2) 差异化方法实现 ===
+
+ @override
+ Map getMePage2WalletBackground() {
+ // 原始应用默认钱包背景配置
+ return {
+ 'gradient': [
+ Color(0xFFFF9500),
+ Color(0xCCFF9500), // withOpacity(0.8)
+ ],
+ 'borderRadius': 12.0,
+ 'shadow': {
+ 'color': Color(0x1A000000), // Colors.black.withOpacity(0.1)
+ 'blurRadius': 12.0,
+ 'offset': Offset(0, 4.0),
+ },
+ };
+ }
+
+ @override
+ Map getMePage2StatisticsColors() {
+ // 原始应用统计信息颜色配置
+ return {
+ 'numberColor': Color(0xFF333333),
+ 'labelColor': Color(0xFFB1B1B1),
+ 'dividerColor': Color(0xFFE6E6E6),
+ };
+ }
+
+ @override
+ Map getMePage2FunctionIcons() {
+ // 原始应用功能卡片图标路径映射
+ return {
+ 'invite': 'sc_images/general/sc_icon_invite.png',
+ 'task': 'sc_images/general/sc_icon_task.png',
+ 'store': 'sc_images/general/sc_icon_shop.png',
+ 'items': 'sc_images/general/sc_icon_items.png',
+ 'level': 'sc_images/general/sc_icon_level.png',
+ 'badge': 'sc_images/general/sc_icon_badge.png',
+ 'host': 'sc_images/general/sc_icon_host.png',
+ 'bd': 'sc_images/general/sc_icon_bd.png',
+ 'feedback': 'sc_images/general/sc_icon_feedback.png',
+ 'settings': 'sc_images/general/sc_icon_settings_card.png',
+ };
+ }
+
+ @override
+ Map getMePage2CardStyles() {
+ // 原始应用卡片样式配置
+ return {
+ 'borderRadius': 8.0,
+ 'shadow': {
+ 'color': Color(0x0D000000), // Colors.black.withOpacity(0.05)
+ 'blurRadius': 8.0,
+ 'offset': Offset(0, 2.0),
+ },
+ 'border': null, // 无边框
+ };
+ }
+
+ /// === Admin编辑页面差异化方法实现 ===
+
+ @override
+ String getAdminEditingBackgroundImage() {
+ // 原始应用:编辑页面背景图片
+ return "sc_images/room/sc_icon_room_settig_bg.png";
+ }
+
+ @override
+ List getAdminEditingButtonGradient(String buttonType) {
+ // 原始应用:编辑页面按钮渐变颜色,两个按钮使用相同的渐变
+ return [
+ const Color(0xffC670FF),
+ const Color(0xff7726FF),
+ ];
+ }
+
+ @override
+ String getAdminEditingIcon(String iconType) {
+ // 原始应用:编辑页面图标路径
+ switch (iconType) {
+ case 'specialIdBg':
+ return "sc_images/general/sc_icon_special_id_bg.png";
+ case 'normalIdBg':
+ return "sc_images/general/sc_icon_id_bg.png";
+ case 'copyId':
+ return "sc_images/room/sc_icon_user_card_copy_id.png";
+ case 'addPic':
+ return "sc_images/general/sc_icon_add_pic.png";
+ case 'closePic':
+ return "sc_images/general/sc_icon_pic_close.png";
+ case 'checked':
+ return "sc_images/general/sc_icon_checked.png";
+ default:
+ return "";
+ }
+ }
+
+ @override
+ BoxDecoration getAdminEditingInputDecoration() {
+ // 原始应用:编辑页面输入框装饰样式
+ return BoxDecoration(
+ color: Colors.white,
+ borderRadius: BorderRadius.circular(8),
+ border: Border.all(
+ color: const Color(0xffE6E6E6),
+ width: 1.0,
+ ),
+ );
+ }
+
+ @override
+ int getAdminEditingMaxImageUploadCount() {
+ // 原始应用:最大图片上传数量(pic01, pic02, pic03)
+ return 3;
+ }
+
+ @override
+ int getAdminEditingDescriptionMaxLength() {
+ // 原始应用:描述文本框最大字符数
+ return 200;
+ }
+
+ @override
+ Map getAdminEditingViolationTypeMapping(String targetType) {
+ // 原始应用:违规类型ID映射
+ if (targetType == 'User') {
+ return {
+ 'Pornography': 1,
+ 'Illegal information': 2,
+ };
+ } else if (targetType == 'Room') {
+ return {
+ 'Pornography': 3,
+ 'Illegal information': 4,
+ 'Fraud': 5,
+ 'Other': 6,
+ };
+ }
+ return {};
+ }
+
+ /// === Admin搜索页面差异化方法实现 ===
+
+ @override
+ String getAdminSearchBackgroundImage(String pageType) {
+ // 原始应用:搜索页面背景图片
+ return "sc_images/index/sc_icon_coupon_head_bg.png";
+ }
+
+ @override
+ List getAdminSearchButtonGradient(String pageType) {
+ // 原始应用:搜索按钮渐变颜色 - 透明渐变
+ return [
+ Colors.transparent,
+ Colors.transparent,
+ ];
+ }
+
+ @override
+ Color getAdminSearchButtonTextColor(String pageType) {
+ // 原始应用:搜索按钮文本颜色
+ return Colors.black;
+ }
+
+ @override
+ String getAdminSearchEditIcon(String pageType) {
+ // 原始应用:编辑图标路径
+ return "sc_images/room/sc_icon_room_edit.png";
+ }
+
+ @override
+ Color getAdminSearchInputBorderColor(String pageType) {
+ // 原始应用:搜索框边框颜色
+ return Colors.black12;
+ }
+
+ @override
+ Color getAdminSearchInputTextColor(String pageType) {
+ // 原始应用:搜索框文本颜色
+ return Colors.grey;
+ }
+
+ @override
+ String getAdminSearchUserInfoIcon(String iconType) {
+ // 原始应用:用户信息图标路径
+ switch (iconType) {
+ case 'specialIdBg':
+ return "sc_images/general/sc_icon_special_id_bg.png";
+ case 'normalIdBg':
+ return "sc_images/general/sc_icon_id_bg.png";
+ case 'copyId':
+ return "sc_images/room/sc_icon_user_card_copy_id.png";
+ default:
+ return "";
+ }
+ }
+
+ /// === 主登录页面差异化方法实现 ===
+
+ @override
+ String getLoginMainBackgroundImage() {
+ // 原始应用默认背景图片
+ return "sc_images/login/sc_login.png";
+ }
+
+ @override
+ String getLoginMainAppIcon() {
+ // 原始应用默认应用图标
+ return "sc_images/splash/sc_icon_splash_icon.png";
+ }
+
+ @override
+ String getLoginMainGoogleIcon() {
+ // 原始应用默认Google图标
+ return "sc_images/login/sc_icon_google.png";
+ }
+
+ @override
+ String getLoginMainAppleIcon() {
+ // 原始应用默认Apple图标
+ return "sc_images/login/sc_icon_iphone.png";
+ }
+
+ @override
+ String getLoginMainAccountIcon() {
+ // 原始应用默认账号图标
+ return "sc_images/login/sc_icon_account.png";
+ }
+
+ @override
+ String getLoginMainAgreementIcon(bool isSelected) {
+ // 原始应用默认协议图标
+ return isSelected
+ ? "sc_images/login/sc_icon_login_ser_select.png"
+ : "sc_images/login/sc_icon_login_ser_select_un.png";
+ }
+
+ @override
+ Color getLoginMainDividerColor() {
+ // 原始应用默认分割线颜色
+ return const Color(0xFFCCCCCC);
+ }
+
+ @override
+ Color getLoginMainButtonBorderColor() {
+ // 原始应用默认按钮边框颜色
+ return const Color(0xFFE6E6E6);
+ }
+
+ @override
+ Color getLoginMainButtonBackgroundColor() {
+ // 原始应用默认按钮背景颜色
+ return Colors.white;
+ }
+
+ @override
+ Color getLoginMainLinkColor() {
+ // 原始应用默认链接颜色
+ return const Color(0xFFFF9500);
+ }
+
+ @override
+ Color getLoginMainButtonTextColor() {
+ // 原始应用默认按钮文本颜色
+ return Colors.black;
+ }
+
+ /// === 编辑个人资料页面差异化方法实现 ===
+
+ @override
+ String getEditProfileBackgroundImage() {
+ // 原始应用默认背景图片
+ return "sc_images/login/edit_profile_bg.png";
+ }
+
+ @override
+ String getEditProfileDefaultAvatarImage() {
+ // 原始应用默认头像图片
+ return "sc_images/login/sc_icon_profile_head.png";
+ }
+
+ @override
+ String getEditProfileGenderIcon(bool isMale) {
+ // 原始应用默认性别图标
+ return isMale
+ ? "sc_images/login/sc_icon_sex_man.png"
+ : "sc_images/login/sc_icon_sex_woman.png";
+ }
+
+ @override
+ List getEditProfileGenderButtonGradient(bool isMale, bool isSelected) {
+ // 原始应用默认性别按钮渐变颜色
+ return [
+ const Color(0xffFF9326),
+ const Color(0xffFEB219),
+ ];
+ }
+
+ @override
+ Color getEditProfileInputBackgroundColor() {
+ // 原始应用默认输入框背景颜色
+ return Colors.white38;
+ }
+
+ @override
+ Color getEditProfileDatePickerConfirmColor() {
+ // 原始应用默认日期选择器确认按钮颜色
+ return const Color(0xff7726FF);
+ }
+
+ @override
+ Color getEditProfileContinueButtonColor() {
+ // 原始应用默认继续按钮颜色
+ return const Color(0xff7726FF);
+ }
+
+ /// === Country页面差异化方法实现 ===
+
+ @override
+ String getCountrySelectOkIcon() {
+ // 原始应用默认选择确认图标
+ return "sc_images/general/sc_icon_select_ok.png";
+ }
+
+ @override
+ String getCountrySelectUnOkIcon() {
+ // 原始应用默认选择未确认图标
+ return "sc_images/general/sc_icon_select_un_ok.png";
+ }
+
+ @override
+ String getCountryRadioSelectedIcon() {
+ // 原始应用默认单选选中图标
+ return "sc_images/login/sc_icon_login_ser_select.png";
+ }
+
+ @override
+ String getCountryRadioUnselectedIcon() {
+ // 原始应用默认单选未选中图标
+ return "sc_images/login/sc_icon_login_ser_select_un.png";
+ }
+
+ @override
+ Color getCountryItemBorderColor() {
+ // 原始应用默认国家列表项边框颜色
+ return const Color(0xffE6E6E6);
+ }
+
+ @override
+ Color getCountryPageScaffoldBackgroundColor() {
+ // 原始应用默认Scaffold背景颜色(白色)
+ return Colors.white;
+ }
+
+ @override
+ Color getCountryPageIconColor() {
+ // 原始应用默认图标颜色(黑色)
+ return Colors.black;
+ }
+
+ @override
+ Color getCountryPagePrimaryTextColor() {
+ // 原始应用默认主要文本颜色(黑色)
+ return Colors.black;
+ }
+
+ @override
+ Color getCountryPageSecondaryTextColor() {
+ // 原始应用默认次要文本颜色(黑色45%透明度)
+ return Colors.black45;
+ }
+
+ @override
+ Color getCountryPageContainerBackgroundColor() {
+ // 原始应用默认容器背景颜色(白色)
+ return Colors.white;
+ }
+
+ /// === Chat页面差异化方法实现 ===
+
+ /// === 消息页面 (SCMessagePage) 方法实现 ===
+
+ @override
+ String getMessagePageIndexMaskIcon() {
+ // 原始应用:消息页面索引遮罩图标
+ return "sc_images/index/sc_icon_index_mask.png";
+ }
+
+ @override
+ String getMessagePageAnnouncementTagIcon() {
+ // 原始应用:消息页面公告标签图标
+ return "sc_images/msg/sc_icon_message_activity.png";
+ }
+
+ @override
+ String getMessagePageActivityMessageIcon() {
+ // 原始应用:消息页面活动消息图标
+ return "sc_images/msg/sc_icon_message_activity.png";
+ }
+
+ @override
+ String getMessagePageActivityTitleBackground(bool isRtl) {
+ // 原始应用:消息页面活动消息标题背景图标
+ return isRtl
+ ? "sc_images/msg/sc_icon_activity_title_bg_rtl.png"
+ : "sc_images/msg/sc_icon_message_activity.png";
+ }
+
+ @override
+ String getMessagePageSystemMessageIcon() {
+ // 原始应用:消息页面系统消息图标
+ return "sc_images/msg/sc_icon_message_system.png";
+ }
+
+ @override
+ String getMessagePageSystemTitleBackground(bool isRtl) {
+ // 原始应用:消息页面系统消息标题背景图标
+ return isRtl
+ ? "sc_images/msg/sc_icon_system_title_bg_rtl.png"
+ : "sc_images/msg/sc_icon_system_title_bg.png";
+ }
+
+ @override
+ String getMessagePageNotificationMessageIcon() {
+ // 原始应用:消息页面通知消息图标
+ return "sc_images/msg/sc_icon_message_noti.png";
+ }
+
+ @override
+ String getMessagePageNotificationTitleBackground(bool isRtl) {
+ // 原始应用:消息页面通知消息标题背景图标
+ return isRtl
+ ? "sc_images/msg/sc_icon_notifcation_title_bg_rtl.png"
+ : "sc_images/msg/sc_icon_notifcation_title_bg.png";
+ }
+
+ /// === 聊天页面 (SCMessageChatPage) 方法实现 ===
+
+ @override
+ String getSCMessageChatPageRoomSettingBackground() {
+ // 原始应用:聊天页面房间设置背景图像
+ return "sc_images/room/sc_icon_room_settig_bg.png";
+ }
+
+ @override
+ String getSCMessageChatPageEmojiIcon() {
+ // 原始应用:聊天页面表情图标
+ return "sc_images/msg/sc_icon_emoji.png";
+ }
+
+ @override
+ String getSCMessageChatPageChatKeyboardIcon() {
+ // 原始应用:聊天页面聊天键盘图标
+ return "sc_images/msg/sc_icon_chsc_key.png";
+ }
+
+ @override
+ String getSCMessageChatPageAddIcon() {
+ // 原始应用:聊天页面添加图标
+ return "sc_images/msg/sc_icon_add.png";
+ }
+
+ @override
+ String getSCMessageChatPageSendMessageIcon() {
+ // 原始应用:聊天页面发送消息图标
+ return "sc_images/msg/sc_icon_chsc_message_send.png";
+ }
+
+ @override
+ String getSCMessageChatPageCameraIcon() {
+ // 原始应用:聊天页面相机图标
+ return "sc_images/msg/sc_icon_xiangji.png";
+ }
+
+ @override
+ String getSCMessageChatPagePictureIcon() {
+ // 原始应用:聊天页面图片图标
+ return "sc_images/msg/sc_icon_tupian.png";
+ }
+
+ @override
+ String getSCMessageChatPageRedEnvelopeIcon() {
+ // 原始应用:聊天页面红包图标
+ return "sc_images/msg/sc_icon_hongbao.png";
+ }
+
+ @override
+ String getSCMessageChatPageRedEnvelopeMessageBackground() {
+ // 原始应用:聊天页面红包消息背景图像
+ return "sc_images/msg/sc_icon_msg_send_hongbao_bg.png";
+ }
+
+ @override
+ String getSCMessageChatPageRedEnvelopeConfigTabButtonIcon() {
+ // 原始应用:聊天页面红包配置标签按钮图标
+ return "sc_images/room/sc_icon_red_envelope_config_tab_btn.png";
+ }
+
+ @override
+ String getSCMessageChatPageRedEnvelopeMessageItemBackground() {
+ // 原始应用:聊天页面红包消息项背景图像
+ return "sc_images/msg/sc_icon_red_envelopes_msg_item_bg.png";
+ }
+
+ @override
+ String getSCMessageChatPageRedEnvelopeReceivePackageIcon() {
+ // 原始应用:聊天页面红包接收包图标
+ return "sc_images/room/sc_icon_red_envelope_rec_pack.png";
+ }
+
+ @override
+ String getSCMessageChatPageRedEnvelopeOpenBackground() {
+ // 原始应用:聊天页面红包打开背景图像
+ return "sc_images/msg/sc_icon_red_envelopes_msg_open_bg.png";
+ }
+
+ @override
+ String getSCMessageChatPageRedEnvelopeOpenedBackground() {
+ // 原始应用:聊天页面红包已打开背景图像
+ return "sc_images/msg/sc_icon_red_envelopes_msg_opened_bg.png";
+ }
+
+ @override
+ String getSCMessageChatPageGoldCoinIcon() {
+ // 原始应用:聊天页面金币图标
+ return "sc_images/general/sc_icon_jb.png";
+ }
+
+ @override
+ String getSCMessageChatPageMessageMenuDeleteIcon() {
+ // 原始应用:聊天页面消息菜单删除图标
+ return "sc_images/msg/sc_icon_msg_menu_delete.png";
+ }
+
+ @override
+ String getSCMessageChatPageMessageMenuCopyIcon() {
+ // 原始应用:聊天页面消息菜单复制图标
+ return "sc_images/msg/sc_icon_msg_menu_copy.png";
+ }
+
+ @override
+ String getSCMessageChatPageMessageMenuRecallIcon() {
+ // 原始应用:聊天页面消息菜单撤回图标
+ return "sc_images/msg/sc_icon_msg_menu_recall.png";
+ }
+
+ @override
+ String getSCMessageChatPageLoadingIcon() {
+ // 原始应用:聊天页面加载图标
+ return "sc_images/general/sc_icon_loading.png";
+ }
+
+ @override
+ String getSCMessageChatPageSystemHeadImage() {
+ // 原始应用:聊天页面系统头像图像
+ return "sc_images/msg/head_system.png";
+ }
+
+ @override
+ String getGenderBackgroundImage(bool isFemale) {
+ // 原始应用:性别背景图片
+ return isFemale
+ ? "sc_images/login/sc_icon_sex_woman_bg.png"
+ : "sc_images/login/sc_icon_sex_man_bg.png";
+ }
+
+ @override
+ String getIdBackgroundImage(bool hasSpecialId) {
+ // 原始应用:ID背景图片
+ return hasSpecialId
+ ? "sc_images/general/sc_icon_special_id_bg.png"
+ : "sc_images/general/sc_icon_id_bg.png";
+ }
+
+ @override
+ String getCopyIdIcon() {
+ // 原始应用:复制ID图标
+ return "sc_images/room/sc_icon_user_card_copy_id.png";
+ }
+
+ /// === Gift页面差异化方法实现 ===
+
+ @override
+ String getGiftPageFirstRechargeRoomTagIcon() {
+ // 原始应用:首充房间标签图标
+ return "sc_images/room/sc_icon_first_recharge_room_tag.png";
+ }
+
+ @override
+ String getGiftPageGoldCoinIcon() {
+ // 原始应用:金币图标
+ return "sc_images/general/sc_icon_jb.png";
+ }
+
+ @override
+ String getGiftPageGiveTypeBackground() {
+ // 原始应用:赠送类型背景图像
+ return "sc_images/room/sc_icon_give_type_bg.png";
+ }
+
+ @override
+ String getGiftPageActivityGiftHeadBackground(String giftType) {
+ // 原始应用:活动礼物头部背景图像,根据礼物类型返回不同路径
+ switch (giftType) {
+ case 'ACTIVITY':
+ return "sc_images/room/sc_icon_activity_gift_head_bg.png";
+ case 'LUCK':
+ return "sc_images/room/sc_icon_luck_gift_head_bg.png";
+ case 'CP':
+ return "sc_images/room/sc_icon_cp_gift_head_bg.png";
+ case 'MAGIC':
+ return "sc_images/room/sc_icon_magic_gift_head_bg.png";
+ default:
+ return "sc_images/room/sc_icon_activity_gift_head_bg.png";
+ }
+ }
+
+ @override
+ String getGiftPageCustomizedRuleIcon() {
+ // 原始应用:自定义规则图标
+ return "sc_images/room/sc_icon_customized_rule.png";
+ }
+
+ @override
+ String getGiftPageGiftEffectIcon(String giftType) {
+ // 原始应用:特效礼物图标
+ return "sc_images/room/sc_icon_gift_effect.png";
+ }
+
+ @override
+ String getGiftPageGiftMusicIcon(String giftType) {
+ // 原始应用:音乐礼物图标
+ return "sc_images/room/sc_icon_gift_music.png";
+ }
+
+ @override
+ String getGiftPageGiftLuckIcon(String giftType) {
+ // 原始应用:幸运礼物图标
+ return "sc_images/room/sc_icon_gift_luck.png";
+ }
+
+ @override
+ String getGiftPageGiftCpIcon(String giftType) {
+ // 原始应用:CP礼物图标
+ return "sc_images/room/sc_icon_gift_cp.png";
+ }
+
+ @override
+ String getGiftPageFirstRechargeTextIcon(String languageCode) {
+ // 原始应用:首充文本图标(根据语言显示不同图像)
+ if (languageCode == 'ar') {
+ return "sc_images/index/sc_icon_first_recharge_ar_text.png";
+ } else {
+ // 默认为英语版本
+ return "sc_images/index/sc_icon_first_recharge_en_text.png";
+ }
+ }
+
+ @override
+ String getGiftPageAllOnMicrophoneIcon() {
+ // 原始应用:"全开麦"图标
+ return "sc_images/room/sc_icon_all_on_microphone.png";
+ }
+
+ @override
+ String getGiftPageUsersOnMicrophoneIcon() {
+ // 原始应用:"用户开麦"图标
+ return "sc_images/room/sc_icon_userson_microphone.png";
+ }
+
+ @override
+ String getGiftPageAllInTheRoomIcon() {
+ // 原始应用:"房间所有人"图标
+ return "sc_images/room/sc_icon_all_in_the_room.png";
+ }
+
+ @override
+ String getCommonSelectIcon() {
+ // 原始应用:通用选择图标
+ return "sc_images/general/sc_icon_checked.png";
+ }
+
+ @override
+ String getCommonUnselectIcon() {
+ // 原始应用:通用未选择图标
+ return "sc_images/general/sc_icon_unchecked.png";
+ }
+
+ /// === Media页面差异化方法实现 ===
+
+ @override
+ Color getImagePreviewBackgroundColor() {
+ // 原始应用:图片预览页面背景颜色 - 黑色
+ return Colors.black;
+ }
+
+ @override
+ Color getImagePreviewGalleryBackgroundColor() {
+ // 原始应用:图片预览画廊背景颜色 - 黑色
+ return Colors.black;
+ }
+
+ @override
+ Color getImagePreviewAppBarBackgroundColor() {
+ // 原始应用:图片预览AppBar背景颜色 - 黑色54%透明度
+ return Colors.black54;
+ }
+
+ @override
+ Color getImagePreviewBackIconColor() {
+ // 原始应用:图片预览返回图标颜色 - 白色
+ return Colors.white;
+ }
+
+ @override
+ Color getImagePreviewTextColor() {
+ // 原始应用:图片预览文本颜色 - 白色
+ return Colors.white;
+ }
+
+ @override
+ Color getImagePreviewLoadingIndicatorColor() {
+ // 原始应用:图片预览加载指示器颜色 - 默认主题色
+ // CircularProgressIndicator默认使用主题色
+ return const Color(0xFFFF9500); // 应用主色调
+ }
+
+ @override
+ double getImagePreviewAppBarOpacity() {
+ // 原始应用:图片预览AppBar透明度 - 0.54 (Colors.black54)
+ return 0.54;
+ }
+
+ @override
+ Color getVideoPlayerBackgroundColor() {
+ // 原始应用:视频播放页面背景颜色 - 黑色
+ return Colors.black;
+ }
+
+ @override
+ Color getVideoPlayerControlsBackgroundColor() {
+ // 原始应用:视频播放控制界面背景颜色 - 黑色38%透明度
+ return Colors.black38;
+ }
+
+ @override
+ Color getVideoPlayerIconColor() {
+ // 原始应用:视频播放图标颜色 - 白色
+ return Colors.white;
+ }
+
+ @override
+ Color getVideoPlayerBottomControlsBackgroundColor() {
+ // 原始应用:视频播放底部控制栏背景颜色 - 黑色54%透明度
+ return Colors.black54;
+ }
+
+ @override
+ Color getVideoPlayerProgressBarActiveColor() {
+ // 原始应用:视频播放进度条活动颜色 - 红色
+ return Colors.red;
+ }
+
+ @override
+ Color getVideoPlayerProgressBarInactiveColor() {
+ // 原始应用:视频播放进度条非活动颜色 - 灰色
+ return Colors.grey;
+ }
+
+ @override
+ Color getVideoPlayerTextColor() {
+ // 原始应用:视频播放文本颜色 - 白色
+ return Colors.white;
+ }
+
+ @override
+ Color getVideoPlayerLoadingIndicatorColor() {
+ // 原始应用:视频播放加载指示器颜色 - 红色
+ return Colors.red;
+ }
+
+ @override
+ double getVideoPlayerControlsOpacity() {
+ // 原始应用:视频播放控制界面透明度 - 0.38 (Colors.black38)
+ return 0.38;
+ }
+
+ @override
+ double getVideoPlayerBottomControlsOpacity() {
+ // 原始应用:视频播放底部控制栏透明度 - 0.54 (Colors.black54)
+ return 0.54;
+ }
+
+ @override
+ int getVideoPlayerControlsDisplayDuration() {
+ // 原始应用:视频播放控制界面显示持续时间 - 3秒
+ return 3;
+ }
+
+ /// === 举报页面差异化方法实现 ===
+
+ @override
+ String getReportPageBackgroundImage() {
+ // 原始应用:举报页面背景图片 - 与房间设置背景相同
+ return "sc_images/room/sc_icon_room_settig_bg.png";
+ }
+
+ @override
+ Color getReportPageHintTextColor() {
+ // 原始应用:举报页面提示文本颜色 - Colors.black38
+ return Colors.black38;
+ }
+
+ @override
+ Color getReportPageContainerBackgroundColor() {
+ // 原始应用:举报页面容器背景颜色 - Colors.white
+ return Colors.white;
+ }
+
+ @override
+ Color getReportPageBorderColor() {
+ // 原始应用:举报页面边框颜色 - Color(0xffE6E6E6)
+ return const Color(0xffE6E6E6);
+ }
+
+ @override
+ Color getReportPagePrimaryTextColor() {
+ // 原始应用:举报页面主要文本颜色 - Colors.black
+ return Colors.black;
+ }
+
+ @override
+ Color getReportPageSecondaryHintTextColor() {
+ // 原始应用:举报页面次级提示文本颜色 - Colors.black45
+ return Colors.black45;
+ }
+
+ @override
+ Color getReportPageUnselectedBorderColor() {
+ // 原始应用:举报页面未选中边框颜色 - Colors.grey
+ return Colors.grey;
+ }
+
+ @override
+ Color getReportPageSubmitButtonBackgroundColor() {
+ // 原始应用:举报页面提交按钮背景颜色 - 使用主题主色
+ // 注意:在实际使用时,页面应通过SocialChatTheme.primaryColor获取
+ // 这里返回Colors.blue作为占位符,实际页面应该使用主题颜色
+ // 或者可以考虑返回null,让页面使用默认主题颜色
+ return Colors.blue; // 临时值,需要从主题获取
+ }
+
+ @override
+ Color getReportPageSubmitButtonTextColor() {
+ // 原始应用:举报页面提交按钮文本颜色 - Colors.white
+ return Colors.white;
+ }
+
+ @override
+ String getReportPageIcon(String iconType) {
+ // 原始应用:举报页面图标路径
+ switch (iconType) {
+ case 'addPic':
+ return "sc_images/general/sc_icon_add_pic.png";
+ case 'closePic':
+ return "sc_images/general/sc_icon_pic_close.png";
+ case 'checked':
+ return "sc_images/general/sc_icon_checked.png";
+ default:
+ return ""; // 未知图标类型返回空字符串
+ }
+ }
+
+ /// === 语音房间页面差异化方法实现 ===
+
+ @override
+ Color getVoiceRoomBackgroundColor() {
+ // 原始应用:语音房间页面背景颜色 - Colors.transparent
+ return Colors.transparent;
+ }
+
+ @override
+ Color getVoiceRoomTabLabelColor() {
+ // 原始应用:语音房间页面Tab标签选中颜色 - Colors.white
+ return Colors.white;
+ }
+
+ @override
+ Color getVoiceRoomTabUnselectedLabelColor() {
+ // 原始应用:语音房间页面Tab标签未选中颜色 - Colors.white54
+ return Colors.white54;
+ }
+
+ @override
+ Color getVoiceRoomTabIndicatorColor() {
+ // 原始应用:语音房间页面Tab指示器颜色 - Colors.transparent
+ return Colors.transparent;
+ }
+
+ @override
+ Color getVoiceRoomTabDividerColor() {
+ // 原始应用:语音房间页面Tab分割线颜色 - Colors.transparent
+ return Colors.transparent;
+ }
+
+ @override
+ EdgeInsets getVoiceRoomTabLabelPadding() {
+ // 原始应用:语音房间页面Tab标签内边距 - EdgeInsets.symmetric(horizontal: 12)
+ // 注意:页面需要将数值乘以ScreenUtil().w
+ return const EdgeInsets.symmetric(horizontal: 12);
+ }
+
+ @override
+ EdgeInsetsDirectional getVoiceRoomChatContainerMargin() {
+ // 原始应用:语音房间页面聊天容器外边距 - EdgeInsets.only(right: 52)
+ // 注意:页面需要将数值乘以ScreenUtil().w
+ return const EdgeInsetsDirectional.only(end: 52);
+ }
+
+ @override
+ TextStyle getVoiceRoomTabLabelStyle() {
+ // 原始应用:语音房间页面Tab标签选中文本样式
+ // 字体大小15,字体族"MyCustomFont"
+ // 注意:页面需要将字体大小乘以ScreenUtil().sp
+ return const TextStyle(
+ fontSize: 15,
+ fontFamily: "MyCustomFont",
+ );
+ }
+
+ @override
+ TextStyle getVoiceRoomTabUnselectedLabelStyle() {
+ // 原始应用:语音房间页面Tab标签未选中文本样式
+ // 字体大小13,字体族"MyCustomFont"
+ // 注意:页面需要将字体大小乘以ScreenUtil().sp
+ return const TextStyle(
+ fontSize: 13,
+ fontFamily: "MyCustomFont",
+ );
+ }
+
+ @override
+ String getVoiceRoomDefaultBackgroundImage() {
+ // 原始应用:语音房间默认背景图像路径
+ return "sc_images/room/sc_icon_room_defaut_bg.png";
+ }
+
+ /// === 钱包页面差异化方法实现 ===
+
+ /// === 充值页面差异化方法实现 ===
+
+ @override
+ String getRechargePageBackgroundImage() {
+ // 原始应用:充值页面背景图像路径 - "sc_images/room/sc_icon_room_settig_bg.png"
+ return "sc_images/room/sc_icon_room_settig_bg.png";
+ }
+
+ @override
+ Color getRechargePageScaffoldBackgroundColor() {
+ // 原始应用:充值页面Scaffold背景颜色 - Colors.transparent
+ return Colors.transparent;
+ }
+
+ @override
+ Color getRechargePageDialogBarrierColor() {
+ // 原始应用:充值页面对话框屏障颜色 - Colors.transparent
+ return Colors.transparent;
+ }
+
+ @override
+ Color getRechargePageDialogContainerBackgroundColor() {
+ // 原始应用:充值页面对话框容器背景颜色 - Colors.white30
+ return Colors.white30;
+ }
+
+ @override
+ Color getRechargePageDialogTextColor() {
+ // 原始应用:充值页面对话框文本颜色 - Colors.black38
+ return Colors.black38;
+ }
+
+ @override
+ Color getRechargePageMainContainerBackgroundColor() {
+ // 原始应用:充值页面主容器背景颜色 - Colors.white
+ return Colors.white;
+ }
+
+ @override
+ Color getRechargePageButtonBackgroundColor() {
+ // 原始应用:充值页面按钮背景颜色 - 使用主题颜色
+ // 注意:页面应使用SocialChatTheme.primaryLight
+ return const Color(0xFFE6F7FF); // 近似主题浅色
+ }
+
+ @override
+ Color getRechargePageButtonTextColor() {
+ // 原始应用:充值页面按钮文本颜色 - Colors.white
+ return Colors.white;
+ }
+
+ @override
+ String getRechargePageWalletBackgroundImage() {
+ // 原始应用:充值页面钱包背景图像路径 - 'sc_images/index/sc_icon_wallet_bg.png'
+ return "sc_images/index/sc_icon_wallet_bg.png";
+ }
+
+ @override
+ String getRechargePageWalletIcon() {
+ // 原始应用:充值页面钱包图标路径 - 'sc_images/index/sc_icon_wallet_icon.png'
+ return "sc_images/index/sc_icon_wallet_icon.png";
+ }
+
+ @override
+ Color getRechargePageWalletTextColor() {
+ // 原始应用:充值页面钱包文本颜色 - Colors.white
+ return Colors.white;
+ }
+
+ @override
+ String getRechargePageGoldIcon() {
+ // 原始应用:充值页面金币图标路径(默认图标)- 'sc_images/general/sc_icon_jb.png'
+ return "sc_images/general/sc_icon_jb.png";
+ }
+
+ @override
+ Color getRechargePageSelectedItemBackgroundColor() {
+ // 原始应用:充值页面选中项背景颜色 - 使用主题浅色
+ // 注意:页面应使用SocialChatTheme.primaryLight
+ return const Color(0xFFE6F7FF); // 近似主题浅色
+ }
+
+ @override
+ Color getRechargePageSelectedItemBorderColor() {
+ // 原始应用:充值页面选中项边框颜色 - 使用主题主色
+ // 注意:页面应使用SocialChatTheme.primaryColor
+ return const Color(0xFF1890FF); // 近似主题主色
+ }
+
+ @override
+ Color getRechargePageUnselectedItemBorderColor() {
+ // 原始应用:充值页面未选中项边框颜色 - Color(0xffE6E6E6)
+ return const Color(0xffE6E6E6);
+ }
+
+ @override
+ Color getRechargePageUnselectedItemBackgroundColor() {
+ // 原始应用:充值页面未选中项背景颜色 - Colors.white
+ return Colors.white;
+ }
+
+ @override
+ Color getRechargePageItemTextColor() {
+ // 原始应用:充值页面项目文本颜色 - Colors.black54
+ return Colors.black54;
+ }
+
+ @override
+ Color getRechargePageItemPriceTextColor() {
+ // 原始应用:充值页面价格文本颜色 - Colors.black
+ return Colors.black;
+ }
+
+ @override
+ String getRechargePageGoldIconByIndex(int index) {
+ // 原始应用:根据索引获取充值页面金币图标路径
+ switch (index) {
+ case 0:
+ return "sc_images/general/sc_icon_jb.png";
+ case 1:
+ return "sc_images/general/sc_icon_jb2.png";
+ case 2:
+ return "sc_images/general/sc_icon_jb3.png";
+ default:
+ return "sc_images/general/sc_icon_jb.png"; // 默认图标
+ }
+ }
+
+ @override
+ String getRechargePageRecordIcon() {
+ // 原始应用:充值页面记录图标路径 - "sc_images/index/sc_icon_recharge_recod.png"
+ return "sc_images/index/sc_icon_recharge_recod.png";
+ }
+
+ @override
+ Color getRechargePageAppleItemBackgroundColor() {
+ // 原始应用:充值页面Apple产品项背景颜色 - Colors.white
+ return Colors.white;
+ }
+
+ /// === 金币记录页面差异化方法实现 ===
+
+ @override
+ String getGoldRecordPageBackgroundImage() {
+ // 原始应用:金币记录页面背景图像路径 - "sc_images/room/sc_icon_room_settig_bg.png"
+ return "sc_images/room/sc_icon_room_settig_bg.png";
+ }
+
+ @override
+ Color getGoldRecordPageScaffoldBackgroundColor() {
+ // 原始应用:金币记录页面Scaffold背景颜色 - Colors.transparent
+ return Colors.transparent;
+ }
+
+ @override
+ Color getGoldRecordSCPageListBackgroundColor() {
+ // 原始应用:金币记录页面列表背景颜色 - Colors.transparent
+ return Colors.transparent;
+ }
+
+ @override
+ Color getGoldRecordPageContainerBackgroundColor() {
+ // 原始应用:金币记录页面容器背景颜色 - Colors.white
+ return Colors.white;
+ }
+
+ @override
+ Color getGoldRecordPageBorderColor() {
+ // 原始应用:金币记录页面边框颜色 - Color(0xffE6E6E6)
+ return const Color(0xffE6E6E6);
+ }
+
+ @override
+ Color getGoldRecordPagePrimaryTextColor() {
+ // 原始应用:金币记录页面主要文本颜色 - Colors.black
+ return Colors.black;
+ }
+
+ @override
+ Color getGoldRecordPageSecondaryTextColor() {
+ // 原始应用:金币记录页面次要文本颜色 - Colors.black38
+ return Colors.black38;
+ }
+
+ /// === Store页面差异化方法实现 ===
+
+ @override
+ String getStorePageBackgroundImage() {
+ // 原始应用:Store页面背景图像路径 - "sc_images/room/sc_icon_room_settig_bg.png"
+ return "sc_images/room/sc_icon_room_settig_bg.png";
+ }
+
+ @override
+ String getStorePageShoppingBagIcon() {
+ // 原始应用:Store页面购物袋图标路径 - "sc_images/store/sc_icon_shop_bag.png"
+ return "sc_images/store/sc_icon_shop_bag.png";
+ }
+
+ @override
+ EdgeInsetsDirectional getStorePageShoppingBagMargin() {
+ // 原始应用:Store页面购物袋图标外边距 - EdgeInsetsDirectional.only(end: 10.w)
+ // 注意:这里无法使用.w单位,需要在调用处使用ScreenUtil()
+ return const EdgeInsetsDirectional.only(end: 10);
+ }
+
+ @override
+ EdgeInsets getStorePageTabLabelPadding() {
+ // 原始应用:Store页面Tab标签内边距 - EdgeInsets.symmetric(horizontal: 12.w)
+ // 注意:这里无法使用.w单位,需要在调用处使用ScreenUtil()
+ return const EdgeInsets.symmetric(horizontal: 12);
+ }
+
+ @override
+ TextStyle getStorePageTabLabelStyle() {
+ // 原始应用:Store页面Tab标签选中文本样式
+ // 原始值:TextStyle(fontSize: 15.sp, color: Colors.black87, fontWeight: FontWeight.w600)
+ // 注意:这里无法使用.sp单位,需要在调用处使用ScreenUtil()
+ return const TextStyle(
+ fontSize: 15,
+ color: Color(0xDD000000), // Colors.black87 对应 #DD000000
+ fontWeight: FontWeight.w600,
+ );
+ }
+
+ @override
+ TextStyle getStorePageTabUnselectedLabelStyle() {
+ // 原始应用:Store页面Tab标签未选中文本样式
+ // 原始值:TextStyle(fontSize: 13.sp, color: Colors.black38, fontWeight: FontWeight.w500)
+ // 注意:这里无法使用.sp单位,需要在调用处使用ScreenUtil()
+ return const TextStyle(
+ fontSize: 13,
+ color: Color(0x61000000), // Colors.black38 对应 #61000000
+ fontWeight: FontWeight.w500,
+ );
+ }
+
+ @override
+ Color getStorePageTabIndicatorColor() {
+ // 原始应用:Store页面Tab指示器颜色 - SocialChatTheme.primaryColor
+ // 需要查看SocialChatTheme.primaryColor的值
+ // 从socialchat_theme.dart中查看到primaryColor = Color(0xffFF5722);
+ return const Color(0xffFF5722); // SocialChatTheme.primaryColor
+ }
+
+ @override
+ Color getStorePageTabDividerColor() {
+ // 原始应用:Store页面Tab分割线颜色 - Colors.transparent
+ return Colors.transparent;
+ }
+
+ @override
+ Color getStorePageBottomDividerColor() {
+ // 原始应用:Store页面底部Divider颜色 - Colors.black12
+ return const Color(0x1F000000); // Colors.black12 对应 #1F000000
+ }
+
+ @override
+ double getStorePageBottomDividerThickness() {
+ // 原始应用:Store页面底部Divider厚度 - 0.5
+ // 注意:原始代码中使用0.5,没有.w单位
+ return 0.5;
+ }
+
+ @override
+ double getStorePageBottomDividerHeight() {
+ // 原始应用:Store页面底部Divider高度 - 24.w
+ // 注意:这里无法使用.w单位,需要在调用处使用ScreenUtil()
+ return 24;
+ }
+
+ @override
+ String getStorePageGoldIcon() {
+ // 原始应用:Store页面金币图标路径 - "sc_images/general/sc_icon_jb.png"
+ return "sc_images/general/sc_icon_jb.png";
+ }
+
+ @override
+ Color getStorePageGoldTextColor() {
+ // 原始应用:Store页面金币文本颜色 - Color(0xFFFFE134)
+ return const Color(0xFFFFE134);
+ }
+
+ @override
+ Color getStorePageGoldIconColor() {
+ // 原始应用:Store页面金币图标颜色 - Color(0xFFFFE134)
+ return const Color(0xFFFFE134);
+ }
+
+ /// === Store子页面(商品项)差异化方法实现 ===
+
+ @override
+ Color getStoreItemBackgroundColor() {
+ // 原始应用:Store商品项背景颜色 - Colors.white
+ return Colors.white;
+ }
+
+ @override
+ Color getStoreItemUnselectedBorderColor() {
+ // 原始应用:Store商品项未选中边框颜色 - Colors.black12
+ return const Color(0x1F000000); // Colors.black12 对应 #1F000000
+ }
+
+ @override
+ Color getStoreItemSelectedBorderColor() {
+ // 原始应用:Store商品项选中边框颜色 - SocialChatTheme.primaryLight (Color(0xffFF9500))
+ return const Color(0xffFF9500);
+ }
+
+ @override
+ String getStoreItemGoldIcon() {
+ // 原始应用:Store商品项金币图标路径 - "sc_images/general/sc_icon_jb.png"
+ return "sc_images/general/sc_icon_jb.png";
+ }
+
+ @override
+ Color getStoreItemPriceTextColor() {
+ // 原始应用:Store商品项价格文本颜色 - Colors.black
+ return Colors.black;
+ }
+
+ @override
+ Color getStoreItemBuyButtonColor() {
+ // 原始应用:Store商品项购买按钮背景颜色 - SocialChatTheme.primaryLight (Color(0xffFF9500))
+ return const Color(0xffFF9500);
+ }
+
+ @override
+ Color getStoreItemBuyButtonTextColor() {
+ // 原始应用:Store商品项购买按钮文本颜色 - Colors.white
+ return Colors.white;
+ }
+
+ @override
+ String getStoreItemActionIcon(String itemType) {
+ // 原始应用:Store商品项操作图标路径
+ // 根据商品类型返回不同的图标路径
+ switch (itemType) {
+ case 'headdress':
+ return "sc_images/store/sc_icon_shop_item_search.png"; // 头饰页面使用搜索图标
+ case 'mountains':
+ return "sc_images/store/sc_icon_shop_item_play.png"; // 山脉页面使用播放图标
+ case 'theme':
+ return "sc_images/store/sc_icon_store_theme_rev.png"; // 主题页面使用主题图标
+ case 'chatbox':
+ return "sc_images/store/sc_icon_shop_item_search.png"; // 聊天气泡页面使用搜索图标
+ default:
+ return "sc_images/store/sc_icon_store_theme_rev.png"; // 默认返回theme图标
+ }
+ }
+
+ /// === 动态页面差异化方法实现 ===
+
+ @override
+ String getDynamicPageBackgroundImage() {
+ // 原始应用:动态页面背景图像路径 - "sc_images/index/sc_icon_index_mask.png"
+ return "sc_images/index/sc_icon_index_mask.png";
+ }
+
+ @override
+ Color getDynamicPageScaffoldBackgroundColor() {
+ // 原始应用:动态页面Scaffold背景颜色 - Colors.transparent
+ return Colors.transparent;
+ }
+
+ @override
+ Color getDynamicPageAppBarBackgroundColor() {
+ // 原始应用:动态页面AppBar背景颜色 - Colors.transparent
+ return Colors.transparent;
+ }
+
+ @override
+ Color getDynamicPageTabLabelColor() {
+ // 原始应用:动态页面Tab标签选中颜色 - Colors.black87
+ return Colors.black87;
+ }
+
+ @override
+ Color getDynamicPageTabUnselectedLabelColor() {
+ // 原始应用:动态页面Tab标签未选中颜色 - Colors.black38
+ return Colors.black38;
+ }
+
+ @override
+ Color getDynamicPageTabIndicatorColor() {
+ // 原始应用:动态页面Tab指示器颜色 - Colors.transparent
+ return Colors.transparent;
+ }
+
+ @override
+ Color getDynamicPageTabDividerColor() {
+ // 原始应用:动态页面Tab分割线颜色 - Colors.transparent
+ return Colors.transparent;
+ }
+
+ @override
+ String getDynamicPageAddButtonIcon() {
+ // 原始应用:动态页面添加动态按钮图标路径 - "sc_images/dynamic/sc_icon_add_dynamic_btn.png"
+ return "sc_images/dynamic/sc_icon_add_dynamic_btn.png";
+ }
+
+ @override
+ bool shouldDynamicPageTabScrollable() {
+ // 原始应用:动态页面Tab标签是否可滚动 - true
+ return true;
+ }
+
+ @override
+ TextStyle getDynamicPageTabLabelStyle() {
+ // 原始应用:动态页面Tab标签选中文本样式 - TextStyle(fontWeight: FontWeight.bold, fontSize: 16.sp)
+ // 注意:这里无法使用.sp单位,需要在调用处使用ScreenUtil()
+ return const TextStyle(
+ fontWeight: FontWeight.bold,
+ fontSize: 16,
+ );
+ }
+
+ @override
+ TextStyle getDynamicPageTabUnselectedLabelStyle() {
+ // 原始应用:动态页面Tab标签未选中文本样式 - TextStyle(fontWeight: FontWeight.normal, fontSize: 15.sp)
+ // 注意:这里无法使用.sp单位,需要在调用处使用ScreenUtil()
+ return const TextStyle(
+ fontWeight: FontWeight.normal,
+ fontSize: 15,
+ );
+ }
+
+ /// === 启动页面差异化方法实现 ===
+
+ @override
+ String getSplashPageBackgroundImage() {
+ // 原始应用:启动页面背景图像路径 - "sc_images/splash/splash.png"
+ return "sc_images/splash/sc_splash.png";
+ }
+
+ @override
+ String getSplashPageIcon() {
+ // 原始应用:启动页面图标路径 - "sc_images/splash/sc_icon_splash_icon.png"
+ return "sc_images/splash/sc_icon_splash_icon.png";
+ }
+
+ @override
+ String getSplashPageSkipButtonBackground() {
+ // 原始应用:启动页面跳过按钮背景图像路径 - "sc_images/splash/sc_icon_splash_skip_bg.png"
+ return "sc_images/splash/sc_icon_splash_skip_bg.png";
+ }
+
+ @override
+ Color getSplashPageSkipButtonTextColor() {
+ // 原始应用:启动页面跳过按钮文本颜色 - Colors.white
+ return Colors.white;
+ }
+
+ @override
+ String getSplashPageKingGamesNameBackground() {
+ // 原始应用:启动页面游戏名称背景图像路径 - "sc_images/index/sc_icon_splash_king_games_name_bg.png"
+ return "sc_images/index/sc_icon_splash_king_games_name_bg.png";
+ }
+
+ @override
+ Color getSplashPageKingGamesTextColor() {
+ // 原始应用:启动页面游戏名称文本颜色 - Colors.white
+ return Colors.white;
+ }
+
+ @override
+ String getSplashPageCpNameBackground() {
+ // 原始应用:启动页面CP名称背景图像路径 - "sc_images/index/sc_icon_splash_cp_name_bg.png"
+ return "sc_images/index/sc_icon_splash_cp_name_bg.png";
+ }
+
+ @override
+ Color getSplashPageCpTextColor() {
+ // 原始应用:启动页面CP名称文本颜色 - Colors.white
+ return Colors.white;
+ }
+
+ /// === WebView页面差异化方法实现 ===
+
+ @override
+ Color getWebViewPageAppBarBackgroundColor() {
+ // 原始应用:WebView页面AppBar背景颜色 - Colors.white
+ return Colors.white;
+ }
+
+ @override
+ Color getWebViewPageTitleTextColor() {
+ // 原始应用:WebView页面标题文本颜色 - Color(0xff333333)
+ return const Color(0xff333333);
+ }
+
+ @override
+ Color getWebViewPageBackArrowColor() {
+ // 原始应用:WebView页面返回箭头图标颜色 - 使用默认图标颜色
+ return const Color(0xff333333);
+ }
+
+ @override
+ Color getWebViewPageProgressBarBackgroundColor() {
+ // 原始应用:WebView页面进度条背景颜色 - Colors.white70.withOpacity(0)
+ return Colors.white70.withOpacity(0);
+ }
+
+ @override
+ Color getWebViewPageProgressBarActiveColor() {
+ // 原始应用:WebView页面进度条活动颜色 - Color(0xffFF6000)
+ return const Color(0xffFF6000);
+ }
+
+ @override
+ Color getGameWebViewCloseIconColor() {
+ // 原始应用:游戏WebView页面关闭图标颜色 - Colors.white
+ return Colors.white;
+ }
+
+ @override
+ Color getGameWebViewScaffoldBackgroundColor() {
+ // 原始应用:游戏WebView页面Scaffold背景颜色 - Colors.transparent
+ return Colors.transparent;
+ }
+
+ @override
+ Color getGameWebViewProgressBarBackgroundColor() {
+ // 原始应用:游戏WebView页面进度条背景颜色 - Colors.white70.withOpacity(0)
+ return Colors.white70.withOpacity(0);
+ }
+
+ @override
+ Color getGameWebViewLoadingIndicatorColor() {
+ // 原始应用:游戏WebView页面加载指示器颜色 - Color(0xffFF6000)
+ return const Color(0xffFF6000);
+ }
+
+ /// === 搜索页面差异化方法实现 ===
+
+ @override
+ Color getSearchPageScaffoldBackgroundColor() {
+ // 原始应用:搜索页面Scaffold背景颜色 - Colors.white
+ return Colors.white;
+ }
+
+ @override
+ Color getSearchPageBackIconColor() {
+ // 原始应用:搜索页面返回图标颜色 - Color(0xffBBBBBB)
+ return const Color(0xffBBBBBB);
+ }
+
+ @override
+ Color getSearchPageInputBorderColor() {
+ // 原始应用:搜索页面搜索框边框颜色 - Colors.transparent
+ return Colors.transparent;
+ }
+
+ @override
+ Color getSearchPageInputTextColor() {
+ // 原始应用:搜索页面搜索框文本颜色 - Colors.grey
+ return Colors.grey;
+ }
+
+ @override
+ Color getSearchPageButtonTextColor() {
+ // 原始应用:搜索页面搜索按钮文本颜色 - Colors.black
+ return Colors.black;
+ }
+
+ @override
+ List getSearchPageButtonGradient() {
+ // 原始应用:搜索页面搜索按钮渐变颜色 - [Colors.transparent, Colors.transparent]
+ return [Colors.transparent, Colors.transparent];
+ }
+
+ @override
+ Color getSearchPageHistoryTitleTextColor() {
+ // 原始应用:搜索页面历史记录标题文本颜色 - Colors.black
+ return Colors.black;
+ }
+
+ @override
+ Color getSearchPageHistoryItemTextColor() {
+ // 原始应用:搜索页面历史项文本颜色 - Colors.white
+ return Colors.white;
+ }
+
+ @override
+ Color getSearchPageHistoryItemBackgroundColor() {
+ // 原始应用:搜索页面历史项背景颜色 - SocialChatTheme.primaryLight (Color(0xffFF9500))
+ return const Color(0xffFF9500);
+ }
+
+ @override
+ Color getSearchPageTabIndicatorGradientStartColor() {
+ // 原始应用:搜索页面Tab指示器渐变开始颜色 - Color(0xffFFA500)
+ return const Color(0xffFFA500);
+ }
+
+ @override
+ Color getSearchPageTabIndicatorGradientEndColor() {
+ // 原始应用:搜索页面Tab指示器渐变结束颜色 - Color(0xffFFD700)
+ return const Color(0xffFFD700);
+ }
+
+ @override
+ Color getSearchPageTabSelectedLabelColor() {
+ // 原始应用:搜索页面Tab标签选中颜色 - Colors.black
+ return Colors.black;
+ }
+
+ @override
+ Color getSearchPageTabDividerColor() {
+ // 原始应用:搜索页面Tab分割线颜色 - Colors.transparent
+ return Colors.transparent;
+ }
+
+ @override
+ Color getSearchPageTabUnselectedLabelColor() {
+ // 原始应用:搜索页面Tab标签未选中颜色 - Colors.black26
+ return Colors.black26;
+ }
+
+ @override
+ Color getSearchPageDividerContainerBackgroundColor() {
+ // 原始应用:搜索页面分隔容器背景颜色 - Color(0xffFFF8DA)
+ return const Color(0xffFFF8DA);
+ }
+
+ @override
+ TextStyle getSearchPageTabSelectedLabelStyle() {
+ // 原始应用:搜索页面Tab标签选中文本样式 - TextStyle(fontSize: 18.sp, fontWeight: FontWeight.w600)
+ // 注意:这里无法使用.sp单位,需要在调用处使用ScreenUtil()
+ return const TextStyle(
+ fontSize: 18,
+ fontWeight: FontWeight.w600,
+ color: Colors.black,
+ );
+ }
+
+ @override
+ TextStyle getSearchPageTabUnselectedLabelStyle() {
+ // 原始应用:搜索页面Tab标签未选中文本样式 - TextStyle(fontSize: 17.sp, fontWeight: FontWeight.w400)
+ // 注意:这里无法使用.sp单位,需要在调用处使用ScreenUtil()
+ return const TextStyle(
+ fontSize: 17,
+ fontWeight: FontWeight.w400,
+ color: Colors.black26,
+ );
+ }
+
+ @override
+ EdgeInsets getSearchPageResultTabLabelPadding() {
+ // 原始应用:搜索页面搜索结果Tab标签内边距 - EdgeInsets.symmetric(horizontal: 15)
+ return const EdgeInsets.symmetric(horizontal: 15);
+ }
+
+ @override
+ Color getSearchPageResultTabLabelColor() {
+ // 原始应用:搜索页面搜索结果Tab标签选中颜色 - Colors.black
+ return Colors.black;
+ }
+
+ @override
+ Color getSearchPageResultTabUnselectedLabelColor() {
+ // 原始应用:搜索页面搜索结果Tab标签未选中颜色 - Colors.black26
+ return Colors.black26;
+ }
+
+ @override
+ TextStyle getSearchPageResultTabUnselectedLabelStyle() {
+ // 原始应用:搜索页面搜索结果Tab标签未选中文本样式 - TextStyle(fontSize: 17, fontWeight: FontWeight.w400, color: Colors.black26)
+ return const TextStyle(
+ fontSize: 17,
+ fontWeight: FontWeight.w400,
+ color: Colors.black26,
+ );
+ }
+
+ @override
+ TextStyle getSearchPageResultTabLabelStyle() {
+ // 原始应用:搜索页面搜索结果Tab标签选中文本样式 - TextStyle(fontSize: 18, fontWeight: FontWeight.w600, color: Colors.black87)
+ return const TextStyle(
+ fontSize: 18,
+ fontWeight: FontWeight.w600,
+ color: Colors.black87,
+ );
+ }
+
+ @override
+ LinearGradient getSearchPageResultTabIndicatorColor() {
+ // 原始应用:搜索页面搜索结果Tab指示器颜色 - LinearGradient(colors: [Colors.transparent, Colors.transparent])
+ return const LinearGradient(
+ colors: [Colors.transparent, Colors.transparent],
+ );
+ }
+
+ @override
+ double getSearchPageResultTabIndicatorWidth() {
+ // 原始应用:搜索页面搜索结果Tab指示器宽度 - 15.0
+ return 15.0;
+ }
+
+ @override
+ Color getSearchPageResultBackgroundColor() {
+ // 原始应用:搜索页面搜索结果背景颜色 - Color(0xffFFF8DA)
+ return const Color(0xffFFF8DA);
+ }
+
+ @override
+ String getSearchPageClearHistoryIcon() {
+ // 原始应用:搜索页面清除历史记录图标路径
+ return "sc_images/general/sc_icon_delete.png";
+ }
+
+ @override
+ String getSearchPageEmptyDataIcon() {
+ // 原始应用:搜索页面空数据图标路径
+ return "sc_images/room/sc_icon_room_defaut_bg.png";
+ }
+
+ // === 任务页面差异化方法 ===
+
+ @override
+ String getTaskPageBackgroundImage() {
+ // 原始应用:任务页面背景图像 - "sc_images/room/sc_icon_room_settig_bg.png"
+ return "sc_images/room/sc_icon_room_settig_bg.png";
+ }
+
+ @override
+ Color getTaskPageBackButtonColor() {
+ // 原始应用:任务页面返回按钮颜色 - Colors.black
+ return Colors.black;
+ }
+
+ @override
+ Color getTaskPageScaffoldBackgroundColor() {
+ // 原始应用:任务页面Scaffold背景颜色 - Colors.white
+ return Colors.white;
+ }
+
+ @override
+ Color getTaskPageContainerBackgroundColor() {
+ // 原始应用:任务页面容器背景颜色 - Colors.white
+ return Colors.white;
+ }
+
+ @override
+ Color getTaskPageBorderColor() {
+ // 原始应用:任务页面边框颜色 - Color(0xffE6E6E6)
+ return const Color(0xffE6E6E6);
+ }
+
+ @override
+ Color getTaskPageSpecialBorderColor() {
+ // 原始应用:任务页面特殊边框颜色 - Color(0xffBB92FF)
+ return const Color(0xffBB92FF);
+ }
+
+ @override
+ Color getTaskPagePrimaryTextColor() {
+ // 原始应用:任务页面主要文本颜色 - Colors.white
+ return Colors.white;
+ }
+
+ @override
+ Color getTaskPageGoldTextColor() {
+ // 原始应用:任务页面金币文本颜色 - Color(0xffFFB627)
+ return const Color(0xffFFB627);
+ }
+
+ @override
+ Color getTaskPageExpTextColor() {
+ // 原始应用:任务页面经验文本颜色 - Color(0xff52FF90)
+ return const Color(0xff52FF90);
+ }
+
+ @override
+ Color getTaskPageThemeColor() {
+ // 原始应用:任务页面主题颜色 - SocialChatTheme.primaryColor
+ return const Color(0xffFF5722); // SocialChatTheme.primaryColor
+ }
+
+ @override
+ Color getTaskPageThemeLightColor() {
+ // 原始应用:任务页面浅主题颜色 - SocialChatTheme.primaryLight
+ return const Color(0xffFF9500); // SocialChatTheme.primaryLight
+ }
+
+ @override
+ List getTaskPageReceivableButtonGradient() {
+ // 原始应用:任务页面可领取按钮渐变颜色 - [Color(0xffBB92FF), Color(0xff8B45FF)]
+ return [const Color(0xffBB92FF), const Color(0xff8B45FF)];
+ }
+
+ @override
+ List getTaskPageCompletedButtonGradient() {
+ // 原始应用:任务页面已完成按钮渐变颜色 - [Color(0xffDADADA), Color(0xff585859)]
+ return [const Color(0xffDADADA), const Color(0xff585859)];
+ }
+
+ @override
+ Color getTaskPageButtonTextColor() {
+ // 原始应用:任务页面按钮文本颜色 - Colors.white
+ return Colors.white;
+ }
+
+ @override
+ Color getTaskPageMaskColor() {
+ // 原始应用:任务页面遮罩颜色 - Colors.black
+ return Colors.black;
+ }
+
+ @override
+ String getTaskPageHeadBackgroundImage() {
+ // 原始应用:任务页面头部背景图像 - "sc_images/index/sc_icon_task_head_bg.png"
+ return "sc_images/index/sc_icon_task_head_bg.png";
+ }
+
+ @override
+ String getTaskPageGoldIcon() {
+ // 原始应用:任务页面金币图标 - "sc_images/general/sc_icon_jb.png"
+ return "sc_images/general/sc_icon_jb.png";
+ }
+
+ @override
+ String getTaskPageExpIcon() {
+ // 原始应用:任务页面经验图标 - "sc_images/index/sc_icon_task_exp.png"
+ return "sc_images/index/sc_icon_task_exp.png";
+ }
+
+ @override
+ String getTaskPageInvitationRewardBackgroundImage() {
+ // 原始应用:任务页面邀请奖励背景图像 - "sc_images/index/sc_icon_invitation_bg.png"
+ return "sc_images/index/sc_icon_invitation_bg.png";
+ }
+
+ @override
+ Color getTaskPageGiftBagTextColor() {
+ // 原始应用:任务页面礼包文本颜色 - Colors.white
+ return Colors.white;
+ }
+
+ @override
+ Color getTaskPageAppBarBackgroundColor() {
+ // 原始应用:任务页面AppBar背景颜色 - Colors.transparent
+ return Colors.transparent;
+ }
+
+ @override
+ Color getTaskPageTransparentContainerColor() {
+ // 原始应用:任务页面透明容器颜色 - Colors.transparent
+ return Colors.transparent;
+ }
+
+ /// === 设置页面差异化方法实现 ===
+
+ @override
+ String getSettingsPageBackgroundImage() {
+ // 原始应用:设置页面背景图像路径 - "sc_images/person/sc_icon_edit_userinfo_bg.png"
+ return "sc_images/person/sc_icon_edit_userinfo_bg.png";
+ }
+
+ @override
+ Color getSettingsPageMainContainerBackgroundColor() {
+ // 原始应用:设置页面主容器背景颜色 - Colors.white
+ return Colors.white;
+ }
+
+ @override
+ Color getSettingsPageMainContainerBorderColor() {
+ // 原始应用:设置页面主容器边框颜色 - Color(0xffE6E6E6)
+ return const Color(0xffE6E6E6);
+ }
+
+ @override
+ Color getSettingsPagePrimaryTextColor() {
+ // 原始应用:设置页面主文本颜色 - Colors.black
+ return Colors.black;
+ }
+
+ @override
+ Color getSettingsPageSecondaryTextColor() {
+ // 原始应用:设置页面次要文本颜色 - Colors.black38
+ return Colors.black38;
+ }
+
+ @override
+ Color getSettingsPageIconColor() {
+ // 原始应用:设置页面图标颜色 - Colors.black26
+ return Colors.black26;
+ }
+
+ @override
+ Color getSettingsPageCommonTextColor() {
+ // 原始应用:设置页面常见文本颜色 - Colors.black38
+ return Colors.black38;
+ }
+
+ @override
+ Color getSettingsPageAboutTextColor() {
+ // 原始应用:设置页面关于文本颜色 - Colors.black38
+ return Colors.black38;
+ }
+
+ @override
+ Color getSettingsPageContainerBorderColor() {
+ // 原始应用:设置页面容器边框颜色 - Color(0xffE6E6E6)
+ return const Color(0xffE6E6E6);
+ }
+
+ @override
+ Color getSettingsPageContainerBackgroundColor() {
+ // 原始应用:设置页面容器背景颜色 - Colors.white
+ return Colors.white;
+ }
+
+ @override
+ Color getSettingsPageButtonBackgroundColor() {
+ // 原始应用:设置页面按钮背景颜色 - Color(0xffBBBBBB)
+ return const Color(0xffBBBBBB);
+ }
+
+ @override
+ Color getSettingsPageButtonTextColor() {
+ // 原始应用:设置页面按钮文本颜色 - Colors.white
+ return Colors.white;
+ }
+
+ /// === 语言页面差异化方法实现 ===
+
+ @override
+ String getLanguagePageBackgroundImage() {
+ // 原始应用:语言页面背景图像路径 - "sc_images/person/sc_icon_edit_userinfo_bg.png"
+ return "sc_images/person/sc_icon_edit_userinfo_bg.png";
+ }
+
+ @override
+ Color getLanguagePageCheckboxActiveColor() {
+ // 原始应用:语言页面复选框选中颜色 - SocialChatTheme.primaryColor
+ return const Color(0xffFF5722); // SocialChatTheme.primaryColor
+ }
+
+ @override
+ Color getLanguagePageCheckboxBorderColor() {
+ // 原始应用:语言页面复选框边框颜色 - Color(0xffD4D4D4)
+ return const Color(0xffD4D4D4);
+ }
+
+ @override
+ Color getLanguagePagePrimaryTextColor() {
+ // 原始应用:语言页面主文本颜色 - Colors.black
+ return Colors.black;
+ }
+
+ @override
+ Color getLanguagePageCheckColor() {
+ // 原始应用:语言页面复选框对勾颜色 - Colors.transparent
+ return Colors.transparent;
+ }
+
+ @override
+ double getLanguagePageCheckboxBorderRadius() {
+ // 原始应用:语言页面复选框边框圆角 - 15
+ return 15;
+ }
+
+ @override
+ double getLanguagePageCheckboxBorderWidth() {
+ // 原始应用:语言页面复选框边框宽度 - 2
+ return 2;
+ }
+
+ @override
+ Color getLanguagePageScaffoldBackgroundColor() {
+ // 原始应用:语言页面Scaffold背景颜色 - Colors.transparent
+ return Colors.transparent;
+ }
+
+ /// === 账户页面差异化方法实现 ===
+
+ @override
+ String getAccountPageBackgroundImage() {
+ // 原始应用:账户页面背景图像路径 - "sc_images/person/sc_icon_edit_userinfo_bg.png"
+ return "sc_images/person/sc_icon_edit_userinfo_bg.png";
+ }
+
+ @override
+ Color getAccountPageMainContainerBackgroundColor() {
+ // 原始应用:账户页面主容器背景颜色 - Colors.white
+ return Colors.white;
+ }
+
+ @override
+ Color getAccountPageMainContainerBorderColor() {
+ // 原始应用:账户页面主容器边框颜色 - Color(0xffE6E6E6)
+ return const Color(0xffE6E6E6);
+ }
+
+ @override
+ Color getAccountPagePrimaryTextColor() {
+ // 原始应用:账户页面主文本颜色 - Colors.black
+ return Colors.black;
+ }
+
+ @override
+ Color getAccountPageSecondaryTextColor() {
+ // 原始应用:账户页面次要文本颜色 - Colors.black38
+ return Colors.black38;
+ }
+
+ @override
+ Color getAccountPageIconColor() {
+ // 原始应用:账户页面图标颜色 - Colors.black26
+ return Colors.black26;
+ }
+
+ @override
+ Color getAccountPageDividerColor() {
+ // 原始应用:账户页面分隔线颜色 - Colors.black12
+ return Colors.black12;
+ }
+
+ @override
+ Color getAccountPageScaffoldBackgroundColor() {
+ // 原始应用:账户页面Scaffold背景颜色 - Colors.transparent
+ return Colors.transparent;
+ }
+ @override
+ Color getGoldRecordPageListBackgroundColor() {
+ // 马甲包策略:金币记录页面列表背景颜色 - 深灰色
+ return const Color(0xff1a1a1a); // #1a1a1a
+ }
+}
\ No newline at end of file
diff --git a/lib/app/config/strategies/variant1_business_logic_strategy.dart b/lib/app/config/strategies/variant1_business_logic_strategy.dart
new file mode 100644
index 0000000..c26eab7
--- /dev/null
+++ b/lib/app/config/strategies/variant1_business_logic_strategy.dart
@@ -0,0 +1,2565 @@
+import 'package:flutter/material.dart';
+import 'package:yumi/app/config/strategies/base_business_logic_strategy.dart';
+import 'package:yumi/app_localizations.dart';
+import 'package:yumi/shared/tools/sc_dialog_utils.dart';
+import 'package:yumi/ui_kit/theme/socialchat_theme.dart';
+
+import '../../../modules/home/popular/event/home_event_page.dart';
+import '../../../modules/home/popular/mine/sc_home_mine_page.dart';
+import '../../../modules/home/popular/party/sc_home_party_page.dart';
+
+/// 马甲包业务逻辑策略实现
+/// 提供与原始应用不同的业务逻辑
+class Variant1BusinessLogicStrategy extends BaseBusinessLogicStrategy {
+
+ /// 马甲包版本:调整Tab顺序,家族放在最后
+ @override
+ List getHomeTabPages(BuildContext context) {
+ final List pages = [];
+ pages.add(SCHomePartyPage());
+ pages.add(SCHomeMinePage());
+ // pages.add(HomeEventPage());
+ return pages;
+ }
+
+ @override
+ List getHomeTabLabels(BuildContext context) {
+ final List tabs = [];
+ tabs.add(Tab(text: SCAppLocalizations.of(context)!.party));
+ tabs.add(Tab(text: SCAppLocalizations.of(context)!.me));
+ // 马甲包:家族标签放在最后
+ // tabs.add(Tab(text: SCAppLocalizations.of(context)!.event));
+ return tabs;
+ }
+
+ @override
+ int getHomeInitialTabIndex() {
+ // 马甲包:从探索页开始
+ return 0; // explore页
+ }
+
+ /// 马甲包版本:不同的首充提示位置
+ @override
+ Map getFirstRechargePosition() {
+ // 马甲包:调整到左上角,提供完整的四个键值对
+ return {'top': 100.0, 'start': 15.0, 'bottom': null, 'end': null};
+ }
+
+ /// 马甲包版本:增强的首充提示点击处理
+ @override
+ void onFirstRechargeTap(BuildContext context) {
+ // 马甲包:显示更详细的首充对话框
+ SCDialogUtils.showFirstRechargeDialog(context);
+ // 额外逻辑:记录点击事件或触发其他行为
+ debugPrint('马甲包首充提示被点击');
+ }
+
+ /// === 登录页面差异化方法实现(马甲包专属样式)===
+
+ @override
+ String getLoginBackgroundImage() {
+ // 马甲包专属背景图片
+ // TODO: 根据Figma设计添加马甲包专属背景图片
+ return "sc_images/splash/sc_splash.png";
+ }
+
+ @override
+ String getLoginAppIcon() {
+ // 马甲包专属应用图标
+ // TODO: 根据Figma设计添加马甲包专属图标
+ return "sc_images/splash/sc_icon_splash_icon.png";
+ }
+
+ @override
+ Color getLoginButtonColor() {
+ // 马甲包按钮颜色 - 使用主题色
+ return const Color(0xffFF5722); // SocialChatTheme.primaryColor
+ }
+
+ @override
+ List? getLoginButtonGradient() {
+ // 马甲包按钮渐变:从Figma设计中提取的橙色渐变
+ return [
+ const Color(0xffB4FCCE), // rgb(254, 178, 25)
+ const Color(0xff5AF492), // rgb(254, 178, 25)
+ const Color(0xff077142), // rgb(255, 147, 38)
+ ];
+ }
+
+ @override
+ Color getLoginButtonTextColor() {
+ // 马甲包按钮文本颜色(白色,与渐变背景形成对比)
+ return Colors.white;
+ }
+
+ @override
+ Color getLoginLabelTextColor() {
+ // 马甲包标签文本颜色(黑色)
+ return Colors.white;
+ }
+
+ @override
+ BoxDecoration getLoginInputDecoration() {
+ // 马甲包输入框装饰:浅灰色背景,圆形边框
+ return BoxDecoration(
+ color: Colors.white24, // #f2f2f2
+ borderRadius: BorderRadius.circular(12), // 56px圆角
+ border: Border.all(color: Colors.transparent, width: 0),
+ );
+ }
+
+ @override
+ EdgeInsets getLoginPagePadding() {
+ // 马甲包页面内边距:根据Figma设计调整
+ return const EdgeInsets.only(top: 120); // 顶部319px间距
+ }
+
+ @override
+ bool shouldShowLoginStatusBar() {
+ // 马甲包:显示黑色状态栏
+ return true;
+ }
+
+ @override
+ Color getLoginHintTextColor() {
+ // 马甲包:提示文本颜色(黑色45%透明度)
+ return Colors.white;
+ }
+
+ @override
+ Color getLoginInputTextColor() {
+ // 马甲包:输入文本颜色(黑色)
+ return Colors.white;
+ }
+
+ /// === 家族页面差异化方法实现(马甲包专属) ===
+
+
+
+
+
+
+ @override
+ bool shouldShowPasswordRoomIcon() {
+ // 马甲包策略:不显示密码房间图标,简化UI
+ return false;
+ }
+
+ /// === 探索页面差异化方法实现(马甲包专属) ===
+
+ @override
+ int getExploreRoomDisplayThreshold() {
+ // 马甲包策略:显示更多房间在抽屉上方,减少抽屉使用
+ return 9;
+ }
+
+ @override
+ String getExploreGridIcon() {
+ // 马甲包策略:使用马甲包专属网格视图图标
+ // TODO: 根据Figma设计添加马甲包专属图标
+ return "sc_images/index/sc_icon_index_room_model_1.png";
+ }
+
+ @override
+ String getExploreListIcon() {
+ // 马甲包策略:使用马甲包专属列表视图图标
+ // TODO: 根据Figma设计添加马甲包专属图标
+ return "sc_images/index/sc_icon_index_room_model_2.png";
+ }
+
+ @override
+ String getExploreRankIconPattern(bool isGrid, int rank) {
+ // 马甲包策略:使用统一的排名图标,不区分网格/列表视图
+ // TODO: 根据Figma设计添加马甲包专属排名图标
+ if (isGrid) {
+ return "sc_images/index/sc_icon_explore_room_model_1_rank_$rank.png";
+ } else {
+ return "sc_images/index/sc_icon_explore_room_model_2_rank_$rank.png";
+ }
+ }
+
+ @override
+ Color getExploreRoomBorderColor() {
+ // 马甲包策略:使用马甲包主题色作为边框颜色
+ return SocialChatTheme.primaryLight; // 马甲包主题色
+ }
+
+ @override
+ double getExploreRoomBorderWidth() {
+ // 马甲包策略:更细的边框,更简洁的UI
+ return 1.0;
+ }
+
+ @override
+ int getExploreDrawerGridCrossAxisCount() {
+ // 马甲包策略:4列网格,更紧凑的布局
+ return 4;
+ }
+
+ @override
+ int getExploreRoomNameMarqueeThreshold() {
+ // 马甲包策略:更长的房间名称才显示滚动效果,减少不必要的动画
+ return 15;
+ }
+
+ @override
+ int getExploreRoomDescMarqueeThreshold() {
+ // 马甲包策略:更长的房间描述才显示滚动效果
+ return 18;
+ }
+
+ /// === 个人主页差异化方法实现(马甲包专属) ===
+
+ @override
+ String getMePageDefaultBackgroundImage() {
+ // 马甲包策略:使用马甲包专属默认背景图片
+ // TODO: 根据Figma设计添加马甲包专属背景图片
+ return "sc_images/person/sc_icon_my_head_bg_defalt.png";
+ }
+
+ @override
+ String getMePageGenderBackgroundImage(bool isFemale) {
+ // 马甲包策略:使用统一的背景图片,不区分性别
+ // TODO: 根据Figma设计添加马甲包专属背景图片
+ return "sc_images/person/sc_icon_my_head_bg_defalt.png";
+ }
+
+ @override
+ String getMePageCpDialogHeadImage() {
+ // 马甲包策略:使用马甲包专属CP对话框头像图片
+ // TODO: 根据Figma设计添加马甲包专属图标
+ return "sc_images/person/sc_icon_send_cp_requst_dialog_head.png";
+ }
+
+ @override
+ String getMePageDefaultAvatarImage() {
+ // 马甲包策略:使用马甲包专属默认头像图片
+ // TODO: 根据Figma设计添加马甲包专属头像图标
+ return "sc_images/general/sc_icon_avar_defalt.png";
+ }
+
+ @override
+ String getMePageIdBackgroundImage(bool hasSpecialId) {
+ // 马甲包策略:使用统一的ID背景图片,简化UI
+ // TODO: 根据Figma设计添加马甲包专属ID背景图片
+ return "sc_images/general/sc_icon_id_bg.png";
+ }
+
+ @override
+ String getMePageCopyIdIcon() {
+ // 马甲包策略:使用马甲包专属复制ID图标
+ // TODO: 根据Figma设计添加马甲包专属图标
+ return "sc_images/room/sc_icon_user_card_copy_id.png";
+ }
+
+ @override
+ String getMePageGenderAgeBackgroundImage(bool isFemale) {
+ // 马甲包策略:使用统一的性别年龄背景图片,不区分性别
+ // TODO: 根据Figma设计添加马甲包专属背景图片
+ return "sc_images/login/sc_icon_sex_woman_bg.png";
+ }
+
+ @override
+ String getMePageVisitorsFollowFansBackgroundImage(bool isFemale) {
+ // 马甲包策略:使用统一的访客关注粉丝背景图片,不区分性别
+ // TODO: 根据Figma设计添加马甲包专属背景图片
+ return "sc_images/person/sc_icon_vistors_follow_fans_bg_woman.png";
+ }
+
+ @override
+ String getMePageEditUserInfoIcon() {
+ // 马甲包策略:使用马甲包专属编辑用户信息图标
+ // TODO: 根据Figma设计添加马甲包专属图标
+ return "sc_images/person/sc_icon_edit_user_info2.png";
+ }
+
+ @override
+ Color getMePageShineColor() {
+ // 马甲包策略:使用马甲包主题色作为闪耀文本颜色
+ return const Color(0xffFF5722); // 马甲包主题色
+ }
+
+ @override
+ List getMePageGradientColors(bool isFemale) {
+ // 马甲包策略:使用统一的渐变颜色,不区分性别
+ return [
+ const Color(0xffFF5722), // 马甲包主题色
+ const Color(0xffFEB219), // 马甲包辅助色
+ const Color(0xffFF9326), // 马甲包辅助色
+ ];
+ }
+
+ @override
+ List getMePageTabIndicatorGradient(bool isFemale) {
+ // 马甲包策略:使用统一的Tab指示器渐变,不区分性别
+ return [
+ const Color(0xffFF5722), // 马甲包主题色
+ const Color(0xffFEB219), // 马甲包辅助色
+ ];
+ }
+
+ @override
+ Color getMePageVisitorsFollowFansTextColor() {
+ // 马甲包策略:使用更亮的文本颜色,提高可读性
+ return const Color(0xffFFFFFF); // 白色
+ }
+
+ @override
+ int getMePageInitialTabIndex() {
+ // 马甲包策略:从动态页开始,鼓励用户发布内容
+ return 0; // dynamic页
+ }
+
+ @override
+ double getMePageScrollOpacityThreshold() {
+ // 马甲包策略:降低滚动阈值,更快显示AppBar效果
+ return 200.0;
+ }
+
+ @override
+ int getMePageNicknameScrollThreshold() {
+ // 马甲包策略:提高昵称滚动阈值,减少不必要的动画
+ return 18;
+ }
+
+ @override
+ int getMePageAgeDisplayWidthThreshold() {
+ // 马甲包策略:降低年龄显示宽度阈值,更早调整布局
+ return 99;
+ }
+
+ @override
+ double getMePageOpacityThresholdForAvatarDisplay() {
+ // 马甲包策略:降低头像显示透明度阈值,更早显示头像
+ return 0.3;
+ }
+
+ /// === 热门页面差异化方法实现(马甲包专属) ===
+
+ @override
+ String getPopularLeaderboardBackgroundImage(String leaderboardType) {
+ // 马甲包策略:使用马甲包专属的排行榜背景图片
+ // 原始应用:使用现有的图像资源路径
+ switch (leaderboardType) {
+ case 'room':
+ return "sc_images/index/sc_icon_leader_spinner_room_bg.png";
+ case 'wealth':
+ return "sc_images/index/sc_icon_leader_spinner_wealth_bg.png";
+ case 'charm':
+ return "sc_images/index/sc_icon_leader_spinner_charm_bg.png";
+ default:
+ return "sc_images/index/sc_icon_leader_spinner_room_bg.png";
+ }
+ }
+
+ /// === 游戏页面差异化方法实现(马甲包专属) ===
+
+ @override
+ String getGameRankBackgroundImage(int rank) {
+ // 马甲包策略:使用统一的背景图片,简化UI
+ return "sc_images/game/sc_icon_game_list_item_bg_variant1.png";
+ }
+
+ @override
+ String getGameRankIcon(int rank) {
+ // 马甲包策略:使用统一的排名图标
+ return "sc_images/game/sc_icon_game_rank_variant1.png";
+ }
+
+ @override
+ Color getGamePageThemeColor() {
+ // 马甲包策略:使用马甲包主题色
+ return const Color(0xffFF9326);
+ }
+
+ @override
+ Color getGamePageBackgroundColor() {
+ // 马甲包策略:更亮的背景颜色
+ return const Color(0xfffafafa);
+ }
+
+ @override
+ int getGamePageGridCrossAxisCount() {
+ // 马甲包策略:4列网格,更紧凑的布局
+ return 4;
+ }
+
+ @override
+ double getGamePageGridChildAspectRatio() {
+ // 马甲包策略:更高的高度比例
+ return 1.5;
+ }
+
+ @override
+ Color getGameRankTextColor(int rank) {
+ // 马甲包策略:使用统一的文本颜色,简化UI
+ return const Color(0xffFF5722);
+ }
+
+ @override
+ Color getGamePageGradientSecondColor() {
+ // 马甲包策略:使用马甲包风格的渐变第二颜色
+ return const Color(0xffFFE0B2);
+ }
+
+ @override
+ String getGameHotTagBackgroundImage() {
+ // 马甲包策略:使用马甲包风格的热门游戏标签背景图片
+ return "sc_images/index/sc_icon_hotgames_tag_bg_variant1.png";
+ }
+
+ @override
+ String getGameNewTagImage() {
+ // 马甲包策略:使用马甲包风格的新游戏标签图片
+ return "sc_images/index/sc_icon_game_new_tag_variant1.png";
+ }
+
+ @override
+ String getGamePageMaskImage() {
+ // 马甲包策略:使用马甲包风格的游戏页面遮罩图片
+ return "sc_images/index/sc_icon_index_mask_variant1.png";
+ }
+
+ /// === VIP页面差异化方法实现(马甲包专属) ===
+
+ @override
+ String getVipPageBackgroundImage(int vipLevel) {
+ // 原始应用:使用现有的VIP背景图像模式
+ return "sc_images/vip/sc_icon_vip_level_bg_$vipLevel.png";
+ }
+
+ @override
+ String getVipPageIcon(int vipLevel) {
+ // 原始应用:使用现有的VIP图标模式
+ return "sc_images/vip/sc_icon_vip_level_$vipLevel.png";
+ }
+
+ @override
+ List getVipPageButtonGradient() {
+ // 原始应用:VIP按钮渐变颜色
+ return [const Color(0xffFF5722), const Color(0xffFEB219)];
+ }
+
+ @override
+ int getVipPageGridCrossAxisCount() {
+ // 原始应用:3列网格
+ return 3;
+ }
+
+ @override
+ double getVipPageGridChildAspectRatio() {
+ // 原始应用:默认高度比例
+ return 1.5;
+ }
+
+ @override
+ String getVipPageHeadBackgroundImage(int vipLevel) {
+ // 原始应用:VIP头部背景图像模式
+ return "sc_images/vip/sc_icon_vip_head_bg_v$vipLevel.png";
+ }
+
+ @override
+ String getVipPageTabSelectedIcon(int vipLevel) {
+ // 原始应用:Tab选中状态图标模式
+ return "sc_images/vip/sc_icon_tab_vip_text_on_v$vipLevel.png";
+ }
+
+ @override
+ String getVipPageTabUnselectedIcon(int vipLevel) {
+ // 原始应用:Tab未选中状态图标模式
+ return "sc_images/vip/sc_icon_tab_vip_text_no_v$vipLevel.png";
+ }
+
+ @override
+ String getVipPageLargeIcon(int vipLevel) {
+ // 原始应用:VIP页面大图标路径模式
+ return "sc_images/vip/sc_icon_vip${vipLevel}_ic.webp";
+ }
+
+ @override
+ String getVipPageTitleImage(int vipLevel) {
+ // 原始应用:VIP页面标题图像路径模式
+ return "sc_images/vip/sc_icon_vip${vipLevel}_t1.png";
+ }
+
+ @override
+ String getVipPageTagImage(int vipLevel, int tagIndex) {
+ // 原始应用:VIP页面标签图像路径模式
+ return "sc_images/vip/sc_icon_vip${vipLevel}_tag$tagIndex.png";
+ }
+
+ @override
+ String getVipPageItemBackgroundImage(int vipLevel) {
+ // 原始应用:VIP页面功能项背景图像路径模式
+ return "sc_images/vip/sc_icon_vip${vipLevel}_item_bg.png";
+ }
+
+ @override
+ String getVipPagePrivilegeIcon(int vipLevel, int privilegeIndex) {
+ // 原始应用:VIP页面特权图标路径模式
+ return "sc_images/vip/sc_icon_vip${vipLevel}_privilege$privilegeIndex.png";
+ }
+
+ @override
+ String getVipPageFeatureIcon(int vipLevel, String featureName) {
+ // 原始应用:VIP页面功能图标路径模式
+ return "sc_images/vip/sc_icon_vip${vipLevel}_$featureName.png";
+ }
+
+ @override
+ String getVipPagePreviewImage(
+ int vipLevel,
+ String previewType,
+ String featureName,
+ ) {
+ // 原始应用:VIP页面预览图像路径模式
+ if (featureName == 'profile_frame') {
+ return "sc_images/vip/sc_icon_vip${vipLevel}_profile_rev.png";
+ } else if (featureName == 'profile_card') {
+ return "sc_images/vip/sc_icon_vip${vipLevel}_profile_card_rev.png";
+ } else if (featureName == 'room_cover_headdress') {
+ return "sc_images/vip/sc_icon_vip${vipLevel}_room_cover_border_rev.png";
+ } else if (featureName == 'mic_rippl_theme') {
+ return "sc_images/vip/sc_icon_vip${vipLevel}_sesc_rev.png";
+ } else if (featureName == 'chatbox') {
+ return "sc_images/vip/sc_icon_vip${vipLevel}_chatbox_pre.png";
+ } else {
+ return "sc_images/vip/sc_icon_vip${vipLevel}_${featureName}_$previewType.png";
+ }
+ }
+
+ @override
+ String getVipPagePurchaseBackgroundImage(int vipLevel) {
+ // 原始应用:VIP页面购买背景图像路径模式
+ return "sc_images/vip/sc_icon_vip${vipLevel}_buy_bg.png";
+ }
+
+ @override
+ String getVipPagePurchaseButtonImage() {
+ // 原始应用:VIP页面购买按钮图像路径
+ return "sc_images/vip/sc_icon_vip_buy_btn.png";
+ }
+
+ @override
+ Color getVipPageTextColor(int vipLevel) {
+ // 原始应用:根据VIP等级返回不同的文本颜色
+ switch (vipLevel) {
+ case 1:
+ return const Color(0xFF71D671);
+ case 2:
+ return const Color(0xFF7179D6);
+ case 3:
+ return const Color(0xFFAA71D6);
+ case 4:
+ return const Color(0xFF71D6B3);
+ case 5:
+ return const Color(0xFFD67171);
+ case 6:
+ return const Color(0xFFFEE5BB);
+ default:
+ return Colors.white;
+ }
+ }
+
+ /// === 通用页面差异化方法实现 ===
+
+ @override
+ String getCommonRankBackgroundImage(String pageType, int rank) {
+ // 原始应用:通用的排名背景图像模式
+ return "sc_images/$pageType/sc_icon_${pageType}_rank_bg_$rank.png";
+ }
+
+ @override
+ String getCommonRankIcon(String pageType, int rank) {
+ // 原始应用:通用的排名图标模式
+ return "sc_images/$pageType/sc_icon_${pageType}_rank_$rank.png";
+ }
+
+ @override
+ int getCommonPageGridCrossAxisCount(String pageType) {
+ // 原始应用:通用的2列网格
+ return 2;
+ }
+
+ @override
+ double getCommonPageGridChildAspectRatio(String pageType) {
+ // 原始应用:通用的高度比例
+ return 1.4;
+ }
+
+ /// === Admin编辑页面差异化方法实现(马甲包专属) ===
+
+ @override
+ String getAdminEditingBackgroundImage() {
+ // 马甲包策略:使用马甲包专属背景图片
+ // TODO: 根据Figma设计添加马甲包专属背景图片
+ return "sc_images/room/sc_icon_room_settig_bg.png";
+ }
+
+ @override
+ List getAdminEditingButtonGradient(String buttonType) {
+ // 马甲包策略:使用马甲包主题渐变
+ return [
+ const Color(0xffFF9326), // 马甲包主题色
+ const Color(0xffFEB219), // 马甲包辅助色
+ ];
+ }
+
+ @override
+ String getAdminEditingIcon(String iconType) {
+ // 马甲包策略:使用统一的图标,简化UI
+ // TODO: 根据Figma设计添加马甲包专属图标
+ switch (iconType) {
+ case 'specialIdBg':
+ return "sc_images/general/sc_icon_special_id_bg.png";
+ case 'normalIdBg':
+ return "sc_images/general/sc_icon_id_bg.png";
+ case 'copyId':
+ return "sc_images/room/sc_icon_user_card_copy_id.png";
+ case 'addPic':
+ return "sc_images/general/sc_icon_add_pic.png";
+ case 'closePic':
+ return "sc_images/general/sc_icon_pic_close.png";
+ case 'checked':
+ return "sc_images/general/sc_icon_checked.png";
+ default:
+ return "";
+ }
+ }
+
+ @override
+ BoxDecoration getAdminEditingInputDecoration() {
+ // 马甲包策略:使用马甲包风格的输入框装饰
+ return BoxDecoration(
+ color: const Color(0xfff2f2f2), // #f2f2f2
+ borderRadius: BorderRadius.circular(56), // 56px圆角,与登录页保持一致
+ border: Border.all(color: Colors.transparent, width: 0),
+ );
+ }
+
+ @override
+ int getAdminEditingMaxImageUploadCount() {
+ // 马甲包策略:增加图片上传数量,支持更多图片
+ return 5; // 允许上传最多5张图片
+ }
+
+ @override
+ int getAdminEditingDescriptionMaxLength() {
+ // 马甲包策略:增加描述最大长度
+ return 300; // 允许更长的描述
+ }
+
+ @override
+ Map getAdminEditingViolationTypeMapping(String targetType) {
+ // 马甲包策略:使用相同的违规类型映射,或可自定义
+ // 暂时使用原始应用的映射,后续可根据需求调整
+ if (targetType == 'User') {
+ return {'Pornography': 1, 'Illegal information': 2};
+ } else if (targetType == 'Room') {
+ return {
+ 'Pornography': 3,
+ 'Illegal information': 4,
+ 'Fraud': 5,
+ 'Other': 6,
+ };
+ }
+ return {};
+ }
+
+ /// === Admin搜索页面差异化方法实现(马甲包专属) ===
+
+ @override
+ String getAdminSearchBackgroundImage(String pageType) {
+ // 马甲包策略:使用马甲包专属背景图片
+ // TODO: 根据Figma设计添加马甲包专属背景图片
+ return "sc_images/index/sc_icon_coupon_head_bg.png";
+ }
+
+ @override
+ List getAdminSearchButtonGradient(String pageType) {
+ // 马甲包策略:使用马甲包主题渐变
+ return [
+ const Color(0xffFF9326), // 马甲包主题色
+ const Color(0xffFEB219), // 马甲包辅助色
+ ];
+ }
+
+ @override
+ Color getAdminSearchButtonTextColor(String pageType) {
+ // 马甲包策略:使用白色文本,提高可读性
+ return Colors.white;
+ }
+
+ @override
+ String getAdminSearchEditIcon(String pageType) {
+ // 马甲包策略:使用马甲包专属编辑图标
+ // TODO: 根据Figma设计添加马甲包专属图标
+ return "sc_images/room/sc_icon_room_edit.png";
+ }
+
+ @override
+ Color getAdminSearchInputBorderColor(String pageType) {
+ // 马甲包策略:使用马甲包主题色作为边框
+ return const Color(0xffFF5722); // 马甲包主题色
+ }
+
+ @override
+ Color getAdminSearchInputTextColor(String pageType) {
+ // 马甲包策略:使用更深的文本颜色
+ return Colors.black87;
+ }
+
+ @override
+ String getAdminSearchUserInfoIcon(String iconType) {
+ // 马甲包策略:使用统一的图标
+ // TODO: 根据Figma设计添加马甲包专属图标
+ switch (iconType) {
+ case 'specialIdBg':
+ return "sc_images/general/sc_icon_special_id_bg.png";
+ case 'normalIdBg':
+ return "sc_images/general/sc_icon_id_bg.png";
+ case 'copyId':
+ return "sc_images/room/sc_icon_user_card_copy_id.png";
+ default:
+ return "";
+ }
+ }
+
+ /// === 主登录页面差异化方法实现(马甲包专属) ===
+
+ @override
+ String getLoginMainBackgroundImage() {
+ // 马甲包策略:使用马甲包专属背景图片
+ // TODO: 根据Figma设计添加马甲包专属背景图片
+ return "sc_images/splash/sc_splash.png";
+ }
+
+ @override
+ String getLoginMainAppIcon() {
+ // 马甲包策略:使用马甲包专属应用图标
+ // TODO: 根据Figma设计添加马甲包专属图标
+ return "sc_images/splash/sc_icon_splash_icon.png";
+ }
+
+ @override
+ String getLoginMainGoogleIcon() {
+ // 马甲包策略:使用马甲包专属Google图标
+ // TODO: 根据Figma设计添加马甲包专属图标
+ return "sc_images/login/sc_icon_google.png";
+ }
+
+ @override
+ String getLoginMainAppleIcon() {
+ // 马甲包策略:使用马甲包专属Apple图标
+ // TODO: 根据Figma设计添加马甲包专属图标
+ return "sc_images/login/sc_icon_iphone.png";
+ }
+
+ @override
+ String getLoginMainAccountIcon() {
+ // 马甲包策略:使用马甲包专属账号图标
+ // TODO: 根据Figma设计添加马甲包专属图标
+ return "sc_images/login/sc_icon_account.png";
+ }
+
+ @override
+ String getLoginMainAgreementIcon(bool isSelected) {
+ // 马甲包策略:使用马甲包专属协议图标
+ // TODO: 根据Figma设计添加马甲包专属图标
+ return isSelected
+ ? "sc_images/login/sc_icon_login_ser_select.png"
+ : "sc_images/login/sc_icon_login_ser_select_un.png";
+ }
+
+ @override
+ Color getLoginMainDividerColor() {
+ // 马甲包策略:使用马甲包主题色作为分割线颜色
+ return const Color(0xffE6E6E6); // 马甲包主题色
+ }
+
+ @override
+ Color getLoginMainButtonBorderColor() {
+ // 马甲包策略:使用马甲包主题色作为按钮边框颜色
+ return Colors.white24; // 马甲包主题色
+ }
+
+ @override
+ Color getLoginMainButtonBackgroundColor() {
+ // 马甲包策略:使用浅色背景,提高可读性
+ return Colors.white24; // 浅灰色
+ }
+
+ @override
+ Color getLoginMainButtonTextColor() {
+ // 马甲包策略:按钮文本颜色(黑色)
+ return Colors.white;
+ }
+
+ @override
+ Color getLoginMainLinkColor() {
+ // 马甲包策略:使用马甲包主题色作为链接颜色
+ return const Color(0xff18F2B1); // 马甲包主题色
+ }
+
+ /// === 编辑个人资料页面差异化方法实现(马甲包专属) ===
+
+ @override
+ String getEditProfileBackgroundImage() {
+ // 马甲包策略:使用马甲包专属背景图片
+ // TODO: 根据Figma设计添加马甲包专属背景图片
+ return "sc_images/splash/sc_splash.png";
+ }
+
+ @override
+ String getEditProfileDefaultAvatarImage() {
+ // 马甲包策略:使用马甲包专属默认头像图片
+ // TODO: 根据Figma设计添加马甲包专属头像图标
+ return "sc_images/general/sc_icon_avar_defalt.png";
+ }
+
+ @override
+ String getEditProfileGenderIcon(bool isMale) {
+ // 马甲包策略:使用马甲包专属性别图标
+ // TODO: 根据Figma设计添加马甲包专属图标
+ return isMale
+ ? "sc_images/login/sc_icon_avar_sex_man.png"
+ : "sc_images/login/sc_icon_avar_sex_woman.png";
+ }
+
+ @override
+ List getEditProfileGenderButtonGradient(bool isMale, bool isSelected) {
+ // 马甲包策略:使用马甲包主题渐变
+ return [
+ const Color(0xff18F2B1), // 马甲包主题色
+ const Color(0xff18F2B1), // 马甲包辅助色
+ ];
+ }
+
+ @override
+ Color getEditProfileInputBackgroundColor() {
+ // 马甲包策略:使用更亮的背景颜色,提高可读性
+ return Colors.white24;
+ }
+
+ @override
+ Color getEditProfileDatePickerConfirmColor() {
+ // 马甲包策略:使用马甲包主题色
+ return const Color(0xff18F2B1); // 马甲包主题色
+ }
+
+ @override
+ Color getEditProfileContinueButtonColor() {
+ // 马甲包策略:使用马甲包主题色
+ return const Color(0xff18F2B1); // 马甲包主题色
+ }
+
+ /// === Country页面差异化方法实现(马甲包专属) ===
+
+ @override
+ String getCountrySelectOkIcon() {
+ // 马甲包策略:使用马甲包专属选择确认图标
+ // TODO: 根据Figma设计添加马甲包专属图标
+ return "sc_images/general/sc_icon_select_ok.png";
+ }
+
+ @override
+ String getCountrySelectUnOkIcon() {
+ // 马甲包策略:使用马甲包专属选择未确认图标
+ // TODO: 根据Figma设计添加马甲包专属图标
+ return "sc_images/general/sc_icon_select_un_ok.png";
+ }
+
+ @override
+ String getCountryRadioSelectedIcon() {
+ // 马甲包策略:使用马甲包专属单选选中图标
+ // TODO: 根据Figma设计添加马甲包专属图标
+ return "sc_images/login/sc_icon_login_ser_select.png";
+ }
+
+ @override
+ String getCountryRadioUnselectedIcon() {
+ // 马甲包策略:使用马甲包专属单选未选中图标
+ // TODO: 根据Figma设计添加马甲包专属图标
+ return "sc_images/login/sc_icon_login_ser_select_un.png";
+ }
+
+ @override
+ Color getCountryItemBorderColor() {
+ // 马甲包策略:使用马甲包主题色作为边框颜色
+ return SocialChatTheme.primaryLight; // 马甲包主题色
+ }
+
+ @override
+ Color getCountryPageScaffoldBackgroundColor() {
+ // 马甲包策略:使用浅灰色背景
+ return const Color(0xfff5f5f5);
+ }
+
+ @override
+ Color getCountryPageIconColor() {
+ // 马甲包策略:使用深灰色图标
+ return const Color(0xff333333);
+ }
+
+ @override
+ Color getCountryPagePrimaryTextColor() {
+ // 马甲包策略:使用深灰色文本
+ return const Color(0xff212121);
+ }
+
+ @override
+ Color getCountryPageSecondaryTextColor() {
+ // 马甲包策略:使用中等灰色文本
+ return const Color(0xff757575);
+ }
+
+ @override
+ Color getCountryPageContainerBackgroundColor() {
+ // 马甲包策略:使用白色容器背景
+ return Colors.white;
+ }
+
+ /// === Chat页面差异化方法实现(马甲包专属) ===
+
+ /// === 消息页面 (SCMessagePage) 方法实现 ===
+
+ @override
+ String getMessagePageIndexMaskIcon() {
+ // 马甲包策略:使用马甲包专属索引遮罩图标
+ // TODO: 根据Figma设计添加马甲包专属图标
+ return "sc_images/index/sc_icon_index_bg.png";
+ }
+
+ @override
+ String getMessagePageAnnouncementTagIcon() {
+ // 马甲包策略:使用马甲包专属公告标签图标
+ // TODO: 根据Figma设计添加马甲包专属图标
+ return "sc_images/msg/sc_icon_message_activity.png";
+ }
+
+ @override
+ String getMessagePageActivityMessageIcon() {
+ // 马甲包策略:使用马甲包专属活动消息图标
+ // TODO: 根据Figma设计添加马甲包专属图标
+ return "sc_images/msg/sc_icon_message_activity.png";
+ }
+
+ @override
+ String getMessagePageActivityTitleBackground(bool isRtl) {
+ // 马甲包策略:使用马甲包专属活动消息标题背景图标
+ // TODO: 根据Figma设计添加马甲包专属图标
+ return isRtl
+ ? "sc_images/msg/sc_icon_message_activity.png"
+ : "sc_images/msg/sc_icon_message_activity.png";
+ }
+
+ @override
+ String getMessagePageSystemMessageIcon() {
+ // 马甲包策略:使用马甲包专属系统消息图标
+ // TODO: 根据Figma设计添加马甲包专属图标
+ return "sc_images/msg/sc_icon_message_system.png";
+ }
+
+ @override
+ String getMessagePageSystemTitleBackground(bool isRtl) {
+ // 马甲包策略:使用马甲包专属系统消息标题背景图标
+ // TODO: 根据Figma设计添加马甲包专属图标
+ return isRtl
+ ? "sc_images/msg/sc_icon_system_title_bg_rtl.png"
+ : "sc_images/msg/sc_icon_system_title_bg.png";
+ }
+
+ @override
+ String getMessagePageNotificationMessageIcon() {
+ // 马甲包策略:使用马甲包专属通知消息图标
+ // TODO: 根据Figma设计添加马甲包专属图标
+ return "sc_images/msg/sc_icon_message_noti.png";
+ }
+
+ @override
+ String getMessagePageNotificationTitleBackground(bool isRtl) {
+ // 马甲包策略:使用马甲包专属通知消息标题背景图标
+ // TODO: 根据Figma设计添加马甲包专属图标
+ return isRtl
+ ? "sc_images/msg/sc_icon_notifcation_title_bg_rtl.png"
+ : "sc_images/msg/sc_icon_notifcation_title_bg.png";
+ }
+
+ /// === 聊天页面 (SCMessageChatPage) 方法实现 ===
+
+ @override
+ String getSCMessageChatPageRoomSettingBackground() {
+ // 马甲包策略:使用马甲包专属房间设置背景图像
+ // TODO: 根据Figma设计添加马甲包专属背景图片
+ return "sc_images/person/sc_icon_edit_userinfo_bg.png";
+ }
+
+ @override
+ String getSCMessageChatPageEmojiIcon() {
+ // 马甲包策略:使用马甲包专属表情图标
+ // TODO: 根据Figma设计添加马甲包专属图标
+ return "sc_images/msg/sc_icon_msg_emoji.png";
+ }
+
+ @override
+ String getSCMessageChatPageChatKeyboardIcon() {
+ // 马甲包策略:使用马甲包专属聊天键盘图标
+ // TODO: 根据Figma设计添加马甲包专属图标
+ return "sc_images/msg/sc_icon_chat_key.png";
+ }
+
+ @override
+ String getSCMessageChatPageAddIcon() {
+ // 马甲包策略:使用马甲包专属添加图标
+ // TODO: 根据Figma设计添加马甲包专属图标
+ return "sc_images/msg/sc_icon_add.png";
+ }
+
+ @override
+ String getSCMessageChatPageSendMessageIcon() {
+ // 马甲包策略:使用马甲包专属发送消息图标
+ // TODO: 根据Figma设计添加马甲包专属图标
+ return "sc_images/msg/sc_icon_chat_message_send.png";
+ }
+
+ @override
+ String getSCMessageChatPageCameraIcon() {
+ // 马甲包策略:使用马甲包专属相机图标
+ // TODO: 根据Figma设计添加马甲包专属图标
+ return "sc_images/msg/sc_icon_xiangji.png";
+ }
+
+ @override
+ String getSCMessageChatPagePictureIcon() {
+ // 马甲包策略:使用马甲包专属图片图标
+ // TODO: 根据Figma设计添加马甲包专属图标
+ return "sc_images/msg/sc_icon_tupian.png";
+ }
+
+ @override
+ String getSCMessageChatPageRedEnvelopeIcon() {
+ // 马甲包策略:使用马甲包专属红包图标
+ // TODO: 根据Figma设计添加马甲包专属图标
+ return "sc_images/msg/sc_icon_hongbao.png";
+ }
+
+ @override
+ String getSCMessageChatPageRedEnvelopeMessageBackground() {
+ // 马甲包策略:使用马甲包专属红包消息背景图像
+ // TODO: 根据Figma设计添加马甲包专属背景图片
+ return "sc_images/msg/sc_icon_msg_send_hongbao_bg.png";
+ }
+
+ @override
+ String getSCMessageChatPageRedEnvelopeConfigTabButtonIcon() {
+ // 马甲包策略:使用马甲包专属红包配置标签按钮图标
+ // TODO: 根据Figma设计添加马甲包专属图标
+ return "sc_images/room/sc_icon_red_envelope_config_tab_btn.png";
+ }
+
+ @override
+ String getSCMessageChatPageRedEnvelopeMessageItemBackground() {
+ // 马甲包策略:使用马甲包专属红包消息项背景图像
+ // TODO: 根据Figma设计添加马甲包专属背景图片
+ return "sc_images/msg/sc_icon_red_envelopes_msg_item_bg.png";
+ }
+
+ @override
+ String getSCMessageChatPageRedEnvelopeReceivePackageIcon() {
+ // 马甲包策略:使用马甲包专属红包接收包图标
+ // TODO: 根据Figma设计添加马甲包专属图标
+ return "sc_images/room/sc_icon_red_envelope_rec_pack.png";
+ }
+
+ @override
+ String getSCMessageChatPageRedEnvelopeOpenBackground() {
+ // 马甲包策略:使用马甲包专属红包打开背景图像
+ // TODO: 根据Figma设计添加马甲包专属背景图片
+ return "sc_images/msg/sc_icon_red_envelopes_msg_open_bg.png";
+ }
+
+ @override
+ String getSCMessageChatPageRedEnvelopeOpenedBackground() {
+ // 马甲包策略:使用马甲包专属红包已打开背景图像
+ // TODO: 根据Figma设计添加马甲包专属背景图片
+ return "sc_images/msg/sc_icon_red_envelopes_msg_opened_bg.png";
+ }
+
+ @override
+ String getSCMessageChatPageGoldCoinIcon() {
+ // 马甲包策略:使用马甲包专属金币图标
+ // TODO: 根据Figma设计添加马甲包专属图标
+ return "sc_images/general/sc_icon_jb.png";
+ }
+
+ @override
+ String getSCMessageChatPageMessageMenuDeleteIcon() {
+ // 马甲包策略:使用马甲包专属消息菜单删除图标
+ // TODO: 根据Figma设计添加马甲包专属图标
+ return "sc_images/msg/sc_icon_msg_menu_delete.png";
+ }
+
+ @override
+ String getSCMessageChatPageMessageMenuCopyIcon() {
+ // 马甲包策略:使用马甲包专属消息菜单复制图标
+ // TODO: 根据Figma设计添加马甲包专属图标
+ return "sc_images/msg/sc_icon_msg_menu_copy.png";
+ }
+
+ @override
+ String getSCMessageChatPageMessageMenuRecallIcon() {
+ // 马甲包策略:使用马甲包专属消息菜单撤回图标
+ // TODO: 根据Figma设计添加马甲包专属图标
+ return "sc_images/msg/sc_icon_msg_menu_recall.png";
+ }
+
+ @override
+ String getSCMessageChatPageLoadingIcon() {
+ // 马甲包策略:使用马甲包专属加载图标
+ // TODO: 根据Figma设计添加马甲包专属图标
+ return "sc_images/general/sc_icon_loading.png";
+ }
+
+ @override
+ String getGenderBackgroundImage(bool isFemale) {
+ // 马甲包策略:使用马甲包专属性别背景图片
+ // TODO: 根据Figma设计添加马甲包专属性别背景图片
+ return isFemale
+ ? "sc_images/login/sc_icon_sex_woman_bg.png"
+ : "sc_images/login/sc_icon_sex_man_bg.png";
+ }
+
+ @override
+ String getIdBackgroundImage(bool hasSpecialId) {
+ // 马甲包策略:使用马甲包专属ID背景图片
+ // TODO: 根据Figma设计添加马甲包专属ID背景图片
+ return hasSpecialId
+ ? "sc_images/general/sc_icon_special_id_bg.png"
+ : "sc_images/general/sc_icon_id_bg.png";
+ }
+
+ @override
+ String getCopyIdIcon() {
+ // 马甲包策略:使用马甲包专属复制ID图标
+ // TODO: 根据Figma设计添加马甲包专属复制ID图标
+ return "sc_images/room/sc_icon_user_card_copy_id.png";
+ }
+
+ @override
+ String getSCMessageChatPageSystemHeadImage() {
+ // 马甲包策略:使用马甲包专属系统头像图像
+ // TODO: 根据Figma设计添加马甲包专属头像图片
+ return "sc_images/msg/head_system.png";
+ }
+
+ /// === Gift页面差异化方法实现(马甲包专属) ===
+
+ @override
+ String getGiftPageFirstRechargeRoomTagIcon() {
+ // 马甲包策略:使用马甲包专属首充房间标签图标
+ // TODO: 根据Figma设计添加马甲包专属图标
+ return "sc_images/room/sc_icon_first_recharge_room_tag.png";
+ }
+
+ @override
+ String getGiftPageGoldCoinIcon() {
+ // 马甲包策略:使用马甲包专属金币图标
+ // TODO: 根据Figma设计添加马甲包专属图标
+ return "sc_images/general/sc_icon_jb.png";
+ }
+
+ @override
+ String getGiftPageGiveTypeBackground() {
+ // 马甲包策略:使用马甲包专属赠送类型背景图标
+ // TODO: 根据Figma设计添加马甲包专属图标
+ return "sc_images/room/sc_icon_give_type_bg.png";
+ }
+
+ @override
+ String getGiftPageActivityGiftHeadBackground(String giftType) {
+ // 马甲包策略:使用马甲包专属活动礼物头部背景图标
+ // TODO: 根据Figma设计添加马甲包专属图标
+ switch (giftType) {
+ case 'ACTIVITY':
+ return "sc_images/room/sc_icon_activity_gift_head_bg.png";
+ case 'LUCK':
+ return "sc_images/room/sc_icon_luck_gift_head_bg.png";
+ case 'CP':
+ return "sc_images/room/sc_icon_cp_gift_head_bg.png";
+ case 'MAGIC':
+ return "sc_images/room/sc_icon_magic_gift_head_bg.png";
+ default:
+ return "sc_images/room/sc_icon_activity_gift_head_bg.png";
+ }
+ }
+
+ @override
+ String getGiftPageCustomizedRuleIcon() {
+ // 马甲包策略:使用马甲包专属定制规则图标
+ // TODO: 根据Figma设计添加马甲包专属图标
+ return "sc_images/room/sc_icon_customized_rule.png";
+ }
+
+ @override
+ String getGiftPageGiftEffectIcon(String giftType) {
+ // 马甲包策略:使用马甲包专属礼物效果图标
+ // TODO: 根据Figma设计添加马甲包专属图标
+ return "sc_images/room/sc_icon_gift_effect.png";
+ }
+
+ @override
+ String getGiftPageGiftMusicIcon(String giftType) {
+ // 马甲包策略:使用马甲包专属礼物音乐图标
+ // TODO: 根据Figma设计添加马甲包专属图标
+ return "sc_images/room/sc_icon_gift_music.png";
+ }
+
+ @override
+ String getGiftPageGiftLuckIcon(String giftType) {
+ // 马甲包策略:使用马甲包专属礼物幸运图标
+ // TODO: 根据Figma设计添加马甲包专属图标
+ return "sc_images/room/sc_icon_gift_luck.png";
+ }
+
+ @override
+ String getGiftPageGiftCpIcon(String giftType) {
+ // 马甲包策略:使用马甲包专属礼物CP图标
+ // TODO: 根据Figma设计添加马甲包专属图标
+ return "sc_images/room/sc_icon_gift_cp.png";
+ }
+
+ @override
+ String getGiftPageFirstRechargeTextIcon(String languageCode) {
+ // 马甲包策略:使用马甲包专属首充文本图标
+ // TODO: 根据Figma设计添加马甲包专属图标
+ if (languageCode == 'ar') {
+ return "sc_images/index/sc_icon_first_recharge_ar_text.png";
+ } else {
+ // 默认为英语版本
+ return "sc_images/index/sc_icon_first_recharge_en_text.png";
+ }
+ }
+
+ @override
+ String getGiftPageAllOnMicrophoneIcon() {
+ // 马甲包策略:使用马甲包专属"全开麦"图标
+ // TODO: 根据Figma设计添加马甲包专属图标
+ return "sc_images/room/sc_icon_all_on_microphone.png";
+ }
+
+ @override
+ String getGiftPageUsersOnMicrophoneIcon() {
+ // 马甲包策略:使用马甲包专属"用户开麦"图标
+ // TODO: 根据Figma设计添加马甲包专属图标
+ return "sc_images/room/sc_icon_userson_microphone.png";
+ }
+
+ @override
+ String getGiftPageAllInTheRoomIcon() {
+ // 马甲包策略:使用马甲包专属"房间所有人"图标
+ // TODO: 根据Figma设计添加马甲包专属图标
+ return "sc_images/room/sc_icon_all_in_the_room.png";
+ }
+
+ @override
+ String getCommonSelectIcon() {
+ // 马甲包策略:使用马甲包专属选择图标
+ // TODO: 根据Figma设计添加马甲包专属图标
+ return "sc_images/general/sc_icon_checked.png";
+ }
+
+ @override
+ String getCommonUnselectIcon() {
+ // 马甲包策略:使用马甲包专属未选择图标
+ // TODO: 根据Figma设计添加马甲包专属图标
+ return "sc_images/general/sc_icon_unchecked.png";
+ }
+
+ /// === Media页面差异化方法实现(马甲包专属) ===
+
+ @override
+ Color getImagePreviewBackgroundColor() {
+ // 马甲包策略:图片预览页面背景颜色 - 深灰色
+ return const Color(0xff1a1a1a); // #1a1a1a
+ }
+
+ @override
+ Color getImagePreviewGalleryBackgroundColor() {
+ // 马甲包策略:图片预览画廊背景颜色 - 深灰色
+ return const Color(0xff1a1a1a); // #1a1a1a
+ }
+
+ @override
+ Color getImagePreviewAppBarBackgroundColor() {
+ // 马甲包策略:图片预览AppBar背景颜色 - 深灰色70%透明度
+ return const Color(0xB31a1a1a); // withOpacity(0.7)
+ }
+
+ @override
+ Color getImagePreviewBackIconColor() {
+ // 马甲包策略:图片预览返回图标颜色 - 浅灰色
+ return const Color(0xffe6e6e6); // #e6e6e6
+ }
+
+ @override
+ Color getImagePreviewTextColor() {
+ // 马甲包策略:图片预览文本颜色 - 浅灰色
+ return const Color(0xffe6e6e6); // #e6e6e6
+ }
+
+ @override
+ Color getImagePreviewLoadingIndicatorColor() {
+ // 马甲包策略:图片预览加载指示器颜色 - 马甲包主题色(橙色)
+ return const Color(0xffFF5722); // 马甲包主题色
+ }
+
+ @override
+ double getImagePreviewAppBarOpacity() {
+ // 马甲包策略:图片预览AppBar透明度 - 0.7
+ return 0.7;
+ }
+
+ @override
+ Color getVideoPlayerBackgroundColor() {
+ // 马甲包策略:视频播放页面背景颜色 - 深灰色
+ return const Color(0xff1a1a1a); // #1a1a1a
+ }
+
+ @override
+ Color getVideoPlayerControlsBackgroundColor() {
+ // 马甲包策略:视频播放控制界面背景颜色 - 深灰色50%透明度
+ return const Color(0x801a1a1a); // withOpacity(0.5)
+ }
+
+ @override
+ Color getVideoPlayerIconColor() {
+ // 马甲包策略:视频播放图标颜色 - 浅灰色
+ return const Color(0xffe6e6e6); // #e6e6e6
+ }
+
+ @override
+ Color getVideoPlayerBottomControlsBackgroundColor() {
+ // 马甲包策略:视频播放底部控制栏背景颜色 - 深灰色60%透明度
+ return const Color(0x991a1a1a); // withOpacity(0.6)
+ }
+
+ @override
+ Color getVideoPlayerProgressBarActiveColor() {
+ // 马甲包策略:视频播放进度条活动颜色 - 马甲包主题色(橙色)
+ return const Color(0xffFF5722); // 马甲包主题色
+ }
+
+ @override
+ Color getVideoPlayerProgressBarInactiveColor() {
+ // 马甲包策略:视频播放进度条非活动颜色 - 深灰色
+ return const Color(0xff666666); // 深灰色
+ }
+
+ @override
+ Color getVideoPlayerTextColor() {
+ // 马甲包策略:视频播放文本颜色 - 浅灰色
+ return const Color(0xffe6e6e6); // #e6e6e6
+ }
+
+ @override
+ Color getVideoPlayerLoadingIndicatorColor() {
+ // 马甲包策略:视频播放加载指示器颜色 - 马甲包主题色(橙色)
+ return const Color(0xffFF5722); // 马甲包主题色
+ }
+
+ @override
+ double getVideoPlayerControlsOpacity() {
+ // 马甲包策略:视频播放控制界面透明度 - 0.5
+ return 0.5;
+ }
+
+ @override
+ double getVideoPlayerBottomControlsOpacity() {
+ // 马甲包策略:视频播放底部控制栏透明度 - 0.6
+ return 0.6;
+ }
+
+ @override
+ int getVideoPlayerControlsDisplayDuration() {
+ // 马甲包策略:视频播放控制界面显示持续时间 - 5秒
+ return 5;
+ }
+
+ /// === 举报页面差异化方法实现 ===
+
+ @override
+ String getReportPageBackgroundImage() {
+ // 马甲包策略:举报页面背景图片 - 与房间设置背景相同(与原始应用相同)
+ return "sc_images/person/sc_icon_edit_userinfo_bg.png";
+ }
+
+ @override
+ Color getReportPageHintTextColor() {
+ // 马甲包策略:举报页面提示文本颜色 - 深灰色
+ return Colors.white54; // 深灰色
+ }
+
+ @override
+ Color getReportPageContainerBackgroundColor() {
+ // 马甲包策略:举报页面容器背景颜色 - 白色(与原始应用相同)
+ return Color(0xff09372E).withOpacity(0.5);
+ }
+
+ @override
+ Color getReportPageBorderColor() {
+ // 马甲包策略:举报页面边框颜色 - 浅灰色
+ return const Color(0xffCCCCCC); // 浅灰色
+ }
+
+ @override
+ Color getReportPagePrimaryTextColor() {
+ // 马甲包策略:举报页面主要文本颜色 - 黑色(与原始应用相同)
+ return Colors.white; // 黑色
+ }
+
+ @override
+ Color getReportPageSecondaryHintTextColor() {
+ // 马甲包策略:举报页面次级提示文本颜色 - 深灰色
+ return Colors.white54; // 深灰色
+ }
+
+ @override
+ Color getReportPageUnselectedBorderColor() {
+ // 马甲包策略:举报页面未选中边框颜色 - 灰色
+ return Colors.grey; // 灰色
+ }
+
+ @override
+ Color getReportPageSubmitButtonBackgroundColor() {
+ // 马甲包策略:举报页面提交按钮背景颜色 - 马甲包主题色(橙色)
+ return SocialChatTheme.primaryLight; // 马甲包主题色
+ }
+
+ @override
+ Color getReportPageSubmitButtonTextColor() {
+ // 马甲包策略:举报页面提交按钮文本颜色 - 白色(与原始应用相同)
+ return Colors.white;
+ }
+
+ @override
+ String getReportPageIcon(String iconType) {
+ // 马甲包策略:举报页面图标路径(目前使用与原始应用相同的图标)
+ switch (iconType) {
+ case 'addPic':
+ return "sc_images/general/sc_icon_reort_add_pic.png";
+ case 'closePic':
+ return "sc_images/general/sc_icon_pic_close.png";
+ case 'checked':
+ return "sc_images/login/sc_icon_login_ser_select.png";
+ default:
+ return ""; // 未知图标类型返回空字符串
+ }
+ }
+
+ /// === 语音房间页面差异化方法实现 ===
+
+ @override
+ Color getVoiceRoomBackgroundColor() {
+ // 马甲包策略:语音房间页面背景颜色 - 深灰色
+ return const Color(0xff1a1a1a); // #1a1a1a
+ }
+
+ @override
+ Color getVoiceRoomTabLabelColor() {
+ // 马甲包策略:语音房间页面Tab标签选中颜色 - 浅灰色
+ return const Color(0xffe6e6e6); // #e6e6e6
+ }
+
+ @override
+ Color getVoiceRoomTabUnselectedLabelColor() {
+ // 马甲包策略:语音房间页面Tab标签未选中颜色 - 灰色
+ return const Color(0xff999999); // 灰色
+ }
+
+ @override
+ Color getVoiceRoomTabIndicatorColor() {
+ // 马甲包策略:语音房间页面Tab指示器颜色 - 马甲包主题色(橙色)
+ return const Color(0xffFF5722); // 马甲包主题色
+ }
+
+ @override
+ Color getVoiceRoomTabDividerColor() {
+ // 马甲包策略:语音房间页面Tab分割线颜色 - 深灰色
+ return Colors.transparent; // 深灰色
+ }
+
+ @override
+ EdgeInsets getVoiceRoomTabLabelPadding() {
+ // 马甲包策略:语音房间页面Tab标签内边距 - 与原始应用相同
+ return const EdgeInsets.symmetric(horizontal: 12);
+ }
+
+ @override
+ EdgeInsetsDirectional getVoiceRoomChatContainerMargin() {
+ // 马甲包策略:语音房间页面聊天容器外边距 - 与原始应用相同
+ return const EdgeInsetsDirectional.only(end: 52);
+ }
+
+ @override
+ TextStyle getVoiceRoomTabLabelStyle() {
+ // 马甲包策略:语音房间页面Tab标签选中文本样式 - 与原始应用相同
+ return const TextStyle(fontSize: 15, fontFamily: "MyCustomFont");
+ }
+
+ @override
+ TextStyle getVoiceRoomTabUnselectedLabelStyle() {
+ // 马甲包策略:语音房间页面Tab标签未选中文本样式 - 与原始应用相同
+ return const TextStyle(fontSize: 13, fontFamily: "MyCustomFont");
+ }
+
+ @override
+ String getVoiceRoomDefaultBackgroundImage() {
+ // 马甲包策略:语音房间默认背景图像路径 - 与原始应用相同
+ return "sc_images/room/sc_icon_room_defaut_bg.png";
+ }
+
+ /// === 钱包页面差异化方法实现 ===
+
+ /// === 充值页面差异化方法实现 ===
+
+ @override
+ String getRechargePageBackgroundImage() {
+ // 马甲包策略:充值页面背景图像路径 - 与原始应用相同
+ return "sc_images/person/sc_icon_edit_userinfo_bg.png";
+ }
+
+ @override
+ Color getRechargePageScaffoldBackgroundColor() {
+ // 马甲包策略:充值页面Scaffold背景颜色 - 深灰色
+ return Colors.transparent; // #1a1a1a
+ }
+
+ @override
+ Color getRechargePageDialogBarrierColor() {
+ // 马甲包策略:充值页面对话框屏障颜色 - 深灰色半透明
+ return const Color(0xCC1a1a1a); // withOpacity(0.8)
+ }
+
+ @override
+ Color getRechargePageDialogContainerBackgroundColor() {
+ // 马甲包策略:充值页面对话框容器背景颜色 - 深灰色
+ return const Color(0xff333333); // 深灰色
+ }
+
+ @override
+ Color getRechargePageDialogTextColor() {
+ // 马甲包策略:充值页面对话框文本颜色 - 浅灰色
+ return const Color(0xffe6e6e6); // #e6e6e6
+ }
+
+ @override
+ Color getRechargePageMainContainerBackgroundColor() {
+ // 马甲包策略:充值页面主容器背景颜色 - 深灰色
+ return Colors.transparent; // #1a1a1a
+ }
+
+ @override
+ Color getRechargePageButtonBackgroundColor() {
+ // 马甲包策略:充值页面按钮背景颜色 - 马甲包主题色(橙色)
+ return SocialChatTheme.primaryLight; // 马甲包主题色
+ }
+
+ @override
+ Color getRechargePageButtonTextColor() {
+ // 马甲包策略:充值页面按钮文本颜色 - 白色(与原始应用相同)
+ return Colors.white;
+ }
+
+ @override
+ String getRechargePageWalletBackgroundImage() {
+ // 马甲包策略:充值页面钱包背景图像路径 - 与原始应用相同
+ return "sc_images/index/sc_icon_wallet_bg.png";
+ }
+
+ @override
+ String getRechargePageWalletIcon() {
+ // 马甲包策略:充值页面钱包图标路径 - 与原始应用相同
+ return "sc_images/index/sc_icon_wallet_icon.png";
+ }
+
+ @override
+ Color getRechargePageWalletTextColor() {
+ // 马甲包策略:充值页面钱包文本颜色 - 浅灰色
+ return Colors.white; // #e6e6e6
+ }
+
+ @override
+ String getRechargePageGoldIcon() {
+ // 马甲包策略:充值页面金币图标路径(默认图标)- 与原始应用相同
+ return "sc_images/general/sc_icon_jb.png";
+ }
+
+ @override
+ Color getRechargePageSelectedItemBackgroundColor() {
+ // 马甲包策略:充值页面选中项背景颜色 - 马甲包主题色半透明
+ return const Color(0x33FF5722); // withOpacity(0.2)
+ }
+
+ @override
+ Color getRechargePageSelectedItemBorderColor() {
+ // 马甲包策略:充值页面选中项边框颜色 - 马甲包主题色
+ return SocialChatTheme.primaryLight; // 马甲包主题色
+ }
+
+ @override
+ Color getRechargePageUnselectedItemBorderColor() {
+ // 马甲包策略:充值页面未选中项边框颜色 - 深灰色
+ return const Color(0xff666666); // 深灰色
+ }
+
+ @override
+ Color getRechargePageUnselectedItemBackgroundColor() {
+ // 马甲包策略:充值页面未选中项背景颜色 - 深灰色
+ return const Color(0xff2a2a2a); // 深灰色背景
+ }
+
+ @override
+ Color getRechargePageItemTextColor() {
+ // 马甲包策略:充值页面项目文本颜色 - 浅灰色
+ return const Color(0xffe6e6e6); // #e6e6e6
+ }
+
+ @override
+ Color getRechargePageItemPriceTextColor() {
+ // 马甲包策略:充值页面价格文本颜色 - 白色
+ return Colors.white;
+ }
+
+ @override
+ String getRechargePageGoldIconByIndex(int index) {
+ // 马甲包策略:根据索引获取充值页面金币图标路径 - 与原始应用相同
+ switch (index) {
+ case 0:
+ return "sc_images/general/sc_icon_jb.png";
+ case 1:
+ return "sc_images/general/sc_icon_jb2.png";
+ case 2:
+ return "sc_images/general/sc_icon_jb3.png";
+ default:
+ return "sc_images/general/sc_icon_jb.png"; // 默认图标
+ }
+ }
+
+ @override
+ Color getRechargePageAppleItemBackgroundColor() {
+ // 马甲包策略:充值页面Apple产品项背景颜色 - 深灰色
+ return const Color(0xff2a2a2a); // 深灰色
+ }
+
+ @override
+ String getRechargePageRecordIcon() {
+ // 马甲包策略:充值页面记录图标路径 - 与原始应用相同
+ return "sc_images/index/sc_icon_recharge_recod.png";
+ }
+
+ /// === 金币记录页面差异化方法实现 ===
+
+ @override
+ String getGoldRecordPageBackgroundImage() {
+ // 马甲包策略:金币记录页面背景图像路径 - 与原始应用相同
+ return "sc_images/person/sc_icon_edit_userinfo_bg.png";
+ }
+
+ @override
+ Color getGoldRecordPageScaffoldBackgroundColor() {
+ // 马甲包策略:金币记录页面Scaffold背景颜色 - 深灰色
+ return Colors.transparent; // #1a1a1a
+ }
+
+ @override
+ Color getGoldRecordSCPageListBackgroundColor() {
+ // 马甲包策略:金币记录页面列表背景颜色 - 深灰色
+ return const Color(0xff1a1a1a); // #1a1a1a
+ }
+
+ @override
+ Color getGoldRecordPageContainerBackgroundColor() {
+ // 马甲包策略:金币记录页面容器背景颜色 - 深灰色
+ return Colors.black38; // #1a1a1a
+ }
+
+ @override
+ Color getGoldRecordPageBorderColor() {
+ // 马甲包策略:金币记录页面边框颜色 - 深灰色
+ return Colors.white12; // 深灰色
+ }
+
+ @override
+ Color getGoldRecordPagePrimaryTextColor() {
+ // 马甲包策略:金币记录页面主要文本颜色 - 浅灰色
+ return const Color(0xffe6e6e6); // #e6e6e6
+ }
+
+ @override
+ Color getGoldRecordPageSecondaryTextColor() {
+ // 马甲包策略:金币记录页面次要文本颜色 - 灰色
+ return const Color(0xff999999); // 灰色
+ }
+
+ /// === Store页面差异化方法实现 ===
+
+ @override
+ String getStorePageBackgroundImage() {
+ // 马甲包策略:Store页面背景图像路径 - 使用相同背景图像(保持一致性)
+ // 注意:如果需要差异化,可以返回不同的背景图像路径
+ return "sc_images/person/sc_icon_edit_userinfo_bg.png";
+ }
+
+ @override
+ String getStorePageShoppingBagIcon() {
+ // 马甲包策略:Store页面购物袋图标路径 - 使用相同图标(保持一致性)
+ // 注意:如果需要差异化,可以返回不同的图标路径
+ return "sc_images/store/sc_icon_shop_bag.png";
+ }
+
+ @override
+ EdgeInsetsDirectional getStorePageShoppingBagMargin() {
+ // 马甲包策略:Store页面购物袋图标外边距 - 保持相同外边距
+ return const EdgeInsetsDirectional.only(end: 10);
+ }
+
+ @override
+ EdgeInsets getStorePageTabLabelPadding() {
+ // 马甲包策略:Store页面Tab标签内边距 - 保持相同内边距
+ return const EdgeInsets.symmetric(horizontal: 12);
+ }
+
+ @override
+ TextStyle getStorePageTabLabelStyle() {
+ // 马甲包策略:Store页面Tab标签选中文本样式
+ // 差异化:使用马甲包主题色作为选中文本颜色
+ return const TextStyle(
+ fontSize: 15,
+ color: Colors.black87, // 马甲包主题橙色,替代Colors.black87
+ fontWeight: FontWeight.w600,
+ );
+ }
+
+ @override
+ TextStyle getStorePageTabUnselectedLabelStyle() {
+ // 马甲包策略:Store页面Tab标签未选中文本样式
+ // 差异化:调整未选中文本颜色为灰色系
+ return const TextStyle(
+ fontSize: 13,
+ color: Colors.white54, // 灰色,替代Colors.black38
+ fontWeight: FontWeight.w500,
+ );
+ }
+
+ @override
+ Color getStorePageTabIndicatorColor() {
+ // 马甲包策略:Store页面Tab指示器颜色 - 使用马甲包主题色
+ // 注意:原始应用使用SocialChatTheme.primaryColor,马甲包使用相同值
+ return SocialChatTheme.primaryLight; // SocialChatTheme.primaryColor
+ }
+
+ @override
+ Color getStorePageTabDividerColor() {
+ // 马甲包策略:Store页面Tab分割线颜色 - 保持透明
+ return Colors.transparent;
+ }
+
+ @override
+ Color getStorePageBottomDividerColor() {
+ // 马甲包策略:Store页面底部Divider颜色 - 调整为浅灰色
+ return const Color(0xffEEEEEE); // 浅灰色,替代Colors.black12
+ }
+
+ @override
+ double getStorePageBottomDividerThickness() {
+ // 马甲包策略:Store页面底部Divider厚度 - 保持相同
+ return 0.5;
+ }
+
+ @override
+ double getStorePageBottomDividerHeight() {
+ // 马甲包策略:Store页面底部Divider高度 - 保持相同
+ return 24;
+ }
+
+ @override
+ String getStorePageGoldIcon() {
+ // 马甲包策略:Store页面金币图标路径 - 使用相同图标
+ return "sc_images/general/sc_icon_jb.png";
+ }
+
+ @override
+ Color getStorePageGoldTextColor() {
+ // 马甲包策略:Store页面金币文本颜色 - 使用马甲包主题色
+ return SocialChatTheme.primaryLight; // 马甲包主题橙色,替代Color(0xFFFFE134)
+ }
+
+ @override
+ Color getStorePageGoldIconColor() {
+ // 马甲包策略:Store页面金币图标颜色 - 使用马甲包主题色
+ return SocialChatTheme.primaryLight; // 马甲包主题橙色,替代Color(0xFFFFE134)
+ }
+
+ /// === Store子页面(商品项)差异化方法实现 ===
+
+ @override
+ Color getStoreItemBackgroundColor() {
+ // 马甲包策略:Store商品项背景颜色 - 使用马甲包表面色
+ return Color(0xff18F2B1).withOpacity(0.1); // 马甲包表面色,替代Colors.white
+ }
+
+ @override
+ Color getStoreItemUnselectedBorderColor() {
+ // 马甲包策略:Store商品项未选中边框颜色 - 调整为浅灰色
+ return Colors.transparent; // 浅灰色,替代Colors.black12
+ }
+
+ @override
+ Color getStoreItemSelectedBorderColor() {
+ // 马甲包策略:Store商品项选中边框颜色 - 使用马甲包主题色
+ return SocialChatTheme.primaryLight; // 马甲包主题橙色,替代Color(0xffFF9500)
+ }
+
+ @override
+ String getStoreItemGoldIcon() {
+ // 马甲包策略:Store商品项金币图标路径 - 使用相同图标
+ return "sc_images/general/sc_icon_jb.png";
+ }
+
+ @override
+ Color getStoreItemPriceTextColor() {
+ // 马甲包策略:Store商品项价格文本颜色 - 使用马甲包主要文本颜色
+ return SocialChatTheme.primaryLight; // 马甲包主要文本颜色,替代Colors.black
+ }
+
+ @override
+ Color getStoreItemBuyButtonColor() {
+ // 马甲包策略:Store商品项购买按钮背景颜色 - 使用马甲包主题色
+ return const Color(0xffFF5722); // 马甲包主题橙色,替代Color(0xffFF9500)
+ }
+
+ @override
+ Color getStoreItemBuyButtonTextColor() {
+ // 马甲包策略:Store商品项购买按钮文本颜色 - 使用马甲包主色上的文本颜色
+ return SocialChatTheme.textOnPrimary; // 马甲包主色上的文本颜色,替代Colors.white
+ }
+
+ @override
+ String getStoreItemActionIcon(String itemType) {
+ // 马甲包策略:Store商品项操作图标路径
+ // 使用相同的图标路径,确保功能一致
+ switch (itemType) {
+ case 'headdress':
+ return "sc_images/store/sc_icon_shop_item_search.png"; // 头饰页面使用搜索图标
+ case 'mountains':
+ return "sc_images/store/sc_icon_shop_item_play.png"; // 山脉页面使用播放图标
+ case 'theme':
+ return "sc_images/store/sc_icon_store_theme_rev.png"; // 主题页面使用主题图标
+ case 'chatbox':
+ return "sc_images/store/sc_icon_shop_item_search.png"; // 聊天气泡页面使用搜索图标
+ default:
+ return "sc_images/store/sc_icon_store_theme_rev.png"; // 默认返回theme图标
+ }
+ }
+
+ /// === 动态页面差异化方法实现 ===
+
+ @override
+ String getDynamicPageBackgroundImage() {
+ // 马甲包策略:动态页面背景图像路径 - 使用相同图像保持功能一致
+ return "sc_images/index/sc_icon_index_mask.png";
+ }
+
+ @override
+ Color getDynamicPageScaffoldBackgroundColor() {
+ // 马甲包策略:动态页面Scaffold背景颜色 - 保持透明以保持视觉效果
+ return Colors.transparent;
+ }
+
+ @override
+ Color getDynamicPageAppBarBackgroundColor() {
+ // 马甲包策略:动态页面AppBar背景颜色 - 保持透明以保持视觉效果
+ return Colors.transparent;
+ }
+
+ @override
+ Color getDynamicPageTabLabelColor() {
+ // 马甲包策略:动态页面Tab标签选中颜色 - 使用马甲包主要文本颜色
+ return SocialChatTheme.textPrimary; // 马甲包主要文本颜色,替代Colors.black87
+ }
+
+ @override
+ Color getDynamicPageTabUnselectedLabelColor() {
+ // 马甲包策略:动态页面Tab标签未选中颜色 - 使用马甲包次要文本颜色
+ return SocialChatTheme.textSecondary; // 马甲包次要文本颜色,替代Colors.black38
+ }
+
+ @override
+ Color getDynamicPageTabIndicatorColor() {
+ // 马甲包策略:动态页面Tab指示器颜色 - 使用马甲包主题色
+ return const Color(0xffFF5722); // 马甲包主题橙色,替代Colors.transparent
+ }
+
+ @override
+ Color getDynamicPageTabDividerColor() {
+ // 马甲包策略:动态页面Tab分割线颜色 - 保持透明以保持简洁设计
+ return Colors.transparent;
+ }
+
+ @override
+ String getDynamicPageAddButtonIcon() {
+ // 马甲包策略:动态页面添加动态按钮图标路径 - 使用相同图标保持功能一致
+ return "sc_images/dynamic/sc_icon_add_dynamic_btn.png";
+ }
+
+ @override
+ bool shouldDynamicPageTabScrollable() {
+ // 马甲包策略:动态页面Tab标签是否可滚动 - 保持相同行为
+ return true;
+ }
+
+ @override
+ TextStyle getDynamicPageTabLabelStyle() {
+ // 马甲包策略:动态页面Tab标签选中文本样式 - 使用相同样式但可能应用主题颜色
+ // 注意:这里无法使用.sp单位,需要在调用处使用ScreenUtil()
+ return TextStyle(
+ fontWeight: FontWeight.bold,
+ fontSize: 16,
+ color: SocialChatTheme.textPrimary, // 应用马甲包文本颜色
+ );
+ }
+
+ @override
+ TextStyle getDynamicPageTabUnselectedLabelStyle() {
+ // 马甲包策略:动态页面Tab标签未选中文本样式 - 使用相同样式但可能应用主题颜色
+ // 注意:这里无法使用.sp单位,需要在调用处使用ScreenUtil()
+ return TextStyle(
+ fontWeight: FontWeight.normal,
+ fontSize: 15,
+ color: SocialChatTheme.textSecondary, // 应用马甲包次要文本颜色
+ );
+ }
+
+ /// === 启动页面差异化方法实现 ===
+
+ @override
+ String getSplashPageBackgroundImage() {
+ // 马甲包策略:启动页面背景图像路径 - 使用马甲包专属启动背景图像
+ // TODO: 根据Figma设计添加马甲包专属启动背景图像
+ // 目前先使用相同图像,确保功能正常
+ return "sc_images/splash/sc_splash.png";
+ }
+
+ @override
+ String getSplashPageIcon() {
+ // 马甲包策略:启动页面图标路径 - 使用马甲包专属启动图标
+ // TODO: 根据Figma设计添加马甲包专属启动图标
+ // 目前先使用相同图标,确保功能正常
+ return "sc_images/splash/sc_icon_splash_icon.png";
+ }
+
+ @override
+ String getSplashPageSkipButtonBackground() {
+ // 马甲包策略:启动页面跳过按钮背景图像路径 - 使用马甲包专属跳过按钮背景
+ // TODO: 根据Figma设计添加马甲包专属跳过按钮背景图像
+ // 目前先使用相同图像,确保功能正常
+ return "sc_images/splash/sc_icon_splash_skip_bg.png";
+ }
+
+ @override
+ Color getSplashPageSkipButtonTextColor() {
+ // 马甲包策略:启动页面跳过按钮文本颜色 - 使用马甲包主色上的文本颜色
+ return SocialChatTheme.textOnPrimary; // 马甲包主色上的文本颜色,替代Colors.white
+ }
+
+ @override
+ String getSplashPageKingGamesNameBackground() {
+ // 马甲包策略:启动页面游戏名称背景图像路径 - 使用马甲包专属背景图像
+ // TODO: 根据Figma设计添加马甲包专属游戏名称背景图像
+ // 目前先使用相同图像,确保功能正常
+ return "sc_images/index/sc_icon_splash_king_games_name_bg.png";
+ }
+
+ @override
+ Color getSplashPageKingGamesTextColor() {
+ // 马甲包策略:启动页面游戏名称文本颜色 - 使用马甲包主色上的文本颜色
+ return SocialChatTheme.textOnPrimary; // 马甲包主色上的文本颜色,替代Colors.white
+ }
+
+ @override
+ String getSplashPageCpNameBackground() {
+ // 马甲包策略:启动页面CP名称背景图像路径 - 使用马甲包专属背景图像
+ // TODO: 根据Figma设计添加马甲包专属CP名称背景图像
+ // 目前先使用相同图像,确保功能正常
+ return "sc_images/index/sc_icon_splash_cp_name_bg.png";
+ }
+
+ @override
+ Color getSplashPageCpTextColor() {
+ // 马甲包策略:启动页面CP名称文本颜色 - 使用马甲包主色上的文本颜色
+ return SocialChatTheme.textOnPrimary; // 马甲包主色上的文本颜色,替代Colors.white
+ }
+
+ /// === WebView页面差异化方法实现 ===
+
+ @override
+ Color getWebViewPageAppBarBackgroundColor() {
+ // 马甲包策略:WebView页面AppBar背景颜色 - 使用马甲包背景颜色
+ return SocialChatTheme.backgroundColor; // 马甲包背景颜色,替代Colors.white
+ }
+
+ @override
+ Color getWebViewPageTitleTextColor() {
+ // 马甲包策略:WebView页面标题文本颜色 - 使用马甲包主要文本颜色
+ return SocialChatTheme.textPrimary; // 马甲包主要文本颜色,替代Color(0xff333333)
+ }
+
+ @override
+ Color getWebViewPageBackArrowColor() {
+ // 马甲包策略:WebView页面返回箭头图标颜色 - 使用马甲包主要文本颜色
+ return SocialChatTheme.textPrimary; // 马甲包主要文本颜色,替代Color(0xff333333)
+ }
+
+ @override
+ Color getWebViewPageProgressBarBackgroundColor() {
+ // 马甲包策略:WebView页面进度条背景颜色 - 使用透明背景
+ return Colors.transparent; // 透明背景,替代Colors.white70.withOpacity(0)
+ }
+
+ @override
+ Color getWebViewPageProgressBarActiveColor() {
+ // 马甲包策略:WebView页面进度条活动颜色 - 使用马甲包主题色
+ return SocialChatTheme.primaryColor; // 马甲包主题色,替代Color(0xffFF6000)
+ }
+
+ @override
+ Color getGameWebViewCloseIconColor() {
+ // 马甲包策略:游戏WebView页面关闭图标颜色 - 使用马甲包主要文本颜色
+ return SocialChatTheme.textPrimary; // 马甲包主要文本颜色,替代Colors.white
+ }
+
+ @override
+ Color getGameWebViewScaffoldBackgroundColor() {
+ // 马甲包策略:游戏WebView页面Scaffold背景颜色 - 使用马甲包背景颜色
+ return SocialChatTheme.backgroundColor; // 马甲包背景颜色,替代Colors.transparent
+ }
+
+ @override
+ Color getGameWebViewProgressBarBackgroundColor() {
+ // 马甲包策略:游戏WebView页面进度条背景颜色 - 使用马甲包背景颜色(透明)
+ return SocialChatTheme.backgroundColor.withOpacity(0.3); // 马甲包背景颜色,半透明
+ }
+
+ @override
+ Color getGameWebViewLoadingIndicatorColor() {
+ // 马甲包策略:游戏WebView页面加载指示器颜色 - 使用马甲包主题色
+ return SocialChatTheme.primaryColor; // 马甲包主题色,替代Color(0xffFF6000)
+ }
+
+ /// === 搜索页面差异化方法实现 ===
+
+ @override
+ Color getSearchPageScaffoldBackgroundColor() {
+ // 马甲包策略:搜索页面Scaffold背景颜色 - 使用浅灰色背景
+ return Colors.transparent; // 马甲包浅灰色背景颜色,替代Colors.white
+ }
+
+ @override
+ Color getSearchPageBackIconColor() {
+ // 马甲包策略:搜索页面返回图标颜色 - 使用深灰色
+ return const Color(0xff666666); // 深灰色,替代Color(0xffBBBBBB)
+ }
+
+ @override
+ Color getSearchPageInputBorderColor() {
+ // 马甲包策略:搜索页面搜索框边框颜色 - 使用马甲包主题色
+ return SocialChatTheme.transparent; // 马甲包主题色,替代Colors.transparent
+ }
+
+ @override
+ Color getSearchPageInputTextColor() {
+ // 马甲包策略:搜索页面搜索框文本颜色 - 使用马甲包主要文本颜色
+ return SocialChatTheme.textPrimary; // 马甲包主要文本颜色,替代Colors.grey
+ }
+
+ @override
+ Color getSearchPageButtonTextColor() {
+ // 马甲包策略:搜索页面搜索按钮文本颜色 - 使用白色
+ return Colors.white; // 马甲包使用白色文本,替代Colors.black
+ }
+
+ @override
+ List getSearchPageButtonGradient() {
+ // 马甲包策略:搜索页面搜索按钮渐变颜色 - 使用马甲包主题色渐变
+ return [
+ SocialChatTheme.transparent,
+ SocialChatTheme.transparent,
+ ]; // 马甲包主题色渐变,替代[Colors.transparent, Colors.transparent]
+ }
+
+ @override
+ Color getSearchPageHistoryTitleTextColor() {
+ // 马甲包策略:搜索页面历史记录标题文本颜色 - 使用马甲包主要文本颜色
+ return SocialChatTheme.textPrimary; // 马甲包主要文本颜色,替代Colors.black
+ }
+
+ @override
+ Color getSearchPageHistoryItemTextColor() {
+ // 马甲包策略:搜索页面历史项文本颜色 - 使用白色
+ return Colors.white; // 马甲包使用白色文本,替代Colors.white
+ }
+
+ @override
+ Color getSearchPageHistoryItemBackgroundColor() {
+ // 马甲包策略:搜索页面历史项背景颜色 - 使用马甲包主题色
+ return SocialChatTheme.primaryColor; // 马甲包主题色,替代Color(0xffFF9500)
+ }
+
+ @override
+ Color getSearchPageTabIndicatorGradientStartColor() {
+ // 马甲包策略:搜索页面Tab指示器渐变开始颜色 - 使用马甲包主题色变体
+ return SocialChatTheme.primaryColor; // 马甲包主题色,替代Color(0xffFFA500)
+ }
+
+ @override
+ Color getSearchPageTabIndicatorGradientEndColor() {
+ // 马甲包策略:搜索页面Tab指示器渐变结束颜色 - 使用马甲包主题色变体
+ return SocialChatTheme.primaryLight; // 马甲包浅主题色,替代Color(0xffFFD700)
+ }
+
+ @override
+ Color getSearchPageTabSelectedLabelColor() {
+ // 马甲包策略:搜索页面Tab标签选中颜色 - 使用马甲包主要文本颜色
+ return SocialChatTheme.primaryLight; // 马甲包主要文本颜色,替代Colors.black
+ }
+
+ @override
+ Color getSearchPageTabDividerColor() {
+ // 马甲包策略:搜索页面Tab分割线颜色 - 使用马甲包分割线颜色
+ return SocialChatTheme.transparent; // 马甲包分割线颜色,替代Colors.transparent
+ }
+
+ @override
+ Color getSearchPageTabUnselectedLabelColor() {
+ // 马甲包策略:搜索页面Tab标签未选中颜色 - 使用马甲包次要文本颜色
+ return SocialChatTheme.textPrimary; // 马甲包次要文本颜色,替代Colors.black26
+ }
+
+ @override
+ Color getSearchPageDividerContainerBackgroundColor() {
+ // 马甲包策略:搜索页面分隔容器背景颜色 - 使用马甲包背景颜色
+ return Color(0xffFFF8DA); // 马甲包背景颜色,替代Color(0xffFFF8DA)
+ }
+
+ @override
+ TextStyle getSearchPageTabSelectedLabelStyle() {
+ // 马甲包策略:搜索页面Tab标签选中文本样式 - 使用马甲包样式
+ // 注意:这里无法使用.sp单位,需要在调用处使用ScreenUtil()
+ return const TextStyle(
+ fontSize: 18,
+ fontWeight: FontWeight.w600,
+ color: Colors.black, // 将在调用处替换为马甲包主要文本颜色
+ ).copyWith(color: SocialChatTheme.textPrimary);
+ }
+
+ @override
+ TextStyle getSearchPageTabUnselectedLabelStyle() {
+ // 马甲包策略:搜索页面Tab标签未选中文本样式 - 使用马甲包样式
+ // 注意:这里无法使用.sp单位,需要在调用处使用ScreenUtil()
+ return const TextStyle(
+ fontSize: 17,
+ fontWeight: FontWeight.w400,
+ color: Colors.black26, // 将在调用处替换为马甲包次要文本颜色
+ ).copyWith(color: SocialChatTheme.textSecondary);
+ }
+
+ @override
+ EdgeInsets getSearchPageResultTabLabelPadding() {
+ // 马甲包策略:搜索页面搜索结果Tab标签内边距 - 与原始应用相同
+ return const EdgeInsets.symmetric(horizontal: 15);
+ }
+
+ @override
+ Color getSearchPageResultTabLabelColor() {
+ // 马甲包策略:搜索页面搜索结果Tab标签选中颜色 - 使用马甲包主要文本颜色
+ return SocialChatTheme.textPrimary; // 马甲包主要文本颜色,替代Colors.black
+ }
+
+ @override
+ Color getSearchPageResultTabUnselectedLabelColor() {
+ // 马甲包策略:搜索页面搜索结果Tab标签未选中颜色 - 使用马甲包次要文本颜色
+ return SocialChatTheme.textSecondary; // 马甲包次要文本颜色,替代Colors.black26
+ }
+
+ @override
+ TextStyle getSearchPageResultTabUnselectedLabelStyle() {
+ // 马甲包策略:搜索页面搜索结果Tab标签未选中文本样式 - 使用马甲包样式
+ return const TextStyle(
+ fontSize: 17,
+ fontWeight: FontWeight.w400,
+ color: Colors.black26, // 将在调用处替换为马甲包次要文本颜色
+ ).copyWith(color: SocialChatTheme.textSecondary);
+ }
+
+ @override
+ TextStyle getSearchPageResultTabLabelStyle() {
+ // 马甲包策略:搜索页面搜索结果Tab标签选中文本样式 - 使用马甲包样式
+ return const TextStyle(
+ fontSize: 18,
+ fontWeight: FontWeight.w600,
+ color: Colors.black87, // 将在调用处替换为马甲包主要文本颜色
+ ).copyWith(color: SocialChatTheme.textPrimary);
+ }
+
+ @override
+ LinearGradient getSearchPageResultTabIndicatorColor() {
+ // 马甲包策略:搜索页面搜索结果Tab指示器颜色 - 使用马甲包主题渐变
+ return const LinearGradient(
+ colors: [SocialChatTheme.primaryColor, Color(0xffFF9A00)],
+ );
+ }
+
+ @override
+ double getSearchPageResultTabIndicatorWidth() {
+ // 马甲包策略:搜索页面搜索结果Tab指示器宽度 - 与原始应用相同
+ return 15.0;
+ }
+
+ @override
+ Color getSearchPageResultBackgroundColor() {
+ // 马甲包策略:搜索页面搜索结果背景颜色 - 使用浅橙色背景
+ return const Color(0xffFFECB3); // 马甲包浅橙色背景,替代Color(0xffFFF8DA)
+ }
+
+ @override
+ String getSearchPageClearHistoryIcon() {
+ // 马甲包策略:搜索页面清除历史记录图标路径 - 使用相同图标
+ return "sc_images/general/sc_icon_delete.png";
+ }
+
+ @override
+ String getSearchPageEmptyDataIcon() {
+ // 马甲包策略:搜索页面空数据图标路径 - 使用相同图标
+ return "sc_images/room/sc_icon_room_defaut_bg.png";
+ }
+
+ // === 任务页面差异化方法 ===
+
+ @override
+ String getTaskPageBackgroundImage() {
+ // 马甲包策略:任务页面背景图像 - 使用相同图片
+ return "sc_images/room/sc_icon_room_settig_bg.png";
+ }
+
+ @override
+ Color getTaskPageBackButtonColor() {
+ // 马甲包策略:任务页面返回按钮颜色 - 使用马甲包主要文本颜色
+ return SocialChatTheme.textPrimary; // 马甲包主要文本颜色,替代Colors.black
+ }
+
+ @override
+ Color getTaskPageScaffoldBackgroundColor() {
+ // 马甲包策略:任务页面Scaffold背景颜色 - 使用马甲包背景颜色
+ return const Color(0xfff5f5f5); // 马甲包背景颜色
+ }
+
+ @override
+ Color getTaskPageContainerBackgroundColor() {
+ // 马甲包策略:任务页面容器背景颜色 - 使用马甲包表面颜色
+ return SocialChatTheme.surfaceColor; // 马甲包表面颜色,替代Color(0xffE6E6E6)
+ }
+
+ @override
+ Color getTaskPageBorderColor() {
+ // 马甲包策略:任务页面边框颜色 - 使用马甲包边框颜色
+ return SocialChatTheme.borderColor; // 马甲包边框颜色,替代Color(0xffE6E6E6)
+ }
+
+ @override
+ Color getTaskPageSpecialBorderColor() {
+ // 马甲包策略:任务页面特殊边框颜色 - 使用马甲包主题色
+ return SocialChatTheme.primaryColor; // 马甲包主题色,替代Color(0xffBB92FF)
+ }
+
+ @override
+ Color getTaskPagePrimaryTextColor() {
+ // 马甲包策略:任务页面主要文本颜色 - 使用马甲包主要文本颜色
+ return SocialChatTheme.textPrimary; // 马甲包主要文本颜色,替代Colors.black
+ }
+
+ @override
+ Color getTaskPageGoldTextColor() {
+ // 马甲包策略:任务页面金币文本颜色 - 使用马甲包主题色
+ return SocialChatTheme.primaryColor; // 马甲包主题色,替代Color(0xffFFB627)
+ }
+
+ @override
+ Color getTaskPageExpTextColor() {
+ // 马甲包策略:任务页面经验文本颜色 - 使用马甲包成功颜色
+ return SocialChatTheme.successColor; // 马甲包成功颜色,替代Color(0xff52FF90)
+ }
+
+ @override
+ Color getTaskPageThemeColor() {
+ // 马甲包策略:任务页面主题颜色 - 使用马甲包主题色
+ return SocialChatTheme.primaryColor; // 马甲包主题色,替代Color(0xffFF5722)
+ }
+
+ @override
+ Color getTaskPageThemeLightColor() {
+ // 马甲包策略:任务页面浅主题颜色 - 使用马甲包浅主题色
+ return SocialChatTheme.primaryLight; // 马甲包浅主题色,替代Color(0xffFF9500)
+ }
+
+ @override
+ List getTaskPageReceivableButtonGradient() {
+ // 马甲包策略:任务页面可领取按钮渐变颜色 - 使用马甲包主题色渐变
+ return [
+ SocialChatTheme.primaryColor,
+ const Color(0xffFF9A00),
+ ]; // 马甲包主题色渐变,替代[Color(0xffBB92FF), Color(0xff8B45FF)]
+ }
+
+ @override
+ List getTaskPageCompletedButtonGradient() {
+ // 马甲包策略:任务页面已完成按钮渐变颜色 - 使用灰色渐变
+ return [
+ const Color(0xffCCCCCC),
+ const Color(0xff999999),
+ ]; // 马甲包灰色渐变,替代[Color(0xffDADADA), Color(0xff585859)]
+ }
+
+ @override
+ Color getTaskPageButtonTextColor() {
+ // 马甲包策略:任务页面按钮文本颜色 - 使用马甲包主色上的文本颜色
+ return SocialChatTheme.textOnPrimary; // 马甲包主色上的文本颜色,替代Colors.white
+ }
+
+ @override
+ Color getTaskPageMaskColor() {
+ // 马甲包策略:任务页面遮罩颜色 - 半透明黑色
+ return Colors.black.withOpacity(0.5);
+ }
+
+ @override
+ String getTaskPageHeadBackgroundImage() {
+ // 马甲包策略:任务页面头部背景图像 - 使用相同图片
+ return "sc_images/index/sc_icon_task_head_bg.png";
+ }
+
+ @override
+ String getTaskPageGoldIcon() {
+ // 马甲包策略:任务页面金币图标 - 使用相同图标
+ return "sc_images/general/sc_icon_jb.png";
+ }
+
+ @override
+ String getTaskPageExpIcon() {
+ // 马甲包策略:任务页面经验图标 - 使用相同图标
+ return "sc_images/index/sc_icon_task_exp.png";
+ }
+
+ @override
+ String getTaskPageInvitationRewardBackgroundImage() {
+ // 马甲包策略:任务页面邀请奖励背景图像 - 使用相同图片
+ return "sc_images/index/sc_icon_invitation_bg.png";
+ }
+
+ @override
+ Color getTaskPageGiftBagTextColor() {
+ // 马甲包策略:任务页面礼包文本颜色 - 使用马甲包主色上的文本颜色
+ return SocialChatTheme.textOnPrimary; // 马甲包主色上的文本颜色,替代Colors.white
+ }
+
+ @override
+ Color getTaskPageAppBarBackgroundColor() {
+ // 马甲包策略:任务页面AppBar背景颜色 - 保持透明,与原始应用一致
+ return Colors.transparent;
+ }
+
+ @override
+ Color getTaskPageTransparentContainerColor() {
+ // 马甲包策略:任务页面透明容器颜色 - 保持透明,与原始应用一致
+ return Colors.transparent;
+ }
+
+ /// === 设置页面差异化方法实现 ===
+
+ @override
+ String getSettingsPageBackgroundImage() {
+ // 马甲包策略:设置页面背景图像路径 - 使用相同图片
+ return "sc_images/person/sc_icon_edit_userinfo_bg.png";
+ }
+
+ @override
+ Color getSettingsPageMainContainerBackgroundColor() {
+ // 马甲包策略:设置页面主容器背景颜色 - 使用马甲包背景色
+ return Color(0xff18F2B1).withOpacity(0.1); // 马甲包背景色,与原始应用一致
+ }
+
+ @override
+ Color getSettingsPageMainContainerBorderColor() {
+ // 马甲包策略:设置页面主容器边框颜色 - 使用马甲包边框色
+ return SocialChatTheme.borderColor; // 马甲包边框色,替代Color(0xffE6E6E6)
+ }
+
+ @override
+ Color getSettingsPagePrimaryTextColor() {
+ // 马甲包策略:设置页面主文本颜色 - 使用马甲包主要文本颜色
+ return SocialChatTheme.textPrimary; // 马甲包主要文本颜色,替代Colors.black
+ }
+
+ @override
+ Color getSettingsPageSecondaryTextColor() {
+ // 马甲包策略:设置页面次要文本颜色 - 使用马甲包次要文本颜色
+ return SocialChatTheme.textSecondary; // 马甲包次要文本颜色,替代Colors.black38
+ }
+
+ @override
+ Color getSettingsPageIconColor() {
+ // 马甲包策略:设置页面图标颜色 - 使用马甲包次要文本颜色
+ return SocialChatTheme.textPrimary; // 马甲包次要文本颜色,替代Colors.black26
+ }
+
+ @override
+ Color getSettingsPageCommonTextColor() {
+ // 马甲包策略:设置页面常见文本颜色 - 使用深灰色
+ return const Color(0xff666666);
+ }
+
+ @override
+ Color getSettingsPageAboutTextColor() {
+ // 马甲包策略:设置页面关于文本颜色 - 使用深灰色
+ return const Color(0xff666666);
+ }
+
+ @override
+ Color getSettingsPageContainerBorderColor() {
+ // 马甲包策略:设置页面容器边框颜色 - 使用浅灰色
+ return Colors.transparent;
+ }
+
+ @override
+ Color getSettingsPageContainerBackgroundColor() {
+ // 马甲包策略:设置页面容器背景颜色 - 使用白色(与原始应用相同)
+ return Color(0xff18F2B1).withOpacity(0.1);
+ }
+
+ @override
+ Color getSettingsPageButtonBackgroundColor() {
+ // 马甲包策略:设置页面按钮背景颜色 - 使用马甲包主题色
+ return Color(0xff18F2B1).withOpacity(0.1);
+ }
+
+ @override
+ Color getSettingsPageButtonTextColor() {
+ // 马甲包策略:设置页面按钮文本颜色 - 使用白色
+ return Colors.white;
+ }
+
+ /// === 语言页面差异化方法实现 ===
+
+ @override
+ String getLanguagePageBackgroundImage() {
+ // 马甲包策略:语言页面背景图像路径 - 使用相同图片
+ return "sc_images/person/sc_icon_edit_userinfo_bg.png";
+ }
+
+ @override
+ Color getLanguagePageCheckboxActiveColor() {
+ // 马甲包策略:语言页面复选框选中颜色 - 使用马甲包主题色
+ return SocialChatTheme.primaryColor; // 马甲包主题色,替代Color(0xffFF5722)
+ }
+
+ @override
+ Color getLanguagePageCheckboxBorderColor() {
+ // 马甲包策略:语言页面复选框边框颜色 - 使用马甲包边框色
+ return Colors.white54; // 马甲包边框色,替代Colors.grey
+ }
+
+ @override
+ Color getLanguagePagePrimaryTextColor() {
+ // 马甲包策略:语言页面主文本颜色 - 使用马甲包主要文本颜色
+ return SocialChatTheme.textPrimary; // 马甲包主要文本颜色,替代Colors.black
+ }
+
+ @override
+ Color getLanguagePageCheckColor() {
+ // 马甲包策略:语言页面复选框对勾颜色 - 使用透明色
+ return Colors.transparent;
+ }
+
+ @override
+ double getLanguagePageCheckboxBorderRadius() {
+ // 马甲包策略:语言页面复选框边框圆角 - 使用相同的圆角值15
+ return 15;
+ }
+
+ @override
+ double getLanguagePageCheckboxBorderWidth() {
+ // 马甲包策略:语言页面复选框边框宽度 - 使用相同的边框宽度2
+ return 2;
+ }
+
+ @override
+ Color getLanguagePageScaffoldBackgroundColor() {
+ // 马甲包策略:语言页面Scaffold背景颜色 - 使用透明色
+ return Colors.transparent;
+ }
+
+ /// === 账户页面差异化方法实现 ===
+
+ @override
+ String getAccountPageBackgroundImage() {
+ // 马甲包策略:账户页面背景图像路径 - 使用相同图片
+ return "sc_images/person/sc_icon_edit_userinfo_bg.png";
+ }
+
+ @override
+ Color getAccountPageMainContainerBackgroundColor() {
+ // 马甲包策略:账户页面主容器背景颜色 - 使用马甲包背景色
+ return Color(0xff18F2B1).withOpacity(0.1);
+ }
+
+ @override
+ Color getAccountPageMainContainerBorderColor() {
+ // 马甲包策略:账户页面主容器边框颜色 - 使用马甲包边框色
+ return const Color(0xffE0E0E0); // SocialChatTheme.borderColor
+ }
+
+ @override
+ Color getAccountPagePrimaryTextColor() {
+ // 马甲包策略:账户页面主文本颜色 - 使用马甲包主要文本颜色
+ return SocialChatTheme.textPrimary; // 马甲包主要文本颜色,替代Colors.black
+ }
+
+ @override
+ Color getAccountPageSecondaryTextColor() {
+ // 马甲包策略:账户页面次要文本颜色 - 使用马甲包次要文本颜色
+ return SocialChatTheme.textSecondary; // 马甲包次要文本颜色,替代Colors.black38
+ }
+
+ @override
+ Color getAccountPageIconColor() {
+ // 马甲包策略:账户页面图标颜色 - 使用马甲包次要文本颜色
+ return SocialChatTheme.textPrimary; // 马甲包次要文本颜色,替代Colors.black26
+ }
+
+ @override
+ Color getAccountPageDividerColor() {
+ // 马甲包策略:账户页面分隔线颜色 - 使用马甲包边框颜色
+ return SocialChatTheme.borderColor; // 马甲包边框颜色,替代Colors.black12
+ }
+
+ @override
+ Color getAccountPageScaffoldBackgroundColor() {
+ // 马甲包策略:账户页面Scaffold背景颜色 - 使用透明色
+ return Colors.transparent;
+ }
+
+ @override
+ Color getGoldRecordPageListBackgroundColor() {
+ // 马甲包策略:金币记录页面列表背景颜色 - 深灰色
+ return Colors.transparent; // #1a1a1a
+ }
+}
diff --git a/lib/app/constants/sc_app_colors.dart b/lib/app/constants/sc_app_colors.dart
new file mode 100644
index 0000000..60e937a
--- /dev/null
+++ b/lib/app/constants/sc_app_colors.dart
@@ -0,0 +1,40 @@
+import 'dart:ui';
+
+import 'package:flutter/cupertino.dart';
+import 'package:yumi/app/config/app_config.dart';
+import 'package:yumi/ui_kit/theme/socialchat_theme.dart';
+
+/// 主题颜色配置(兼容层)
+
+///主题色 - 从AppConfig获取主色
+@deprecated
+Color get themeColor => SocialChatTheme.primaryColor;
+
+/// 次要主题色 - 基于主色的浅色版本
+@deprecated
+Color get themeColor2 => SocialChatTheme.primaryLight;
+
+/// 欢迎页面颜色
+@deprecated
+const int welcomeColorValue = 0xFFD0D3B5;
+@deprecated
+const Color color999 = Color(0xFF999999);
+
+/// 主题色值(兼容旧代码)
+@deprecated
+int get THEME_COLOR_VALUE => SocialChatTheme.primaryColor.value;
+@deprecated
+const int WELCOME_COLOR_VALUE = 0xFFD0D3B5;
+
+/// 分隔线颜色 - 使用SocialChat主题系统的颜色
+@deprecated
+Color get dividerColor => SocialChatTheme.dividerColor;
+
+@deprecated
+LinearGradient getLinearGradient(List colorValues, {bool vertical = false, double opacity = 1}){
+ if(vertical){
+ return LinearGradient(colors: colorValues.map((e) => Color(e).withOpacity(opacity)).toList(), begin: Alignment.topCenter, end: Alignment.bottomCenter);
+ } else{
+ return LinearGradient(colors: colorValues.map((e) => Color(e).withOpacity(opacity)).toList(), begin: Alignment.centerLeft, end: Alignment.centerRight);
+ }
+}
\ No newline at end of file
diff --git a/lib/app/constants/sc_emoji_datas.dart b/lib/app/constants/sc_emoji_datas.dart
new file mode 100644
index 0000000..d580d0a
--- /dev/null
+++ b/lib/app/constants/sc_emoji_datas.dart
@@ -0,0 +1,34 @@
+class SCEmojiDatas{
+ static const List smileys = [
+ '😀', '😃', '😄', '😁', '😆', '😅', '😂', '🤣', '😊', '😇',
+ '🙂', '🙃', '😉', '😌', '😍', '🥰', '😘', '😗', '😙', '😚',
+ '😋', '😛', '😝', '😜', '🤪', '🤨', '🧐', '🤓', '😎', '🤩',
+ '🥳', '😏', '😒', '😞', '😔', '😟', '😕', '🙁', '☹️', '😣',
+ '😖', '😫', '😩', '🥺', '😢', '😭', '😤', '😠', '😡', '🤬',
+ '🤯', '😳', '🥵', '🥶', '😱', '😨', '😰', '😥', '😓', '🤗',
+ '🤔', '🤭', '🤫', '🤥', '😶', '😐', '😑', '😬', '🙄', '😯',
+ '😦', '😧', '😮', '😲', '🥱', '😴', '🤤', '😪', '😵', '🤐',
+ '🥴', '🤢', '🤮', '🤧', '😷', '🤒', '🤕', '🤑', '🤠', '😈',
+ '👿', '👹', '👺', '🤡', '💩', '👻', '💀', '☠️', '👽', '👾',
+ '🤖', '🎃', '😺', '😸', '😹', '😻', '😼', '😽', '🙀', '😿',
+ '😾','🐶', '🐱', '🐭', '🐹', '🐰', '🦊', '🐻', '🐼', '🐨', '🐯',
+ '🦁', '🐮', '🐷', '🐽', '🐸', '🐵', '🙈', '🙉', '🙊', '🐒',
+ '🐔', '🐧', '🐦', '🐤', '🐣', '🐥', '🦆', '🦅', '🦉', '🦇',
+ '🐺', '🐗', '🐴', '🦄', '🐝', '🐛', '🦋', '🐌', '🐞', '🐜',
+ '🦟', '🦗', '🕷️', '🕸️', '🦂', '🐢', '🐍', '🦎', '🦖', '🦕',
+ '🐙', '🦑', '🦐', '🦞', '🦀', '🐡', '🐠', '🐟', '🐬', '🐳',
+ '🐋', '🦈', '🐊', '🐅', '🐆', '🦓', '🦍', '🦧', '🐘',
+ '🦛', '🦏', '🐪', '🐫', '🦒', '🦘', '🐃', '🐂', '🐄',
+ '🐎', '🐖', '🐏', '🐑', '🦙', '🐐', '🦌', '🐕', '🐩', '🦮',
+ '🐕🦺', '🐈', '🐓', '🦃', '🦚', '🦜', '🦢',
+ '🦩', '🕊️', '🐇', '🦝', '🦨', '🦡', '🦦', '🦥', '🐁',
+ '🐀', '🐿️', '🦔', '🐾', '🐉', '🐲', '🥬', '🥒', '🌶️', '🌽', '🥕', '🧄', '🧅', '🥔',
+ '🍠', '🥐', '🥯', '🍞', '🥖', '🥨', '🧀', '🥚', '🍳', '🧈',
+ '🥞', '🧇', '🥓', '🥩', '🍗', '🍖', '🦴', '🌭', '🍔', '🍟',
+ '🍕', '🥪', '🥙', '🧆', '🌮', '🌯', '🥗', '🥘',
+ '🥫', '🍝', '🍜', '🍲', '🍛', '🍣', '🍱', '🥟', '🦪', '🏍️', '🛺', '🚨', '🚔', '🚍', '🚘', '🚖', '🚡', '🚠', '🚟',
+ '🚃', '🚋', '🚞', '🚝', '🚄', '🚅', '🚈', '🚂', '🚆', '🚇',
+ '🚊', '🚉', '✈️', '🛫', '🛬', '🛩️', '💺', '🛰️', '🚀', '🛸', '⚽', '🏀', '🏈', '⚾', '🥎', '🎾', '🏐', '🏉', '🥏', '🎱',
+ '🪀', '🏓', '🏸', '🏒', '🏑', '🥍', '🏏',
+ ];
+}
\ No newline at end of file
diff --git a/lib/app/constants/sc_global_config.dart b/lib/app/constants/sc_global_config.dart
new file mode 100644
index 0000000..bbf2aef
--- /dev/null
+++ b/lib/app/constants/sc_global_config.dart
@@ -0,0 +1,97 @@
+import 'package:yumi/app/config/app_config.dart';
+import 'package:yumi/app/config/business_logic_strategy.dart';
+
+class SCGlobalConfig {
+ static String get apiHost => AppConfig.current.apiHost;
+ static String get imgHost => AppConfig.current.imgHost;
+ static String get privacyAgreementUrl => AppConfig.current.privacyAgreementUrl;
+ static String get userAgreementUrl => AppConfig.current.userAgreementUrl;
+
+ // 以下URL从AppConfig获取
+ static String get anchorAgentUrl => AppConfig.current.anchorAgentUrl;
+ static String get hostCenterUrl => AppConfig.current.hostCenterUrl;
+ static String get bdCenterUrl => AppConfig.current.bdCenterUrl;
+ static String get bdLeaderUrl => AppConfig.current.bdLeaderUrl;
+ static String get coinSellerUrl => AppConfig.current.coinSellerUrl;
+ static String get adminUrl => AppConfig.current.adminUrl;
+ static String get agencyCenterUrl => AppConfig.current.agencyCenterUrl;
+ static String get gamesKingUrl => AppConfig.current.gamesKingUrl;
+
+ // 应用下载链接需要根据Flavor调整
+ static String get appDownloadUrlGoogle => AppConfig.current.appDownloadUrlGoogle;
+ static String get appDownloadUrlApple => AppConfig.current.appDownloadUrlApple;
+
+ ///语言
+ static String lang = "en";
+
+ ///设备号
+ static String imei = "";
+
+ ///版本
+ static String version = "1.0.0";
+ static String build = "1";
+ static String model = "SM-G9550";
+ static String sysVersion = "9";
+ static int sdkInt = 28;
+
+ ///高于这个值才播放特效,避免低性能手机卡顿
+ static int maxSdkNoAnim = 27;
+
+ ///渠道SocialChat
+ static String channel = "Google";
+ static String origin = "ATYOU";
+ static String originChild = "ATYOU";
+
+ static String get tencentImAppid => AppConfig.current.tencentImAppid;
+ static String get agoraRtcAppid => AppConfig.current.agoraRtcAppid;
+
+ static num get gameAppid => AppConfig.current.gameAppid;
+ static String get gameAppChannel => AppConfig.current.gameAppChannel;
+
+ ///全服广播大群
+ static String get bigBroadcastGroup => AppConfig.current.bigBroadcastGroup;
+
+ static String get imAdmin => AppConfig.current.imAdmin;
+
+ ///财富榜单
+ static String get wealthRankUrl => AppConfig.current.wealthRankUrl;
+
+ ///魅力榜
+ static String get charmRankUrl => AppConfig.current.charmRankUrl;
+
+ ///房间榜单
+ static String get roomRankUrl => AppConfig.current.roomRankUrl;
+
+ ///邀请新用户活动链接
+ static String get inviteNewUserUrl => AppConfig.current.inviteNewUserUrl;
+
+ ///是否在审核
+ static bool? _isReviewOverride;
+ static bool get isReview => _isReviewOverride ?? AppConfig.current.isReview;
+ static set isReview(bool value) => _isReviewOverride = value;
+
+ ///礼物特效开关
+ static bool _isGiftSpecialEffects = true;
+ static bool get isGiftSpecialEffects => _isGiftSpecialEffects;
+ static set isGiftSpecialEffects(bool value) => _isGiftSpecialEffects = value;
+
+ ///入场秀
+ static bool _isEntryVehicleAnimation = true;
+ static bool get isEntryVehicleAnimation => _isEntryVehicleAnimation;
+ static set isEntryVehicleAnimation(bool value) => _isEntryVehicleAnimation = value;
+
+ ///全局飘屏
+ static bool _isFloatingAnimationInGlobal = true;
+ static bool get isFloatingAnimationInGlobal => _isFloatingAnimationInGlobal;
+ static set isFloatingAnimationInGlobal(bool value) => _isFloatingAnimationInGlobal = value;
+
+ ///幸运礼物特效开关
+ static bool _isLuckGiftSpecialEffects = true;
+ static bool get isLuckGiftSpecialEffects => _isLuckGiftSpecialEffects;
+ static set isLuckGiftSpecialEffects(bool value) => _isLuckGiftSpecialEffects = value;
+
+ /// 获取当前业务逻辑策略
+ static BusinessLogicStrategy get businessLogicStrategy {
+ return AppConfig.current.businessLogicStrategy;
+ }
+}
diff --git a/lib/app/constants/sc_room_msg_type.dart b/lib/app/constants/sc_room_msg_type.dart
new file mode 100644
index 0000000..d6cb82e
--- /dev/null
+++ b/lib/app/constants/sc_room_msg_type.dart
@@ -0,0 +1,113 @@
+class SCRoomMsgType {
+ static const String text = "TEXT";
+ static const String image = "IMAGE";
+ static const String joinRoom = "JOIN_ROOM";
+ static const String systemTips = "SYSTEM_TIPS";
+
+ ///表情包
+ static const String emoticons = "EMOTICONS";
+
+
+ ///新用户
+ static const String newUser = "NEW_USER";
+
+ ///上麦
+ static const String shangMai = "SHANG_MAI";
+
+ ///下麦
+ static const String xiaMai = "XIA_MAI";
+
+ ///踢下麦
+ static const String killXiaMai = "KILL_XIA_MAI";
+
+ ///请出房间
+ static const String qcfj = "QCFJ";
+
+ ///封麦
+ static const String fengMai = "FENG_MAI";
+
+ ///解封
+ static const String jieFeng = "JIE_FENG";
+
+ ///禁麦
+ static const String jinMai = "JIN_MAI";
+
+ ///解禁
+ static const String jieJin = "JIE_JIN";
+
+ ///送礼
+ static const String gift = "GIFT";
+
+ ///幸运礼物飘向麦位
+ static const String luckGiftAnimOther = "LUCK_GIFT_ANIM_OTHER";
+
+ ///送礼
+ static const String allGift = "ALL_GIFT";
+
+ ///收到礼物
+ static const String reciverGift = "RECIVER_GIFT";
+
+ ///抱上麦
+ static const String bsm = "BSM";
+
+ ///欢迎语
+ static const String welcome = "WELCOME";
+
+ ///禁言变动
+ static const String jinyanList = "JINYAN_LIST";
+
+ ///麦位变动
+ static const String micChange = "MIC_CHANGE";
+
+ ///房间身份变动
+ static const String roomRoleChange = "ROOM_ROLE_CHANGE";
+
+ ///火箭进度条更新
+ static const String rocketEnergyUpdate = "ROCKET_ENERGY_UPDSCE";
+
+ ///房间红包
+ static const String roomRedPacket = "ROOM_RED_PACKET";
+
+ ///邀请进入房间
+ static const String inviteRoom = "INVITE_ROOM";
+
+ ///用户火箭中奖
+ static const String rocketRewardUser = "ROCKET_REWARD_USER";
+
+ ///管理变动
+ static const String managerList = "MANAGER_LIST";
+
+ ///房间设置更新
+ static const String roomSettingUpdate = "ROOM_SETTING_UPDSCE";
+
+ ///掷骰子
+ static const String roomDice = "ROOM_DICE";
+
+ ///石头剪刀布
+ static const String roomRPS = "ROOM_RPS";
+
+ ///幸运数字
+ static const String roomLuckNumber = "ROOM_LUCK_NUMBER";
+
+ ///房间背景更新
+ static const String roomBGUpdate = "ROOM_BG_UPDSCE";
+
+ ///幸运礼物
+ static const String gameLuckyGift = "GAME_LUCKY_GIFT";
+
+ ///幸运礼物中奖5倍以及以上
+ static const String gameLuckyGift_5 = "GAME_LUCKY_GIFT_5";
+
+ ///房间多人游戏关闭
+ static const String roomGameClose = "ROOM_GAME_CLOSE";
+
+ ///房间游戏创建
+ static const String roomGameCreate = "ROOM_GAME_CRESCE";
+
+ ///暂时不用监听这个
+ static const String sendGift = "SEND_GIFT";
+ static const String gameBurstCrystalSprint = "GAME_BURST_CRYSTAL_SPRINT";
+ static const String gameBurstCrystalBox = "GAME_BURST_CRYSTAL_BOX";
+ static const String refreshOnlineUser = "REFRESH_ONLINE_USER";
+
+}
diff --git a/lib/app/constants/sc_screen.dart b/lib/app/constants/sc_screen.dart
new file mode 100644
index 0000000..1a34769
--- /dev/null
+++ b/lib/app/constants/sc_screen.dart
@@ -0,0 +1,19 @@
+import 'package:flutter_screenutil/flutter_screenutil.dart';
+
+class SCScreen{
+ static double designWidth = 375;
+ static double designHeight = 667;
+ static double width = ScreenUtil().setWidth(designWidth);
+ static double height = ScreenUtil().setHeight(designHeight);
+}
+
+double width(double width) {
+ return ScreenUtil().setWidth(width);
+}
+
+double height(double height) {
+ return ScreenUtil().setHeight(height);
+}
+double sp(double sp) {
+ return ScreenUtil().setSp(sp);
+}
\ No newline at end of file
diff --git a/lib/app/routes/sc_404_page.dart b/lib/app/routes/sc_404_page.dart
new file mode 100644
index 0000000..95076c7
--- /dev/null
+++ b/lib/app/routes/sc_404_page.dart
@@ -0,0 +1,15 @@
+import 'package:flutter/material.dart';
+
+class SCWidgetNotFound extends StatelessWidget {
+ @override
+ Widget build(BuildContext context) {
+ return Scaffold(
+ appBar: AppBar(
+ title: Text('页面不存在'),
+ ),
+ body: Center(
+ child: Text('页面不存在'),
+ ),
+ );
+ }
+}
diff --git a/lib/app/routes/sc_fluro_navigator.dart b/lib/app/routes/sc_fluro_navigator.dart
new file mode 100644
index 0000000..9b4d97e
--- /dev/null
+++ b/lib/app/routes/sc_fluro_navigator.dart
@@ -0,0 +1,141 @@
+import 'dart:io';
+
+import 'package:fluro/fluro.dart';
+import 'package:flutter/material.dart';
+import 'package:yumi/shared/data_sources/sources/remote/net/network_client.dart';
+import 'package:yumi/modules/chat/chat_route.dart';
+import 'package:yumi/modules/auth/login_route.dart';
+import 'package:yumi/app/routes/sc_lk_application.dart';
+
+/// 安卓页面切换时长
+const Duration kAndroidTransitionDuration = Duration(milliseconds: 375);
+
+/// 进入房间页动画时长
+const Duration kOpenRoomTransitionDuration = Duration(milliseconds: 325);
+
+
+/// 进入房间页过渡动画
+SlideTransition kOpenRoomTransitionBuilder( BuildContext context,
+ Animation animation,
+ Animation secondaryAnimation,
+ Widget child,) {
+ return SlideTransition(
+ position: Tween(
+ begin: const Offset(0.0, 1.0),
+ end: const Offset(0.0, 0.0),
+ ).animate(CurvedAnimation(parent: animation, curve: Curves.ease)),
+ child: child,
+ );
+}
+
+/// fluro的路由跳转工具类
+class SCNavigatorUtils {
+ static bool inChatPage = false;
+ static bool inLoginPage = false;
+ //不需要页面返回值的跳转
+ static Future push(BuildContext context, String path,
+ {bool replace = false,
+ bool clearStack = false,
+ TransitionType? transition,
+ Duration? transitionDuration,
+ RouteTransitionsBuilder? transitionBuilder}) async {
+ FocusScope.of(context).unfocus();
+ inLoginPage = path.startsWith("${LoginRouter.login}");
+ inChatPage = path.startsWith("${SCChatRouter.chat}");
+ final result = await SCLkApplication.router.navigateTo(context, path,
+ replace: replace,
+ clearStack: clearStack,
+ ///在系统语言为ar语会有问题
+ transition: (Platform.isAndroid
+ ? null
+ : TransitionType.cupertino),
+ // transitionDuration: transitionDuration ??
+ // (Platform.isAndroid ? kAndroidTransitionDuration : null),
+ // transitionBuilder: transitionBuilder ??
+ // (Platform.isAndroid ? (context, animation, secondaryAnimation, child) {
+ // return ScaleTransition(
+ // scale: Tween(begin: 1.0,end: 0.9).animate(CurvedAnimation(parent: secondaryAnimation, curve: Curves.ease)),
+ // child: SlideTransition(
+ // position: Tween(
+ // begin: const Offset(1.0, 0.0),
+ // end: const Offset(0.0, 0.0),
+ // ).animate(CurvedAnimation(parent: animation, curve: Curves.ease)),
+ // child: child,
+ // ),
+ // );
+ // } : null)
+ );
+
+ return result;
+ }
+
+ //需要页面返回值的跳转
+ static pushResult(
+ BuildContext context, String path, Function(Object) function,
+ {bool replace = false,
+ bool clearStack = false,
+ TransitionType? transition}) {
+ FocusScope.of(context).unfocus();
+ inLoginPage = path == LoginRouter.login;
+ inChatPage = path.startsWith("${SCChatRouter.chat}");
+ SCLkApplication.router
+ .navigateTo(context, path,
+ replace: replace,
+ clearStack: clearStack,
+ // transition: transition ??
+ // (Platform.isAndroid
+ // ? TransitionType.custom
+ // : TransitionType.cupertino),
+ // transitionDuration:
+ // Platform.isAndroid ? kAndroidTransitionDuration : null,
+ // transitionBuilder:
+ // Platform.isAndroid ? (context, animation, secondaryAnimation, child) {
+ // return ScaleTransition(
+ // scale: Tween(begin: 1.0,end: 0.9).animate(CurvedAnimation(parent: secondaryAnimation, curve: Curves.ease)),
+ // child: SlideTransition(
+ // position: Tween(
+ // begin: const Offset(1.0, 0.0),
+ // end: const Offset(0.0, 0.0),
+ // ).animate(CurvedAnimation(parent: animation, curve: Curves.ease)),
+ // child: child,
+ // ),
+ // );
+ // } : null
+ )
+ .then((result) {
+ // 页面返回result为null
+ if (result == null) {
+ return;
+ }
+ function(result);
+ }).catchError((error) {
+ print('$error');
+ });
+ }
+
+ /// 直接返回
+ static void goBack(BuildContext context) {
+ if(inChatPage){
+ inChatPage = false;
+ }
+ FocusScope.of(context).unfocus();
+ Navigator.pop(context);
+ }
+
+ /// 带参数返回
+ static void goBackWithParams(BuildContext context, result) {
+ if(inChatPage){
+ inChatPage = false;
+ }
+ FocusScope.of(context).unfocus();
+ Navigator.pop(context, result);
+ }
+
+ static void popUntil(BuildContext context, RoutePredicate predicate) {
+ if(inChatPage){
+ inChatPage = false;
+ }
+ FocusScope.of(context).unfocus();
+ Navigator.popUntil(context, predicate);
+ }
+}
diff --git a/lib/app/routes/sc_lk_application.dart b/lib/app/routes/sc_lk_application.dart
new file mode 100644
index 0000000..e625013
--- /dev/null
+++ b/lib/app/routes/sc_lk_application.dart
@@ -0,0 +1,5 @@
+import 'package:fluro/fluro.dart' as fluro;
+
+class SCLkApplication {
+ static fluro.FluroRouter router = fluro.FluroRouter();
+}
diff --git a/lib/app/routes/sc_router_init.dart b/lib/app/routes/sc_router_init.dart
new file mode 100644
index 0000000..0517434
--- /dev/null
+++ b/lib/app/routes/sc_router_init.dart
@@ -0,0 +1,7 @@
+
+import 'package:fluro/fluro.dart';
+
+abstract class SCIRouterProvider{
+
+ void initRouter(FluroRouter router);
+}
\ No newline at end of file
diff --git a/lib/app/routes/sc_routes.dart b/lib/app/routes/sc_routes.dart
new file mode 100644
index 0000000..113b1f7
--- /dev/null
+++ b/lib/app/routes/sc_routes.dart
@@ -0,0 +1,75 @@
+import 'package:fluro/fluro.dart' as fluro;
+import 'package:flutter/material.dart';
+import 'package:yumi/app/routes/sc_router_init.dart';
+import 'package:yumi/modules/country/country_route.dart';
+import 'package:yumi/modules/index/main_route.dart';
+import 'package:yumi/modules/chat/chat_route.dart';
+import 'package:yumi/modules/store/store_route.dart';
+import 'package:yumi/modules/index/index_page.dart';
+import 'package:yumi/modules/user/settings/settings_route.dart';
+import 'package:yumi/modules/wallet/wallet_route.dart';
+import 'package:yumi/modules/auth/login_route.dart';
+import 'package:yumi/modules/room/voice_room_route.dart';
+import 'package:yumi/app/routes/sc_404_page.dart';
+
+class SCRoutes {
+ static String home = '/';
+
+ static List _listRouter = [];
+
+ static void configureRoutes(fluro.FluroRouter router) {
+ /// 指定路由跳转错误返回页
+ router.notFoundHandler = fluro.Handler(handlerFunc: (BuildContext? context, Map> params) {
+ debugPrint('未找到目标页');
+ return SCWidgetNotFound();
+ });
+
+ router.define(home,
+ handler: fluro.Handler(handlerFunc: (BuildContext? context, Map> params) => SCIndexPage()));
+
+ _listRouter.clear();
+
+ /// 各自路由由各自模块管理,统一在此添加初始化
+
+ /// 登陆路由组
+ _listRouter.add(LoginRouter());
+ _listRouter.add(CountryRoute());
+ _listRouter.add(SettingsRoute());
+ _listRouter.add(VoiceRoomRoute());
+ _listRouter.add(SCMainRoute());
+ _listRouter.add(WalletRoute());
+ _listRouter.add(StoreRoute());
+ _listRouter.add(SCChatRouter());
+
+ /// 初始化路由
+ for (var routerProvider in _listRouter) {
+ routerProvider.initRouter(router);
+ }
+ }
+}
+
+// PS:路由使用方法
+
+// 1、不需要传参的 替换所有历史记录
+/// SCNavigatorUtils.push(context, LoginRouter.loginPage, replace: true);
+/// 2、不需要传参的 不替换历史记录
+/// SCNavigatorUtils.push(context, LoginRouter.loginPage, replace: false);
+
+// 需要传参的
+// 3、SCNavigatorUtils.push(context,'${SCRoutes.webViewPage}?param1=${Uri.encodeComponent(content1)}¶m2=${Uri.encodeComponent(content2)}', replace: true);
+// 4、SCNavigatorUtils.push(context, '${MarketRouter.hotCoin}?id=xxxxxxx');
+
+// 有返回值跳转
+/// 5、SCNavigatorUtils.pushResult(context, MarketRouter.hotCoin, (result){
+// setState(() {
+// //result是返回的结果
+// TestModel model = result;
+// _name = model.name;
+// });
+// });
+
+// 返回上一级
+// 6、SCNavigatorUtils.goBack(context);
+
+// 带参数返回上一级
+// 7、SCNavigatorUtils.goBackWithParams(context, result);
diff --git a/lib/app_localizations.dart b/lib/app_localizations.dart
new file mode 100644
index 0000000..1747257
--- /dev/null
+++ b/lib/app_localizations.dart
@@ -0,0 +1,1601 @@
+import 'dart:convert';
+
+import 'package:flutter/cupertino.dart';
+import 'package:flutter/services.dart';
+
+class SCAppLocalizations {
+ final Locale locale;
+
+ SCAppLocalizations(this.locale);
+
+ static SCAppLocalizations? of(BuildContext context) {
+ return Localizations.of(context, SCAppLocalizations);
+ }
+
+ static const LocalizationsDelegate delegate =
+ _SCAppLocalizationsDelegate();
+
+ Map? _localizedStrings;
+
+ Future load() async {
+ final jsonString = await rootBundle.loadString(
+ 'assets/l10n/intl_${locale.languageCode}.json',
+ );
+
+ final Map jsonMap = json.decode(jsonString);
+
+ _localizedStrings = jsonMap.map((key, value) {
+ return MapEntry(key, value.toString());
+ });
+
+ return true;
+ }
+
+ String translate(String key) {
+ return _localizedStrings?[key] ?? key;
+ }
+
+ // 添加具体翻译键的getter方法
+ String get signInWithGoogle => translate('signInWithGoogle');
+
+ String get or => translate('or');
+
+ String get yes => translate('yes');
+
+ String get sound2 => translate('sound2');
+
+ String get recent => translate('recent');
+
+ String get shop => translate('shop');
+
+ String get startYourBrandNewJourney => translate('startYourBrandNewJourney');
+
+ String get other => translate('other');
+
+ String get maliciousHarassment => translate('maliciousHarassment');
+
+ String get roomEdit => translate('roomEdit');
+
+ String get roomOwner => translate('roomOwner');
+
+ String get searchNoDataTips => translate('searchNoDataTips');
+
+ String get preventBeingBlocked => translate('preventBeingBlocked');
+
+ String get enableRankIncognitoMode => translate('enableRankIncognitoMode');
+
+ String get vipPrivilege => translate('vipPrivilege');
+
+ String get expirationTime => translate('expirationTime');
+
+ String get inviteNewUsersToEarnCoins => translate('inviteNewUsersToEarnCoins');
+
+ String get avoidBeingKicked => translate('avoidBeingKicked');
+
+ String get vipEntranceEffect => translate('vipEntranceEffect');
+
+ String get vipSpecialGiftTassel => translate('vipSpecialGiftTassel');
+
+ String get youHaveNotHadVIPYet => translate('youHaveNotHadVIPYet');
+
+ String get games => translate('games');
+
+ String get popularEvents => translate('popularEvents');
+
+ String get pleaseEnterContent => translate('pleaseEnterContent');
+
+ String get profilePhoto => translate('profilePhoto');
+
+ String get aboutMe => translate('aboutMe');
+
+ String get numberOfMic => translate('numberOfMic');
+
+ String get noHistoricalRecordsAvailable => translate('noHistoricalRecordsAvailable');
+
+ String get myRoom => translate('myRoom');
+
+ String get cancelRoomPassword => translate('cancelRoomPassword');
+
+ String get roomMemberFee => translate('roomMemberFee');
+
+ String get roomPassword => translate('roomPassword');
+
+ String get roomTheme2 => translate('roomTheme2');
+
+ String get blockedList2 => translate('blockedList2');
+
+ String get crateMyRoom => translate('crateMyRoom');
+
+ String get exclusiveEmojiWillBeReleasedAfterBecoming => translate('exclusiveEmojiWillBeReleasedAfterBecoming');
+
+ String get socialPrivilege => translate('socialPrivilege');
+
+ String get mysteriousInvisibility => translate('mysteriousInvisibility');
+
+ String get antiBlock => translate('antiBlock');
+
+ String get goToUpgrade => translate('goToUpgrade');
+
+ String get createFamilyForFree => translate('createFamilyForFree');
+
+ String get privateChat => translate('privateChat');
+
+ String get everyone => translate('everyone');
+
+ String get basicPermissions => translate('basicPermissions');
+
+ String get vipBirthdayGift => translate('vipBirthdayGift');
+
+ String get pleaseUpgradeYourVipLevel => translate('pleaseUpgradeYourVipLevel');
+
+ String get membershipFreeChatSpeak => translate('membershipFreeChatSpeak');
+
+ String get priorityRoomSorting => translate('priorityRoomSorting');
+
+ String get userColoredID => translate('userColoredID');
+
+ String get casualInteraction => translate('casualInteraction');
+
+ String get haveGamePlayingTips => translate('haveGamePlayingTips');
+
+ String get historicalTour => translate('historicalTour');
+
+ String get gameCenter => translate('gameCenter');
+
+ String get returnToVoiceChat => translate('returnToVoiceChat');
+
+ String get exitGameMode => translate('exitGameMode');
+
+ String get enterTheRoom => translate('enterTheRoom');
+
+ String get taskNamePersonalGameConsume => translate('taskNamePersonalGameConsume');
+
+ String get taskNamePersonalMicInRoom => translate('taskNamePersonalMicInRoom');
+
+ String get taskNamePersonalActiveInRoom => translate('taskNamePersonalActiveInRoom');
+
+ String get taskNameRoomOwnerMicTime => translate('taskNameRoomOwnerMicTime');
+
+ String get taskNamePersonalLuckyGiftGold => translate('taskNamePersonalLuckyGiftGold');
+
+ String get taskNamePersonalMagicGiftGold => translate('taskNamePersonalMagicGiftGold');
+
+ String get taskNameRoomOwnerSendGiftGold => translate('taskNameRoomOwnerSendGiftGold');
+
+ String get taskNameRoomUserSendGiftGold => translate('taskNameRoomUserSendGiftGold');
+
+ String get taskNameRoomOwnerInviteMic => translate('taskNameRoomOwnerInviteMic');
+
+ String get taskNameRoomOnlineUserCount => translate('taskNameRoomOnlineUserCount');
+
+ String get taskNamePersonalSendGift => translate('taskNamePersonalSendGift');
+
+ String get taskNameRoomMicUser30Min => translate('taskNameRoomMicUser30Min');
+
+ String get taskNameRoomMicUser60Min => translate('taskNameRoomMicUser60Min');
+
+ String get taskNameRoomMicUser120Min => translate('taskNameRoomMicUser120Min');
+
+ String get taskNameRoomOwnerSendGiftUser => translate('taskNameRoomOwnerSendGiftUser');
+
+ String get taskNameRoomOwnerSendRedPacket => translate('taskNameRoomOwnerSendRedPacket');
+
+ String get taskNameRoomNewMember => translate('taskNameRoomNewMember');
+
+ String get copyLink => translate('copyLink');
+
+ String get shareTo => translate('shareTo');
+
+ String get invite => translate('invite');
+
+ String get faceBook => translate('faceBook');
+
+ String get whatsApp => translate('whatsApp');
+
+ String get snapChat => translate('snapChat');
+
+ String get complete => translate('complete');
+
+ String get claim => translate('claim');
+
+ String get inviteGoRoomTips => translate('inviteGoRoomTips');
+
+ String get dailyCoinBonanzaRules => translate('dailyCoinBonanzaRules');
+
+ String get dailyCoinBonanzaRulesDetail => translate('dailyCoinBonanzaRulesDetail');
+
+ String get personalTasks => translate('personalTasks');
+
+ String get roomOwnerTasks => translate('roomOwnerTasks');
+
+ String get getPaidToRefer => translate('getPaidToRefer');
+
+ String get weekStart => translate('weekStart');
+
+ String get kingQuuen => translate('kingQuuen');
+
+ String get coinsReceived => translate('coinsReceived');
+
+ String get operationFail => translate('operationFail');
+
+ String get forMoreRewardsPleaseCheckTheTaskCenter => translate('forMoreRewardsPleaseCheckTheTaskCenter');
+
+ String get likedYourComment => translate('likedYourComment');
+
+ String get deleteAccountTips2 => translate('deleteAccountTips2');
+
+ String get likedYourDynamic => translate('likedYourDynamic');
+
+ String get doYouWantToKeepTheDraft => translate('doYouWantToKeepTheDraft');
+
+ String get createDynamicSuccess => translate('createDynamicSuccess');
+
+ String get like => translate('like');
+
+ String get noPromptsToday => translate('noPromptsToday');
+
+ String get currentVip => translate('currentVip');
+
+ String get ramadan => translate('ramadan');
+
+ String get deleteDynamicTips => translate('deleteDynamicTips');
+
+ String get deleteCommentTips => translate('deleteCommentTips');
+
+ String get deleteSuccessful => translate('deleteSuccessful');
+
+ String get itemsLeft => translate('itemsLeft');
+
+ String get replySucc => translate('replySucc');
+
+ String get basicFeatures => translate('basicFeatures');
+
+ String get areYouSureYouWantToDeleteYourAccount => translate('areYouSureYouWantToDeleteYourAccount');
+
+ String get game => translate('game');
+
+ String get accountDeletionNotice => translate('accountDeletionNotice');
+
+ String get deleteAccountTips => translate('deleteAccountTips');
+
+ String get thisUserHasBeenBlacklisted => translate('thisUserHasBeenBlacklisted');
+
+ String get comment => translate('comment');
+
+ String get cantSendDynamicTips => translate('cantSendDynamicTips');
+
+ String get customizedGiftRules => translate('customizedGiftRules');
+
+ String get customizedGiftRulesContent => translate('customizedGiftRulesContent');
+
+ String get clearCache => translate('clearCache');
+
+ String get saySomething => translate('saySomething');
+
+ String get catchFirstComment => translate('catchFirstComment');
+
+ String get dynamicT => translate('dynamic');
+
+ String get more => translate('more');
+
+ String get roomAnnouncement => translate('roomAnnouncement');
+
+ String get reply => translate('reply');
+
+ String get importantReminder => translate('importantReminder');
+
+ String get enterThisVoiceChatRoom => translate('enterThisVoiceChatRoom');
+
+ String get swipeLeftOnTheFloatingScreenAreaToQuicklyCloseIt => translate('swipeLeftOnTheFloatingScreenAreaToQuicklyCloseIt');
+
+ String get areYouSureYouWantToClearLocalCache => translate('areYouSureYouWantToClearLocalCache');
+
+ String get multiple => translate('multiple');
+
+ String get posting => translate('posting');
+
+ String get showMore => translate('showMore');
+
+ String get showLess => translate('showLess');
+
+ String get clearCacheSuccessfully => translate('clearCacheSuccessfully');
+
+ String get successfullyAddedToTheBlacklist => translate('successfullyAddedToTheBlacklist');
+
+ String get successfullyRemovedFromTheBlacklist => translate('successfullyRemovedFromTheBlacklist');
+
+ String get successfullyRemovedFromTheDynamicBlacklist => translate('successfullyRemovedFromTheDynamicBlacklist');
+
+ String get successfullyAddedToTheDynamicBlacklist => translate('successfullyAddedToTheDynamicBlacklist');
+
+ String get areYouSureToCancelBlacklist =>
+ translate('areYouSureToCancelBlacklist');
+
+ String get areYouSureYouWantToBlockThisUser =>
+ translate('areYouSureYouWantToBlockThisUser');
+
+ String get areYouSureYouWantToDynamicBlockThisUser =>
+ translate('areYouSureYouWantToDynamicBlockThisUser');
+
+ String get removeFromBlacklist => translate('removeFromBlacklist');
+
+ String get unblockUserDynamic => translate('unblockUserDynamic');
+
+ String get blockUserDynamic => translate('blockUserDynamic');
+
+ String get moveToBlacklist => translate('moveToBlacklist');
+
+ String get userBlacklist => translate('userBlacklist');
+
+ String get areYouSureToCancelDynamicBlacklist => translate('areYouSureToCancelDynamicBlacklist');
+
+ String get thisFeatureIsCurrentlyUnavailable =>
+ translate('thisFeatureIsCurrentlyUnavailable');
+
+ String get pleaseSelectTheRecipient => translate('pleaseSelectTheRecipient');
+
+ String get searchMemberIdHint => translate('searchMemberIdHint');
+
+ String get win => translate('win');
+
+ String get luckGiftSpecialEffects => translate('luckGiftSpecialEffects');
+
+ String get receivedFromALuckyGift => translate('receivedFromALuckyGift');
+
+ String get entryVehicleAnimation => translate('entryVehicleAnimation');
+
+ String get entryVehicleAnimation2 => translate('entryVehicleAnimation2');
+
+ String get floatingAnimationInGlobal =>
+ translate('floatingAnimationInGlobal');
+
+ String get theRedEnvelopeHasExpired => translate('theRedEnvelopeHasExpired');
+
+ String get wishingYouHappinessEveryDay =>
+ translate('wishingYouHappinessEveryDay');
+
+ String get newMessage => translate('newMessage');
+
+ String get familyNews => translate('familyNews');
+
+ String get familyName => translate('familyName');
+
+ String get help => translate('help');
+
+ String get open => translate('open');
+
+ String get canSendMsgTips => translate('canSendMsgTips');
+
+ String get systemAnnouncement => translate('systemAnnouncement');
+
+ String get systemAnnouncementTips1 => translate('systemAnnouncementTips1');
+
+ String get contactUs => translate('contactUs');
+
+ String get sentARedEnvelope => translate('sentARedEnvelope');
+
+ String get systemAnnouncementTips => translate('systemAnnouncementTips');
+
+ String get doNotClickUnfamiliarTips => translate('doNotClickUnfamiliarTips');
+
+ String get disbandTheFamilyTips => translate('disbandTheFamilyTips');
+
+ String get familyHelpTips => translate('familyHelpTips');
+
+ String get familyInfo => translate('familyInfo');
+
+ String get joinRequest => translate('joinRequest');
+
+ String get createRoomSuccsess => translate('createRoomSuccsess');
+
+ String get enterFamilyInfo => translate('enterFamilyInfo');
+
+ String get searchFamilyIdHint => translate('searchFamilyIdHint');
+
+ String get enterFamilyName => translate('enterFamilyName');
+
+ String get cpList => translate('cpList');
+
+ String get redEnvelopeNotYetClaimed => translate('redEnvelopeNotYetClaimed');
+
+ String get refuse => translate('refuse');
+
+ String get sayHi2 => translate('sayHi2');
+
+ String get rulesUpload => translate('rulesUpload');
+
+ String get agree => translate('agree');
+
+ String get coins3 => translate('coins3');
+
+ String get trend => translate('trend');
+
+ String get discard => translate('discard');
+
+ String get atTag => translate('atTag');
+
+ String get keep => translate('keep');
+
+ String get magic => translate('magic');
+
+ String get customized => translate('customized');
+
+ String get unclaimedRedEnvelopes => translate('unclaimedRedEnvelopes');
+
+ String get boxContributeTips => translate('boxContributeTips');
+
+ String get supporterWeeklyRank => translate('supporterWeeklyRank');
+
+ String get hostWeeklyRank => translate('hostWeeklyRank');
+
+ String get noMatchedCP => translate('noMatchedCP');
+
+ String get giftSpecialEffects => translate('giftSpecialEffects');
+
+ String get familyLevel => translate('familyLevel');
+
+ String get applyToJoin => translate('applyToJoin');
+
+ String get msgSendRedEnvelopeTips => translate('msgSendRedEnvelopeTips');
+
+ String get ownerSendTheRedEnvelope => translate('ownerSendTheRedEnvelope');
+
+ String get hotGames => translate('hotGames');
+
+ String get levelPrivileges => translate('levelPrivileges');
+
+ String get cpRequest => translate('cpRequest');
+
+ String get areYouSureYouWantToSpend3 =>
+ translate('areYouSureYouWantToSpend3');
+
+ String get areYouSureYouWantToSpend => translate('areYouSureYouWantToSpend');
+
+ String get areYouSureYouWantToSpend2 =>
+ translate('areYouSureYouWantToSpend2');
+
+ String get allGames => translate('allGames');
+
+ String get restorePurchases => translate('restorePurchases');
+
+ String get createFamily => translate('createFamily');
+
+ String get agreeJoinFamilyTips => translate('agreeJoinFamilyTips');
+
+ String get refuseJoinFamilyTips => translate('refuseJoinFamilyTips');
+
+ String get welcomeToMyFamily => translate('welcomeToMyFamily');
+
+ String get slotsClass => translate('slotsClass');
+
+ String get greedyClass => translate('greedyClass');
+
+ String get raceSeries => translate('raceSeries');
+
+ String get fishClass => translate('fishClass');
+
+ String get supporterList => translate('supporterList');
+
+ String get hostList => translate('hostList');
+
+ String get pending => translate('pending');
+
+ String get approved => translate('approved');
+
+ String get restorePurchasesTips => translate('restorePurchasesTips');
+
+ String get rejected => translate('rejected');
+
+ String get applicationRecord => translate('applicationRecord');
+
+ String get joinFamily => translate('joinFamily');
+
+ String get received => translate('received');
+
+ String get others => translate('others');
+
+ String get cpSexTips => translate('cpSexTips');
+
+ String get editProfile => translate('editProfile');
+
+ String get myPhoto => translate('myPhoto');
+
+ String get balanceNotEnough => translate('balanceNotEnough');
+
+ String get chooseFromAblum => translate('chooseFromAblum');
+
+ String get information => translate('information');
+
+ String get memberList => translate('memberList');
+
+ String get supporter => translate('supporter');
+
+ String get family => translate('family');
+
+ String get spaceBackground => translate('spaceBackground');
+
+ String get currentProgress => translate('currentProgress');
+
+ String get redEnvelopeTips2 => translate('redEnvelopeTips2');
+
+ String get openTheTreasureChest => translate('openTheTreasureChest');
+
+ String get number2 => translate('number2');
+
+ String get underReview => translate('underReview');
+
+ String get createAFamily => translate('createAFamily');
+
+ String get doYouWantToDeleteIt => translate('doYouWantToDeleteIt');
+
+ String get lastWeekProgress => translate('lastWeekProgress');
+
+ String get roomReward => translate('roomReward');
+
+ String get goToRecharge => translate('goToRecharge');
+
+ String get insufhcientGoldsGoToRecharge =>
+ translate('insufhcientGoldsGoToRecharge');
+
+ String get redEnvelopeRecTips2 => translate('redEnvelopeRecTips2');
+
+ String get redEnvelopeRecTips3 => translate('redEnvelopeRecTips3');
+
+ String get sendARedEnvelope => translate('sendARedEnvelope');
+
+ String get redEnvelopeSendingRecords =>
+ translate('redEnvelopeSendingRecords');
+
+ String get countdownMinutes => translate('countdownMinutes');
+
+ String get spam => translate('spam');
+
+ String get sendRedPackConfirmTips => translate('sendRedPackConfirmTips');
+
+ String get redEnvelopeTips1 => translate('redEnvelopeTips1');
+
+ String get roomTools => translate('roomTools');
+
+ String get fraud => translate('fraud');
+
+ String get redEnvelope => translate('redEnvelope');
+
+ String get dice => translate('dice');
+
+ String get rps => translate('rps');
+
+ String get operationsAreTooFrequent => translate('operationsAreTooFrequent');
+
+ String get luckNumber => translate('luckNumber');
+
+ String get entertainment => translate('entertainment');
+
+ String get reportSucc => translate('reportSucc');
+
+ String get reportInputTips => translate('reportInputTips');
+
+ String get pornography => translate('pornography');
+
+ String get redEnvelopeRecTips1 => translate('redEnvelopeRecTips1');
+
+ String get inappropriateContent => translate('inappropriateContent');
+
+ String get personalAttack => translate('personalAttack');
+
+ String get illegalInformation => translate('illegalInformation');
+
+ String get pleaseSelectTheTypeContent =>
+ translate('pleaseSelectTheTypeContent');
+
+ String get searchUserId => translate('searchUserId');
+
+ String get sendUser => translate('sendUser');
+
+ String get userName => translate('userName');
+
+ String get identity => translate('identity');
+
+ String get roomProfilePicture => translate('roomProfilePicture');
+
+ String get userProfilePicture => translate('userProfilePicture');
+
+ String get roomNotice => translate('roomNotice');
+
+ String get roomTheme => translate('roomTheme');
+
+ String get warning => translate('warning');
+
+ String get adjust => translate('adjust');
+
+ String get inputDesHint => translate('inputDesHint');
+
+ String get screenshotTips => translate('screenshotTips');
+
+ String get description => translate('description');
+
+ String get pleaseSelectTheTypeToProcess =>
+ translate('pleaseSelectTheTypeToProcess');
+
+ String get enterTheRoomId => translate('enterTheRoomId');
+
+ String get enterTheUserId => translate('enterTheUserId');
+
+ String get roomEditing => translate('roomEditing');
+
+ String get userEditing => translate('userEditing');
+
+ String get wearHonor => translate('wearHonor');
+
+ String get youDontHaveAnyHonorYet => translate('youDontHaveAnyHonorYet');
+
+ String get activityHonor => translate('activityHonor');
+
+ String get achievementHonor => translate('achievementHonor');
+
+ String get letGoToWatch => translate('letGoToWatch');
+
+ String get launchedARocket => translate('launchedARocket');
+
+ String get useCoupontips => translate('useCoupontips');
+
+ String get joinMemberTips2 => translate('joinMemberTips2');
+
+ String get leaveRoomIdentityTips => translate('leaveRoomIdentityTips');
+
+ String get followSucc => translate('followSucc');
+
+ String get searchCouponHint => translate('searchCouponHint');
+
+ String get signInWithYourAccount => translate('signInWithYourAccount');
+
+ String get signInWithApple => translate('signInWithApple');
+
+ String get deleteConversationTips => translate('deleteConversationTips');
+
+ String get loginRepresentsAgreementTo =>
+ translate('loginRepresentsAgreementTo');
+
+ String get termsofService => translate('termsofService');
+
+ String get theImageSizeCannotExceed => translate('theImageSizeCannotExceed');
+
+ String get privaceyPolicy => translate('privaceyPolicy');
+
+ String get youHaventFollowed => translate('youHaventFollowed');
+
+ String get tips => translate('tips');
+
+ String get inviteYouToBecomeBD => translate('inviteYouToBecomeBD');
+
+ String get bDLeaderInviteYouToBecomeBDLeader =>
+ translate('bDLeaderInviteYouToBecomeBDLeader');
+
+ String get adminInviteRechargeAgent => translate('adminInviteRechargeAgent');
+
+ String get task => translate('task');
+
+ String get honor => translate('honor');
+
+ String get bio => translate('bio');
+
+ String get hobby => translate('hobby');
+
+ String get search => translate('search');
+
+ String get sendCoupontips => translate('sendCoupontips');
+
+ String get coupon => translate('coupon');
+
+ String get done => translate('done');
+
+ String get join => translate('join');
+
+ String get roomRocketHelpTips => translate('roomRocketHelpTips');
+
+ String get giveUpIdentity => translate('giveUpIdentity');
+
+ String get bdLeader => translate('bdLeader');
+
+ String get picture => translate('picture');
+
+ String get signedin => translate('signedin');
+
+ String get couponRecord => translate('couponRecord');
+
+ String get improvementTasks => translate('improvementTasks');
+
+ String get image => translate('image');
+
+ String get inRocket => translate('inRocket');
+
+ String get video => translate('video');
+
+ String get get => translate('get');
+
+ String get sound => translate('sound');
+
+ String get wearMedal => translate('wearMedal');
+
+ String get sureUnfollowThisRoom => translate('sureUnfollowThisRoom');
+
+ String get camera => translate('camera');
+
+ String get crop => translate('crop');
+
+ String get inRoom => translate('inRoom');
+
+ String get youDontHaveAnyCouponsYet => translate('youDontHaveAnyCouponsYet');
+
+ String get finish => translate('finish');
+
+ String get visitorList => translate('visitorList');
+
+ String get gift2 => translate('gift2');
+
+ String get receiveSucc => translate('receiveSucc');
+
+ String get album => translate('album');
+
+ String get dailyTasks => translate('dailyTasks');
+
+ String get reject => translate('reject');
+
+ String get messageHasBeenRecalled => translate('messageHasBeenRecalled');
+
+ String get accept => translate('accept');
+
+ String get go => translate('go');
+
+ String get copy => translate('copy');
+
+ String get openUserProfleCard => translate('openUserProfleCard');
+
+ String get deleteOnAllDevices => translate('deleteOnAllDevices');
+
+ String get deleteFromMyDevice => translate('deleteFromMyDevice');
+
+ String get recallThisMessage => translate('recallThisMessage');
+
+ String get recall => translate('recall');
+
+ String get followedYou => translate('followedYou');
+
+ String get confirmAcceptTheInvitation =>
+ translate('confirmAcceptTheInvitation');
+
+ String get confirmDeclineTheInvitation =>
+ translate('confirmDeclineTheInvitation');
+
+ String get propMessagePrompt => translate('propMessagePrompt');
+
+ String get chats => translate('chats');
+
+ String get delete => translate('delete');
+
+ String get enterRoomConfirmTips => translate('enterRoomConfirmTips');
+
+ String get inputUserId => translate('inputUserId');
+
+ String get enterNickname => translate('enterNickname');
+
+ String get inviteCode => translate('inviteCode');
+
+ String get notifcation => translate('notifcation');
+
+ String get gameRules => translate('gameRules');
+
+ String get male => translate('male');
+
+ String get familyNotifcations => translate('familyNotifcations');
+
+ String get female => translate('female');
+
+ String get pullToLoadMore => translate('pullToLoadMore');
+
+ String get loadingFailedClickToRetry =>
+ translate('loadingFailedClickToRetry');
+
+ String get releaseToLoadMore => translate('releaseToLoadMore');
+
+ String get haveMyLimits => translate('haveMyLimits');
+
+ String get becomeAgent => translate('becomeAgent');
+
+ String get setAccount => translate('setAccount');
+
+ String get deleteAccount => translate('deleteAccount');
+
+ String get backTheRoom => translate('backTheRoom');
+
+ String get spendCoinsToGainExperiencePoints =>
+ translate('spendCoinsToGainExperiencePoints');
+
+ String get enterRoomName => translate('enterRoomName');
+
+ String get selectYourCountry => translate('selectYourCountry');
+
+ String get theMembershipFee => translate('theMembershipFee');
+
+ String get termsOfServicePrivacyPolicyTips =>
+ translate('termsOfServicePrivacyPolicyTips');
+
+ String get and => translate('and');
+
+ String get inviteYouToBecomeHost => translate('inviteYouToBecomeHost');
+
+ String get inviteYouToBecomeAgent => translate('inviteYouToBecomeAgent');
+
+ String get theVideoSizeCannotExceed => translate('theVideoSizeCannotExceed');
+
+ String get clickHereToStartChatting => translate('clickHereToStartChatting');
+
+ String get music => translate('music');
+
+ String get unread => translate('unread');
+
+ String get checkInSuccessful => translate('checkInSuccessful');
+
+ String get sginTips => translate('sginTips');
+
+ String get adminCenter => translate('adminCenter');
+
+ String get confirm => translate('confirm');
+
+ String get cancel => translate('cancel');
+
+ String get reapply => translate('reapply');
+
+ String get takeTheMic => translate('takeTheMic');
+
+ String get unlockTheMic => translate('unlockTheMic');
+
+ String get lockTheMic => translate('lockTheMic');
+
+ String get removeTheMic => translate('removeTheMic');
+
+ String get leavelTheMic => translate('leavelTheMic');
+
+ String get muteTheMic => translate('muteTheMic');
+
+ String get openTheMic => translate('openTheMic');
+
+ String get leavFamilyTips => translate('leavFamilyTips');
+
+ String get leavingTheFamily => translate('leavingTheFamily');
+
+ String get inviteToTheMicrophone => translate('inviteToTheMicrophone');
+
+ String get toConsume => translate('toConsume');
+
+ String get userLevel => translate('userLevel');
+
+ String get settings => translate('settings');
+
+ String get receive => translate('receive');
+
+ String get sendTheCpRequest => translate('sendTheCpRequest');
+
+ String get addCp => translate('addCp');
+
+ String get scrollToTheBottom => translate('scrollToTheBottom');
+
+ String get host => translate('host');
+
+ String get read => translate('read');
+
+ String get system => translate('system');
+
+ String get receivedAMessage => translate('receivedAMessage');
+
+ String get stop => translate('stop');
+
+ String get familyOwner2 => translate('familyOwner2');
+
+ String get agent => translate('agent');
+
+ String get obtain => translate('obtain');
+
+ String get apple => translate('apple');
+
+ String get google => translate('google');
+
+ String get wins => translate('wins');
+
+ String get ra => translate('ra');
+
+ String get bd => translate('bd');
+
+ String get charm => translate('charm');
+
+ String get specialEffectsManagement => translate('specialEffectsManagement');
+
+ String get giftCounter => translate('giftCounter');
+
+ String get resetLoginPasswordtTips2 => translate('resetLoginPasswordtTips2');
+
+ String get enterYourOldPassword => translate('enterYourOldPassword');
+
+ String get inputYourOldPassword => translate('inputYourOldPassword');
+
+ String get localMusic => translate('localMusic');
+
+ String get pleaseUpgradeYourVipLevelFirst =>
+ translate('pleaseUpgradeYourVipLevelFirst');
+
+ String get howToUpgrade => translate('howToUpgrade');
+
+ String get higherLevelFancierAvatarFrame =>
+ translate('higherLevelFancierAvatarFrame');
+
+ String get touristsTakeToTheMic => translate('touristsTakeToTheMic');
+
+ String get pleaseChatFfriendly => translate('pleaseChatFfriendly');
+
+ String get startVoiceParty => translate('startVoiceParty');
+
+ String get mountains => translate('mountains');
+
+ String get account => translate('account');
+
+ String get fromLuckyGifts => translate('fromLuckyGifts');
+
+ String get setLoginPassword => translate('setLoginPassword');
+
+ String get theTwoPasswordsDoNotMatch =>
+ translate('theTwoPasswordsDoNotMatch');
+
+ String get confirmYourPassword => translate('confirmYourPassword');
+
+ String get resetLoginPasswordtTips1 => translate('resetLoginPasswordtTips1');
+
+ String get medalAndAvatarFrameRewards =>
+ translate('medalAndAvatarFrameRewards');
+
+ String get theModificationsMade => translate('theModificationsMade');
+
+ String get touristsSendText => translate('touristsSendText');
+
+ String get membershipFeeTips1 => translate('membershipFeeTips1');
+
+ String get membershipFeeTips2 => translate('membershipFeeTips2');
+
+ String get membershipFee => translate('membershipFee');
+
+ String get setYourPassword => translate('setYourPassword');
+
+ String get vip => translate('vip');
+
+ String get vip1 => translate('vip1');
+
+ String get vip2 => translate('vip2');
+
+ String get vip3 => translate('vip3');
+
+ String get vip4 => translate('vip4');
+
+ String get vip5 => translate('vip5');
+
+ String get vip6 => translate('vip6');
+
+ String get vipChatBox => translate('vipChatBox');
+
+ String get sendTo => translate('sendTo');
+
+ String get level => translate('level');
+
+ String get add => translate('add');
+
+ String get free => translate('free');
+
+ String get openRedPackDialogTip => translate('openRedPackDialogTip');
+
+ String get start => translate('start');
+
+ String get vipUseThisThemeTips => translate('vipUseThisThemeTips');
+
+ String get charmGameRulesTips => translate('charmGameRulesTips');
+
+
+ String get enterYourNewPassword => translate('enterYourNewPassword');
+
+ String get confirmSwitchMicThemeTips =>
+ translate('confirmSwitchMicThemeTips');
+
+ String get confirmSwitchMicModelTips =>
+ translate('confirmSwitchMicModelTips');
+
+ String get micTheme => translate('micTheme');
+
+ String get conntinue => translate('conntinue');
+
+ String get renewVip => translate('renewVip');
+
+ String get buyVip => translate('buyVip');
+
+ String get couple2 => translate('couple2');
+
+ String get personal2 => translate('personal2');
+
+ String get family2 => translate('family2');
+
+ String get password => translate('password');
+
+ String get days => translate('days');
+
+ String get vipMicTheme => translate('vipMicTheme');
+
+ String get myMusic => translate('myMusic');
+
+ String get partWays => translate('partWays');
+
+ String get reconcileInvitationTips => translate('reconcileInvitationTips');
+
+ String get reconcileInvitation => translate('reconcileInvitation');
+
+ String get reconcile => translate('reconcile');
+
+ String get areYouSureYouWantToSpend4 =>
+ translate('areYouSureYouWantToSpend4');
+
+ String get partWaysTips => translate('partWaysTips');
+
+ String get areYouSureYouWantToPartWaysWithYourCP =>
+ translate('areYouSureYouWantToPartWaysWithYourCP');
+
+ String get separated => translate('separated');
+
+ String classicMic(String name) =>
+ translate('classicMic').replaceAll('{1}', name);
+
+ String redEnvelopeAmount(String name) =>
+ translate('redEnvelopeAmount').replaceAll('{1}', name);
+
+ String yesterday(String name) =>
+ translate('yesterday').replaceAll('{1}', name);
+
+ String monday(String name) => translate('monday').replaceAll('{1}', name);
+
+ String tuesday(String name) => translate('tuesday').replaceAll('{1}', name);
+
+ String wednesday(String name) =>
+ translate('wednesday').replaceAll('{1}', name);
+
+ String vipEmoticon(String name) =>
+ translate('vipEmoticon').replaceAll('{1}', name);
+
+ String family3(String name) =>
+ translate('family3').replaceAll('{1}', name);
+
+ String onlineUsers(String name1, String name2) =>
+ translate(
+ 'onlineUsers',
+ ).replaceAll('{1}', name1).replaceAll('{2}', name2);
+
+ String timeSpentTogether(String name) =>
+ translate('timeSpentTogether').replaceAll('{1}', name);
+
+ String firstDay(String name) => translate('firstDay').replaceAll('{1}', name);
+
+ String thursday(String name) => translate('thursday').replaceAll('{1}', name);
+
+ String friday(String name) => translate('friday').replaceAll('{1}', name);
+
+ String saturday(String name) => translate('saturday').replaceAll('{1}', name);
+
+ String sunday(String name) => translate('sunday').replaceAll('{1}', name);
+
+ String win2(String name) => translate('win2').replaceAll('{1}', name);
+
+ String numberOfMyCPs(String name1, String name2) =>
+ translate(
+ 'numberOfMyCPs',
+ ).replaceAll('{1}', name1).replaceAll('{2}', name2);
+
+ String sendUserId(String name) =>
+ translate('sendUserId').replaceAll('{1}', name);
+
+ String youAccepted(String name) =>
+ translate('youAccepted').replaceAll('{1}', name);
+
+ String acceptedYour(String name) =>
+ translate('acceptedYour').replaceAll('{1}', name);
+
+ String couple(String name) => translate('couple').replaceAll('{1}', name);
+
+ String areYouSureYouWantToSpend5(String name) =>
+ translate('areYouSureYouWantToSpend5').replaceAll('{1}', name);
+
+ String areYouSureYouWantToSpend6(String name) =>
+ translate('areYouSureYouWantToSpend6').replaceAll('{1}', name);
+
+ String get micManagement => translate('micManagement');
+
+ String get logIn => translate('logIn');
+
+ String get sayHi => translate('sayHi');
+
+ String get permanent => translate('permanent');
+
+ String get enterAccount => translate('enterAccount');
+
+ String get cantBuyVip => translate('cantBuyVip');
+
+ String get vipRoomCoverBorder => translate('vipRoomCoverBorder');
+
+ String get bdCenter => translate('bdCenter');
+
+ String get number => translate('number');
+
+ String get successfulWear => translate('successfulWear');
+
+ String get successfullyUnloaded => translate('successfullyUnloaded');
+
+ String get common => translate('common');
+
+ String get wealthLevel => translate('wealthLevel');
+
+ String get roomName => translate('roomName');
+
+ String get enterPassword => translate('enterPassword');
+
+ String get goToUpload => translate('goToUpload');
+
+ String get language => translate('language');
+
+ String get feedback => translate('feedback');
+
+ String get about => translate('about');
+
+ String get unFollow => translate('unFollow');
+
+ String get vipBadge => translate('vipBadge');
+
+ String get vipProfileFrame => translate('vipProfileFrame');
+
+ String get vipProfileCard => translate('vipProfileCard');
+
+ String get profile => translate('profile');
+
+ String get props => translate('props');
+
+ String get relationShip => translate('relationShip');
+
+ String get medal => translate('medal');
+
+ String get blockedList => translate('blockedList');
+
+ String get renewal => translate('renewal');
+
+ String get daily => translate('daily');
+
+ String get vipExclusiveVehicles => translate('vipExclusiveVehicles');
+
+ String get kickPrevention => translate('kickPrevention');
+
+ String get freeChatSpeak => translate('freeChatSpeak');
+
+ String get weekly => translate('weekly');
+
+ String get monthly => translate('monthly');
+
+ String get resetLoginPassword => translate('resetLoginPassword');
+
+ String get confirmUseTips => translate('confirmUseTips');
+
+ String get confirmUnUseTips => translate('confirmUnUseTips');
+
+ String get inUse => translate('inUse');
+
+ String get themeGoToUploadTips => translate('themeGoToUploadTips');
+
+ String get myItems => translate('myItems');
+
+ String get items => translate('items');
+
+ String get admin => translate('admin');
+
+ String get medals => translate('medals');
+
+ String get fansList => translate('fansList');
+
+ String get message => translate('message');
+
+ String get friends => translate('friends');
+
+ String get rechargeAgency => translate('rechargeAgency');
+
+ String get announcement => translate('announcement');
+
+ String get aboutUs => translate('aboutUs');
+
+ String get logout => translate('logout');
+
+ String get home => translate('home');
+
+ String get followList => translate('followList');
+
+ String get country2 => translate('country2');
+
+ String get giftwall => translate('giftwall');
+
+ String get purchaseIsSuccessful => translate('purchaseIsSuccessful');
+
+ String get member => translate('member');
+
+ String get explore => translate('explore');
+
+ String get me => translate('me');
+
+ String get expired => translate('expired');
+
+ String get confirmBuyTips => translate('confirmBuyTips');
+
+ String get buy => translate('buy');
+
+ String get use => translate('use');
+
+ String get unUse => translate('unUse');
+
+ String get day => translate('day');
+
+ String get popular => translate('popular');
+
+ String get recommend => translate('recommend');
+
+ String get follow => translate('follow');
+
+ String get followed => translate('followed');
+
+ String get following => translate('following');
+
+ String get history => translate('history');
+
+ String get hotRooms => translate('hotRooms');
+
+ String get viewMore => translate('viewMore');
+
+ String get noData => translate('noData');
+
+ String get freePrice => translate('freePrice');
+
+ String get purchase => translate('purchase');
+
+ String get wallet => translate('wallet');
+
+ String get viewFrame => translate('viewFrame');
+
+ String get touristsAreNotAllowedToGoOnTheMic =>
+ translate('touristsAreNotAllowedToGoOnTheMic');
+
+ String get inputRoomPassword => translate('inputRoomPassword');
+
+ String get users => translate('users');
+
+ String get rooms => translate('rooms');
+
+ String get store => translate('store');
+
+ String get bag => translate('bag');
+
+ String get coins => translate('coins');
+
+ String get coins4 => translate('coins4');
+
+ String get custom => translate('custom');
+
+ String get touristsCannotSendMessages =>
+ translate('touristsCannotSendMessages');
+
+ String get setRoomPassword => translate('setRoomPassword');
+
+ String get goldList => translate('goldList');
+
+ String get submit => translate('submit');
+
+ String get theme => translate('theme');
+
+ String get chatBox => translate('chatBox');
+
+ String get pleaseUploadUserAvatar => translate('pleaseUploadUserAvatar');
+
+ String get headdress => translate('headdress');
+
+ String get searchInputHint => translate('searchInputHint');
+
+ String get kickRoomTips => translate('kickRoomTips');
+
+ String get joinRoomTips => translate('joinRoomTips');
+
+ String get youAreCurrentlyCPRelationshipPleaseDissolve =>
+ translate('youAreCurrentlyCPRelationshipPleaseDissolve');
+
+ String get joinMemberTips => translate('joinMemberTips');
+
+ String get systemRoomTips => translate('systemRoomTips');
+
+ String get roomSetting => translate('roomSetting');
+
+ String get roomDetails => translate('roomDetails');
+
+ String get copiedToClipboard => translate('copiedToClipboard');
+
+ String get recharge => translate('recharge');
+
+ String get enter => translate('enter');
+
+ String get roomMember => translate('roomMember');
+
+ String get alreadyAnAdministrator => translate('alreadyAnAdministrator');
+
+ String get alreadyAnMember => translate('alreadyAnMember');
+
+ String get alreadyAnTourist => translate('alreadyAnTourist');
+
+ String get operationSuccessful => translate('operationSuccessful');
+
+ String get setUpAnIdentity => translate('setUpAnIdentity');
+
+ String get kickedOutOfRoom => translate('kickedOutOfRoom');
+
+ String get playGiftMusicAndDynamicMusic =>
+ translate('playGiftMusicAndDynamicMusic');
+
+ String get agentCenter => translate('agentCenter');
+
+ String get becomeHost => translate('becomeHost');
+
+ String get report => translate('report');
+
+ String get goldListort => translate('goldListort');
+
+ String get rechargeList => translate('rechargeList');
+
+ String get edit => translate('edit');
+
+ String get save => translate('save');
+
+ String get guest => translate('guest');
+
+ String get nickName => translate('nickName');
+
+ String get gender => translate('gender');
+
+ String get superFans => translate('superFans');
+
+ String get dateOfBirth => translate('dateOfBirth');
+
+ String get country => translate('country');
+
+ String get activity => translate('activity');
+
+ String get luck => translate('luck');
+
+ String get cp => translate('cp');
+
+ String get treasureChest => translate('treasureChest');
+
+ String get countryRegion => translate('countryRegion');
+
+ String get birthday => translate('birthday');
+
+ String get man => translate('man');
+
+ String get woman => translate('woman');
+
+ String get mute => translate('mute');
+
+ String get exit => translate('exit');
+
+ String get owner => translate('owner');
+
+ String get adminByHomeowner => translate('adminByHomeowner');
+
+ String get memberByHomeowner => translate('memberByHomeowner');
+
+ String get touristByHomeowner => translate('touristByHomeowner');
+
+ String get allInTheRoom => translate('allInTheRoom');
+
+ String get mInimize => translate('mInimize');
+
+ String get hostCenter => translate('hostCenter');
+
+ String get allOnMicrophone => translate('allOnMicrophone');
+
+ String get pleaseEnterNickname => translate('pleaseEnterNickname');
+
+ String get pleaseSelectYourCountry => translate('pleaseSelectYourCountry');
+
+ String get pleaseSelectYourGender => translate('pleaseSelectYourGender');
+
+ String get usersOnMicrophone => translate('usersOnMicrophone');
+
+ String get send => translate('send');
+
+ String get familyAnnouncement => translate('familyAnnouncement');
+
+ String get enterFamilyAnnouncement => translate('enterFamilyAnnouncement');
+
+ String get disbandTheFamily => translate('disbandTheFamily');
+
+ String get editFamily => translate('editFamily');
+
+ String get createFamilySuccess => translate('createFamilySuccess');
+
+ String get sent => translate('sent');
+
+ String get mine => translate('mine');
+
+ String get party => translate('party');
+
+ String get event => translate('event');
+
+ String get vistors => translate('vistors');
+
+ String get fans => translate('fans');
+
+ String get lockTheRoom => translate('lockTheRoom');
+
+ String get unLockTheRoom => translate('unLockTheRoom');
+
+ String get all => translate('all');
+
+ String get chat => translate('chat');
+
+ String get gift => translate('gift');
+
+ String get activityMedal => translate('activityMedal');
+
+ String get achievementMedal => translate('achievementMedal');
+
+ String get knapsack => translate('knapsack');
+
+ String get cancelRequest => translate('cancelRequest');
+
+ String get kickOutOfFamily => translate('kickOutOfFamily');
+
+ String get kickFamilyUserTips => translate('kickFamilyUserTips');
+
+ String get cancelFamilyAdmin => translate('cancelFamilyAdmin');
+
+ String get setAsFamilyAdmin => translate('setAsFamilyAdmin');
+
+ String get pleaseGetOnTheMicFirst => translate('pleaseGetOnTheMicFirst');
+
+ String get special => translate('special');
+
+ String get skip2 => translate('skip2');
+
+ String get updateNow => translate('updateNow');
+
+ String get clearMessage => translate('clearMessage');
+
+ String get pleaseSelectaItem => translate('pleaseSelectaItem');
+
+ String get areYouRureRoRecharge => translate('areYouRureRoRecharge');
+
+ String get giftGivingSuccessful => translate('giftGivingSuccessful');
+
+ String get theAccountPasswordCannotBeEmpty =>
+ translate('theAccountPasswordCannotBeEmpty');
+
+ String invitesYouToTheMicrophone(String name) =>
+ translate('invitesYouToTheMicrophone').replaceAll('{1}', name);
+
+ String enterRoomTips(String name) =>
+ translate('enterRoomTips').replaceAll('{1}', name);
+
+ String userLevelXPBoost(String name) =>
+ translate('userLevelXPBoost').replaceAll('{1}', name);
+
+ String dailyTaskRewardBonus(String name) =>
+ translate('dailyTaskRewardBonus').replaceAll('{1}', name);
+
+ String storeDiscount(String name) =>
+ translate('storeDiscount').replaceAll('{1}', name);
+
+ String confirmInviteThisUserToTheRoom(String name) =>
+ translate('confirmInviteThisUserToTheRoom').replaceAll('{1}', name);
+
+ String upToAdmins(String name) =>
+ translate('upToAdmins').replaceAll('{1}', name);
+
+ String upToMembers(String name) =>
+ translate('upToMembers').replaceAll('{1}', name);
+
+ String xxfamily(String name) => translate('xxfamily').replaceAll('{1}', name);
+
+ String collectionTimeTips(String time,
+ String remainCount,
+ String totalCount,) =>
+ translate('collectionTimeTips')
+ .replaceAll('{1}', time)
+ .replaceAll("{2}", remainCount)
+ .replaceAll("{3}", totalCount);
+
+ String yourVipWillExpire(String name) =>
+ translate('yourVipWillExpire').replaceAll('{1}', name);
+
+ String andAboveUsers(String name) =>
+ translate('andAboveUsers').replaceAll('{1}', name);
+
+ String privileges(String name) =>
+ translate('privileges').replaceAll('{1}', name);
+
+ String remainingNumberTips(String name1, String name2) =>
+ translate(
+ 'remainingNumberTips',
+ ).replaceAll('{1}', name1).replaceAll("{2}", name2);
+
+ String coins2(String name) => translate('coins2').replaceAll('{1}', name);
+
+ String credits(String name) => translate('credits').replaceAll('{1}', name);
+
+ String currentStage(String name) =>
+ translate('currentStage').replaceAll('{1}', name);
+
+ String roomReward2(String name) =>
+ translate('roomReward2').replaceAll('{1}', name);
+
+ String ownerIncomeCoins(String name) =>
+ translate('ownerIncomeCoins').replaceAll('{1}', name);
+
+ String rewardCoins(String name) =>
+ translate('rewardCoins').replaceAll('{1}', name);
+
+ String deleteAccount2(String name) =>
+ translate('deleteAccount2').replaceAll('{1}', name);
+
+ String skip(String name) => translate('skip').replaceAll('{1}', name);
+
+ String familyMember2(String name1, String name2) =>
+ translate(
+ 'familyMember2',
+ ).replaceAll('{1}', name1).replaceAll('{2}', name2);
+
+ String familyMember3(String name1) =>
+ translate('familyMember3').replaceAll('{1}', name1);
+
+ String familyAdmin2(String name1, String name2) =>
+ translate(
+ 'familyAdmin2',
+ ).replaceAll('{1}', name1).replaceAll('{2}', name2);
+
+ String follow2(String name) => translate('follow2').replaceAll('{1}', name);
+
+ String fans2(String name) => translate('fans2').replaceAll('{1}', name);
+
+ String vistors2(String name) => translate('vistors2').replaceAll('{1}', name);
+
+ String duration2(String name) =>
+ translate('duration2').replaceAll('{1}', name);
+
+ String cancelRequestFamilyMsg(String name) =>
+ translate('cancelRequestFamilyMsg').replaceAll('{1}', name);
+
+ String appUpdateTip(String name) =>
+ translate('appUpdateTip').replaceAll('{1}', name);
+
+ String numberOfSign(String name) =>
+ translate('numberOfSign').replaceAll('{1}', name);
+}
+
+class _SCAppLocalizationsDelegate
+ extends LocalizationsDelegate {
+ const _SCAppLocalizationsDelegate();
+
+ @override
+ bool isSupported(Locale locale) =>
+ ['en', 'zh', 'ar','bn','tr'].contains(locale.languageCode);
+
+ @override
+ Future load(Locale locale) async {
+ final localizations = SCAppLocalizations(locale);
+ await localizations.load();
+ return localizations;
+ }
+
+ @override
+ bool shouldReload(covariant LocalizationsDelegate old) =>
+ false;
+}
diff --git a/lib/config/pickImage.dart b/lib/config/pickImage.dart
new file mode 100644
index 0000000..a1bfb5d
--- /dev/null
+++ b/lib/config/pickImage.dart
@@ -0,0 +1,107 @@
+import 'dart:io';
+
+import 'package:flutter/cupertino.dart';
+import 'package:image_picker/image_picker.dart';
+
+import '../shared/tools/sc_path_utils.dart';
+import '../ui_kit/components/sc_tts.dart';
+
+class ImagePick {
+ static final ImagePicker _picker = ImagePicker();
+
+ /// 选择图片和视频
+ static Future?> pickPicAndVideoFromGallery(
+ BuildContext context,
+ ) async {
+ try {
+ // 调用 pickImage 方法,source 设置为 gallery 即可调用相册
+ final XFile? pickedFile = await _picker.pickMedia(
+ // 以下为可选参数,用于控制输出图像
+ maxWidth: 1800, // 限制图片最大宽度
+ maxHeight: 1800, // 限制图片最大高度
+ imageQuality: 85, // 图片压缩质量 (0-100)
+ );
+ if (pickedFile != null) {
+ if (!SCPathUtils.fileTypeIsPicAndMP4(pickedFile.path)) {
+ SCTts.show( "Please select sc_images in .jpg, .jpeg, .png format.");
+ return null;
+ }
+ return [File(pickedFile.path)];
+ }
+ return null;
+ } catch (e) {
+ // 处理异常,例如权限被拒绝或选择器被取消
+ print("图片选择出错: $e");
+ // 可以在这里添加用户友好的提示信息
+ return null;
+ }
+ }
+
+ /// 从相册选择多张图片
+ static Future?> pickMultipleFromGallery(
+ BuildContext context,
+ ) async {
+ try {
+ final List pickedFiles = await _picker.pickMultiImage(
+ maxWidth: 1800,
+ maxHeight: 1800,
+ imageQuality: 85,
+ limit: 9,
+ );
+ if (pickedFiles.isNotEmpty) {
+ return pickedFiles
+ .where((file) {
+ return file.mimeType?.startsWith('image/') == true;
+ })
+ .map((xFile) => File(xFile.path))
+ .toList();
+ }
+ return null;
+ } catch (e) {
+ print("多图选择出错: $e");
+ return null;
+ }
+ }
+
+ /// 从相册选择单张图片
+ static Future pickSingleFromGallery(BuildContext context) async {
+ try {
+ final XFile? pickedFile = await _picker.pickImage(
+ source: ImageSource.gallery,
+ maxWidth: 1800,
+ maxHeight: 1800,
+ imageQuality: 85,
+ );
+ if (pickedFile != null) {
+ if (!SCPathUtils.fileTypeIsPic(pickedFile.path)) {
+ SCTts.show( "Please select sc_images in .jpg, .jpeg, .png format.");
+ return null;
+ }
+ return File(pickedFile.path);
+ }
+ return null;
+ } catch (e) {
+ print("图片选择出错: $e");
+ return null;
+ }
+ }
+
+ /// 使用相机拍摄照片
+ static Future pickFromCamera(BuildContext context) async {
+ try {
+ final XFile? pickedFile = await _picker.pickImage(
+ source: ImageSource.camera,
+ maxWidth: 1800,
+ maxHeight: 1800,
+ imageQuality: 85,
+ );
+ if (pickedFile != null) {
+ return File(pickedFile.path);
+ }
+ return null;
+ } catch (e) {
+ print("相机拍照出错: $e");
+ return null;
+ }
+ }
+}
diff --git a/lib/main.dart b/lib/main.dart
new file mode 100644
index 0000000..c392c59
--- /dev/null
+++ b/lib/main.dart
@@ -0,0 +1,381 @@
+import 'dart:async';
+import 'dart:io';
+import 'dart:ui';
+
+import 'package:firebase_core/firebase_core.dart';
+import 'package:firebase_crashlytics/firebase_crashlytics.dart';
+import 'package:fluro/fluro.dart' as fluro;
+import 'package:flutter/cupertino.dart';
+import 'package:flutter/gestures.dart';
+import 'package:flutter/material.dart';
+import 'package:flutter/foundation.dart';
+import 'package:flutter/services.dart';
+import 'package:flutter_localizations/flutter_localizations.dart';
+import 'package:flutter_screenutil/flutter_screenutil.dart';
+import 'package:flutter_smart_dialog/flutter_smart_dialog.dart';
+import 'package:yumi/shared/tools/sc_keybord_util.dart';
+import 'package:yumi/shared/data_sources/sources/local/data_persistence.dart';
+import 'package:provider/provider.dart';
+import 'package:provider/single_child_widget.dart';
+import 'package:pull_to_refresh/pull_to_refresh.dart';
+
+import 'app_localizations.dart';
+import 'app/config/app_config.dart';
+import 'app/constants/sc_global_config.dart';
+import 'app/constants/sc_screen.dart';
+import 'app/routes/sc_routes.dart';
+import 'app/routes/sc_lk_application.dart';
+import 'shared/tools/sc_deep_link_handler.dart';
+import 'shared/tools/sc_deviceId_utils.dart';
+import 'modules/splash/splash_page.dart';
+import 'services/general/sc_app_general_manager.dart';
+import 'services/payment/apple_payment_manager.dart';
+import 'services/auth/authentication_manager.dart';
+import 'services/gift/gift_animation_manager.dart';
+import 'services/gift/gift_system_manager.dart';
+import 'services/payment/google_payment_manager.dart';
+import 'services/localization/localization_manager.dart';
+import 'services/room/rc_room_manager.dart';
+import 'services/audio/rtc_manager.dart';
+import 'services/audio/rtm_manager.dart';
+import 'services/shop/shop_manager.dart';
+import 'services/theme/theme_manager.dart';
+import 'services/auth/user_profile_manager.dart';
+import 'ui_kit/theme/socialchat_theme.dart';
+
+
+void main() async {
+
+ // 初始化应用配置
+ AppConfig.initialize();
+
+
+ // 2. 使用 runZonedGuarded 创建一个隔离区域来捕获所有异步错误
+ runZonedGuarded(
+ () async {
+ // 1. 确保 Widget 绑定初始化
+ WidgetsFlutterBinding.ensureInitialized();
+ // 性能优化:启用手势重采样
+ GestureBinding.instance.resamplingEnabled = true;
+ // 阶段1:初始化绝对必要的服务(不阻塞UI)
+ await _setupA();
+ // 使用重试机制初始化存储
+ await _initStore();
+ // 立即运行应用,不等待非必要服务初始化
+ runApp(const RootAppWithProviders());
+ },
+ // 9. runZonedGuarded 的错误回调(这是捕获异步错误的主要方式)
+ (error, stackTrace) {
+ // 这是捕获 runZonedGuarded 区域内所有未捕获异步错误的地方
+ FirebaseCrashlytics.instance.recordError(error, stackTrace, fatal: true);
+ debugPrint('Zoned Error: $error\nStack: $stackTrace');
+ },
+ );
+}
+
+/// 设置核心服务(重命名自_initializeEssentialServices)
+Future _setupA() async {
+ // 配置设备方向:仅竖屏
+ await SystemChrome.setPreferredOrientations([DeviceOrientation.portraitUp]);
+
+ // Android平台状态栏样式设置
+ if (Platform.isAndroid) {
+ SystemChrome.setSystemUIOverlayStyle(
+ const SystemUiOverlayStyle(
+ statusBarColor: Colors.transparent,
+ statusBarIconBrightness: Brightness.dark,
+ ),
+ );
+ }
+
+ // 键盘工具初始化
+ SCKeybordUtil.init();
+
+ // Firebase核心初始化(必需组件)
+ try {
+ await Firebase.initializeApp();
+ if (kDebugMode) {
+ debugPrint('Firebase初始化完成');
+ }
+ } catch (e, stackTrace) {
+ debugPrint('Firebase初始化异常: $e\n$stackTrace');
+ // 非阻塞错误处理:记录但继续运行
+ }
+
+ // Flutter错误拦截器配置
+ FlutterError.onError = (details) {
+ FirebaseCrashlytics.instance.recordFlutterFatalError(details);
+ FlutterError.presentError(details);
+ };
+
+ // 平台层错误处理器
+ PlatformDispatcher.instance.onError = (error, stack) {
+ FirebaseCrashlytics.instance.recordError(error, stack, fatal: true);
+ return true; // 错误已处理
+ };
+
+ // 启用崩溃收集
+ await FirebaseCrashlytics.instance.setCrashlyticsCollectionEnabled(true);
+}
+
+
+/// 带重试的数据存储初始化(重命名自_initializeStorageWithRetry)
+Future _initStore() async {
+ const maxAttempts = 3;
+ int attemptCount = 0;
+ bool success = false;
+
+ while (attemptCount < maxAttempts && !success) {
+ attemptCount++;
+ try {
+ await DataPersistence.initialize();
+ success = true;
+ if (kDebugMode) {
+ debugPrint('数据存储初始化成功(尝试次数: $attemptCount)');
+ }
+ } catch (e) {
+ debugPrint('数据存储初始化尝试 $attemptCount 失败: $e');
+
+ if (attemptCount >= maxAttempts) {
+ debugPrint('数据存储初始化失败,已达最大重试次数: $maxAttempts');
+ // 不抛出异常,允许应用继续运行
+ return;
+ }
+
+ // 递增延迟:500ms, 1000ms, 1500ms...
+ int delayMs = 500 * attemptCount;
+ await Future.delayed(Duration(milliseconds: delayMs));
+ }
+ }
+}
+
+/// 带有所有Provider的根组件
+class RootAppWithProviders extends StatelessWidget {
+ const RootAppWithProviders({super.key});
+
+ @override
+ Widget build(BuildContext context) {
+ return MultiProvider(providers: _buildP(), child: const YumiApplication());
+ }
+
+ /// 构建应用Provider列表 - 重新排序以优化性能
+ List _buildP() {
+ return [
+ // 核心用户相关Provider - 必须立即初始化
+ ChangeNotifierProvider(
+ lazy: false,
+ create: (context) => SocialChatAuthenticationManager(),
+ ),
+ ChangeNotifierProvider(
+ lazy: false,
+ create: (context) => SocialChatUserProfileManager(),
+ ),
+
+ // UI与主题相关Provider - 懒加载
+ ChangeNotifierProvider(
+ lazy: true,
+ create: (context) => ThemeManager(),
+ ),
+ ChangeNotifierProvider(
+ lazy: true,
+ create: (context) => LocalizationManager(),
+ ),
+
+ // 实时通信Provider - 懒加载
+ ChangeNotifierProvider(
+ lazy: true,
+ create: (context) => RealTimeCommunicationManager(),
+ ),
+ ChangeNotifierProvider(
+ lazy: true,
+ create: (context) => RealTimeMessagingManager(),
+ ),
+
+ // 房间与社交功能Provider - 懒加载
+ ChangeNotifierProvider(
+ lazy: true,
+ create: (context) => SocialChatRoomManager(),
+ ),
+
+ // 礼物与动画系统Provider - 懒加载
+ ChangeNotifierProvider(
+ lazy: true,
+ create: (context) => SocialChatGiftSystemManager(),
+ ),
+ ChangeNotifierProvider(
+ lazy: true,
+ create: (context) => GiftAnimationManager(),
+ ),
+
+ // 支付与商店Provider - 懒加载
+ ChangeNotifierProvider(
+ lazy: true,
+ create: (context) => AndroidPaymentProcessor(),
+ ),
+ ChangeNotifierProvider(
+ lazy: true,
+ create: (context) => IOSPaymentProcessor(),
+ ),
+ ChangeNotifierProvider(
+ lazy: true,
+ create: (context) => ShopManager(),
+ ),
+
+
+ // 通用应用管理Provider - 懒加载
+ ChangeNotifierProvider(
+ lazy: true,
+ create: (context) => SCAppGeneralManager(),
+ ),
+ ];
+ }
+}
+
+final GlobalKey navigatorKey = GlobalKey();
+final RouteObserver routeObserver = RouteObserver();
+
+class YumiApplication extends StatefulWidget {
+ const YumiApplication({super.key});
+
+ @override
+ State createState() => _YumiApplicationState();
+}
+
+class _YumiApplicationState extends State {
+ late fluro.FluroRouter _router;
+ final SCDeepLinkHandler _deepLinkHandler = SCDeepLinkHandler();
+
+ @override
+ void initState() {
+ super.initState();
+ // 初始化深层链接处理
+ _initLink();
+ // 延迟初始化路由和设备信息
+ WidgetsBinding.instance.addPostFrameCallback((_) {
+ _initRouter();
+ SCDeviceIdUtils.initDeviceinfo();
+ });
+ }
+
+ @override
+ dispose() {
+ _deepLinkHandler.dispose();
+ super.dispose();
+ }
+
+ Future _initLink() async {
+ // 初始化,并传递一个回调函数用于处理链接
+ await _deepLinkHandler.initDeepLinks(
+ onLinkReceived: (Uri uri) {
+ // 当收到链接时,无论应用在哪个页面,都可以进行路由
+ _handleLink(uri);
+ },
+ );
+ }
+
+ void _handleLink(Uri uri) {
+ // 这是处理链接的核心路由逻辑
+ print('App 根层收到链接: $uri');
+ String path = uri.path;
+ String id = uri.queryParameters['id'] ?? '';
+ }
+
+ void _initRouter() {
+ _router = fluro.FluroRouter();
+ SCRoutes.configureRoutes(_router);
+ SCLkApplication.router = _router;
+ }
+
+ @override
+ Widget build(BuildContext context) {
+ return _buildUI();
+ }
+
+ // 构建下拉刷新配置的页脚部件
+ Widget Function() _buildFooter() {
+ return () => CustomFooter(
+ builder: (BuildContext context, LoadStatus? mode) {
+ Widget body;
+ if (mode == LoadStatus.idle) {
+ body = Text(
+ SCAppLocalizations.of(context)!.pullToLoadMore,
+ );
+ } else if (mode == LoadStatus.loading) {
+ body = CupertinoActivityIndicator(color: Colors.white24);
+ } else if (mode == LoadStatus.failed) {
+ body = Text(
+ SCAppLocalizations.of(context)!.loadingFailedClickToRetry,
+ );
+ } else if (mode == LoadStatus.canLoading) {
+ body = Text(
+ SCAppLocalizations.of(context)!.releaseToLoadMore,
+ );
+ } else {
+ body = Text(
+ "",
+ style: TextStyle(
+ fontSize: 12.sp,
+ color: Color(0xff999999),
+ ),
+ );
+ }
+ return Container(
+ height: kTextTabBarHeight + ScreenUtil().statusBarHeight,
+ child: Center(child: body),
+ );
+ },
+ );
+ }
+
+
+ Widget _buildUI() {
+ return Consumer(
+ builder: (context, localeProvider, child) {
+ // 只有在LocaleProvider可用时才设置语言
+ SCGlobalConfig.lang = localeProvider.locale?.languageCode ?? "en";
+ return Consumer(
+ builder: (context, themeManager, child) {
+ return ScreenUtilInit(
+ designSize: Size(SCScreen.designWidth, SCScreen.designHeight),
+ splitScreenMode: false,
+ minTextAdapt: true,
+ builder: (context, child) {
+ return AnnotatedRegion(
+ value: SystemUiOverlayStyle.dark,
+ child: RefreshConfiguration(
+ headerBuilder: () => MaterialClassicHeader(color: SocialChatTheme.primaryColor),
+ footerBuilder: _buildFooter(),
+ child: MaterialApp(
+ title: 'Yumi',
+ locale: Provider.of(context).locale,
+ localizationsDelegates: [
+ SCAppLocalizations.delegate,
+ GlobalMaterialLocalizations.delegate,
+ GlobalCupertinoLocalizations.delegate,
+ GlobalWidgetsLocalizations.delegate,
+ ],
+ supportedLocales: [
+ const Locale('en', ''),
+ const Locale('zh', ''),
+ const Locale('ar', ''),
+ const Locale('tr', ''),
+ const Locale('bn', ''),
+ ],
+ navigatorKey: navigatorKey,
+ debugShowCheckedModeBanner: false,
+ onGenerateRoute: SCLkApplication.router.generator,
+ theme: themeManager.currentTheme,
+ home: SplashPage(),
+ builder: FlutterSmartDialog.init(),
+ navigatorObservers: [routeObserver],
+ ),
+ ),
+ );
+ },
+ );
+ },
+ );
+ },
+ );
+ }
+}
diff --git a/lib/modules/admin/editing/sc_editing_user_room_page.dart b/lib/modules/admin/editing/sc_editing_user_room_page.dart
new file mode 100644
index 0000000..faa4149
--- /dev/null
+++ b/lib/modules/admin/editing/sc_editing_user_room_page.dart
@@ -0,0 +1,701 @@
+import 'package:flutter/cupertino.dart';
+import 'package:flutter/material.dart';
+import 'package:flutter/services.dart';
+import 'package:flutter_debouncer/flutter_debouncer.dart';
+import 'package:flutter_screenutil/flutter_screenutil.dart';
+import 'package:yumi/app_localizations.dart';
+import 'package:yumi/app/config/business_logic_strategy.dart';
+import 'package:yumi/ui_kit/components/sc_compontent.dart';
+import 'package:yumi/ui_kit/components/text/sc_text.dart';
+import 'package:yumi/shared/tools/sc_pick_utils.dart';
+import 'package:yumi/shared/data_sources/sources/local/user_manager.dart';
+import 'package:yumi/shared/data_sources/sources/repositories/sc_room_repository_imp.dart';
+import 'package:yumi/shared/data_sources/sources/repositories/sc_user_repository_impl.dart';
+import 'package:yumi/shared/business_logic/models/res/login_res.dart';
+
+import 'package:yumi/ui_kit/components/appbar/socialchat_appbar.dart';
+import 'package:yumi/ui_kit/components/sc_tts.dart';
+import 'package:yumi/app/constants/sc_screen.dart';
+import 'package:yumi/app/constants/sc_global_config.dart';
+import 'package:yumi/app/routes/sc_fluro_navigator.dart';
+import 'package:yumi/shared/tools/sc_room_utils.dart';
+import 'package:yumi/shared/business_logic/models/res/room_res.dart';
+import 'package:yumi/modules/index/main_route.dart';
+
+class SCEditingUserRoomPage extends StatefulWidget {
+ final String type;
+
+ ///被举报的id(用户id或者房间id)
+ final SocialChatUserProfile? userProfile;
+ final SocialChatRoomRes? roomProfile;
+
+ const SCEditingUserRoomPage({
+ Key? key,
+ required this.type,
+ this.userProfile,
+ this.roomProfile,
+ }) : super(key: key);
+
+ @override
+ _SCEditingUserRoomPageState createState() => _SCEditingUserRoomPageState();
+}
+
+class _SCEditingUserRoomPageState extends State {
+ // 业务逻辑策略访问器
+ BusinessLogicStrategy get _strategy => SCGlobalConfig.businessLogicStrategy;
+
+ num selectedIndex = 0;
+ String reportReason = "";
+ List imageUrls = []; // 动态图片URL列表
+
+ int violationType = 1;
+ final TextEditingController _descriptionController = TextEditingController();
+ Debouncer debouncer = Debouncer();
+
+ @override
+ void initState() {
+ super.initState();
+ final violationTypeMapping = _strategy.getAdminEditingViolationTypeMapping(widget.type);
+ if (violationTypeMapping.isNotEmpty) {
+ // 获取第一个值作为默认违规类型
+ violationType = violationTypeMapping.values.first;
+ }
+ // 初始化图片URL列表,长度为最大上传数量
+ final maxImageCount = _strategy.getAdminEditingMaxImageUploadCount();
+ imageUrls = List.generate(maxImageCount, (index) => '');
+ }
+
+ @override
+ Widget build(BuildContext context) {
+ return Stack(
+ children: [
+ Image.asset(
+ _strategy.getAdminEditingBackgroundImage(),
+ width: ScreenUtil().screenWidth,
+ height: ScreenUtil().screenHeight,
+ fit: BoxFit.fill,
+ ),
+ Scaffold(
+ backgroundColor: Colors.transparent,
+ resizeToAvoidBottomInset: false,
+ appBar: SocialChatStandardAppBar(
+ actions: [],
+ title:
+ widget.type == "User"
+ ? SCAppLocalizations.of(context)!.userEditing
+ : SCAppLocalizations.of(context)!.roomEditing,
+ backgroundColor: Colors.transparent,
+ ),
+ body: SafeArea(
+ top: false,
+ child: SingleChildScrollView(
+ child: Column(
+ crossAxisAlignment: CrossAxisAlignment.start,
+ children: [
+ widget.type == "User"
+ ? Container(
+ padding: EdgeInsets.symmetric(
+ vertical: 8.w,
+ horizontal: 5.w,
+ ),
+ margin: EdgeInsets.symmetric(horizontal: 15.w),
+ decoration: BoxDecoration(
+ color: Colors.white,
+ border: Border.all(color: Colors.black12, width: 1.w),
+ borderRadius: BorderRadius.all(Radius.circular(12.w)),
+ ),
+ child: Row(
+ children: [
+ GestureDetector(
+ onTap: () {
+ SCNavigatorUtils.push(
+ context,
+ "${SCMainRoute.person}?isMe=${AccountStorage().getCurrentUser()?.userProfile?.id == widget.userProfile?.id}&tageId=${widget.userProfile?.id}",
+ );
+ },
+ behavior: HitTestBehavior.opaque,
+ child: head(
+ url: widget.userProfile?.userAvatar ?? "",
+ width: 55.w,
+ ),
+ ),
+ SizedBox(width: 2.w),
+ Expanded(
+ child: Column(
+ crossAxisAlignment: CrossAxisAlignment.start,
+ children: [
+ Row(
+ children: [
+ xb(
+ widget.userProfile?.userSex,
+ color:
+ widget.userProfile?.userSex == 1
+ ? Colors.blue
+ : Colors.purpleAccent,
+ ),
+ SizedBox(width: 5.w),
+ // richText(
+ // txt: data.userNickname ?? "",
+ // key: (widget as SearchUserList).text,
+ // highlight: SocialChatTheme.primaryColor,
+ // defaultColor: Colors.black,
+ // ),
+ Expanded(
+ child: text(
+ widget.userProfile?.userNickname ??
+ "",
+ fontSize: 15.sp,
+ fontWeight: FontWeight.w600,
+ textColor: Colors.black,
+ ),
+ ),
+ SizedBox(width: 5.w),
+ // dj(data.level.toString()),
+ ],
+ ),
+ Row(
+ children: [
+ GestureDetector(
+ child: Container(
+ padding: EdgeInsets.symmetric(
+ vertical: 8.w,
+ ),
+ decoration: BoxDecoration(
+ image: DecorationImage(
+ image: AssetImage(
+ (widget.userProfile
+ ?.hasSpecialId() ??
+ false)
+ ? _strategy.getAdminEditingIcon('specialIdBg')
+ : _strategy.getAdminEditingIcon('normalIdBg'),
+ ),
+ fit: BoxFit.fitWidth,
+ ),
+ ),
+ child: Row(
+ textDirection: TextDirection.ltr,
+ children: [
+ SizedBox(width: 38.w),
+ text(
+ widget.userProfile?.getID() ??
+ "",
+ fontSize: 12.sp,
+ textColor: Colors.white,
+ fontWeight: FontWeight.bold,
+ ),
+ SizedBox(width: 5.w),
+ Image.asset(
+ _strategy.getAdminEditingIcon('copyId'),
+ width: 12.w,
+ height: 12.w,
+ ),
+ SizedBox(width: 8.w),
+ ],
+ ),
+ ),
+ onTap: () {
+ Clipboard.setData(
+ ClipboardData(
+ text:
+ widget.userProfile?.getID() ??
+ "",
+ ),
+ );
+ SCTts.show(
+ SCAppLocalizations.of(
+ context,
+ )!.copiedToClipboard,
+ );
+ },
+ ),
+ ],
+ ),
+ ],
+ ),
+ ),
+ SizedBox(width: 5.w),
+ ],
+ ),
+ )
+ : Container(
+ padding: EdgeInsets.symmetric(
+ vertical: 8.w,
+ horizontal: 5.w,
+ ),
+ margin: EdgeInsets.symmetric(horizontal: 15.w),
+ decoration: BoxDecoration(
+ color: Colors.white,
+ border: Border.all(color: Colors.black12, width: 1.w),
+ borderRadius: BorderRadius.all(Radius.circular(12.w)),
+ ),
+ child: Row(
+ children: [
+ GestureDetector(
+ onTap: () {
+ SCRoomUtils.goRoom(
+ widget.roomProfile?.id ?? "",
+ context,
+ );
+ },
+ behavior: HitTestBehavior.opaque,
+ child: head(
+ url: widget.roomProfile?.roomCover ?? "",
+ width: 55.w,
+ ),
+ ),
+ SizedBox(width: 2.w),
+ Expanded(
+ child: Column(
+ crossAxisAlignment: CrossAxisAlignment.start,
+ children: [
+ Row(
+ children: [
+ Expanded(
+ child: text(
+ widget.roomProfile?.roomName ?? "",
+ fontSize: 15.sp,
+ fontWeight: FontWeight.w600,
+ textColor: Colors.black,
+ ),
+ ),
+ SizedBox(width: 5.w),
+ // dj(data.level.toString()),
+ ],
+ ),
+ Row(
+ children: [
+ GestureDetector(
+ child: Container(
+ padding: EdgeInsets.symmetric(
+ vertical: 8.w,
+ ),
+ child: Row(
+ textDirection: TextDirection.ltr,
+ children: [
+ SizedBox(width: 5.w),
+ text(
+ "ID:${widget.roomProfile?.roomAccount}",
+ fontSize: 12.sp,
+ textColor: Colors.black26,
+ fontWeight: FontWeight.bold,
+ ),
+ SizedBox(width: 5.w),
+ Image.asset(
+ _strategy.getAdminEditingIcon('copyId'),
+ width: 12.w,
+ height: 12.w,
+ color: Colors.black26,
+ ),
+ SizedBox(width: 8.w),
+ ],
+ ),
+ ),
+ onTap: () {
+ Clipboard.setData(
+ ClipboardData(
+ text:
+ widget
+ .roomProfile
+ ?.roomAccount ??
+ "",
+ ),
+ );
+ SCTts.show(
+ SCAppLocalizations.of(
+ context,
+ )!.copiedToClipboard,
+ );
+ },
+ ),
+ ],
+ ),
+ ],
+ ),
+ ),
+ SizedBox(width: 5.w),
+ ],
+ ),
+ ),
+ SizedBox(height: 10.w),
+ Row(
+ children: [
+ SizedBox(width: 15.w),
+ text(
+ SCAppLocalizations.of(
+ context,
+ )!.pleaseSelectTheTypeToProcess,
+ fontSize: 14.sp,
+ fontWeight: FontWeight.w600,
+ textColor: Colors.black,
+ ),
+ SizedBox(width: 15.w),
+ ],
+ ),
+ Container(
+ decoration: BoxDecoration(
+ borderRadius: BorderRadius.circular(12),
+ color: Colors.white,
+ border: Border.all(color: Color(0xffE6E6E6), width: 1.w),
+ ),
+ margin: EdgeInsets.only(top: 10.w, left: 15.w, right: 15.w),
+ padding: EdgeInsets.symmetric(horizontal: 15.w),
+ child: Column(
+ children: [
+ // 动态生成违规类型选项
+ ..._buildViolationTypeOptions(context),
+ SizedBox(height: 20.w,),
+ Row(
+ children: [
+ text(
+ SCAppLocalizations.of(context)!.description,
+ fontSize: 14.sp,
+ fontWeight: FontWeight.w500,
+ textColor: Colors.black,
+ ),
+ Spacer(),
+ ],
+ ),
+ SizedBox(height: 8.w),
+ Container(
+ padding: EdgeInsets.all(5.w),
+ decoration: _strategy.getAdminEditingInputDecoration(),
+ child: TextField(
+ controller: _descriptionController,
+ onChanged: (text) {},
+ maxLength: _strategy.getAdminEditingDescriptionMaxLength(),
+ maxLines: 5,
+ decoration: InputDecoration(
+ hintText:
+ SCAppLocalizations.of(context)!.inputDesHint,
+ hintStyle: TextStyle(
+ color: Colors.black45,
+ fontSize: 14.sp,
+ ),
+ contentPadding: EdgeInsets.only(top: 0.w),
+
+ isDense: true,
+ filled: false,
+ focusColor: Colors.transparent,
+ hoverColor: Colors.transparent,
+ border: InputBorder.none,
+ enabledBorder: InputBorder.none,
+ focusedBorder: InputBorder.none,
+ disabledBorder: InputBorder.none,
+ errorBorder: InputBorder.none,
+ focusedErrorBorder: InputBorder.none,
+ // enabledBorder: UnderlineInputBorder(
+ // borderSide: BorderSide(width: 0.5,color: Colors.white,style: BorderStyle.solid),),
+ // focusedBorder: UnderlineInputBorder(
+ // borderSide: BorderSide(width: 0.5,color: Colors.white,style: BorderStyle.solid),),
+ // prefixIcon: Padding(padding: EdgeInsets.all(8.w), child: Image.asset("images/login/sc_icon_phone.png",width: 20.w, height: 20.w,fit: BoxFit.fill,),),
+ fillColor: Colors.black45,
+ ),
+ style: TextStyle(
+ fontSize: sp(15),
+ color: Colors.black,
+ textBaseline: TextBaseline.alphabetic,
+ ),
+ ),
+ ),
+ SizedBox(height: 5.w),
+ Row(
+ children: [
+ text(
+ SCAppLocalizations.of(context)!.screenshotTips,
+ fontSize: 14.sp,
+ textColor: Colors.black,
+ fontWeight: FontWeight.w500,
+ ),
+ Spacer(),
+ ],
+ ),
+ SizedBox(height: 8.w),
+ Row(
+ children: [
+ // 动态生成图片上传组件
+ ...List.generate(_strategy.getAdminEditingMaxImageUploadCount(), (index) {
+ return Expanded(
+ child: GestureDetector(
+ child: Stack(
+ children: [
+ imageUrls[index].isNotEmpty
+ ? netImage(url: imageUrls[index], height: 100.w)
+ : Image.asset(
+ _strategy.getAdminEditingIcon('addPic'),
+ height: 100.w,
+ ),
+ imageUrls[index].isNotEmpty
+ ? Positioned(
+ top: 5.w,
+ right: 5.w,
+ child: GestureDetector(
+ child: Image.asset(
+ _strategy.getAdminEditingIcon('closePic'),
+ width: 14.w,
+ height: 14.w,
+ ),
+ onTap: () {
+ setState(() {
+ imageUrls[index] = "";
+ });
+ },
+ ),
+ )
+ : Container(),
+ ],
+ ),
+ onTap: () {
+ SCPickUtils.pickImage(context, (
+ bool success,
+ String url,
+ ) {
+ if (success) {
+ setState(() {
+ imageUrls[index] = url;
+ });
+ }
+ });
+ },
+ ),
+ );
+ }).expand((widget) => [widget, if (_strategy.getAdminEditingMaxImageUploadCount() > 1 && widget != Expanded) SizedBox(width: 5.w)]).toList(),
+ ],
+ ),
+ SizedBox(height: 15.w),
+ ],
+ ),
+ ),
+ SizedBox(height: 45.w),
+ GestureDetector(
+ behavior: HitTestBehavior.opaque,
+ onTap: () {
+ debouncer.debounce(
+ duration: Duration(milliseconds: 350),
+ onDebounce: () {
+ List uploadedImages = imageUrls.where((url) => url.isNotEmpty).toList();
+ if (widget.type == "User") {
+ SCAccountRepository().userViolationHandle(
+ widget.userProfile?.id ?? "",
+ violationType,
+ 1,
+ _descriptionController.text,
+ imageUrls: imageUrls,
+ ).then((b){
+ SCTts.show(SCAppLocalizations.of(context)!.operationSuccessful);
+ SCNavigatorUtils.goBack(context);
+ }).catchError((e){
+
+ });
+ } else {
+ SCChatRoomRepository().roomViolationHandle(
+ widget.roomProfile?.id ?? "",
+ violationType,
+ 1,
+ _descriptionController.text,
+ imageUrls: imageUrls,
+ ).then((b){
+ SCTts.show(SCAppLocalizations.of(context)!.operationSuccessful);
+ SCNavigatorUtils.goBack(context);
+ }).catchError((e){
+
+ });
+ }
+ },
+ );
+ },
+ child: Container(
+ height: 40.w,
+ width: double.infinity,
+ alignment: Alignment.center,
+ margin: EdgeInsets.symmetric(horizontal: 45.w),
+ decoration: BoxDecoration(
+ gradient: LinearGradient(
+ begin: AlignmentDirectional.topCenter,
+ end: AlignmentDirectional.bottomCenter,
+ colors: _strategy.getAdminEditingButtonGradient('warning'),
+ ),
+ borderRadius: BorderRadius.circular(25.w),
+ ),
+ child: Text(
+ SCAppLocalizations.of(context)!.warning,
+ style: TextStyle(
+ color: Colors.white,
+ fontSize: 16.sp,
+ fontWeight: FontWeight.w600,
+ ),
+ ),
+ ),
+ ),
+ SizedBox(height: 20.w),
+ GestureDetector(
+ behavior: HitTestBehavior.opaque,
+ onTap: () {
+ debouncer.debounce(
+ duration: Duration(milliseconds: 350),
+ onDebounce: () {
+ List uploadedImages = imageUrls.where((url) => url.isNotEmpty).toList();
+ if (widget.type == "User") {
+ SCAccountRepository().userViolationHandle(
+ widget.userProfile?.id ?? "",
+ violationType,
+ 2,
+ _descriptionController.text,
+ imageUrls: imageUrls,
+ ).then((b){
+ SCTts.show(SCAppLocalizations.of(context)!.operationSuccessful);
+ SCNavigatorUtils.goBack(context);
+ }).catchError((e){
+
+ });
+ } else {
+ SCChatRoomRepository().roomViolationHandle(
+ widget.roomProfile?.id ?? "",
+ violationType,
+ 2,
+ _descriptionController.text,
+ imageUrls: imageUrls,
+ ).then((b){
+ SCTts.show(SCAppLocalizations.of(context)!.operationSuccessful);
+ SCNavigatorUtils.goBack(context);
+ }).catchError((e){
+
+ });
+ }
+ },
+ );
+ },
+ child: Container(
+ height: 40.w,
+ width: double.infinity,
+ alignment: Alignment.center,
+ margin: EdgeInsets.symmetric(horizontal: 45.w),
+ decoration: BoxDecoration(
+ gradient: LinearGradient(
+ begin: AlignmentDirectional.topCenter,
+ end: AlignmentDirectional.bottomCenter,
+ colors: _strategy.getAdminEditingButtonGradient('adjust'),
+ ),
+ borderRadius: BorderRadius.circular(25.w),
+ ),
+ child: Text(
+ SCAppLocalizations.of(context)!.adjust,
+ style: TextStyle(
+ color: Colors.white,
+ fontSize: 16.sp,
+ fontWeight: FontWeight.w600,
+ ),
+ ),
+ ),
+ ),
+ SizedBox(height: 35.w),
+ ],
+ ),
+ ),
+ ),
+ ),
+ ],
+ );
+ }
+
+ List _buildViolationTypeOptions(BuildContext context) {
+ final violationTypeMapping = _strategy.getAdminEditingViolationTypeMapping(widget.type);
+ final List options = [];
+
+ if (violationTypeMapping.isEmpty) {
+ // 如果没有映射,返回默认选项
+ if (widget.type == "User") {
+ options.add(_item(SCAppLocalizations.of(context)!.userName, 0, 1));
+ options.add(_item(SCAppLocalizations.of(context)!.userProfilePicture, 1, 2));
+ } else {
+ options.add(_item(SCAppLocalizations.of(context)!.roomName, 0, 3));
+ options.add(_item(SCAppLocalizations.of(context)!.roomProfilePicture, 1, 4));
+ options.add(_item(SCAppLocalizations.of(context)!.roomNotice, 2, 5));
+ options.add(_item(SCAppLocalizations.of(context)!.roomTheme, 3, 6));
+ }
+ return options;
+ }
+
+ // 根据映射动态生成选项
+ int index = 0;
+ violationTypeMapping.forEach((displayName, typeId) {
+ // 需要将英文显示名称转换为本地化文本
+ String localizedName;
+ switch (displayName) {
+ case 'Pornography':
+ localizedName = SCAppLocalizations.of(context)!.pornography;
+ break;
+ case 'Illegal information':
+ localizedName = SCAppLocalizations.of(context)!.illegalInformation;
+ break;
+ case 'Fraud':
+ localizedName = SCAppLocalizations.of(context)!.fraud;
+ break;
+ case 'Other':
+ localizedName = SCAppLocalizations.of(context)!.others;
+ break;
+ case 'User Name':
+ localizedName = SCAppLocalizations.of(context)!.userName;
+ break;
+ case 'User Profile Picture':
+ localizedName = SCAppLocalizations.of(context)!.userProfilePicture;
+ break;
+ case 'Room Name':
+ localizedName = SCAppLocalizations.of(context)!.roomName;
+ break;
+ case 'Room Profile Picture':
+ localizedName = SCAppLocalizations.of(context)!.roomProfilePicture;
+ break;
+ case 'Room Notice':
+ localizedName = SCAppLocalizations.of(context)!.roomNotice;
+ break;
+ case 'Room Theme':
+ localizedName = SCAppLocalizations.of(context)!.roomTheme;
+ break;
+ default:
+ localizedName = displayName;
+ }
+ options.add(_item(localizedName, index, typeId));
+ index++;
+ });
+
+ return options;
+ }
+
+ Widget _item(String str, int index, int vtype) {
+ return GestureDetector(
+ behavior: HitTestBehavior.opaque,
+ onTap: () {
+ setState(() {
+ reportReason = str;
+ selectedIndex = index;
+ violationType = vtype;
+ });
+ },
+ child: Container(
+ width: double.infinity,
+ height: 35.w,
+ child: Row(
+ crossAxisAlignment: CrossAxisAlignment.center,
+ children: [
+ text(str, fontSize: 13.sp, textColor: Colors.black,fontWeight: FontWeight.w500),
+ Spacer(),
+ selectedIndex == index
+ ? Image.asset(
+ _strategy.getAdminEditingIcon('checked'),
+ width: 20.w,
+ fit: BoxFit.fitWidth,
+ )
+ : Container(
+ width: 20.w,
+ height: 20.w,
+ decoration: BoxDecoration(
+ shape: BoxShape.circle,
+ border: Border.all(color: Colors.grey, width: 2.w),
+ ),
+ ),
+ ],
+ ),
+ ),
+ );
+ }
+}
diff --git a/lib/modules/admin/search/sc_edit_room_search_admin_page.dart b/lib/modules/admin/search/sc_edit_room_search_admin_page.dart
new file mode 100644
index 0000000..ae1fc93
--- /dev/null
+++ b/lib/modules/admin/search/sc_edit_room_search_admin_page.dart
@@ -0,0 +1,232 @@
+import 'dart:convert';
+
+import 'package:flutter/cupertino.dart';
+import 'package:flutter/material.dart';
+import 'package:flutter/services.dart';
+import 'package:flutter_screenutil/flutter_screenutil.dart';
+import 'package:yumi/shared/tools/sc_loading_manager.dart';
+import 'package:yumi/shared/tools/sc_room_utils.dart';
+import 'package:yumi/modules/index/main_route.dart';
+import 'package:yumi/app_localizations.dart';
+import 'package:yumi/ui_kit/components/appbar/socialchat_appbar.dart';
+import 'package:yumi/ui_kit/components/sc_compontent.dart';
+import 'package:yumi/ui_kit/components/socialchat_gradient_button.dart';
+import 'package:yumi/ui_kit/components/text/sc_text.dart';
+import 'package:yumi/ui_kit/theme/socialchat_theme.dart';
+import 'package:yumi/app/constants/sc_screen.dart';
+import 'package:yumi/app/routes/sc_fluro_navigator.dart';
+import 'package:yumi/app/constants/sc_global_config.dart';
+import 'package:yumi/app/config/business_logic_strategy.dart';
+import 'package:yumi/shared/data_sources/sources/repositories/sc_room_repository_imp.dart';
+import 'package:yumi/shared/data_sources/sources/repositories/sc_user_repository_impl.dart';
+import 'package:yumi/shared/business_logic/models/res/room_res.dart';
+
+class SCEditRoomSearchAdminPage extends StatefulWidget {
+ @override
+ _SCEditRoomSearchAdminPageState createState() =>
+ _SCEditRoomSearchAdminPageState();
+}
+
+class _SCEditRoomSearchAdminPageState extends State
+ with SingleTickerProviderStateMixin {
+ final TextEditingController _textEditingController = TextEditingController();
+ List rooms = [];
+ bool canEdit = false;
+
+ BusinessLogicStrategy get _strategy => SCGlobalConfig.businessLogicStrategy;
+
+ @override
+ void initState() {
+ super.initState();
+ }
+
+ @override
+ Widget build(BuildContext context) {
+ return Stack(
+ children: [
+ Image.asset(
+ _strategy.getAdminSearchBackgroundImage('roomSearch'),
+ width: ScreenUtil().screenWidth,
+ height: 150.w,
+ fit: BoxFit.fill,
+ ),
+ Scaffold(
+ backgroundColor: Colors.transparent,
+ resizeToAvoidBottomInset: false,
+ appBar: SocialChatStandardAppBar(
+ title: SCAppLocalizations.of(context)!.roomEditing,
+ actions: [],
+ ),
+ body: SafeArea(
+ top: false,
+ child: Container(
+ margin: EdgeInsetsDirectional.only(top: 15.w),
+ width: ScreenUtil().screenWidth,
+ height: ScreenUtil().screenHeight,
+ decoration: BoxDecoration(
+ color: Colors.white,
+ borderRadius: BorderRadiusDirectional.only(
+ topStart: Radius.circular(35.w),
+ ),
+ ),
+ child: Column(
+ children: [
+ SizedBox(height: 10.w),
+ Row(
+ children: [
+ SizedBox(width: 10.w),
+ Expanded(
+ child: searchWidget(
+ hint: SCAppLocalizations.of(context)!.enterTheRoomId,
+ controller: _textEditingController,
+ borderColor: _strategy.getAdminSearchInputBorderColor('roomSearch'),
+ textColor: _strategy.getAdminSearchInputTextColor('roomSearch'),
+ ),
+ ),
+ socialchatGradientButton(
+ text: SCAppLocalizations.of(context)!.search,
+ radius: 25,
+ textSize: 14.sp,
+ textColor: _strategy.getAdminSearchButtonTextColor('roomSearch'),
+ gradient: LinearGradient(
+ colors: _strategy.getAdminSearchButtonGradient('roomSearch'),
+ begin: Alignment.centerLeft,
+ end: Alignment.centerRight,
+ ),
+ onPress: () {
+ if (_textEditingController.text.isNotEmpty) {
+ _searchUser();
+ }
+ },
+ ),
+ SizedBox(width: 10.w),
+ ],
+ ),
+ SizedBox(height: 10.w),
+ rooms.isNotEmpty
+ ? Expanded(
+ child: ListView.separated(
+ itemBuilder: (context, i) => buildItem(rooms[i]),
+ itemCount: rooms.length,
+ padding: EdgeInsets.zero,
+ separatorBuilder:
+ (context, i) => Divider(
+ height: height(1),
+ color: SocialChatTheme.dividerColor,
+ indent: width(28), //25+50+10
+ endIndent: width(15),
+ ),
+ ),
+ )
+ : mainEmpty(),
+ ],
+ ),
+ ),
+ ),
+ ),
+ ],
+ );
+ }
+
+ Widget buildItem(SocialChatRoomRes data) {
+ return Container(
+ padding: EdgeInsets.symmetric(vertical: 8.w, horizontal: 5.w),
+ margin: EdgeInsets.symmetric(horizontal: 15.w),
+ decoration: BoxDecoration(
+ color: Colors.white,
+ border: Border.all(color: Colors.black12, width: 1.w),
+ borderRadius: BorderRadius.all(Radius.circular(12.w)),
+ ),
+ child: Row(
+ children: [
+ GestureDetector(
+ onTap: () {
+ SCRoomUtils.goRoom(data.id ?? "", context);
+ },
+ behavior: HitTestBehavior.opaque,
+ child: head(url: data.roomCover ?? "", width: 55.w),
+ ),
+ SizedBox(width: 2.w),
+ Expanded(
+ child: Column(
+ crossAxisAlignment: CrossAxisAlignment.start,
+ children: [
+ Row(
+ children: [
+ // richText(
+ // txt: data.userNickname ?? "",
+ // key: (widget as SearchUserList).text,
+ // highlight: SocialChatTheme.primaryColor,
+ // defaultColor: Colors.black,
+ // ),
+ Expanded(
+ child: text(
+ data.roomName ?? "",
+ fontSize: 15.sp,
+ textColor: Colors.black,
+ fontWeight: FontWeight.w600,
+ ),
+ ),
+ SizedBox(width: 5.w),
+ // dj(data.level.toString()),
+ ],
+ ),
+ Row(
+ children: [
+ text(
+ "ID:${data.roomAccount}",
+ fontSize: 12.sp,
+ textColor: Colors.black26,
+ fontWeight: FontWeight.w600,
+ ),
+ ],
+ ),
+ ],
+ ),
+ ),
+ canEdit
+ ? GestureDetector(
+ child: Container(
+ alignment: AlignmentDirectional.center,
+ width: 20.w,
+ height: 20.w,
+ child: Image.asset(
+ _strategy.getAdminSearchEditIcon('roomSearch'),
+ color: Colors.black,
+ ),
+ ),
+ onTap: () {
+ SCNavigatorUtils.push(
+ context,
+ "${SCMainRoute.editingUserRoomAdmin}?type=Room&profile=${Uri.encodeComponent(jsonEncode(data.toJson()))}",
+ );
+ },
+ )
+ : Container(),
+ SizedBox(width: 5.w),
+ ],
+ ),
+ );
+ }
+
+ void _searchUser() async {
+ try {
+ SCLoadingManager.show();
+ rooms.clear();
+ rooms = await SCChatRoomRepository().searchRoom(
+ _textEditingController.text,
+ );
+ var userIdentity = await SCAccountRepository().userIdentity(
+ userId: rooms.first.userId ?? "",
+ );
+ if (!(userIdentity.admin ?? false) &&
+ !(userIdentity.superAdmin ?? false)) {
+ canEdit = true;
+ }
+ SCLoadingManager.hide();
+ setState(() {});
+ } catch (e) {
+ SCLoadingManager.hide();
+ }
+ }
+}
diff --git a/lib/modules/admin/search/sc_edit_user_search_admin_page.dart b/lib/modules/admin/search/sc_edit_user_search_admin_page.dart
new file mode 100644
index 0000000..d8b14cc
--- /dev/null
+++ b/lib/modules/admin/search/sc_edit_user_search_admin_page.dart
@@ -0,0 +1,277 @@
+import 'dart:convert';
+
+import 'package:flutter/cupertino.dart';
+import 'package:flutter/material.dart';
+import 'package:flutter/services.dart';
+import 'package:flutter_screenutil/flutter_screenutil.dart';
+import 'package:yumi/shared/tools/sc_loading_manager.dart';
+import 'package:yumi/shared/data_sources/sources/repositories/sc_user_repository_impl.dart';
+
+import 'package:yumi/app_localizations.dart';
+import 'package:yumi/ui_kit/components/appbar/socialchat_appbar.dart';
+import 'package:yumi/ui_kit/components/sc_compontent.dart';
+import 'package:yumi/ui_kit/components/socialchat_gradient_button.dart';
+import 'package:yumi/ui_kit/components/text/sc_text.dart';
+import 'package:yumi/ui_kit/components/sc_tts.dart';
+import 'package:yumi/ui_kit/theme/socialchat_theme.dart';
+import 'package:yumi/app/constants/sc_screen.dart';
+import 'package:yumi/app/routes/sc_fluro_navigator.dart';
+import 'package:yumi/shared/data_sources/sources/local/user_manager.dart';
+import 'package:yumi/shared/business_logic/models/res/login_res.dart';
+import 'package:yumi/modules/index/main_route.dart';
+import 'package:yumi/app/constants/sc_global_config.dart';
+import 'package:yumi/app/config/business_logic_strategy.dart';
+
+class SCEditUserSearchAdminPage extends StatefulWidget {
+ @override
+ _SCEditUserSearchAdminPageState createState() =>
+ _SCEditUserSearchAdminPageState();
+}
+
+class _SCEditUserSearchAdminPageState extends State
+ with SingleTickerProviderStateMixin {
+ final TextEditingController _textEditingController = TextEditingController();
+ List users = [];
+
+ bool canEdit = false;
+
+ BusinessLogicStrategy get _strategy => SCGlobalConfig.businessLogicStrategy;
+
+ @override
+ void initState() {
+ super.initState();
+ }
+
+ @override
+ Widget build(BuildContext context) {
+ return Stack(
+ children: [
+ Image.asset(
+ _strategy.getAdminSearchBackgroundImage('userSearch'),
+ width: ScreenUtil().screenWidth,
+ height: 150.w,
+ fit: BoxFit.fill,
+ ),
+ Scaffold(
+ backgroundColor: Colors.transparent,
+ resizeToAvoidBottomInset: false,
+ appBar: SocialChatStandardAppBar(
+ title: SCAppLocalizations.of(context)!.userEditing,
+ actions: [],
+ ),
+ body: SafeArea(
+ top: false,
+ child: Container(
+ margin: EdgeInsetsDirectional.only(top: 15.w),
+ width: ScreenUtil().screenWidth,
+ height: ScreenUtil().screenHeight,
+ decoration: BoxDecoration(
+ color: Colors.white,
+ borderRadius: BorderRadiusDirectional.only(
+ topStart: Radius.circular(35.w),
+ ),
+ ),
+ child: Column(
+ children: [
+ SizedBox(height: 10.w),
+ Row(
+ children: [
+ SizedBox(width: 10.w),
+ Expanded(
+ child: searchWidget(
+ hint: SCAppLocalizations.of(context)!.enterTheUserId,
+ controller: _textEditingController,
+ borderColor: _strategy.getAdminSearchInputBorderColor('userSearch'),
+ textColor: _strategy.getAdminSearchInputTextColor('userSearch'),
+ ),
+ ),
+ socialchatGradientButton(
+ text: SCAppLocalizations.of(context)!.search,
+ radius: 25,
+ textSize: 14.sp,
+ textColor: _strategy.getAdminSearchButtonTextColor('userSearch'),
+ gradient: LinearGradient(
+ colors: _strategy.getAdminSearchButtonGradient('userSearch'),
+ begin: Alignment.centerLeft,
+ end: Alignment.centerRight,
+ ),
+ onPress: () {
+ if (_textEditingController.text.isNotEmpty) {
+ _searchUser();
+ }
+ },
+ ),
+ SizedBox(width: 10.w),
+ ],
+ ),
+ SizedBox(height: 10.w),
+ users.isNotEmpty
+ ? Expanded(
+ child: ListView.separated(
+ itemBuilder: (context, i) => buildItem(users[i]),
+ itemCount: users.length,
+ padding: EdgeInsets.zero,
+ separatorBuilder:
+ (context, i) => Divider(
+ height: height(1),
+ color: SocialChatTheme.dividerColor,
+ indent: width(28), //25+50+10
+ endIndent: width(15),
+ ),
+ ),
+ )
+ : mainEmpty(),
+ ],
+ ),
+ ),
+ ),
+ ),
+ ],
+ );
+ }
+
+ Widget buildItem(SocialChatUserProfile data) {
+ return Container(
+ padding: EdgeInsets.symmetric(vertical: 8.w, horizontal: 5.w),
+ margin: EdgeInsets.symmetric(horizontal: 15.w),
+ decoration: BoxDecoration(
+ color: Colors.white,
+ border: Border.all(color: Colors.black12, width: 1.w),
+ borderRadius: BorderRadius.all(Radius.circular(12.w)),
+ ),
+ child: Row(
+ children: [
+ GestureDetector(
+ onTap: () {
+ SCNavigatorUtils.push(
+ context,
+ "${SCMainRoute.person}?isMe=${AccountStorage().getCurrentUser()?.userProfile?.id == data.id}&tageId=${data.id}",
+ );
+ },
+ behavior: HitTestBehavior.opaque,
+ child: head(url: data.userAvatar ?? "", width: 55.w),
+ ),
+ SizedBox(width: 2.w),
+ Expanded(
+ child: Column(
+ crossAxisAlignment: CrossAxisAlignment.start,
+ children: [
+ Row(
+ children: [
+ xb(
+ data.userSex,
+ color:
+ data.userSex == 1 ? Colors.blue : Colors.purpleAccent,
+ ),
+ SizedBox(width: 5.w),
+ // richText(
+ // txt: data.userNickname ?? "",
+ // key: (widget as SearchUserList).text,
+ // highlight: SocialChatTheme.primaryColor,
+ // defaultColor: Colors.black,
+ // ),
+ Expanded(
+ child: text(
+ data.userNickname ?? "",
+ fontSize: 15.sp,
+ textColor: Colors.black,
+ ),
+ ),
+ SizedBox(width: 5.w),
+ // dj(data.level.toString()),
+ ],
+ ),
+ Row(
+ children: [
+ GestureDetector(
+ child: Container(
+ padding: EdgeInsets.symmetric(vertical: 8.w),
+ decoration: BoxDecoration(
+ image: DecorationImage(
+ image: AssetImage(
+ (data.hasSpecialId() ?? false)
+ ? _strategy.getAdminSearchUserInfoIcon('specialIdBg')
+ : _strategy.getAdminSearchUserInfoIcon('normalIdBg'),
+ ),
+ fit: BoxFit.fitWidth,
+ ),
+ ),
+ child: Row(
+ textDirection: TextDirection.ltr,
+ children: [
+ SizedBox(width: 38.w),
+ text(
+ data.getID(),
+ fontSize: 12.sp,
+ textColor: Colors.white,
+ fontWeight: FontWeight.bold,
+ ),
+ SizedBox(width: 5.w),
+ Image.asset(
+ _strategy.getAdminSearchUserInfoIcon('copyId'),
+ width: 12.w,
+ height: 12.w,
+ ),
+ SizedBox(width: 8.w),
+ ],
+ ),
+ ),
+ onTap: () {
+ Clipboard.setData(ClipboardData(text: data.getID()));
+ SCTts.show(
+ SCAppLocalizations.of(context)!.copiedToClipboard,
+ );
+ },
+ ),
+ ],
+ ),
+ ],
+ ),
+ ),
+ canEdit
+ ? GestureDetector(
+ child: Container(
+ alignment: AlignmentDirectional.center,
+ width: 20.w,
+ height: 20.w,
+ child: Image.asset(
+ _strategy.getAdminSearchEditIcon('userSearch'),
+ color: Colors.black,
+ ),
+ ),
+ onTap: () {
+ SCNavigatorUtils.push(
+ context,
+ "${SCMainRoute.editingUserRoomAdmin}?type=User&profile=${Uri.encodeComponent(jsonEncode(data.toJson()))}",
+ );
+ },
+ )
+ : Container(),
+ SizedBox(width: 5.w),
+ ],
+ ),
+ );
+ }
+
+ void _searchUser() async {
+ try {
+ SCLoadingManager.show();
+ users.clear();
+ var result = await SCAccountRepository().searchUser(
+ _textEditingController.text,
+ );
+ var userIdentity = await SCAccountRepository().userIdentity(
+ userId: result.id,
+ );
+ if (!(userIdentity.admin ?? false) &&
+ !(userIdentity.superAdmin ?? false)) {
+ canEdit = true;
+ }
+ users.add(result);
+ SCLoadingManager.hide();
+ setState(() {});
+ } catch (e) {
+ SCLoadingManager.hide();
+ }
+ }
+}
diff --git a/lib/modules/auth/account/sc_login_with_account_page.dart b/lib/modules/auth/account/sc_login_with_account_page.dart
new file mode 100644
index 0000000..dc0f1f2
--- /dev/null
+++ b/lib/modules/auth/account/sc_login_with_account_page.dart
@@ -0,0 +1,371 @@
+import 'package:flutter/material.dart';
+import 'package:flutter/services.dart';
+import 'package:flutter_screenutil/flutter_screenutil.dart';
+import 'package:yumi/app_localizations.dart';
+import 'package:yumi/ui_kit/components/sc_debounce_widget.dart';
+import 'package:yumi/ui_kit/components/text/sc_text.dart';
+import 'package:yumi/shared/data_sources/sources/local/data_persistence.dart';
+import 'package:yumi/shared/data_sources/sources/local/user_manager.dart';
+import 'package:yumi/ui_kit/components/sc_tts.dart';
+import 'package:yumi/app/constants/sc_screen.dart';
+import 'package:yumi/app/constants/sc_global_config.dart';
+import 'package:yumi/app/config/business_logic_strategy.dart';
+import 'package:yumi/app/routes/sc_routes.dart';
+import 'package:yumi/app/routes/sc_fluro_navigator.dart';
+import 'package:yumi/shared/tools/sc_loading_manager.dart';
+import 'package:yumi/shared/tools/sc_version_utils.dart';
+import 'package:yumi/shared/data_sources/sources/repositories/sc_user_repository_impl.dart';
+import 'package:yumi/shared/business_logic/models/res/login_res.dart';
+
+///密码账户登录
+class SCLoginWithAccountPage extends StatefulWidget {
+ const SCLoginWithAccountPage({super.key});
+
+ @override
+ SCLoginWithAccountPageState createState() => SCLoginWithAccountPageState();
+}
+
+class SCLoginWithAccountPageState extends State
+ with WidgetsBindingObserver {
+ ///显示密码
+ bool showPass = false;
+ String account = "";
+
+ ///账户控制器
+ TextEditingController accountController = TextEditingController();
+
+ ///密码控制器
+ TextEditingController passController = TextEditingController();
+
+ @override
+ void initState() {
+ super.initState();
+ String account = DataPersistence.getString(
+ "Login_Account",
+ defaultValue: "",
+ );
+ String pwd = DataPersistence.getString("Login_Pwd", defaultValue: "");
+ accountController.text = account;
+ passController.text = pwd;
+ }
+
+ @override
+ Widget build(BuildContext context) {
+ final businessLogicStrategy = SCGlobalConfig.businessLogicStrategy;
+ final pagePadding = businessLogicStrategy.getLoginPagePadding();
+
+ return Scaffold(
+ resizeToAvoidBottomInset: false,
+ body: GestureDetector(
+ onTap: () {
+ FocusScope.of(context).unfocus();
+ },
+ child: Stack(
+ alignment: Alignment.topCenter,
+ children: [
+ Image.asset(
+ businessLogicStrategy.getLoginBackgroundImage(),
+ width: ScreenUtil().screenWidth,
+ height: ScreenUtil().screenHeight,
+ fit: BoxFit.cover,
+ ),
+
+ SingleChildScrollView(
+ // 添加滚动视图
+ padding: EdgeInsets.only(
+ bottom:
+ MediaQuery.of(context).viewInsets.bottom + 20, // 添加底部内边距
+ ),
+ child: Column(
+ children: [
+ SizedBox(height: pagePadding.top),
+ Image.asset(
+ businessLogicStrategy.getLoginAppIcon(),
+ width: 107.w,
+ height: 159.w,
+ ),
+ SizedBox(height: 35.w),
+ Container(
+ margin: EdgeInsetsDirectional.only(start: 65.w),
+ alignment: AlignmentDirectional.centerStart,
+ child: text(
+ SCAppLocalizations.of(context)!.account,
+ fontSize: 16.sp,
+ textColor: businessLogicStrategy.getLoginLabelTextColor(),
+ fontWeight: FontWeight.bold,
+ ),
+ ),
+ SizedBox(height: 10.w),
+ _buildAccountInput(businessLogicStrategy),
+ SizedBox(height: 10.w),
+ Container(
+ margin: EdgeInsetsDirectional.only(start: 65.w),
+ alignment: AlignmentDirectional.centerStart,
+ child: text(
+ SCAppLocalizations.of(context)!.password,
+ fontSize: 16.sp,
+ textColor: businessLogicStrategy.getLoginLabelTextColor(),
+ fontWeight: FontWeight.bold,
+ ),
+ ),
+ SizedBox(height: 10.w),
+ _buildPassInput(businessLogicStrategy),
+ SizedBox(height: 80.w),
+ _buildLoginBtn(businessLogicStrategy),
+ ],
+ ),
+ ),
+ ],
+ ),
+ ),
+ );
+ }
+
+ ///登录按钮
+ Widget _buildLoginBtn(BusinessLogicStrategy strategy) {
+ final buttonColor = strategy.getLoginButtonColor();
+ final buttonGradient = strategy.getLoginButtonGradient();
+
+ BoxDecoration buttonDecoration;
+ if (buttonGradient != null && buttonGradient.isNotEmpty) {
+ // 使用渐变
+ buttonDecoration = BoxDecoration(
+ gradient: LinearGradient(
+ colors: buttonGradient,
+ begin: Alignment.centerRight,
+ end: Alignment.centerLeft,
+ ),
+ border: Border.all(color: Color(0xff077142), width: 1.w),
+ borderRadius: BorderRadius.circular(12), // 马甲包设计使用70px圆角
+ );
+ } else {
+ // 使用纯色
+ buttonDecoration = BoxDecoration(
+ color: buttonColor,
+ borderRadius: BorderRadius.all(Radius.circular(height(8))), // 原始应用8px圆角
+ );
+ }
+
+ return Row(
+ children: [
+ Expanded(
+ child: SCDebounceWidget(
+ child: Container(
+ alignment: Alignment.center,
+ margin: EdgeInsets.symmetric(horizontal: 60.w),
+ height: 42.w,
+ decoration: buttonDecoration,
+ child: text(
+ SCAppLocalizations.of(context)!.logIn,
+ textColor: strategy.getLoginButtonTextColor(),
+ fontSize: 16.sp,
+ fontWeight: FontWeight.w600,
+ ),
+ ),
+ onTap: () {
+ _login();
+ },
+ ),
+ ),
+ ],
+ );
+ }
+
+ ///账户输入框
+ Widget _buildAccountInput(BusinessLogicStrategy strategy) {
+ return Row(
+ children: [
+ Expanded(
+ child: Container(
+ margin: EdgeInsets.symmetric(horizontal: 60.w),
+ padding: EdgeInsetsDirectional.only(
+ start: width(12),
+ end: width(12),
+ ),
+ alignment: AlignmentDirectional.centerStart,
+ height: 45.w,
+ width: ScreenUtil().screenWidth,
+ decoration: strategy.getLoginInputDecoration(),
+ child: TextField(
+ controller: accountController,
+ onChanged: (text) {
+ setState(() {
+ account = text;
+ });
+ },
+ maxLength: 30,
+ keyboardType: TextInputType.number,
+ inputFormatters: [
+ FilteringTextInputFormatter.allow(RegExp("[0-9]")),
+ ],
+ decoration: InputDecoration(
+ isDense: true,
+ filled: false,
+ focusColor: Colors.transparent,
+ hoverColor: Colors.transparent,
+ hintText: SCAppLocalizations.of(context)!.enterAccount,
+ hintStyle: TextStyle(
+ color: strategy.getLoginHintTextColor(),
+ fontSize: 14.sp,
+ fontWeight: FontWeight.w600,
+ ),
+ contentPadding: EdgeInsets.only(top: 0.w),
+ counterText: '',
+ border: InputBorder.none,
+ enabledBorder: InputBorder.none,
+ focusedBorder: InputBorder.none,
+ disabledBorder: InputBorder.none,
+ errorBorder: InputBorder.none,
+ focusedErrorBorder: InputBorder.none,
+ // enabledBorder: UnderlineInputBorder(
+ // borderSide: BorderSide(width: 0.5,color: Colors.white,style: BorderStyle.solid),),
+ // focusedBorder: UnderlineInputBorder(
+ // borderSide: BorderSide(width: 0.5,color: Colors.white,style: BorderStyle.solid),),
+ // prefixIcon: Padding(padding: EdgeInsets.all(8.w), child: Image.asset("images/login/sc_icon_phone.png",width: 20.w, height: 20.w,fit: BoxFit.fill,),),
+ suffix: _buildPhoneCancel(),
+ ),
+ style: TextStyle(
+ fontSize: 14.sp,
+ color: strategy.getLoginInputTextColor(),
+ fontWeight: FontWeight.w600,
+ textBaseline: TextBaseline.alphabetic,
+ ),
+ ),
+ ),
+ ),
+ ],
+ );
+ }
+
+ _buildPhoneCancel() {
+ return Offstage(
+ offstage: accountController.text == "",
+ child: GestureDetector(
+ onTap: () {
+ setState(() {
+ accountController.text = '';
+ });
+ },
+ child: Padding(
+ padding: const EdgeInsets.symmetric(horizontal: 8),
+ child: Image.asset("sc_images/login/sc_icon_sc.png", width: 15.w,color: Colors.white,),
+ ),
+ ),
+ );
+ }
+
+ ///密码输入框
+ Widget _buildPassInput(BusinessLogicStrategy strategy) {
+ return Row(
+ children: [
+ Expanded(
+ child: Container(
+ margin: EdgeInsets.symmetric(horizontal: 60.w),
+ padding: REdgeInsetsDirectional.only(
+ start: width(12),
+ end: width(12),
+ ),
+ alignment: AlignmentDirectional.centerStart,
+ height: 45.w,
+ width: ScreenUtil().screenWidth,
+ decoration: strategy.getLoginInputDecoration(),
+ child: TextField(
+ controller: passController,
+ maxLength: 30,
+ maxLines: 1,
+ inputFormatters: [
+ FilteringTextInputFormatter.deny("[\u4e00-\u9fa5]"),
+ ],
+
+ obscureText: !showPass,
+ textInputAction: TextInputAction.done,
+ onChanged: (s) {
+ setState(() {});
+ },
+ decoration: InputDecoration(
+ isDense: true,
+ filled: false,
+ focusColor: Colors.transparent,
+ hoverColor: Colors.transparent,
+ hintText: SCAppLocalizations.of(context)!.enterPassword,
+ hintStyle: TextStyle(
+ color: strategy.getLoginHintTextColor(),
+ fontSize: 14.sp,
+ fontWeight: FontWeight.w600,
+ ),
+ counterText: '',
+ contentPadding: EdgeInsets.only(top: 0.w),
+ border: InputBorder.none,
+ enabledBorder: InputBorder.none,
+ focusedBorder: InputBorder.none,
+ disabledBorder: InputBorder.none,
+ errorBorder: InputBorder.none,
+ focusedErrorBorder: InputBorder.none,
+ // enabledBorder: UnderlineInputBorder(
+ // borderSide: BorderSide(width: 0.5,color: Colors.white,style: BorderStyle.solid),),
+ // focusedBorder: UnderlineInputBorder(
+ // borderSide: BorderSide(width: 0.5,color: Colors.white,style: BorderStyle.solid),),
+ // prefixIcon: Padding(padding: EdgeInsets.all(8.w), child: Image.asset("images/login/sc_icon_pwd.png",width: 20.w, height: 20.w,fit: BoxFit.fill,),),
+ suffix: GestureDetector(
+ behavior: HitTestBehavior.opaque,
+ onTap: () {
+ setState(() {
+ showPass = !showPass;
+ });
+ },
+ child: Padding(
+ padding: const EdgeInsets.symmetric(horizontal: 8),
+ child: Image.asset(
+ !showPass
+ ? "sc_images/login/sc_icon_pass.png"
+ : "sc_images/login/sc_icon_pass1.png",
+ gaplessPlayback: true,
+ color: Colors.white,
+ width: 15.w,
+ ),
+ ),
+ ),
+ ),
+ style: TextStyle(
+ fontSize: 14.sp,
+ color: strategy.getLoginInputTextColor(),
+ fontWeight: FontWeight.w600,
+ ),
+ ),
+ ),
+ ),
+ ],
+ );
+ }
+
+ ///登录
+ _login() async {
+ String account = accountController.text;
+ String pass = passController.text;
+ if (account.isEmpty || pass.isEmpty) {
+ SCTts.show(
+ SCAppLocalizations.of(context)!.theAccountPasswordCannotBeEmpty,
+ );
+ return;
+ }
+ SCLoadingManager.show(context: context);
+ try {
+ final results = await Future.wait([
+ SCAccountRepository().loginForAccount(account, pass),
+ SCVersionUtils.checkReview(),
+ ]);
+ var user = (results[0] as SocialChatLoginRes);
+ AccountStorage().setCurrentUser(user);
+ SCLoadingManager.hide();
+ DataPersistence.setString("Login_Account", account);
+ DataPersistence.setString("Login_Pwd", pass);
+ if (mounted) {
+ SCNavigatorUtils.push(context, SCRoutes.home, clearStack: true);
+ }
+ } catch (e) {
+ SCLoadingManager.hide();
+ // 可以添加错误处理逻辑
+ rethrow;
+ }
+ }
+}
diff --git a/lib/modules/auth/edit/sc_edit_profile_page.dart b/lib/modules/auth/edit/sc_edit_profile_page.dart
new file mode 100644
index 0000000..1c05ee2
--- /dev/null
+++ b/lib/modules/auth/edit/sc_edit_profile_page.dart
@@ -0,0 +1,549 @@
+import 'package:flutter/cupertino.dart';
+import 'package:flutter/material.dart';
+import 'package:flutter/services.dart';
+import 'package:flutter_screenutil/flutter_screenutil.dart';
+import 'package:flutter_smart_dialog/flutter_smart_dialog.dart';
+import 'package:yumi/app_localizations.dart';
+import 'package:yumi/ui_kit/components/sc_compontent.dart';
+import 'package:yumi/ui_kit/components/text/sc_text.dart';
+import 'package:yumi/ui_kit/components/sc_tts.dart';
+import 'package:yumi/shared/tools/sc_loading_manager.dart';
+import 'package:yumi/shared/tools/sc_pick_utils.dart';
+import 'package:yumi/shared/data_sources/sources/repositories/sc_user_repository_impl.dart';
+import 'package:yumi/services/auth/authentication_manager.dart';
+import 'package:provider/provider.dart';
+import 'package:yumi/ui_kit/components/custom_cached_image.dart';
+import 'package:yumi/app/constants/sc_screen.dart';
+import 'package:yumi/app/routes/sc_routes.dart';
+import 'package:yumi/app/routes/sc_fluro_navigator.dart';
+import 'package:yumi/shared/tools/sc_date_utils.dart';
+import 'package:yumi/shared/data_sources/sources/local/user_manager.dart';
+import 'package:yumi/shared/business_logic/models/res/login_res.dart';
+import 'package:yumi/services/general/sc_app_general_manager.dart';
+import 'package:yumi/services/auth/user_profile_manager.dart';
+import 'package:yumi/app/constants/sc_global_config.dart';
+
+import '../../../shared/business_logic/usecases/sc_custom_filtering_textinput_formatter.dart';
+import '../../country/country_page.dart';
+import '../../country/country_route.dart';
+
+///编辑个人信息
+class SCEditProfilePage extends StatefulWidget {
+ const SCEditProfilePage({super.key});
+
+ @override
+ _SCEditProfilePageState createState() => _SCEditProfilePageState();
+}
+
+class _SCEditProfilePageState extends State {
+ ///默认女
+ int type = 0;
+ DateTime birthdayDate = DateTime(2006);
+ TextEditingController nicknameController = TextEditingController();
+ SocialChatUserProfileManager? userProvider;
+
+ @override
+ void initState() {
+ super.initState();
+ userProvider = Provider.of(
+ context,
+ listen: false,
+ );
+ Provider.of(context, listen: false).selectCountryInfo =
+ null;
+ }
+
+ @override
+ void dispose() {
+ userProvider?.resetEditUserData();
+ super.dispose();
+ }
+
+ @override
+ Widget build(BuildContext context) {
+ final businessLogicStrategy = SCGlobalConfig.businessLogicStrategy;
+ return Scaffold(
+ resizeToAvoidBottomInset: false,
+ body: Stack(
+ alignment: Alignment.topCenter,
+ children: [
+ Image.asset(
+ businessLogicStrategy.getEditProfileBackgroundImage(),
+ width: ScreenUtil().screenWidth,
+ height: ScreenUtil().screenHeight,
+ fit: BoxFit.cover,
+ ),
+ Column(
+ children: [
+ SizedBox(height: 120.w),
+ GestureDetector(
+ child: Consumer(
+ builder: (_, provider, __) {
+ return provider.editUser != null &&
+ provider.editUser!.userAvatar != null
+ ? head(
+ url: provider.editUser!.userAvatar ?? "",
+ width: 75.w,
+ )
+ : Image.asset(
+ businessLogicStrategy
+ .getEditProfileDefaultAvatarImage(),
+ width: 75.w,
+ height: 75.w,
+ );
+ },
+ ),
+ onTap: () {
+ SCPickUtils.pickImage(context, (bool success, String url) {
+ if (success) {
+ userProvider?.updateUserAvatar(url);
+ }
+ });
+ },
+ ),
+ SizedBox(height: 15.w),
+ Container(
+ padding: EdgeInsets.only(left: width(12), right: width(12)),
+ alignment: Alignment.center,
+ height: 46.w,
+ width: 300.w,
+ decoration: BoxDecoration(
+ color:
+ businessLogicStrategy
+ .getEditProfileInputBackgroundColor(),
+ borderRadius: BorderRadius.all(Radius.circular(height(8))),
+ ),
+ child: TextField(
+ textAlign: TextAlign.center,
+ controller: nicknameController,
+ onChanged: (text) {
+ setState(() {});
+ },
+ inputFormatters: [SCCustomFilteringTextInputFormatter()],
+ maxLength: 38,
+ decoration: InputDecoration(
+ hintText: SCAppLocalizations.of(context)!.enterNickname,
+ hintStyle: TextStyle(color: Colors.white, fontSize: 14.sp),
+ contentPadding: EdgeInsets.only(top: 0.w),
+ counterText: '',
+ isDense: true,
+ filled: false,
+ focusColor: Colors.transparent,
+ hoverColor: Colors.transparent,
+ border: InputBorder.none,
+ enabledBorder: InputBorder.none,
+ focusedBorder: InputBorder.none,
+ disabledBorder: InputBorder.none,
+ errorBorder: InputBorder.none,
+ focusedErrorBorder: InputBorder.none,
+ fillColor: Colors.black45,
+ ),
+ style: TextStyle(
+ fontSize: sp(15),
+ color: Colors.white,
+ textBaseline: TextBaseline.alphabetic,
+ ),
+ ),
+ ),
+ SizedBox(height: 15.w),
+ Row(
+ mainAxisAlignment: MainAxisAlignment.center,
+ children: [
+ GestureDetector(
+ child: Container(
+ alignment: Alignment.center,
+ child: Column(
+ mainAxisSize: MainAxisSize.min,
+ children: [
+ Container(
+ decoration: BoxDecoration(
+ shape: BoxShape.circle,
+ border: Border.all(
+ width: 2.w,
+ color:
+ type == 1
+ ? Color(0xff18F2B1)
+ : Colors.transparent,
+ ),
+ ),
+ child: Image.asset(
+ businessLogicStrategy.getEditProfileGenderIcon(
+ true,
+ ),
+ width: 55.w,
+ height: 55.w,
+ ),
+ ),
+ SizedBox(height: 8.w),
+ text(
+ SCAppLocalizations.of(context)!.male,
+ textColor: type == 1 ? Colors.white : Colors.white,
+ fontWeight:
+ type == 1 ? FontWeight.w600 : FontWeight.w400,
+ fontSize: 13.sp,
+ ),
+ ],
+ ),
+ ),
+ onTap: () {
+ if (type == 0) {
+ setState(() {
+ type = 1;
+ userProvider?.updateUserSex(type);
+ });
+ }
+ },
+ ),
+ SizedBox(width: 99.w),
+ GestureDetector(
+ child: Container(
+ alignment: Alignment.center,
+ child: Column(
+ mainAxisSize: MainAxisSize.min,
+ children: [
+ Container(
+ decoration: BoxDecoration(
+ shape: BoxShape.circle,
+ border: Border.all(
+ width: 2.w,
+ color:
+ type == 1
+ ? Colors.transparent
+ : Color(0xff18F2B1),
+ ),
+ ),
+ child: Image.asset(
+ businessLogicStrategy.getEditProfileGenderIcon(
+ false,
+ ),
+ width: 55.w,
+ height: 55.w,
+ ),
+ ),
+ SizedBox(height: 8.w),
+ text(
+ SCAppLocalizations.of(context)!.female,
+ textColor: type == 1 ? Colors.white : Colors.white,
+ fontWeight:
+ type == 1 ? FontWeight.w400 : FontWeight.w600,
+ fontSize: 13.sp,
+ ),
+ ],
+ ),
+ ),
+ onTap: () {
+ if (type == 1) {
+ setState(() {
+ type = 0;
+ userProvider?.updateUserSex(type);
+ });
+ }
+ },
+ ),
+ ],
+ ),
+ SizedBox(height: 12.w),
+ GestureDetector(
+ child: Container(
+ padding: EdgeInsets.only(left: width(12), right: width(12)),
+ alignment: Alignment.center,
+ height: 46.w,
+ width: 300.w,
+ decoration: BoxDecoration(
+ color:
+ businessLogicStrategy
+ .getEditProfileInputBackgroundColor(),
+ borderRadius: BorderRadius.all(Radius.circular(height(12))),
+ ),
+ child: Row(
+ children: [
+ text(
+ SCAppLocalizations.of(context)!.birthday,
+ fontSize: 15.sp,
+ textColor: Colors.white,
+ ),
+ Spacer(),
+ text(
+ SCMDateUtils.formatDateTime(birthdayDate),
+ textColor: Colors.white54,
+ fontSize: 15.sp,
+ ),
+ Icon(
+ Icons.chevron_right_outlined,
+ color: Colors.white54,
+ size: 20.w,
+ ),
+ ],
+ ),
+ ),
+ onTap: () {
+ _selectDate();
+ },
+ ),
+ SizedBox(height: 12.w),
+ GestureDetector(
+ child: Consumer(
+ builder: (_, provider, __) {
+ return Container(
+ padding: EdgeInsets.only(
+ left: width(12),
+ right: width(12),
+ ),
+ alignment: Alignment.center,
+ height: 46.w,
+ width: 300.w,
+ decoration: BoxDecoration(
+ color:
+ businessLogicStrategy
+ .getEditProfileInputBackgroundColor(),
+ borderRadius: BorderRadius.all(
+ Radius.circular(height(12)),
+ ),
+ ),
+ child:
+ provider.selectCountryInfo != null
+ ? Row(
+ mainAxisSize: MainAxisSize.min,
+ children: [
+ text(
+ SCAppLocalizations.of(
+ context,
+ )!.countryRegion,
+ fontSize: 15.sp,
+ textColor: Colors.white,
+ ),
+ Spacer(),
+
+ netImage(
+ url:
+ provider
+ .selectCountryInfo!
+ .nationalFlag ??
+ "",
+ borderRadius: BorderRadius.circular(3),
+ width: 26.w,
+ height: 16.w,
+ ),
+ SizedBox(width: 3.w),
+ text(
+ provider.selectCountryInfo!.aliasName ?? "",
+ textColor: Colors.white54,
+ fontSize: 14.sp,
+ ),
+ Icon(
+ Icons.chevron_right_outlined,
+ color: Colors.white54,
+ size: 20.w,
+ ),
+ ],
+ )
+ : Row(
+ children: [
+ text(
+ SCAppLocalizations.of(
+ context,
+ )!.countryRegion,
+ fontSize: 15.sp,
+ textColor: Colors.white,
+ ),
+ Spacer(),
+ text(
+ SCAppLocalizations.of(
+ context,
+ )!.selectYourCountry,
+ textColor: Colors.white54,
+ fontSize: 15.sp,
+ ),
+ Icon(
+ Icons.chevron_right_outlined,
+ color: Colors.white54,
+ size: 20.w,
+ ),
+ ],
+ ),
+ );
+ },
+ ),
+ onTap: () {
+ SCNavigatorUtils.push(
+ context,
+ CountryRoute.country,
+ replace: false,
+ );
+ },
+ ),
+ SizedBox(height: 45.w),
+ GestureDetector(
+ child: Container(
+ padding: EdgeInsets.only(left: width(12), right: width(12)),
+ alignment: Alignment.center,
+ height: 46.w,
+ width: 270.w,
+ decoration: BoxDecoration(
+ color:
+ businessLogicStrategy
+ .getEditProfileContinueButtonColor(),
+ borderRadius: BorderRadius.all(Radius.circular(height(12))),
+ ),
+ child: text(
+ SCAppLocalizations.of(context)!.conntinue,
+ textColor: Colors.white,
+ fontSize: 15.sp,
+ ),
+ ),
+ onTap: () {
+ _submitUserProfile();
+ },
+ ),
+ ],
+ ),
+ ],
+ ),
+ );
+ }
+
+ Future _selectDate() async {
+ showCupertinoModalPopup(
+ context: context,
+ builder:
+ (context) => SafeArea(
+ top: false,
+ child: Container(
+ height: 240.w,
+ padding: EdgeInsets.only(top: 6),
+ decoration: BoxDecoration(
+ image: DecorationImage(
+ image: AssetImage(
+ "sc_images/login/sc_icon_login_edit_data_bg.png",
+ ),
+ fit: BoxFit.fill,
+ ),
+ ),
+ child: Column(
+ children: [
+ SizedBox(height: 10.w),
+ Row(
+ children: [
+ SizedBox(width: 10.w),
+ GestureDetector(
+ child: Container(
+ alignment: Alignment.topCenter,
+ child: text(
+ SCAppLocalizations.of(context)!.cancel,
+ textColor: Colors.white,
+ fontSize: 15.sp,
+ fontWeight: FontWeight.w600,
+ ),
+ ),
+ onTap: () {
+ Navigator.of(context).pop();
+ },
+ ),
+ Spacer(),
+ GestureDetector(
+ child: Container(
+ alignment: Alignment.topCenter,
+ child: text(
+ SCAppLocalizations.of(context)!.confirm,
+ textColor:
+ SCGlobalConfig.businessLogicStrategy
+ .getEditProfileDatePickerConfirmColor(),
+ fontSize: 15.sp,
+ fontWeight: FontWeight.w600,
+ ),
+ ),
+ onTap: () {
+ setState(() {});
+ Navigator.of(context).pop();
+ },
+ ),
+ SizedBox(width: 10.w),
+ ],
+ ),
+ Expanded(
+ child: CupertinoTheme(
+ data: CupertinoThemeData(
+ textTheme: CupertinoTextThemeData(
+ // 在这里设置字体颜色、大小等样式
+ dateTimePickerTextStyle: TextStyle(
+ color: Colors.white, // 设置字体颜色
+ fontSize: 16.sp, // 设置字体大小
+ ),
+ ),
+ ),
+ child: CupertinoDatePicker(
+ mode: CupertinoDatePickerMode.date,
+ initialDateTime: _getBefor18(),
+ maximumDate: _getBefor18(),
+ onDateTimeChanged: (date) => birthdayDate = date,
+ ),
+ ),
+ ),
+ ],
+ ),
+ ),
+ ),
+ );
+ }
+
+ DateTime _getBefor18() {
+ DateTime currentDate = DateTime.now();
+ DateTime eighteenYearsAgo = DateTime(
+ currentDate.year - 18,
+ currentDate.month,
+ currentDate.day,
+ currentDate.hour,
+ currentDate.minute,
+ currentDate.second,
+ currentDate.millisecond,
+ currentDate.microsecond,
+ );
+ return eighteenYearsAgo;
+ }
+
+ ///提交数据
+ void _submitUserProfile() async {
+ if (nicknameController.text.isEmpty) {
+ SCTts.show(SCAppLocalizations.of(context)!.pleaseEnterNickname);
+ return;
+ }
+ if (userProvider?.editUser?.userAvatar == null) {
+ SCTts.show(SCAppLocalizations.of(context)!.pleaseUploadUserAvatar);
+ return;
+ }
+ if (Provider.of(
+ context,
+ listen: false,
+ ).selectCountryInfo ==
+ null) {
+ SCTts.show(SCAppLocalizations.of(context)!.pleaseSelectYourCountry);
+ return;
+ }
+
+ SCLoadingManager.show(context: context);
+ userProvider?.updateUserNickname(nicknameController.text);
+ userProvider?.updateBornYear(birthdayDate.year);
+ userProvider?.updateBornMonth(birthdayDate.month);
+ userProvider?.updateBornDay(birthdayDate.day);
+ num age = DateTime.now().year - birthdayDate.year;
+ userProvider?.updateAge(age.abs());
+ String authType =
+ Provider.of(
+ context,
+ listen: false,
+ ).authType;
+ String idToken =
+ Provider.of(
+ context,
+ listen: false,
+ ).uid;
+ SocialChatLoginRes user = await SCAccountRepository().regist(
+ authType,
+ idToken,
+ userProvider!.editUser!,
+ );
+ AccountStorage().setCurrentUser(user);
+ SCLoadingManager.hide();
+ SCNavigatorUtils.push(context, SCRoutes.home, clearStack: true);
+ }
+}
diff --git a/lib/modules/auth/login_page.dart b/lib/modules/auth/login_page.dart
new file mode 100644
index 0000000..6d71362
--- /dev/null
+++ b/lib/modules/auth/login_page.dart
@@ -0,0 +1,435 @@
+import 'dart:io';
+
+import 'package:flutter/gestures.dart';
+import 'package:flutter/material.dart';
+import 'package:flutter_screenutil/flutter_screenutil.dart';
+import 'package:flutter_smart_dialog/flutter_smart_dialog.dart';
+import 'package:yumi/ui_kit/components/sc_debounce_widget.dart';
+import 'package:provider/provider.dart';
+
+import 'package:yumi/app_localizations.dart';
+import 'package:yumi/ui_kit/components/dialog/dialog_base.dart';
+import 'package:yumi/ui_kit/components/text/sc_text.dart';
+import 'package:yumi/app/constants/sc_global_config.dart';
+import 'package:yumi/app/constants/sc_screen.dart';
+import 'package:yumi/app/routes/sc_fluro_navigator.dart';
+import 'package:yumi/services/auth/authentication_manager.dart';
+import 'package:yumi/ui_kit/widgets/pop/pop_route.dart';
+import 'package:yumi/modules/webview/webview_page.dart';
+import 'package:yumi/modules/auth/login_route.dart';
+
+import '../../shared/data_sources/models/enum/sc_auth_type.dart';
+
+/// 登录
+class LoginPage extends StatefulWidget {
+ const LoginPage({super.key});
+
+ @override
+ LoginPageState createState() => LoginPageState();
+}
+
+class LoginPageState extends State with WidgetsBindingObserver {
+ bool isAgreement = false;
+ SocialChatAuthenticationManager? authProvider;
+
+ @override
+ void initState() {
+ super.initState();
+ WidgetsBinding.instance.addObserver(this);
+ authProvider = Provider.of(
+ context,
+ listen: false,
+ );
+ }
+
+ @override
+ void dispose() {
+ WidgetsBinding.instance.removeObserver(this);
+ super.dispose();
+ }
+
+ @override
+ Widget build(BuildContext context) {
+ final businessLogicStrategy = SCGlobalConfig.businessLogicStrategy;
+
+ return Scaffold(
+ resizeToAvoidBottomInset: false,
+ body: Stack(
+ alignment: Alignment.topCenter,
+ children: [
+ Image.asset(
+ businessLogicStrategy.getLoginMainBackgroundImage(),
+ width: ScreenUtil().screenWidth,
+ height: ScreenUtil().screenHeight,
+ fit: BoxFit.cover,
+ ),
+ Positioned(
+ top: 120,
+ child: Image.asset(
+ businessLogicStrategy.getLoginMainAppIcon(),
+ width: 107.w,
+ height: 159.w,
+ ),
+ ),
+ Positioned(
+ top: 390.w,
+ left: 27.w,
+ right: 27.w,
+ child: SizedBox(
+ width: double.infinity,
+ child: Column(
+ mainAxisAlignment: MainAxisAlignment.start,
+ children: [
+ Column(
+ mainAxisAlignment: MainAxisAlignment.center,
+ children: [
+ Platform.isAndroid
+ ? SCDebounceWidget(
+ child: Container(
+ decoration: BoxDecoration(
+ borderRadius: BorderRadius.circular(12.w),
+ color:
+ businessLogicStrategy
+ .getLoginMainButtonBackgroundColor(),
+ ),
+ padding: EdgeInsets.symmetric(
+ vertical: 12.w,
+ horizontal: 24.w,
+ ),
+ child: Row(
+ mainAxisAlignment: MainAxisAlignment.start,
+ children: [
+ Image.asset(
+ businessLogicStrategy
+ .getLoginMainGoogleIcon(),
+ width: 30.w,
+ height: 30.w,
+ ),
+ SizedBox(width: 20.w),
+ Expanded(
+ child: text(
+ SCAppLocalizations.of(
+ context,
+ )!.signInWithGoogle,
+ textColor:
+ businessLogicStrategy
+ .getLoginMainButtonTextColor(),
+ fontSize: 16.sp,
+ fontWeight: FontWeight.bold,
+ textAlign: TextAlign.center,
+ ),
+ ),
+ ],
+ ),
+ ),
+ onTap: () {
+ _loginByGoogle();
+ },
+ )
+ : Container(),
+ Platform.isIOS ? SizedBox(height: 20.w) : Container(),
+ Platform.isIOS
+ ? SCDebounceWidget(
+ child: Container(
+ decoration: BoxDecoration(
+ borderRadius: BorderRadius.circular(12),
+ color:
+ businessLogicStrategy
+ .getLoginMainButtonBackgroundColor(),
+ ),
+ padding: EdgeInsets.symmetric(
+ vertical: 12.w,
+ horizontal: 24.w,
+ ),
+ child: Row(
+ mainAxisAlignment: MainAxisAlignment.start,
+ children: [
+ Image.asset(
+ businessLogicStrategy
+ .getLoginMainAppleIcon(),
+ width: 30.w,
+ height: 30.w,
+ ),
+ SizedBox(width: 20.w),
+ Expanded(
+ child: text(
+ SCAppLocalizations.of(
+ context,
+ )!.signInWithApple,
+ textColor:
+ businessLogicStrategy
+ .getLoginMainButtonTextColor(),
+ fontSize: 16.sp,
+ fontWeight: FontWeight.bold,
+ textAlign: TextAlign.center,
+ ),
+ ),
+ ],
+ ),
+ ),
+ onTap: () {
+ _loginByApple();
+ },
+ )
+ : Container(),
+ SizedBox(height: 8.w), // 从5.w改为8.w
+ Container(
+ alignment: Alignment.center,
+ child: Row(
+ mainAxisSize: MainAxisSize.min,
+ children: [
+ Container(
+ color:
+ businessLogicStrategy
+ .getLoginMainDividerColor(),
+ height: 0.5.w,
+ width: 82.w,
+ ),
+ SizedBox(width: 20.w),
+ text(
+ SCAppLocalizations.of(context)!.or,
+ textColor:
+ businessLogicStrategy
+ .getLoginMainDividerColor(),
+ fontSize: 18.sp,
+ fontWeight: FontWeight.w600,
+ ),
+ SizedBox(width: 20.w),
+ Container(
+ color:
+ businessLogicStrategy
+ .getLoginMainDividerColor(),
+ height: 0.5.w,
+ width: 82.w,
+ ),
+ ],
+ ),
+ ),
+ SizedBox(height: 12.w), // 从8.w改为12.w
+ SCDebounceWidget(
+ onTap: () {
+ _goLoginWithAccount();
+ },
+ child: Container(
+ decoration: BoxDecoration(
+ borderRadius: BorderRadius.circular(12),
+ color:
+ businessLogicStrategy
+ .getLoginMainButtonBackgroundColor(),
+ ),
+ padding: EdgeInsets.symmetric(
+ vertical: 12.w,
+ horizontal: 24.w,
+ ),
+ child: Row(
+ mainAxisAlignment: MainAxisAlignment.start,
+ children: [
+ Image.asset(
+ businessLogicStrategy.getLoginMainAccountIcon(),
+ width: 30.w,
+ height: 30.w,
+ ),
+ SizedBox(width: 20.w),
+ Expanded(
+ child: text(
+ SCAppLocalizations.of(
+ context,
+ )!.signInWithYourAccount,
+ textColor:
+ businessLogicStrategy
+ .getLoginMainButtonTextColor(),
+ fontSize: 16.sp,
+ fontWeight: FontWeight.bold,
+ textAlign: TextAlign.center,
+ ),
+ ),
+ ],
+ ),
+ ),
+ ),
+ ],
+ ),
+ SizedBox(height: 8.w),
+ Row(
+ crossAxisAlignment: CrossAxisAlignment.start,
+ children: [
+ SizedBox(width: 8.w),
+ Column(
+ children: [
+ GestureDetector(
+ behavior: HitTestBehavior.opaque,
+ onTap: () {
+ setState(() {
+ isAgreement = !isAgreement;
+ });
+ },
+ child: Container(
+ padding: EdgeInsets.all(3.w),
+ child: Image.asset(
+ businessLogicStrategy.getLoginMainAgreementIcon(
+ isAgreement,
+ ),
+ width: 16.w,
+ height: 16.w,
+ ),
+ ),
+ ),
+ ],
+ ),
+ Expanded(
+ child: Container(
+ margin: EdgeInsets.only(top: 3.w),
+ child: Text.rich(
+ TextSpan(
+ children: [
+ TextSpan(
+ text:
+ SCAppLocalizations.of(
+ context,
+ )!.loginRepresentsAgreementTo,
+ style: TextStyle(
+ color: Colors.white,
+ fontSize: sp(12),
+ fontWeight: FontWeight.w400,
+ ),
+ ),
+ TextSpan(
+ text:
+ SCAppLocalizations.of(
+ context,
+ )!.termsofService,
+ style: TextStyle(
+ color:
+ businessLogicStrategy
+ .getLoginMainLinkColor(),
+ fontSize: sp(12),
+ fontWeight: FontWeight.w500,
+ ),
+ recognizer:
+ TapGestureRecognizer()
+ ..onTap = () async {
+ Navigator.push(
+ context,
+ PopRoute(
+ child: WebViewPage(
+ title:
+ SCAppLocalizations.of(
+ context,
+ )!.termsofService,
+ url:
+ SCGlobalConfig
+ .userAgreementUrl,
+ ),
+ ),
+ );
+ },
+ ),
+ TextSpan(
+ text: SCAppLocalizations.of(context)!.and,
+ style: TextStyle(
+ color: Colors.white,
+ fontSize: sp(12),
+ fontWeight: FontWeight.w400,
+ ),
+ ),
+ TextSpan(
+ text:
+ SCAppLocalizations.of(
+ context,
+ )!.privaceyPolicy,
+ style: TextStyle(
+ color:
+ businessLogicStrategy
+ .getLoginMainLinkColor(),
+ fontSize: sp(12),
+ fontWeight: FontWeight.w500,
+ ),
+ recognizer:
+ TapGestureRecognizer()
+ ..onTap = () async {
+ Navigator.push(
+ context,
+ PopRoute(
+ child: WebViewPage(
+ title:
+ SCAppLocalizations.of(
+ context,
+ )!.privaceyPolicy,
+ url:
+ SCGlobalConfig
+ .privacyAgreementUrl,
+ ),
+ ),
+ );
+ },
+ ),
+ ],
+ ),
+ textAlign: TextAlign.center,
+ ),
+ ),
+ ),
+ SizedBox(width: 10.w),
+ ],
+ ),
+ SizedBox(height: 45.w),
+ ],
+ ),
+ ),
+ ),
+ ],
+ ),
+ );
+ }
+
+ void _loginByGoogle() async {
+ if (!isAgreement) {
+ //弹出勾选确认
+ showPolicyConfirm();
+ return;
+ }
+ await authProvider?.authenticateUser(context, SCAuthType.GOOGLE.name);
+ }
+
+ void showPolicyConfirm() {
+ SmartDialog.show(
+ tag: "showConfirmDialog",
+ alignment: Alignment.center,
+ debounce: true,
+ animationType: SmartAnimationType.fade,
+ builder: (_) {
+ return MsgDialog(
+ title: SCAppLocalizations.of(context)!.tips,
+ msg: SCAppLocalizations.of(context)!.termsOfServicePrivacyPolicyTips,
+ btnText: SCAppLocalizations.of(context)!.yes,
+ onEnsure: () {
+ isAgreement = true;
+ setState(() {});
+ },
+ );
+ },
+ );
+ }
+
+ void _goLoginWithAccount() async {
+ if (!isAgreement) {
+ //弹出勾选确认
+ showPolicyConfirm();
+ return;
+ }
+ SCNavigatorUtils.push(
+ context,
+ LoginRouter.loginWithAccount,
+ replace: false,
+ );
+ }
+
+ void _loginByApple() {
+ if (!isAgreement) {
+ //弹出勾选确认
+ showPolicyConfirm();
+ return;
+ }
+ authProvider?.authenticateUser(context, SCAuthType.APPLE.name);
+ }
+}
diff --git a/lib/modules/auth/login_route.dart b/lib/modules/auth/login_route.dart
new file mode 100644
index 0000000..3df0de2
--- /dev/null
+++ b/lib/modules/auth/login_route.dart
@@ -0,0 +1,23 @@
+import 'package:fluro/fluro.dart';
+import 'package:yumi/modules/auth/account/sc_login_with_account_page.dart';
+
+import 'package:yumi/app/routes/sc_router_init.dart';
+import 'package:yumi/modules/auth/edit/sc_edit_profile_page.dart';
+import 'package:yumi/modules/auth/login_page.dart';
+
+class LoginRouter implements SCIRouterProvider {
+ static String login = '/login';
+ static String editProfile = '/login/edit_profile';
+ static String loginWithAccount = '/login/login_account';
+
+ @override
+ void initRouter(FluroRouter router) {
+ router.define(login,
+ handler: Handler(handlerFunc: (_, params) => LoginPage()));
+ router.define(editProfile,
+ handler: Handler(handlerFunc: (_, params) => SCEditProfilePage()));
+ router.define(loginWithAccount,
+ handler: Handler(
+ handlerFunc: (_, params) => SCLoginWithAccountPage()));
+ }
+}
diff --git a/lib/modules/chat/activity/message_activity_page.dart b/lib/modules/chat/activity/message_activity_page.dart
new file mode 100644
index 0000000..d83e9e8
--- /dev/null
+++ b/lib/modules/chat/activity/message_activity_page.dart
@@ -0,0 +1,282 @@
+import 'package:extended_text/extended_text.dart';
+import 'package:flutter/cupertino.dart';
+import 'package:flutter/material.dart';
+import 'package:flutter_screenutil/flutter_screenutil.dart';
+import 'package:yumi/ui_kit/components/sc_compontent.dart';
+import 'package:yumi/shared/data_sources/sources/repositories/sc_user_repository_impl.dart';
+import 'package:provider/provider.dart';
+import 'package:pull_to_refresh/pull_to_refresh.dart';
+
+import 'package:yumi/app_localizations.dart';
+import 'package:yumi/ui_kit/components/appbar/socialchat_appbar.dart';
+import 'package:yumi/app/constants/sc_screen.dart';
+import 'package:yumi/app/routes/sc_fluro_navigator.dart';
+import 'package:yumi/shared/tools/sc_date_utils.dart';
+import 'package:yumi/shared/business_logic/models/res/sc_public_message_page_res.dart';
+import 'package:yumi/services/audio/rtm_manager.dart';
+import 'package:yumi/modules/index/main_route.dart';
+import 'package:yumi/app/constants/sc_global_config.dart';
+import 'package:yumi/app/config/business_logic_strategy.dart';
+
+class MessageActivityPage extends StatefulWidget {
+ @override
+ _MessageActivityPageState createState() => _MessageActivityPageState();
+}
+
+class _MessageActivityPageState extends State {
+ List records = [];
+ num index = 1;
+ final RefreshController _refreshController = RefreshController();
+ final ScrollController _scrollController = ScrollController();
+ RtmProvider? rtmProvider;
+
+ BusinessLogicStrategy get _strategy => SCGlobalConfig.businessLogicStrategy;
+
+ @override
+ void initState() {
+ super.initState();
+ rtmProvider = Provider.of(context, listen: false);
+ rtmProvider?.onNewActivityMessageCurrentConversationListener =
+ _onNewMessage;
+ loadData();
+ }
+
+ _onNewMessage(Records? message) async {
+ if (message == null) {
+ return;
+ }
+
+ int? index;
+ for (var element in records) {
+ if (element.id == message.id) {
+ index = records.indexOf(element);
+ continue;
+ }
+ }
+ if (index != null) {
+ records.removeAt(index);
+ records.insert(index, message);
+ } else {
+ records.insert(0, message);
+ }
+ _scrollController.jumpTo(0.0);
+ setState(() {});
+ }
+
+ @override
+ void dispose() {
+ rtmProvider?.onNewActivityMessageCurrentConversationListener = null;
+ super.dispose();
+ }
+
+ @override
+ Widget build(BuildContext context) {
+ return Stack(
+ children: [
+ Image.asset(
+ _strategy.getSCMessageChatPageRoomSettingBackground(),
+ width: ScreenUtil().screenWidth,
+ height: ScreenUtil().screenHeight,
+ fit: BoxFit.fill,
+ ),
+ Scaffold(
+ backgroundColor: Colors.transparent,
+ resizeToAvoidBottomInset: false,
+ appBar: SocialChatStandardAppBar(
+ title: SCAppLocalizations.of(context)!.activity,
+ actions: [],
+ ),
+ body: SafeArea(
+ top: false,
+ child: SmartRefresher(
+ enablePullDown: false,
+ enablePullUp: true,
+ onLoading: () async {
+ index = index + 1;
+ loadData();
+ },
+ footer: CustomFooter(
+ height: 1,
+ builder: (context, mode) {
+ return SizedBox(
+ height: 1,
+ width: 1,
+ child: SizedBox(height: 1, width: 1),
+ );
+ },
+ ),
+ controller: _refreshController,
+ child:
+ records.isNotEmpty
+ ? Container(
+ child: CustomScrollView(
+ shrinkWrap: records.length > 3 ? false : true,
+ controller: _scrollController,
+ reverse: true,
+ physics: const ClampingScrollPhysics(),
+ // 禁用回弹效果
+ slivers: [
+ SliverList(
+ delegate: SliverChildBuilderDelegate(
+ (c, i) => _MessageItem(message: records[i]),
+ childCount: records.length,
+ ),
+ ),
+ ],
+ ),
+ )
+ : mainEmpty(),
+ ),
+ ),
+ ),
+ ],
+ );
+ }
+
+ void loadData() {
+ SCAccountRepository().publicMessagePage("activity", index, 30).then((
+ result,
+ ) {
+ var list = result.records ?? [];
+ if (list.isNotEmpty) {
+ records.addAll(list);
+ if (list.length == 30) {
+ _refreshController.loadComplete();
+ } else {
+ _refreshController.loadNoData();
+ }
+ } else {
+ _refreshController.loadNoData();
+ }
+ setState(() {});
+ });
+ }
+}
+
+class _MessageItem extends StatelessWidget {
+ final Records message;
+ late BuildContext context;
+
+ _MessageItem({required this.message});
+
+ @override
+ Widget build(BuildContext context) {
+ this.context = context;
+ print('status:${message.status}');
+ String time = SCMDateUtils.formatMessageTime(
+ context,
+ DateTime.fromMillisecondsSinceEpoch(int.parse(message.createdAt ?? "0")),
+ );
+ return Container(
+ margin: EdgeInsets.symmetric(horizontal: 15.w, vertical: 8.w),
+ child: Column(
+ children: [
+ Container(
+ margin: EdgeInsets.only(bottom: 12.w),
+ child: Row(
+ children: [
+ Spacer(),
+ Container(
+ decoration: BoxDecoration(
+ color: Colors.black12,
+ borderRadius: BorderRadius.all(Radius.circular(height(13))),
+ ),
+ alignment: Alignment.center,
+ padding: EdgeInsets.symmetric(
+ horizontal: width(15),
+ vertical: 8.w,
+ ),
+ child: Text(
+ time,
+ style: TextStyle(
+ fontSize: sp(12),
+ color: Colors.white,
+ fontWeight: FontWeight.w400,
+ decoration: TextDecoration.none,
+ height: 1,
+ ),
+ ),
+ ),
+ Spacer(),
+ ],
+ ),
+ ),
+ _msg(message),
+ ],
+ ),
+ );
+ }
+
+ _msg(Records message) {
+ return GestureDetector(
+ child: Container(
+ alignment: AlignmentDirectional.centerStart,
+ decoration: BoxDecoration(
+ color: Color(0xff18F2B1).withOpacity(0.1),
+ borderRadius: BorderRadius.all(Radius.circular(8)),
+ ),
+ padding: EdgeInsets.all(8.0.w),
+ child: Column(
+ children: [
+ Row(
+ children: [
+ SizedBox(width: 5.w),
+ Expanded(
+ child: ExtendedText(
+ message.title ?? "",
+ overflow: TextOverflow.ellipsis,
+ maxLines: 1,
+ // specialTextSpanBuilder: MySpecialTextSpanBuilder(),
+ style: TextStyle(
+ fontSize: sp(16),
+ color: Colors.white,
+ fontWeight: FontWeight.bold,
+ ),
+ ),
+ ),
+ SizedBox(width: 5.w),
+ ],
+ ),
+ message.imageUrl != null && message.imageUrl!.isNotEmpty
+ ? Container(
+ margin: EdgeInsets.all(5.w),
+ child: netImage(
+ url: message.imageUrl ?? "",
+ height: 110.w,
+ fit: BoxFit.contain,
+ borderRadius: BorderRadius.all(Radius.circular(8)),
+ ),
+ )
+ : Container(),
+ Row(
+ children: [
+ SizedBox(width: 5.w),
+ Expanded(
+ child: ExtendedText(
+ message.content ?? "",
+ // specialTextSpanBuilder: MySpecialTextSpanBuilder(),
+ style: TextStyle(fontSize: sp(14), color: Colors.white),
+ ),
+ ),
+ SizedBox(width: 5.w),
+ ],
+ ),
+
+ ],
+ ),
+ ),
+ onTap: () {
+ if (message.extraData != null && message.extraData?.link != null) {
+ if (message.extraData!.link!.startsWith("http") ||
+ message.extraData!.link!.startsWith("https")) {
+ SCNavigatorUtils.push(
+ context,
+ "${SCMainRoute.webViewPage}?url=${Uri.encodeComponent(message.extraData?.link ?? "")}&showTitle=false",
+ replace: false,
+ );
+ }
+ }
+ },
+ );
+ }
+}
diff --git a/lib/modules/chat/chat_route.dart b/lib/modules/chat/chat_route.dart
new file mode 100644
index 0000000..9c05086
--- /dev/null
+++ b/lib/modules/chat/chat_route.dart
@@ -0,0 +1,59 @@
+import 'dart:convert';
+
+import 'package:fluro/fluro.dart';
+import 'package:flutter/cupertino.dart';
+import 'package:yumi/modules/chat/noti/message_notifcation_page.dart';
+import 'package:yumi/modules/chat/system/message_system_page.dart';
+import 'package:tencent_cloud_chat_sdk/models/v2_tim_conversation.dart';
+import 'package:yumi/app/routes/sc_router_init.dart';
+import 'package:yumi/modules/chat/activity/message_activity_page.dart';
+
+import 'message_chat_page.dart';
+
+class SCChatRouter implements SCIRouterProvider {
+ static String chat = '/chat';
+ static String systemChat = '/systemChat';
+ static String dynamicMsg = '/dynamicMsg';
+ static String notifcation = '/chat/notifcation';
+ static String activity = '/chat/activity';
+
+ @override
+ void initRouter(FluroRouter router) {
+ router.define(
+ chat,
+ handler: Handler(
+ handlerFunc:
+ (_, params) => SCMessageChatPage(
+ conversation: V2TimConversation.fromJson(
+ jsonDecode(params['conversation']!.first),
+ ),
+ ),
+ ),
+ );
+
+ router.define(
+ systemChat,
+ handler: Handler(
+ handlerFunc:
+ (_, params) => MessageSystemPage(
+ conversation: V2TimConversation.fromJson(
+ jsonDecode(params['conversation']!.first),
+ ),
+ ),
+ ),
+ );
+ router.define(
+ dynamicMsg,
+ handler: Handler(handlerFunc: (_, params) => Container()),
+ );
+
+ router.define(
+ notifcation,
+ handler: Handler(handlerFunc: (_, params) => MessageNotifcationPage()),
+ );
+ router.define(
+ activity,
+ handler: Handler(handlerFunc: (_, params) => MessageActivityPage()),
+ );
+ }
+}
diff --git a/lib/modules/chat/message/sc_message_friends_page.dart b/lib/modules/chat/message/sc_message_friends_page.dart
new file mode 100644
index 0000000..58f1a03
--- /dev/null
+++ b/lib/modules/chat/message/sc_message_friends_page.dart
@@ -0,0 +1,320 @@
+import 'dart:async';
+import 'dart:convert';
+
+import 'package:flutter/cupertino.dart';
+import 'package:flutter/material.dart';
+import 'package:flutter/services.dart';
+import 'package:flutter_screenutil/flutter_screenutil.dart';
+import 'package:provider/provider.dart';
+import 'package:tencent_cloud_chat_sdk/enum/conversation_type.dart';
+import 'package:tencent_cloud_chat_sdk/models/v2_tim_conversation.dart';
+import 'package:yumi/app_localizations.dart';
+import 'package:yumi/ui_kit/components/sc_tts.dart';
+import 'package:yumi/app/routes/sc_fluro_navigator.dart';
+import 'package:yumi/app/constants/sc_global_config.dart';
+import 'package:yumi/app/config/business_logic_strategy.dart';
+import 'package:yumi/shared/data_sources/sources/repositories/sc_user_repository_impl.dart';
+import 'package:yumi/shared/business_logic/models/res/message_friend_user_res.dart';
+import 'package:yumi/services/general/sc_app_general_manager.dart';
+import 'package:yumi/services/audio/rtm_manager.dart';
+
+import '../../../ui_kit/components/sc_compontent.dart';
+import '../../../ui_kit/components/sc_page_list.dart';
+import '../../../ui_kit/components/text/sc_text.dart';
+import '../chat_route.dart';
+
+class MessageFriendsPage extends SCPageList {
+ @override
+ _MessageFriendsPageState createState() => _MessageFriendsPageState();
+}
+
+class _MessageFriendsPageState
+ extends SCPageListState {
+ BusinessLogicStrategy get _strategy => SCGlobalConfig.businessLogicStrategy;
+
+ String? lastId;
+ late TextEditingController _textEditingController;
+ String search = '';
+ Timer? _searchTimer;
+
+ @override
+ void initState() {
+ super.initState();
+ _textEditingController = TextEditingController();
+ _textEditingController.addListener(() {
+ search = _textEditingController.text;
+ if (search.trim().isNotEmpty) {
+ _searchTimer?.cancel();
+ _searchTimer = Timer(Duration(milliseconds: 550), () {
+ if (search.trim().isNotEmpty) {
+ _search();
+ }
+ });
+ }
+ });
+ enablePullUp = true;
+ backgroundColor = Colors.transparent;
+ isShowDivider = true;
+ loadData(1);
+ }
+
+ _search() {
+ SCAccountRepository()
+ .friendSearch(search)
+ .then((result) {
+ items = result;
+ loadComplete();
+ setState(() {});
+ })
+ .catchError((e) {
+ loadComplete();
+ setState(() {});
+ });
+ }
+
+ @override
+ void dispose() {
+ _searchTimer?.cancel();
+ super.dispose();
+ }
+
+ @override
+ Widget build(BuildContext context) {
+ return Scaffold(
+ backgroundColor: Colors.transparent,
+ body: Column(
+ children: [
+ Container(
+ height: kToolbarHeight + ScreenUtil().statusBarHeight,
+ alignment: Alignment.centerLeft,
+ child: Row(
+ children: [
+ Expanded(
+ child: searchWidget(
+ hint: SCAppLocalizations.of(context)!.inputUserId,
+ borderColor: Colors.white,
+ controller: _textEditingController,
+ ),
+ ),
+ SizedBox(width: 10.w),
+ GestureDetector(
+ child: text(
+ SCAppLocalizations.of(context)!.cancel,
+ fontSize: 14.sp,
+ fontWeight: FontWeight.w600,
+ textColor: Colors.black45,
+ ),
+ onTap: () {
+ _textEditingController.text = "";
+ search = "";
+ loadData(1);
+ },
+ ),
+ SizedBox(width: 10.w),
+ ],
+ ),
+ ),
+ Expanded(child: buildList(context)),
+ ],
+ ),
+ );
+ }
+
+ @override
+ Widget buildItem(MessageFriendUserRes res) {
+ return GestureDetector(
+ child: Container(
+ decoration: BoxDecoration(),
+ child: Row(
+ children: [
+ SizedBox(width: 10.w),
+ head(url: res?.userProfile?.userAvatar ?? "", width: 62.w),
+ SizedBox(width: 10.w),
+ Expanded(
+ child: Column(
+ crossAxisAlignment: CrossAxisAlignment.start,
+ children: [
+ Row(
+ children: [
+ netImage(
+ url:
+ Provider.of(context, listen: false)
+ .findCountryByName(
+ res?.userProfile?.countryName ?? "",
+ )
+ ?.nationalFlag ??
+ "",
+ borderRadius: BorderRadius.all(Radius.circular(3.w)),
+ width: 19.w,
+ height: 14.w,
+ ),
+ SizedBox(width: 3.w),
+ socialchatNickNameText(
+ maxWidth: 160.w,
+ textColor: Colors.black,
+ res.userProfile
+ ?.userNickname ??
+ "",
+ fontSize: 14.sp,
+ type:
+ res.userProfile
+ ?.getVIP()
+ ?.name ??
+ "",
+ needScroll:
+ (res.userProfile
+ ?.userNickname
+ ?.characters.length ??
+ 0) >
+ 14,
+ ),
+ SizedBox(width: 3.w),
+ Container(
+ width: 47.w,
+ height: 24.w,
+ decoration: BoxDecoration(
+ image: DecorationImage(
+ image: AssetImage(
+ _strategy.getGenderBackgroundImage(res?.userProfile?.userSex == 0),
+ ),
+ ),
+ ),
+ child: Row(
+ crossAxisAlignment: CrossAxisAlignment.center,
+ mainAxisAlignment: MainAxisAlignment.center,
+ children: [
+ xb(res?.userProfile?.userSex),
+ text(
+ "${res?.userProfile?.age}",
+ textColor: Colors.white,
+ fontSize: 15.sp,
+ fontWeight: FontWeight.w600,
+ ),
+ ],
+ ),
+ ),
+ ],
+ ),
+ SizedBox(height: 4.w),
+ Row(
+ children: [
+ GestureDetector(
+ child: Container(
+ padding: EdgeInsets.symmetric(vertical: 8.w),
+ decoration: BoxDecoration(
+ image: DecorationImage(
+ image: AssetImage(
+ _strategy.getIdBackgroundImage(res?.userProfile?.hasSpecialId() ?? false),
+ ),
+ fit: BoxFit.fitWidth,
+ ),
+ ),
+ child: Row(
+ textDirection: TextDirection.ltr,
+ children: [
+ SizedBox(width: 38.w),
+ text(
+ "${res?.userProfile?.getID()}",
+ fontSize: 12.sp,
+ textColor: Colors.white,
+ fontWeight: FontWeight.bold,
+ ),
+ SizedBox(width: 5.w),
+ Image.asset(
+ _strategy.getCopyIdIcon(),
+ width: 12.w,
+ height: 12.w,
+ ),
+ SizedBox(width: 8.w),
+ ],
+ ),
+ ),
+ onTap: () {
+ Clipboard.setData(
+ ClipboardData(
+ text: res?.userProfile?.getID() ?? "",
+ ),
+ );
+ SCTts.show(
+ SCAppLocalizations.of(context)!.copiedToClipboard,
+ );
+ },
+ ),
+ SizedBox(width: 8.w),
+ getWealthLevel(
+ res?.userProfile?.wealthLevel ?? 0,
+ width: 58.w,
+ height: 30.w,
+ ),
+ SizedBox(width: 8.w),
+ getUserLevel(
+ res?.userProfile?.charmLevel ?? 0,
+ width: 58.w,
+ height: 30.w,
+ ),
+ ],
+ ),
+ ],
+ ),
+ ),
+ SizedBox(width: 15.w),
+ ],
+ ),
+ ),
+ onTap: () async {
+ var conversation = V2TimConversation(
+ type: ConversationType.V2TIM_C2C,
+ userID: res.userProfile?.id,
+ conversationID: '',
+ );
+ var bool = await Provider.of(
+ context,
+ listen: false,
+ ).startConversation(conversation);
+ if (!bool) return;
+ var json = jsonEncode(conversation.toJson());
+ SCNavigatorUtils.push(
+ context,
+ "${SCChatRouter.chat}?conversation=${Uri.encodeComponent(json)}",
+ );
+ },
+ );
+ }
+
+ @override
+ builderDivider() {
+ return Divider(
+ height: 22.w,
+ color: Color(0xffF2F2F2),
+ indent: 15.w,
+ endIndent: 15.w,
+ );
+ }
+
+ ///加载数据
+ @override
+ loadPage({
+ required int page,
+ required Function(List) onSuccess,
+ Function? onErr,
+ }) async {
+ if (_textEditingController.text.isNotEmpty) {
+ _search();
+ } else {
+ if (page == 1) {
+ lastId = null;
+ }
+ try {
+ var followList = await SCAccountRepository().friendList(lastId: lastId);
+ if (followList.isNotEmpty) {
+ lastId = followList.last.id;
+ }
+ onSuccess(followList);
+ } catch (e) {
+ if (onErr != null) {
+ onErr();
+ }
+ }
+ }
+ }
+}
diff --git a/lib/modules/chat/message/sc_message_page.dart b/lib/modules/chat/message/sc_message_page.dart
new file mode 100644
index 0000000..b74f78c
--- /dev/null
+++ b/lib/modules/chat/message/sc_message_page.dart
@@ -0,0 +1,422 @@
+import 'dart:convert';
+import 'package:flutter/material.dart';
+import 'package:flutter_screenutil/flutter_screenutil.dart';
+import 'package:yumi/app_localizations.dart';
+import 'package:yumi/ui_kit/components/sc_debounce_widget.dart';
+import 'package:yumi/ui_kit/components/text/sc_text.dart';
+import 'package:yumi/services/audio/rtm_manager.dart';
+import 'package:provider/provider.dart';
+import 'package:tencent_cloud_chat_sdk/enum/conversation_type.dart';
+import 'package:tencent_cloud_chat_sdk/models/v2_tim_conversation.dart';
+import 'package:tencent_cloud_chat_sdk/models/v2_tim_value_callback.dart';
+import 'package:tencent_cloud_chat_sdk/tencent_im_sdk_plugin.dart';
+import 'package:yumi/app/constants/sc_global_config.dart';
+import 'package:yumi/app/config/business_logic_strategy.dart';
+import 'package:yumi/app/routes/sc_fluro_navigator.dart';
+import 'package:yumi/shared/data_sources/sources/local/data_persistence.dart';
+import 'package:yumi/shared/data_sources/sources/local/user_manager.dart';
+import 'package:yumi/ui_kit/theme/socialchat_theme.dart';
+import 'package:yumi/ui_kit/widgets/msg/message_conversation_list_page.dart';
+import 'package:yumi/modules/chat/message/sc_message_friends_page.dart';
+
+import '../../index/main_route.dart';
+import '../chat_route.dart';
+
+///消息
+class SCMessagePage extends StatefulWidget {
+ bool isFromRoom = false;
+
+ SCMessagePage({this.isFromRoom = false});
+
+ @override
+ _MessagePageState createState() => _MessagePageState(isFromRoom);
+}
+
+class _MessagePageState extends State {
+ BusinessLogicStrategy get _strategy => SCGlobalConfig.businessLogicStrategy;
+ bool isFromRoom = false;
+ bool showSystemAnnouncementTips = true;
+
+ _MessagePageState(this.isFromRoom);
+
+ @override
+ void initState() {
+ super.initState();
+ showSystemAnnouncementTips = DataPersistence.getBool(
+ "${AccountStorage().getCurrentUser()?.userProfile?.account}-ShowSystemAnnouncementTips",
+ defaultValue: true,
+ );
+ _checkLogin();
+ }
+
+ void _checkLogin() async {
+ V2TimValueCallback getLoginStatusRes =
+ await TencentImSDKPlugin.v2TIMManager.getLoginStatus();
+ if (getLoginStatusRes.code == 0) {
+ var status = getLoginStatusRes.data; // getLoginStatusRes.data为用户登录状态值
+ if (status == 1) {
+ // 已登录
+ ///处理有时候拉不到最后一条消息
+ Provider.of(
+ context,
+ listen: false,
+ ).initConversation().then((value) {
+ Future.delayed(Duration(milliseconds: 550), () {
+ Provider.of(
+ context,
+ listen: false,
+ ).initConversation().then((value) {
+ setState(() {});
+ });
+ });
+ });
+ } else if (status == 2) {
+ // 登录中
+ } else if (status == 3) {
+ // 未登录
+ Provider.of(
+ context,
+ listen: false,
+ ).loginTencetRtm(context).then((value) {
+ _checkLogin();
+ });
+ }
+ setState(() {});
+ }
+ }
+
+ @override
+ void dispose() {
+ super.dispose();
+ }
+
+ @override
+ Widget build(BuildContext context) {
+ return Stack(
+ children: [
+ widget.isFromRoom
+ ? Image.asset(
+ _strategy.getMessagePageIndexMaskIcon(),
+ width: ScreenUtil().screenWidth,
+ fit: BoxFit.cover,
+ )
+ : Container(),
+ DefaultTabController(
+ length: 1,
+ child: Scaffold(
+ backgroundColor: Colors.transparent,
+ appBar: AppBar(
+ backgroundColor: Colors.transparent,
+ leading: null,
+ title: TabBar(
+ tabs:
+ [SCAppLocalizations.of(context)!.message]
+ .map(
+ (e) => Padding(
+ padding: EdgeInsets.only(bottom: 3.w, top: 4.w),
+ child: Text(e),
+ ),
+ )
+ .toList(),
+ dividerColor: Colors.transparent,
+ labelStyle: TextStyle(
+ fontSize: 16.sp,
+ fontWeight: FontWeight.bold,
+ fontStyle: FontStyle.italic,
+ ),
+ unselectedLabelStyle: TextStyle(
+ fontSize: 15.sp,
+ color: Colors.white,
+ fontWeight: FontWeight.normal,
+ ),
+ indicator: BoxDecoration(),
+ //TabBarIndicator(),
+ indicatorSize: TabBarIndicatorSize.label,
+ isScrollable: true,
+ tabAlignment: TabAlignment.start,
+ labelColor: SocialChatTheme.primaryLight,
+ ),
+ actions: [
+ SCDebounceWidget(
+ child: Container(
+ padding: EdgeInsetsDirectional.only(end: 10.w),
+ child: Image.asset(
+ "sc_images/index/sc_icon_serach.png",
+ width: 20.w,
+ height: 20.w,
+ ),
+ ),
+ onTap: () {
+ SCNavigatorUtils.push(context, SCMainRoute.mainSearch);
+ },
+ ),
+ ],
+ ),
+ body: TabBarView(
+ children: [
+ Consumer(
+ builder: (_, provider, __) {
+ return Container(
+ margin: EdgeInsetsDirectional.symmetric(horizontal: 10.w),
+ decoration: BoxDecoration(
+ image: DecorationImage(
+ image: AssetImage(
+ "sc_images/index/sc_index_msg_content_bg.png",
+ ),
+ fit: BoxFit.fill,
+ ),
+ ),
+ child: Column(
+ children: [
+ _headMenu(provider),
+ Expanded(
+ child: Container(
+ margin: EdgeInsets.only(
+ top: 0.w,
+ left: 8.w,
+ right: 8.w,
+ ),
+ child: MessageConversationListPage(false),
+ ),
+ ),
+ ],
+ ),
+ );
+ },
+ ),
+ ],
+ ),
+ ),
+ ),
+ ],
+ );
+ }
+
+ Widget _headMenu(RtmProvider provider) {
+ return Container(
+ margin: EdgeInsetsDirectional.symmetric(horizontal: 25.w,).copyWith(top: 10.w),
+ child: Column(
+ spacing: 15.w,
+ children: [
+ SCDebounceWidget(
+ child: Stack(
+ children: [
+ Row(
+ children: [
+ SizedBox(height: 3.w),
+ Image.asset(
+ _strategy.getMessagePageActivityMessageIcon(),
+ width: 45.w,
+ height: 45.w,
+ ),
+ SizedBox(width: 5.w),
+ Column(
+ crossAxisAlignment: CrossAxisAlignment.start,
+ children: [
+ text(
+ SCAppLocalizations.of(context)!.activity,
+ textColor: Colors.white,
+ fontSize: 14.sp,
+ fontWeight: FontWeight.bold,
+ ),
+ SizedBox(height: 3.w),
+ text(
+ "[${SCAppLocalizations.of(context)!.newMessage}]",
+ fontSize: 12.sp,
+ textColor: Colors.white54,
+ ),
+ ],
+ ),
+ ],
+ ),
+ PositionedDirectional(
+ bottom: 0,
+ end: 10.w,
+ child: Visibility(
+ visible: provider.activityUnReadCount > 0,
+ child: Container(
+ padding: EdgeInsets.symmetric(horizontal: 6.w),
+ alignment: Alignment.center,
+ height: 16.w,
+ decoration: BoxDecoration(
+ //gradient: LinearGradient(colors: [Color(0xffA447FF), Color(0xff623CE9)]),
+ color: Colors.red,
+ shape: BoxShape.circle,
+ //borderRadius: BorderRadius.all(Radius.circular(7.w)),
+ ),
+ child: Text(
+ "${provider.activityUnReadCount > 99 ? '99+' : provider.activityUnReadCount}",
+ style: TextStyle(
+ fontSize: 10.sp,
+ color: Color(0xffffffff),
+ fontWeight: FontWeight.w400,
+ decoration: TextDecoration.none,
+ ),
+ ),
+ ),
+ ),
+ ),
+ ],
+ ),
+ onTap: () {
+ provider.updateActivityCount(0);
+ SCNavigatorUtils.push(
+ context,
+ SCChatRouter.activity,
+ replace: false,
+ );
+ },
+ ),
+ SCDebounceWidget(
+ child: Stack(
+ children: [
+ Row(
+ children: [
+ SizedBox(height: 3.w),
+ Image.asset(
+ _strategy.getMessagePageSystemMessageIcon(),
+ width: 45.w,
+ height: 45.w,
+ ),
+ SizedBox(width: 5.w),
+ Column(
+ crossAxisAlignment: CrossAxisAlignment.start,
+ children: [
+ text(
+ SCAppLocalizations.of(context)!.system,
+ textColor: Colors.white,
+ fontSize: 14.sp,
+ fontWeight: FontWeight.bold,
+ ),
+ SizedBox(height: 3.w),
+ text(
+ "[${SCAppLocalizations.of(context)!.newMessage}]",
+ fontSize: 12.sp,
+ textColor: Colors.white54,
+ ),
+ ],
+ ),
+ ],
+ ),
+ PositionedDirectional(
+ bottom: 0,
+ end: 10.w,
+ child: Visibility(
+ visible: provider.systemUnReadCount > 0,
+ child: Container(
+ padding: EdgeInsets.symmetric(horizontal: 6.w),
+ alignment: Alignment.center,
+ height: 16.w,
+ decoration: BoxDecoration(
+ //gradient: LinearGradient(colors: [Color(0xffA447FF), Color(0xff623CE9)]),
+ color: Colors.red,
+ shape: BoxShape.circle,
+ //borderRadius: BorderRadius.all(Radius.circular(7.w)),
+ ),
+ child: Text(
+ "${provider.systemUnReadCount > 99 ? '99+' : provider.systemUnReadCount}",
+ style: TextStyle(
+ fontSize: 10.sp,
+ color: Color(0xffffffff),
+ fontWeight: FontWeight.w400,
+ decoration: TextDecoration.none,
+ ),
+ ),
+ ),
+ ),
+ ),
+ ],
+ ),
+ onTap: () async {
+ var conversation = V2TimConversation(
+ type: ConversationType.V2TIM_C2C,
+ userID: "atyou-admin",
+ conversationID: SCGlobalConfig.imAdmin,
+ );
+ provider.updateSystemCount(0);
+ var bool = await provider.startConversation(conversation);
+ if (!bool) return;
+ var json = jsonEncode(conversation.toJson());
+ SCNavigatorUtils.push(
+ context,
+ "${SCChatRouter.systemChat}?conversation=${Uri.encodeComponent(json)}",
+ );
+ },
+ ),
+ SCDebounceWidget(
+ child: Stack(
+ children: [
+ Container(
+ alignment: Alignment.center,
+ child: Row(
+ children: [
+ SizedBox(height: 3.w),
+ Image.asset(
+ _strategy.getMessagePageNotificationMessageIcon(),
+ width: 45.w,
+ height: 45.w,
+ ),
+ SizedBox(width: 5.w),
+ Column(
+ crossAxisAlignment: CrossAxisAlignment.start,
+ children: [
+ text(
+ SCAppLocalizations.of(context)!.notifcation,
+ textColor: Colors.white,
+ fontSize: 14.sp,
+ fontWeight: FontWeight.bold,
+ ),
+ SizedBox(height: 3.w),
+ text(
+ "[${SCAppLocalizations.of(context)!.newMessage}]",
+ fontSize: 12.sp,
+ textColor: Colors.white54,
+ ),
+ ],
+ )
+ ],
+ ),
+ ),
+ PositionedDirectional(
+ bottom: 0,
+ end: 10.w,
+ child: Visibility(
+ visible: provider.notifcationUnReadCount > 0,
+ child: Container(
+ padding: EdgeInsets.symmetric(horizontal: 6.w),
+ alignment: Alignment.center,
+ height: 16.w,
+ decoration: BoxDecoration(
+ //gradient: LinearGradient(colors: [Color(0xffA447FF), Color(0xff623CE9)]),
+ color: Colors.red,
+ shape: BoxShape.circle,
+ //borderRadius: BorderRadius.all(Radius.circular(7.w)),
+ ),
+ child: Text(
+ "${provider.notifcationUnReadCount > 99 ? '99+' : provider.notifcationUnReadCount}",
+ style: TextStyle(
+ fontSize: 10.sp,
+ color: Color(0xffffffff),
+ fontWeight: FontWeight.w400,
+ decoration: TextDecoration.none,
+ ),
+ ),
+ ),
+ ),
+ ),
+ ],
+ ),
+ onTap: () {
+ provider.updateNotificationCount(0);
+ SCNavigatorUtils.push(
+ context,
+ SCChatRouter.notifcation,
+ replace: false,
+ );
+ },
+ ),
+ ],
+ ),
+ );
+ }
+}
diff --git a/lib/modules/chat/message_chat_page.dart b/lib/modules/chat/message_chat_page.dart
new file mode 100644
index 0000000..d550eea
--- /dev/null
+++ b/lib/modules/chat/message_chat_page.dart
@@ -0,0 +1,2099 @@
+import 'dart:convert';
+import 'dart:io';
+import 'package:extended_image/extended_image.dart'
+ show ExtendedImage, ExtendedRawImage, ExtendedImageState, LoadState;
+import 'package:extended_text/extended_text.dart';
+import 'package:extended_text_field/extended_text_field.dart';
+import 'package:flutter/cupertino.dart';
+import 'package:flutter/material.dart';
+import 'package:flutter/services.dart';
+import 'package:flutter_screenutil/flutter_screenutil.dart';
+import 'package:flutter_smart_dialog/flutter_smart_dialog.dart';
+import 'package:yumi/app_localizations.dart';
+import 'package:yumi/ui_kit/components/sc_debounce_widget.dart';
+import 'package:yumi/ui_kit/components/text/sc_text.dart';
+import 'package:yumi/ui_kit/components/sc_tts.dart';
+import 'package:yumi/app/constants/sc_emoji_datas.dart';
+import 'package:yumi/shared/tools/sc_date_utils.dart';
+import 'package:yumi/shared/tools/sc_loading_manager.dart';
+import 'package:yumi/shared/tools/sc_message_utils.dart';
+import 'package:yumi/shared/data_sources/sources/repositories/sc_user_repository_impl.dart';
+import 'package:yumi/shared/business_logic/models/res/login_res.dart';
+import 'package:yumi/services/audio/rtm_manager.dart';
+import 'package:marquee/marquee.dart';
+import 'package:provider/provider.dart';
+import 'package:pull_to_refresh/pull_to_refresh.dart';
+import 'package:tencent_cloud_chat_sdk/enum/V2TimAdvancedMsgListener.dart';
+import 'package:tencent_cloud_chat_sdk/enum/message_elem_type.dart';
+import 'package:tencent_cloud_chat_sdk/enum/message_status.dart';
+import 'package:tencent_cloud_chat_sdk/models/v2_tim_callback.dart';
+import 'package:tencent_cloud_chat_sdk/models/v2_tim_conversation.dart';
+import 'package:tencent_cloud_chat_sdk/models/v2_tim_custom_elem.dart';
+import 'package:tencent_cloud_chat_sdk/models/v2_tim_elem.dart';
+import 'package:tencent_cloud_chat_sdk/models/v2_tim_image_elem.dart';
+import 'package:tencent_cloud_chat_sdk/models/v2_tim_message.dart';
+import 'package:tencent_cloud_chat_sdk/models/v2_tim_message_extension.dart';
+import 'package:tencent_cloud_chat_sdk/models/v2_tim_message_online_url.dart';
+import 'package:tencent_cloud_chat_sdk/models/v2_tim_text_elem.dart';
+import 'package:tencent_cloud_chat_sdk/models/v2_tim_value_callback.dart';
+import 'package:tencent_cloud_chat_sdk/models/v2_tim_video_elem.dart';
+import 'package:tencent_cloud_chat_sdk/tencent_im_sdk_plugin.dart';
+
+import 'package:yumi/config/pickImage.dart';
+import 'package:yumi/ui_kit/components/dialog/dialog_base.dart';
+import 'package:yumi/ui_kit/components/sc_compontent.dart';
+import 'package:yumi/ui_kit/theme/socialchat_theme.dart';
+import 'package:yumi/app/constants/sc_global_config.dart';
+import 'package:yumi/app/config/business_logic_strategy.dart';
+import 'package:yumi/app/constants/sc_screen.dart';
+import 'package:yumi/app/routes/sc_fluro_navigator.dart';
+import 'package:yumi/shared/tools/sc_keybord_util.dart';
+import 'package:yumi/shared/tools/sc_message_notifier.dart';
+import 'package:yumi/shared/tools/sc_path_utils.dart';
+import 'package:yumi/shared/data_sources/sources/local/user_manager.dart';
+import 'package:yumi/shared/business_logic/usecases/custom_tab_selector.dart';
+import 'package:yumi/services/auth/user_profile_manager.dart';
+import 'package:yumi/modules/index/main_route.dart';
+
+import '../../shared/business_logic/models/res/sc_user_red_packet_send_res.dart';
+
+class SCMessageChatPage extends StatefulWidget {
+ final V2TimConversation? conversation;
+ final bool shrinkWrap;
+
+ //是否是房间内聊天界面。
+ final bool inRoom;
+
+ const SCMessageChatPage({
+ Key? key,
+ this.conversation,
+ this.shrinkWrap = false,
+ this.inRoom = false,
+ }) : super(key: key);
+
+ @override
+ _SCMessageChatPageState createState() => _SCMessageChatPageState();
+}
+
+class _SCMessageChatPageState extends State {
+ BusinessLogicStrategy get _strategy => SCGlobalConfig.businessLogicStrategy;
+
+ final TextEditingController _textController = TextEditingController();
+ final ScrollController _scrollController = ScrollController();
+ final RefreshController _refreshController = RefreshController();
+
+ // FlutterSoundPlayer? flutterSound;
+ RtmProvider? rtmProvider;
+ V2TimConversation? currentConversation;
+ List currentConversationMessageList = [];
+ final FocusNode _focusNode = FocusNode();
+
+ ///是否显示工具栏
+ bool showTools = false;
+ bool showEmoji = false;
+
+ bool showDoNotClickUnfamiliarTips = true;
+
+ ///互相关注才能互相发送消息
+ bool canSendMsg = false;
+ SocialChatUserProfile? friend;
+
+ ///是否显示发送按钮
+ bool showSend = false;
+
+ List coinsTitles = ["100", "1000", "10000", "50000"];
+ String selecteCoins = "100";
+
+ @override
+ void initState() {
+ super.initState();
+ SCMessageNotifier.canPlay = false;
+ SCMessageUtils.redPacketFutureCache.clear();
+
+ // flutterSound = FlutterSoundPlayer();
+
+ rtmProvider = Provider.of(context, listen: false);
+ currentConversation = widget.conversation;
+ rtmProvider?.onMessageRecvC2CReadListener = _onMessageRecvC2CRead;
+ rtmProvider?.onRevokeMessageListener = _onRevokeMessage;
+ rtmProvider?.onNewMessageCurrentConversationListener = _onNewMessage;
+ loadMsg();
+
+ if (friend == null) {
+ loadFriend();
+ }
+
+ _focusNode.addListener(() {
+ if (_focusNode.hasFocus) {
+ setState(() {
+ showTools = false;
+ showEmoji = false;
+ });
+ }
+ });
+ }
+
+ @override
+ void dispose() {
+ rtmProvider?.onMessageRecvC2CReadListener = null;
+ rtmProvider?.onRevokeMessageListener = null;
+ rtmProvider?.onNewMessageCurrentConversationListener = null;
+ super.dispose();
+ }
+
+ @override
+ Widget build(BuildContext context) {
+ return Consumer(
+ builder: (_, provider, __) {
+ return WillPopScope(
+ onWillPop: () {
+ if (showEmoji || showTools) {
+ setState(() {
+ showEmoji = false;
+ showTools = false;
+ });
+ return Future.value(false);
+ }
+ SCNavigatorUtils.goBack(context);
+ return Future.value(true);
+ },
+ child: Stack(
+ children: [
+ if (!widget.inRoom)
+ // 渐变背景
+ Positioned(
+ left: 0,
+ right: 0,
+ top: 0,
+ child: Column(
+ children: [
+ SizedBox(
+ width: ScreenUtil().screenWidth,
+ height: ScreenUtil().screenHeight,
+ child: Image.asset(
+ _strategy.getSCMessageChatPageRoomSettingBackground(),
+ fit: BoxFit.fill,
+ ),
+ ),
+ ],
+ ),
+ ),
+ Scaffold(
+ //backgroundColor: widget.inRoom ? Colors.transparent: Color(0xfff8f8f8),
+ backgroundColor: Colors.transparent,
+ // appBar: _appBar(),
+ appBar: null,
+ body: SafeArea(
+ top: widget.shrinkWrap ? false : true,
+ bottom: false,
+ child: Column(
+ children: [
+ Row(
+ children: [
+ !widget.inRoom
+ ? GestureDetector(
+ behavior: HitTestBehavior.opaque,
+ onTap: () {
+ Navigator.pop(context);
+ },
+ child: Container(
+ padding: EdgeInsets.symmetric(
+ horizontal: 10.w,
+ vertical: 10.w,
+ ),
+ child: Icon(
+ SCGlobalConfig.lang == "ar"
+ ? Icons.keyboard_arrow_right
+ : Icons.keyboard_arrow_left,
+ size: 28.w,
+ color: Colors.white,
+ ),
+ ),
+ )
+ : Container(),
+ SizedBox(width: 5.w),
+ Expanded(
+ child: Container(
+ alignment: AlignmentDirectional.center,
+ child: socialchatNickNameText(
+ friend?.userNickname ?? "",
+ fontSize: 14.sp,
+ fontWeight: FontWeight.w500,
+ textColor: Colors.white,
+ type: "",
+ needScroll:
+ (friend?.userNickname?.characters.length ??
+ 0) >
+ 22,
+ ),
+ ),
+ ),
+ GestureDetector(
+ behavior: HitTestBehavior.opaque,
+ onTap: () {
+ SCNavigatorUtils.push(
+ context,
+ replace: true,
+ "${SCMainRoute.person}?isMe=${AccountStorage().getCurrentUser()?.userProfile?.id == friend?.id}&tageId=${friend?.id}",
+ );
+ },
+ child: Container(
+ padding: EdgeInsets.symmetric(horizontal: 10.w),
+ child: Icon(
+ Icons.more_vert,
+ size: 22.w,
+ color: Colors.white,
+ ),
+ ),
+ ),
+ ],
+ ),
+ Expanded(child: _msgList()),
+ Container(
+ decoration: BoxDecoration(
+ //color: Colors.white,
+ //border: Border(top: BorderSide(color: Color(0xfff1f1f1)))
+ ),
+ child: SafeArea(
+ top: false,
+ child: Column(
+ children: [
+ if (currentConversation?.conversationID !=
+ "administrator")
+ _input(),
+ _tools(provider),
+ _emoji(),
+ // _fahongbao(),
+ ],
+ ),
+ ),
+ ),
+ ],
+ ),
+ ),
+ ),
+ ],
+ ),
+ );
+ },
+ );
+ }
+
+ void loadFriend() {
+ SCLoadingManager.show();
+ Future.wait([
+ SCAccountRepository().loadUserInfo("${currentConversation?.userID}"),
+ SCAccountRepository().friendRelationCheck(
+ "${currentConversation?.userID}",
+ ),
+ ])
+ .then((result) {
+ SCLoadingManager.hide();
+ friend = result[0] as SocialChatUserProfile;
+ canSendMsg = result[1] as bool;
+ setState(() {});
+ })
+ .catchError((e) {
+ SCLoadingManager.hide();
+ });
+ }
+
+ ///消息列表
+ Widget _msgList() {
+ print('xiaoxiliebiao:${currentConversationMessageList.length}');
+ return SmartRefresher(
+ enablePullDown: false,
+ enablePullUp: true,
+ onLoading: () async {
+ print('onLoading');
+ if (currentConversationMessageList.isNotEmpty) {
+ // 拉取单聊历史消息
+ // 首次拉取,lastMsgID 设置为 null
+ // 再次拉取时,lastMsgID 可以使用返回的消息列表中的最后一条消息的id
+ V2TimValueCallback> v2timValueCallback =
+ await TencentImSDKPlugin.v2TIMManager
+ .getMessageManager()
+ .getC2CHistoryMessageList(
+ userID: currentConversation!.userID ?? "",
+ count: 30,
+ lastMsgID: currentConversationMessageList.last.msgID,
+ );
+ List messages =
+ v2timValueCallback.data as List;
+ print('加载前:${currentConversationMessageList.length}');
+ currentConversationMessageList.addAll(messages);
+ print('加载后:${currentConversationMessageList.length}');
+ if (messages.length == 30) {
+ _refreshController.loadComplete();
+ } else {
+ _refreshController.loadNoData();
+ }
+ } else {
+ _refreshController.loadNoData();
+ }
+ setState(() {});
+ },
+ footer: CustomFooter(
+ height: 1,
+ builder: (context, mode) {
+ return SizedBox(
+ height: 1,
+ width: 1,
+ child: SizedBox(height: 1, width: 1),
+ );
+ },
+ ),
+ controller: _refreshController,
+ child: CustomScrollView(
+ shrinkWrap: true,
+ controller: _scrollController,
+ reverse: true,
+ physics: const ClampingScrollPhysics(),
+ // 禁用回弹效果
+ slivers: [
+ SliverList(
+ delegate: SliverChildBuilderDelegate(
+ (c, i) => _MessageItem(
+ message: currentConversationMessageList[i],
+ preMessage:
+ i < currentConversationMessageList.length - 1
+ ? currentConversationMessageList[i + 1]
+ : null,
+ isSystem:
+ currentConversationMessageList[i].sender == "administrator",
+ friend: friend,
+ currentConversationMessageList: currentConversationMessageList,
+ updateCall: () {
+ setState(() {});
+ },
+ ),
+ childCount: currentConversationMessageList.length,
+ ),
+ ),
+ ],
+ ),
+ );
+ }
+
+ Future loadMsg() async {
+ // 1. 在初始化时,添加高级消息监听器
+ TencentImSDKPlugin.v2TIMManager.getMessageManager().addAdvancedMsgListener(
+ listener: V2TimAdvancedMsgListener(
+ // 监听消息扩展更新
+ onRecvMessageExtensionsChanged: (msgID, extensions) {
+ for (var ext in extensions) {
+ if (ext.extensionKey == "packetID") {
+ String packetID = ext.extensionValue;
+ SCMessageUtils.redPacketFutureCache[packetID] =
+ SCAccountRepository().userRedPacketDetail(packetID);
+ setState(() {});
+ break;
+ }
+ }
+ },
+ ),
+ );
+ V2TimValueCallback> v2timValueCallback =
+ await TencentImSDKPlugin.v2TIMManager
+ .getMessageManager()
+ .getC2CHistoryMessageList(
+ userID: currentConversation!.userID!,
+ count: 100,
+ lastMsgID: null,
+ );
+ List messages = v2timValueCallback.data!;
+ // List messages = await FTIM.getMessageManager().getMessages(conversation: currentConversation);
+ print("messages : ${messages?.length ?? 0}");
+ currentConversationMessageList ??= [];
+ currentConversationMessageList?.clear();
+
+ for (var msg in messages) {
+ if (!msg.isSelf! && msg.isPeerRead!) {
+ TencentImSDKPlugin.v2TIMManager
+ .getMessageManager()
+ .sendMessageReadReceipts(messageIDList: [msg.msgID!]);
+ }
+ }
+ currentConversationMessageList.insertAll(0, messages ?? []);
+ setState(() {});
+ }
+
+ ///输入栏
+ Widget _input() {
+ return Consumer(
+ builder:
+ (_, provider, __) => Container(
+ color: Colors.transparent,
+ height: 56.w,
+ child: Row(
+ crossAxisAlignment: CrossAxisAlignment.center,
+ children: [
+ SizedBox(width: 15.w),
+ Expanded(
+ child: Container(
+ height: 34.w,
+ decoration: BoxDecoration(
+ borderRadius: BorderRadius.circular(52.w),
+ color: Color(0xff18F2B1).withOpacity(0.1),
+ ),
+ child: Row(
+ children: [
+ Expanded(
+ child: ExtendedTextField(
+ controller: _textController,
+ focusNode: _focusNode,
+ onChanged: (s) {
+ setState(() {
+ showSend = _textController.text.isNotEmpty;
+ });
+ },
+ onSubmitted: (s) {
+ if (s.isNotEmpty) {
+ sendMsg(s);
+ showSend = false;
+ setState(() {});
+ _scrollController.jumpTo(0.0);
+ _textController.clear();
+ }
+ },
+ decoration: InputDecoration(
+ hintText:
+ SCAppLocalizations.of(
+ context,
+ )!.clickHereToStartChatting,
+ hintStyle: TextStyle(
+ color: Color(0xff999999),
+ fontSize: 14.sp,
+ ),
+ contentPadding: const EdgeInsets.symmetric(
+ horizontal: 15,
+ ),
+ counterText: '',
+ isDense: true,
+ filled: false,
+ focusColor: Colors.transparent,
+ hoverColor: Colors.transparent,
+ border: InputBorder.none,
+ enabledBorder: InputBorder.none,
+ focusedBorder: InputBorder.none,
+ disabledBorder: InputBorder.none,
+ errorBorder: InputBorder.none,
+ focusedErrorBorder: InputBorder.none,
+ ),
+ style: TextStyle(
+ fontSize: ScreenUtil().setSp(14),
+ color: Colors.white,
+ ),
+ ),
+ ),
+ //原来的emoji按钮
+ //SizedBox(width: 10.w,),
+ ],
+ ),
+ ),
+ ),
+ SizedBox(width: 10.w),
+ !showEmoji
+ ? GestureDetector(
+ behavior: HitTestBehavior.opaque,
+ onTap: () {
+ SCKeybordUtil.hide(context);
+ setState(() {
+ if (showTools) {
+ showTools = false;
+ }
+ showEmoji = !showEmoji;
+ });
+ },
+ child: Image.asset(
+ _strategy.getSCMessageChatPageEmojiIcon(),
+ width: 24.w,
+ color: Colors.white,
+ fit: BoxFit.fill,
+ ),
+ )
+ : Container(),
+ showEmoji
+ ? GestureDetector(
+ behavior: HitTestBehavior.opaque,
+ onTap: () {
+ SCKeybordUtil.hide(context);
+ setState(() {
+ if (showTools) {
+ showTools = false;
+ }
+ showEmoji = !showEmoji;
+ });
+ },
+ child: Image.asset(
+ _strategy.getSCMessageChatPageChatKeyboardIcon(),
+ width: 24.w,
+ color: Colors.white,
+ fit: BoxFit.fill,
+ ),
+ )
+ : Container(),
+ if (!showSend) SizedBox(width: 12.w),
+ if (showSend) SizedBox(width: 5.w),
+ Visibility(
+ visible: !showSend,
+ child: GestureDetector(
+ behavior: HitTestBehavior.opaque,
+ onTap: () {
+ SCKeybordUtil.hide(context);
+ setState(() {
+ if (showEmoji) {
+ showEmoji = false;
+ }
+ showTools = !showTools;
+ });
+ },
+ child: Image.asset(
+ _strategy.getSCMessageChatPageAddIcon(),
+ width: 24.w,
+ color: Colors.white,
+ fit: BoxFit.fill,
+ ),
+ ),
+ ),
+ Visibility(
+ visible: showSend,
+ child: GestureDetector(
+ behavior: HitTestBehavior.opaque,
+ onTap: () async {
+ _scrollController.jumpTo(0.0);
+ if (_textController.text.isNotEmpty) {
+ SCKeybordUtil.hide(context);
+ sendMsg(_textController.text);
+ showSend = false;
+ setState(() {});
+ _textController.clear();
+ }
+ },
+ child: Image.asset(
+ _strategy.getSCMessageChatPageSendMessageIcon(),
+ height: 22.w,
+ color: Colors.white,
+ width: 32.w,
+ ),
+ ),
+ ),
+ SizedBox(width: 15.w),
+ ],
+ ),
+ ),
+ );
+ }
+
+ ///发消息
+ sendMsg(String msg) async {
+ if (!canSendMsg) {
+ SCTts.show(SCAppLocalizations.of(context)!.canSendMsgTips);
+ return;
+ }
+ Provider.of(
+ context,
+ listen: false,
+ ).sendC2CTextMsg(msg, currentConversation!);
+ }
+
+ ///发消息
+ sendCustomMsg(String msg, String extension) async {
+ if (!canSendMsg) {
+ SCTts.show(SCAppLocalizations.of(context)!.canSendMsgTips);
+ return;
+ }
+ Provider.of(
+ context,
+ listen: false,
+ ).sendC2CCustomMsg(msg, currentConversation!, extension);
+ }
+
+ ///工具栏
+ Widget _tools(RtmProvider provider) {
+ return Visibility(
+ visible: showTools,
+ child: Container(
+ color: Colors.white,
+ padding: EdgeInsets.only(bottom: 18.w, top: 5.w),
+ child: Row(
+ mainAxisAlignment: MainAxisAlignment.start,
+ mainAxisSize: MainAxisSize.max,
+ children: [
+ SizedBox(width: 20.w),
+ Expanded(
+ child: _toolsItem(
+ _strategy.getSCMessageChatPageCameraIcon(),
+ SCAppLocalizations.of(context)!.camera,
+ () async {
+ if (!canSendMsg) {
+ SCTts.show(SCAppLocalizations.of(context)!.canSendMsgTips);
+ return;
+ }
+ var pick = await ImagePick.pickFromCamera(context);
+ if (pick != null) {
+ provider.sendImageMsg(
+ file: pick,
+ conversation: currentConversation!,
+ );
+ }
+ },
+ ),
+ ),
+ Expanded(
+ child: _toolsItem(
+ _strategy.getSCMessageChatPagePictureIcon(),
+ SCAppLocalizations.of(context)!.album,
+ () async {
+ if (!canSendMsg) {
+ SCTts.show(SCAppLocalizations.of(context)!.canSendMsgTips);
+ return;
+ }
+ final List? result =
+ await ImagePick.pickPicAndVideoFromGallery(context);
+
+ if (result == null) return; // 用户取消选择
+ if (result.isNotEmpty) {
+ provider.sendImageMsg(
+ selectedList: result,
+ conversation: currentConversation!,
+ );
+ }
+ },
+ ),
+ ),
+ Expanded(flex: 1, child: SizedBox()),
+ Expanded(flex: 1, child: SizedBox()),
+ ],
+ ),
+ ),
+ );
+ }
+
+ _emoji() {
+ return Visibility(
+ visible: showEmoji,
+ child: Container(
+ color: Colors.white,
+ height: 150.w,
+ child: GridView.builder(
+ padding: EdgeInsets.symmetric(horizontal: 15.w),
+ gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
+ crossAxisCount: 8,
+ crossAxisSpacing: 8.w,
+ mainAxisSpacing: 8.w,
+ ),
+ itemBuilder: (c, index) {
+ return GestureDetector(
+ behavior: HitTestBehavior.opaque,
+ onTap: () {
+ var text = SCEmojiDatas.smileys[index];
+ final TextEditingValue value = _textController.value;
+ _textController.value = value.copyWith(
+ text: value.text + text,
+ selection: TextSelection.fromPosition(
+ TextPosition(offset: text.length),
+ ),
+ );
+ showSend = true;
+ setState(() {});
+ },
+ child: Padding(
+ padding: EdgeInsets.all(4.0.w),
+ child: ExtendedText(
+ SCEmojiDatas.smileys[index],
+ // specialTextSpanBuilder: MySpecialTextSpanBuilder(),
+ style: TextStyle(fontSize: sp(15)),
+ ),
+ ),
+ );
+ },
+ itemCount: SCEmojiDatas.smileys.length,
+ ),
+ ),
+ );
+ }
+
+ ///工具项
+ _toolsItem(String image, String title, Function() onclick) {
+ return GestureDetector(
+ behavior: HitTestBehavior.opaque,
+ onTap: onclick,
+ child: Column(
+ children: [
+ Image.asset(image, width: 50.w, fit: BoxFit.fitWidth),
+ SizedBox(height: 9.w),
+ Text(title, style: TextStyle(fontSize: 11.sp, color: Colors.black)),
+ ],
+ ),
+ );
+ }
+
+ _onRevokeMessage(String msgId) {
+ int index = 0;
+ for (var msg in currentConversationMessageList) {
+ if (msgId == msg.msgID) {
+ break;
+ }
+ index = index + 1;
+ }
+ currentConversationMessageList.removeAt(index);
+ setState(() {});
+ }
+
+ _onMessageRecvC2CRead(List messageIDList) {
+ for (var msg in currentConversationMessageList) {
+ for (var id in messageIDList) {
+ if (id == msg.msgID) {
+ msg.isPeerRead = true;
+ }
+ }
+ }
+ setState(() {});
+ }
+
+ _onNewMessage(V2TimMessage? message, {String? msgId}) async {
+ if (message == null) {
+ return;
+ }
+ if (message.userID != currentConversation?.userID) return;
+
+ int? index;
+ for (var element in currentConversationMessageList) {
+ if (msgId != null) {
+ if (msgId == element.msgID) {
+ element.status = MessageStatus.V2TIM_MSG_STATUS_SEND_FAIL;
+ setState(() {});
+ continue;
+ }
+ } else {
+ if (element.msgID == message.msgID) {
+ index = currentConversationMessageList.indexOf(element);
+ continue;
+ }
+ }
+ }
+ if (msgId != null) {
+ return;
+ }
+ if (index != null) {
+ currentConversationMessageList.removeAt(index!);
+ currentConversationMessageList.insert(index!, message);
+ } else {
+ currentConversationMessageList.insert(0, message);
+ }
+ await TencentImSDKPlugin.v2TIMManager
+ .getMessageManager()
+ .markC2CMessageAsRead(userID: currentConversation!.userID!);
+ //发送已读回执
+ await TencentImSDKPlugin.v2TIMManager
+ .getMessageManager()
+ .sendMessageReadReceipts(messageIDList: [message.msgID!]);
+ setState(() {});
+ // await FTIM.getContactManager().setReadMessage(currentConversation);
+ }
+}
+
+class _MessageItem extends StatelessWidget {
+ final V2TimMessage message;
+ final V2TimMessage? preMessage;
+
+ BusinessLogicStrategy get _strategy => SCGlobalConfig.businessLogicStrategy;
+
+ // final FTIMUserProfile userProfile;
+ final SocialChatUserProfile? friend;
+ bool isSystem = false;
+ List currentConversationMessageList = [];
+ Function updateCall;
+
+ ///上一条
+ late BuildContext context;
+
+ _MessageItem({
+ required this.message,
+ this.preMessage,
+ // this.userProfile,
+ this.isSystem = false,
+ required this.currentConversationMessageList,
+ this.friend,
+ required this.updateCall,
+ });
+
+ @override
+ Widget build(BuildContext context) {
+ this.context = context;
+ SocialChatUserProfile? me = AccountStorage().getCurrentUser()?.userProfile;
+ bool showTime = true;
+ int timestamp = (message.timestamp ?? 0) * 1000;
+ int preTimestamp = (preMessage?.timestamp ?? 0) * 1000;
+ if (preMessage != null) {
+ ///5分钟以内 不显示
+ // print('timestamp:$timestamp===preTimestamp:${preTimestamp}');
+ if (DateTime.fromMillisecondsSinceEpoch(timestamp)
+ .difference(DateTime.fromMillisecondsSinceEpoch(preTimestamp))
+ .inMilliseconds <
+ 1000 * 60 * 5) {
+ showTime = false;
+ }
+ }
+ String time = SCMDateUtils.formatMessageTime(
+ context,
+ DateTime.fromMillisecondsSinceEpoch(timestamp ?? 0),
+ );
+ if (message.status == MessageStatus.V2TIM_MSG_STATUS_LOCAL_REVOKED) {
+ return Container(
+ alignment: AlignmentDirectional.center,
+ padding: EdgeInsets.symmetric(horizontal: 5.w, vertical: 5.w),
+ child: text(
+ SCAppLocalizations.of(context)!.messageHasBeenRecalled,
+ fontSize: 12.sp,
+ textColor: Colors.white54,
+ fontWeight: FontWeight.w400,
+ ),
+ );
+ }
+ return Container(
+ margin: EdgeInsets.symmetric(horizontal: 15.w, vertical: 8.w),
+ child: Column(
+ crossAxisAlignment:
+ !message.isSelf!
+ ? CrossAxisAlignment.start
+ : CrossAxisAlignment.end,
+ // textDirection: message.isSelf ? TextDirection.rtl : TextDirection.ltr,
+ children: [
+ Visibility(
+ visible: showTime,
+ child: Container(
+ margin: EdgeInsets.only(bottom: 12.w),
+ child: Row(
+ children: [
+ Spacer(),
+ Container(
+ alignment: Alignment.center,
+ padding: EdgeInsets.symmetric(
+ horizontal: width(15),
+ vertical: 8.w,
+ ),
+ decoration: BoxDecoration(
+ //color: Color(0xFFEAEFF7),
+ borderRadius: BorderRadius.all(
+ Radius.circular(height(13)),
+ ),
+ ),
+ child: Text(
+ time,
+ style: TextStyle(
+ fontSize: sp(12),
+ color: Colors.white54,
+ fontWeight: FontWeight.w400,
+ decoration: TextDecoration.none,
+ height: 1,
+ ),
+ ),
+ ),
+ Spacer(),
+ ],
+ ),
+ ),
+ ),
+ Row(
+ crossAxisAlignment: CrossAxisAlignment.start,
+ mainAxisSize: MainAxisSize.min,
+ textDirection:
+ message.isSelf! ? TextDirection.rtl : TextDirection.ltr,
+ children: [
+ GestureDetector(
+ behavior: HitTestBehavior.opaque,
+ onTap: () {
+ if (isSystem) {
+ return;
+ }
+ SCNavigatorUtils.push(
+ context,
+ replace:
+ AccountStorage().getCurrentUser()?.userProfile?.id !=
+ message.sender,
+ "${SCMainRoute.person}?isMe=${AccountStorage().getCurrentUser()?.userProfile?.id == message.sender}&tageId=${message.sender}",
+ );
+ },
+ child:
+ message.sender == "administrator" ||
+ message.sender == "customer"
+ ? ExtendedImage.asset(
+ _strategy.getSCMessageChatPageSystemHeadImage(),
+ width: 45.w,
+ shape: BoxShape.circle,
+ fit: BoxFit.cover,
+ )
+ : netImage(
+ url:
+ message.isSelf!
+ ? (me?.userAvatar ?? "")
+ : (friend?.userAvatar ?? ""),
+ shape: BoxShape.circle,
+ width: width(45),
+ ),
+ ),
+ // 他人消息的阴影间隔是10dp
+ Container(width: 8.w),
+ Row(
+ textDirection:
+ message.isSelf! ? TextDirection.rtl : TextDirection.ltr,
+ children: [
+ Container(
+ alignment:
+ message.isSelf!
+ ? AlignmentDirectional.topEnd
+ : AlignmentDirectional.topStart,
+ margin: EdgeInsets.only(top: 4.w),
+ child: _msg(),
+ ),
+ SizedBox(width: 6.w),
+ Visibility(
+ visible:
+ message.status ==
+ MessageStatus.V2TIM_MSG_STATUS_SENDING,
+ child: CupertinoActivityIndicator(),
+ ),
+
+ Visibility(
+ visible:
+ message.status ==
+ MessageStatus.V2TIM_MSG_STATUS_SEND_FAIL,
+ child: Icon(Icons.error, color: Colors.red),
+ ),
+ ],
+ ),
+ Spacer(),
+ ],
+ ),
+ ],
+ ),
+ );
+ }
+
+ _msg() {
+ V2TIMElem? elem = message.textElem;
+ if (message.elemType == MessageElemType.V2TIM_ELEM_TYPE_TEXT) {
+ V2TimTextElem textElem = elem as V2TimTextElem;
+ String content = textElem.text ?? "";
+ } else if (message.elemType == MessageElemType.V2TIM_ELEM_TYPE_IMAGE) {
+ V2TimImageElem imageElem = message.imageElem as V2TimImageElem;
+ var image;
+ if (imageElem.path!.length > 2 &&
+ File("${imageElem.path}").existsSync()) {
+ image = Image.file(File(imageElem.path!), fit: BoxFit.cover);
+ } else {
+ image = ExtendedImage.network(
+ '${imageElem.imageList![1]?.url}',
+ fit: BoxFit.cover,
+ width: double.infinity,
+ cache: true,
+ shape: BoxShape.rectangle,
+ borderRadius: BorderRadius.all(Radius.circular(width(6))),
+ loadStateChanged: (ExtendedImageState state) {
+ if (state.extendedImageLoadState == LoadState.completed) {
+ return ExtendedRawImage(
+ image: state.extendedImageInfo?.image,
+ fit: BoxFit.cover,
+ );
+ } else {
+ return Image.asset(
+ _strategy.getSCMessageChatPageLoadingIcon(),
+ fit: BoxFit.cover,
+ );
+ }
+ },
+ );
+ }
+ return Builder(
+ builder: (ct) {
+ return GestureDetector(
+ onTap: () {
+ List ims = [];
+ int initialIndex = 0;
+ int index = 0;
+ for (var imageMsg in currentConversationMessageList) {
+ if (imageMsg.elemType ==
+ MessageElemType.V2TIM_ELEM_TYPE_IMAGE) {
+ String path = imageMsg.imageElem?.imageList![1]?.url ?? "";
+ if (path.isNotEmpty) {
+ ims.add(imageMsg.imageElem?.imageList![1]?.url ?? "");
+ if (imageMsg.msgID == message.msgID) {
+ initialIndex = index;
+ }
+ index = index + 1;
+ }
+ }
+ }
+ String encodedUrls = Uri.encodeComponent(jsonEncode(ims));
+ SCNavigatorUtils.push(
+ context,
+ "${SCMainRoute.imagePreview}?imageUrls=$encodedUrls&initialIndex=$initialIndex",
+ );
+ },
+ onLongPress: () {
+ _showMsgItemMenu(ct, "");
+ },
+ child: Container(
+ constraints: BoxConstraints(maxWidth: 200.w),
+ child: ClipRRect(
+ borderRadius: BorderRadius.circular(6.w),
+ child: image,
+ ),
+ ),
+ );
+ },
+ );
+ } else if (message.elemType == MessageElemType.V2TIM_ELEM_TYPE_VIDEO) {
+ V2TimVideoElem videoElem = message.videoElem as V2TimVideoElem;
+ if (videoElem.snapshotPath != null &&
+ videoElem.snapshotPath!.isNotEmpty) {
+ return Builder(
+ builder: (ct) {
+ return GestureDetector(
+ child: Container(
+ constraints: BoxConstraints(maxWidth: 200.w),
+ child: ClipRRect(
+ borderRadius: BorderRadius.circular(6.w),
+ child: Stack(
+ alignment: Alignment.center,
+ children: [
+ Image.file(
+ File(videoElem.snapshotPath!),
+ fit: BoxFit.cover,
+ ),
+ Icon(Icons.play_circle, color: Colors.white, size: 55.w),
+ ],
+ ),
+ ),
+ ),
+ onTap: () {
+ String encodedVideoUrl = Uri.encodeComponent(
+ videoElem.videoPath ?? "",
+ );
+ SCNavigatorUtils.push(
+ context,
+ "${SCMainRoute.videoPlayer}?videoUrl=$encodedVideoUrl",
+ );
+ },
+ onLongPress: () {
+ _showMsgItemMenu(ct, "");
+ },
+ );
+ },
+ );
+ } else {
+ return FutureBuilder>(
+ // 假设 getMessageOnlineUrlForMessage 是对 TencentImSDKPlugin.v2TIMManager.getMessageManager().getMessageOnlineUrl 的封装,返回 Future
+ future: SCMessageUtils().getMessageOnlineUrl(
+ msgID: message.msgID ?? "",
+ ),
+ builder: (context, snapshot) {
+ // 根据异步任务状态构建UI
+ if (snapshot.connectionState == ConnectionState.waiting) {
+ // 数据加载中,显示占位符
+ return Container();
+ } else if (snapshot.hasError) {
+ // 数据加载失败,显示错误UI
+ return Container();
+ } else if (snapshot.hasData) {
+ // 数据加载成功,更新消息的mediaUrl并构建正常消息UI
+ message.videoElem = snapshot.data?.data?.videoElem!;
+ return Builder(
+ builder: (ct) {
+ return GestureDetector(
+ child: Container(
+ constraints: BoxConstraints(maxWidth: 200.w),
+ child: ClipRRect(
+ borderRadius: BorderRadius.circular(6.w),
+ child: Stack(
+ alignment: Alignment.center,
+ children: [
+ SCPathUtils.getPathType(
+ message.videoElem?.snapshotPath ?? "",
+ ) ==
+ PathType.file
+ ? Image.file(
+ File(message.videoElem?.snapshotPath ?? ""),
+ fit: BoxFit.cover,
+ )
+ : netImage(
+ url: message.videoElem?.snapshotUrl ?? "",
+ ),
+ Icon(
+ Icons.play_circle,
+ color: Colors.white,
+ size: 55.w,
+ ),
+ ],
+ ),
+ ),
+ ),
+ onTap: () {
+ String encodedVideoUrl = Uri.encodeComponent(
+ message.videoElem?.videoUrl ?? "",
+ );
+ SCNavigatorUtils.push(
+ context,
+ "${SCMainRoute.videoPlayer}?videoUrl=$encodedVideoUrl",
+ );
+ },
+ onLongPress: () {
+ _showMsgItemMenu(ct, "");
+ },
+ );
+ },
+ );
+ } else {
+ // 其他情况
+ return Container();
+ }
+ },
+ );
+ }
+ }
+
+ return _text();
+ }
+
+ ///文本消息
+ _text() {
+ String content = "";
+ if (message.elemType == MessageElemType.V2TIM_ELEM_TYPE_TEXT) {
+ V2TimTextElem textElem = message.textElem!;
+ content = textElem.text ?? "";
+ if (isSystem) {}
+ } else if (message.elemType == MessageElemType.V2TIM_ELEM_TYPE_IMAGE) {
+ content = SCAppLocalizations.of(context)!.image;
+ } else if (message.elemType == MessageElemType.V2TIM_ELEM_TYPE_VIDEO) {
+ content = SCAppLocalizations.of(context)!.video;
+ } else if (message.elemType == MessageElemType.V2TIM_ELEM_TYPE_SOUND) {
+ content = SCAppLocalizations.of(context)!.sound;
+ } else if (message.elemType == MessageElemType.V2TIM_ELEM_TYPE_CUSTOM) {
+ V2TimCustomElem customElem = message.customElem!;
+ content = customElem.data ?? "";
+ }
+
+ return Builder(
+ builder: (ct) {
+ return GestureDetector(
+ child: Container(
+ decoration: BoxDecoration(
+ color: Color(0xff18F2B1).withOpacity(0.1),
+ borderRadius: BorderRadius.only(
+ topLeft:
+ message.isSelf! ? Radius.circular(8) : Radius.circular(0),
+ topRight: Radius.circular(8.w),
+ bottomLeft: Radius.circular(8.w),
+ bottomRight:
+ message.isSelf! ? Radius.circular(0) : Radius.circular(8),
+ ),
+ ),
+ padding: EdgeInsets.all(8.0.w),
+ child: Container(
+ constraints: BoxConstraints(maxWidth: width(220)),
+ child: ExtendedText(
+ content,
+ // specialTextSpanBuilder: MySpecialTextSpanBuilder(),
+ style: TextStyle(
+ fontSize: sp(14),
+ color: message.isSelf! ? Colors.white : Colors.white,
+ ),
+ ),
+ ),
+ ),
+ onLongPress: () {
+ _showMsgItemMenu(ct, content);
+ },
+ );
+ },
+ );
+ }
+
+ void _showMsgItemMenu(BuildContext ct, String content) {
+ SmartDialog.showAttach(
+ tag: "showMsgItemMenu",
+ targetContext: ct,
+ alignment: Alignment.topCenter,
+ maskColor: Colors.transparent,
+ animationType: SmartAnimationType.fade,
+ scalePointBuilder: (selfSize) => Offset(selfSize.width, 10),
+ builder: (_) {
+ return Container(
+ margin: EdgeInsets.only(bottom: 10.w),
+ decoration: BoxDecoration(
+ color: Color(0xffdcdddf),
+ borderRadius: BorderRadius.circular(10),
+ ),
+ padding: EdgeInsets.symmetric(horizontal: 10.w, vertical: 5.w),
+ child: Row(
+ mainAxisSize: MainAxisSize.min,
+ children: [
+ GestureDetector(
+ behavior: HitTestBehavior.opaque,
+ onTap: () {
+ SmartDialog.dismiss(tag: "showMsgItemMenu");
+ _delete();
+ },
+ child: Container(
+ margin: EdgeInsets.symmetric(horizontal: 8.w),
+ child: Column(
+ children: [
+ Image.asset(
+ _strategy.getSCMessageChatPageMessageMenuDeleteIcon(),
+ width: 20.w,
+ ),
+ SizedBox(height: 3.w),
+ text(
+ SCAppLocalizations.of(context)!.delete,
+ fontSize: 12.sp,
+ textColor: Color(0xff777777),
+ ),
+ ],
+ ),
+ ),
+ ),
+ content.isNotEmpty
+ ? GestureDetector(
+ behavior: HitTestBehavior.opaque,
+ onTap: () {
+ SmartDialog.dismiss(tag: "showMsgItemMenu");
+ Clipboard.setData(ClipboardData(text: content));
+ SCTts.show(
+ SCAppLocalizations.of(context)!.copiedToClipboard,
+ );
+ },
+ child: Container(
+ margin: EdgeInsets.symmetric(horizontal: 8.w),
+ child: Column(
+ children: [
+ Image.asset(
+ _strategy.getSCMessageChatPageMessageMenuCopyIcon(),
+ width: 20.w,
+ ),
+ SizedBox(height: 3.w),
+ text(
+ SCAppLocalizations.of(context)!.copy,
+ fontSize: 12.sp,
+ textColor: Color(0xff777777),
+ ),
+ ],
+ ),
+ ),
+ )
+ : Container(),
+ (message.isSelf ?? false)
+ ? GestureDetector(
+ onTap: () {
+ SmartDialog.dismiss(tag: "showMsgItemMenu");
+ _revokeMessage();
+ },
+ behavior: HitTestBehavior.opaque,
+ child: Container(
+ margin: EdgeInsets.symmetric(horizontal: 8.w),
+ child: Column(
+ children: [
+ Image.asset(
+ _strategy
+ .getSCMessageChatPageMessageMenuRecallIcon(),
+ width: 20.w,
+ ),
+ SizedBox(height: 3.w),
+ text(
+ SCAppLocalizations.of(context)!.recall,
+ fontSize: 12.sp,
+ textColor: Color(0xff777777),
+ ),
+ ],
+ ),
+ ),
+ )
+ : Container(),
+ ],
+ ),
+ );
+ },
+ );
+ }
+
+ ///撤回消息
+ void _revokeMessage() async {
+ SmartDialog.show(
+ tag: "showConfirmDialog",
+ alignment: Alignment.center,
+ debounce: true,
+ animationType: SmartAnimationType.fade,
+ builder: (_) {
+ return MsgDialog(
+ title: SCAppLocalizations.of(context)!.tips,
+ msg: SCAppLocalizations.of(context)!.recallThisMessage,
+ btnText: SCAppLocalizations.of(context)!.confirm,
+ onEnsure: () async {
+ // 撤回指定msgID的消息
+ V2TimCallback revokeMessage = await TencentImSDKPlugin.v2TIMManager
+ .getMessageManager()
+ .revokeMessage(msgID: message.msgID ?? "");
+ await TencentImSDKPlugin.v2TIMManager
+ .getMessageManager()
+ .deleteMessages(msgIDs: [message.msgID ?? ""]);
+ if (revokeMessage.code == 0) {
+ // 撤回成功
+ int index = 0;
+ for (var value in currentConversationMessageList) {
+ if (value.msgID == message.msgID) {
+ break;
+ }
+ index = index + 1;
+ }
+ currentConversationMessageList.removeAt(index);
+ updateCall();
+ } else {
+ // 撤回失败,可通过 revokeMessage.desc 获取错误描述
+ SCTts.show("fail:${revokeMessage.desc}");
+ }
+ },
+ );
+ },
+ );
+ }
+
+ ///删除消息
+ void _delete() {
+ SmartDialog.show(
+ tag: "showDeleteDialog",
+ alignment: Alignment.bottomCenter,
+ debounce: true,
+ animationType: SmartAnimationType.fade,
+ builder: (_) {
+ return SafeArea(
+ child: Container(
+ height: 168.w,
+ decoration: BoxDecoration(
+ color: Colors.white,
+ borderRadius: BorderRadius.only(
+ topLeft: Radius.circular(8.0),
+ topRight: Radius.circular(8.0),
+ ),
+ ),
+ child: Column(
+ children: [
+ SizedBox(height: 10.w),
+ Row(
+ mainAxisAlignment: MainAxisAlignment.center,
+ children: [
+ text(
+ SCAppLocalizations.of(context)!.tips,
+ fontSize: 16.sp,
+ textColor: Colors.black,
+ fontWeight: FontWeight.bold,
+ ),
+ ],
+ ),
+ SizedBox(height: 5.w),
+ Divider(height: height(1), color: SocialChatTheme.dividerColor),
+ GestureDetector(
+ child: Container(
+ padding: EdgeInsets.symmetric(vertical: 10.w),
+ color: Colors.transparent,
+ child: Row(
+ mainAxisAlignment: MainAxisAlignment.center,
+ children: [
+ text(
+ SCAppLocalizations.of(context)!.deleteFromMyDevice,
+ fontSize: 14.sp,
+ textColor: Colors.black,
+ ),
+ ],
+ ),
+ ),
+ onTap: () async {
+ V2TimCallback deleteMessageFromLocalStorage =
+ await TencentImSDKPlugin.v2TIMManager
+ .getMessageManager()
+ .deleteMessageFromLocalStorage(
+ msgID: message.msgID ?? "",
+ );
+ if (deleteMessageFromLocalStorage.code == 0) {
+ //删除成功
+ int index = 0;
+ for (var value in currentConversationMessageList) {
+ if (value.msgID == message.msgID) {
+ break;
+ }
+ index = index + 1;
+ }
+ currentConversationMessageList.removeAt(index);
+ updateCall();
+ SmartDialog.dismiss(tag: "showDeleteDialog");
+ }
+ },
+ ),
+ Divider(height: height(1), color: SocialChatTheme.dividerColor),
+ GestureDetector(
+ onTap: () async {
+ V2TimCallback deleteMessageFromLocalStorage =
+ await TencentImSDKPlugin.v2TIMManager
+ .getMessageManager()
+ .deleteMessages(msgIDs: [message.msgID ?? ""]);
+ if (deleteMessageFromLocalStorage.code == 0) {
+ //删除成功
+ int index = 0;
+ for (var value in currentConversationMessageList) {
+ if (value.msgID == message.msgID) {
+ break;
+ }
+ index = index + 1;
+ }
+ currentConversationMessageList.removeAt(index);
+ updateCall();
+ SmartDialog.dismiss(tag: "showDeleteDialog");
+ }
+ },
+ child: Container(
+ padding: EdgeInsets.symmetric(vertical: 10.w),
+ color: Colors.transparent,
+ child: Row(
+ mainAxisAlignment: MainAxisAlignment.center,
+ children: [
+ text(
+ SCAppLocalizations.of(context)!.deleteOnAllDevices,
+ fontSize: 14.sp,
+ textColor: Colors.black,
+ ),
+ ],
+ ),
+ ),
+ ),
+ Divider(height: height(1), color: SocialChatTheme.dividerColor),
+ GestureDetector(
+ onTap: () async {
+ SmartDialog.dismiss(tag: "showDeleteDialog");
+ },
+ child: Container(
+ padding: EdgeInsets.symmetric(vertical: 10.w),
+ color: Colors.transparent,
+ child: Row(
+ mainAxisAlignment: MainAxisAlignment.center,
+ children: [
+ text(
+ SCAppLocalizations.of(context)!.cancel,
+ fontSize: 14.sp,
+ textColor: Colors.black,
+ ),
+ ],
+ ),
+ ),
+ ),
+ ],
+ ),
+ ),
+ );
+ },
+ );
+ }
+
+ Future updateRedPacketStatus(String messageID, String packetID) async {
+ // 构建扩展信息,例如标记为已领取,并包含领取者ID
+ Map extensionMap = {"packetID": packetID};
+
+ List extensions =
+ extensionMap.entries
+ .map(
+ (e) => V2TimMessageExtension(
+ extensionKey: e.key,
+ extensionValue: e.value,
+ ),
+ )
+ .toList();
+
+ await TencentImSDKPlugin.v2TIMManager
+ .getMessageManager()
+ .setMessageExtensions(
+ msgID: messageID, // 原始红包消息的ID
+ extensions: extensions,
+ );
+ }
+
+ void _showOpenDialog(SCUserRedPacketSendRes resData) {
+ SmartDialog.show(
+ tag: "showOpenDialog",
+ alignment: Alignment.center,
+ debounce: true,
+ animationType: SmartAnimationType.fade,
+ builder: (_) {
+ return Container(
+ height: 400.w,
+ alignment: Alignment.topCenter,
+ decoration: BoxDecoration(
+ image: DecorationImage(
+ image: AssetImage(
+ _strategy.getSCMessageChatPageRedEnvelopeOpenBackground(),
+ ),
+ fit: BoxFit.fill,
+ ),
+ ),
+ child: Column(
+ children: [
+ SizedBox(height: 100.w),
+ SCDebounceWidget(
+ child: Container(
+ alignment: Alignment.center,
+ width: 60.w,
+ height: 60.w,
+ color: Colors.transparent,
+ child: text(
+ SCAppLocalizations.of(context)!.open,
+ textColor: Colors.white,
+ fontSize: 16.sp,
+ fontWeight: FontWeight.w900,
+ ),
+ ),
+ onTap: () {
+ SmartDialog.dismiss(tag: "showOpenDialog");
+ SCLoadingManager.show();
+ SCAccountRepository()
+ .userRedPacketGrab(resData.packetId ?? "")
+ .then((res) {
+ var future = SCAccountRepository().userRedPacketDetail(
+ resData.packetId ?? "",
+ );
+ updateRedPacketStatus(
+ message.msgID ?? "",
+ resData.packetId ?? "",
+ );
+ SCMessageUtils.redPacketFutureCache[resData.packetId ??
+ ""] =
+ future;
+ future
+ .then((res2) {
+ SCLoadingManager.hide();
+ updateCall();
+ _showOpenedDialog(res2);
+ })
+ .catchError((e) {
+ SCLoadingManager.hide();
+ });
+ })
+ .catchError((e) {
+ SCLoadingManager.hide();
+ });
+ },
+ ),
+ SizedBox(height: 35.w),
+ Row(
+ mainAxisAlignment: MainAxisAlignment.center,
+ children: [
+ text(
+ SCAppLocalizations.of(context)!.openRedPackDialogTip,
+ fontWeight: FontWeight.w600,
+ textColor: Colors.white,
+ fontSize: 14.sp,
+ ),
+ SizedBox(width: 3.w),
+ Container(
+ margin: EdgeInsets.only(bottom: 1.w),
+ height: 18.w,
+ constraints: BoxConstraints(maxWidth: 65.w),
+ child:
+ (resData.senderInfo?.nickName?.length ?? 0) > 6
+ ? Marquee(
+ text: resData.senderInfo?.nickName ?? "",
+ style: TextStyle(
+ fontSize: 14.sp,
+ color: Colors.white,
+ fontWeight: FontWeight.w600,
+ decoration: TextDecoration.none,
+ ),
+ scrollAxis: Axis.horizontal,
+ crossAxisAlignment: CrossAxisAlignment.start,
+ blankSpace: 20.0,
+ velocity: 40.0,
+ pauseAfterRound: Duration(seconds: 1),
+ accelerationDuration: Duration(seconds: 1),
+ accelerationCurve: Curves.easeOut,
+ decelerationDuration: Duration(milliseconds: 550),
+ decelerationCurve: Curves.easeOut,
+ )
+ : Text(
+ resData.senderInfo?.nickName ?? "",
+ maxLines: 1,
+ overflow: TextOverflow.ellipsis,
+ style: TextStyle(
+ fontSize: 14.sp,
+ color: Colors.white,
+ fontWeight: FontWeight.w600,
+ decoration: TextDecoration.none,
+ ),
+ ),
+ ),
+ SizedBox(width: 3.w),
+ Container(
+ child: text(
+ SCAppLocalizations.of(context)!.sent,
+ fontWeight: FontWeight.w600,
+ textColor: Colors.white,
+ fontSize: 14.sp,
+ ),
+ height: 18.w,
+ ),
+ ],
+ ),
+ SizedBox(height: 15.w),
+ Row(
+ crossAxisAlignment: CrossAxisAlignment.center,
+ mainAxisAlignment: MainAxisAlignment.center,
+ children: [
+ text(
+ SCAppLocalizations.of(context)!.wishingYouHappinessEveryDay,
+ fontWeight: FontWeight.w600,
+ textColor: Colors.white70,
+ fontSize: 13.sp,
+ ),
+ ],
+ ),
+ ],
+ ),
+ );
+ },
+ );
+ }
+
+ void _showOpenedDialog(SCUserRedPacketSendRes resData) {
+ SmartDialog.show(
+ tag: "showOpenedDialog",
+ alignment: Alignment.center,
+ debounce: true,
+ animationType: SmartAnimationType.fade,
+ builder: (_) {
+ return Container(
+ margin: EdgeInsets.symmetric(horizontal: 20.w),
+ decoration: BoxDecoration(
+ image: DecorationImage(
+ image: AssetImage(
+ _strategy.getSCMessageChatPageRedEnvelopeOpenedBackground(),
+ ),
+ fit: BoxFit.fill,
+ ),
+ ),
+ child: Column(
+ mainAxisSize: MainAxisSize.min,
+ children: [
+ SizedBox(height: 70.w),
+ Row(
+ mainAxisAlignment: MainAxisAlignment.end,
+ children: [
+ GestureDetector(
+ child: Icon(Icons.close, size: 18.w, color: Colors.white),
+ onTap: () {
+ SmartDialog.dismiss(tag: "showOpenedDialog");
+ },
+ ),
+ SizedBox(width: 10.w),
+ ],
+ ),
+ SizedBox(height: 25.w),
+ Row(
+ mainAxisAlignment: MainAxisAlignment.start,
+ crossAxisAlignment: CrossAxisAlignment.center,
+ children: [
+ SizedBox(width: 20.w),
+ netImage(
+ url: resData.senderInfo?.avatar ?? "",
+ shape: BoxShape.circle,
+ width: 45.w,
+ height: 45.w,
+ ),
+ SizedBox(width: 10.w),
+ Column(
+ crossAxisAlignment: CrossAxisAlignment.start,
+ children: [
+ Row(
+ children: [
+ Container(
+ height: 18.w,
+ constraints: BoxConstraints(maxWidth: 85.w),
+ child:
+ (resData.senderInfo?.nickName?.length ?? 0) > 8
+ ? Marquee(
+ text: resData.senderInfo?.nickName ?? "",
+ style: TextStyle(
+ fontSize: 14.sp,
+ color: Colors.white,
+ fontWeight: FontWeight.w600,
+ decoration: TextDecoration.none,
+ ),
+ scrollAxis: Axis.horizontal,
+ crossAxisAlignment:
+ CrossAxisAlignment.start,
+ blankSpace: 20.0,
+ velocity: 40.0,
+ pauseAfterRound: Duration(seconds: 1),
+ accelerationDuration: Duration(
+ seconds: 1,
+ ),
+ accelerationCurve: Curves.easeOut,
+ decelerationDuration: Duration(
+ milliseconds: 500,
+ ),
+ decelerationCurve: Curves.easeOut,
+ )
+ : Text(
+ resData.senderInfo?.nickName ?? "",
+ maxLines: 1,
+ overflow: TextOverflow.ellipsis,
+ style: TextStyle(
+ fontSize: 14.sp,
+ color: Colors.white,
+ fontWeight: FontWeight.w600,
+ decoration: TextDecoration.none,
+ ),
+ ),
+ ),
+ SizedBox(width: 5.w),
+ Container(
+ child: text(
+ SCAppLocalizations.of(context)!.sentARedEnvelope,
+ fontWeight: FontWeight.w600,
+ textColor: Colors.white,
+ fontSize: 14.sp,
+ ),
+ height: 18.w,
+ ),
+ ],
+ ),
+ SizedBox(height: 5.w),
+ Row(
+ children: [
+ text(
+ SCAppLocalizations.of(
+ context,
+ )!.wishingYouHappinessEveryDay,
+ fontWeight: FontWeight.w600,
+ textColor: Colors.white70,
+ fontSize: 13.sp,
+ ),
+ ],
+ ),
+ ],
+ ),
+ ],
+ ),
+ SizedBox(height: 10.w),
+ AccountStorage().getCurrentUser()?.userProfile?.id ==
+ "${resData.receiverInfo?.userId}"
+ ? Row(
+ mainAxisAlignment: MainAxisAlignment.center,
+ children: [
+ Image.asset(
+ _strategy.getSCMessageChatPageGoldCoinIcon(),
+ height: 35.w,
+ ),
+ text(
+ "${resData.totalAmount ?? 0}",
+ fontWeight: FontWeight.w900,
+ textColor: Color(0xffFFF836),
+ fontSize: 22.sp,
+ ),
+ ],
+ )
+ : Container(),
+ Divider(
+ color: Color(0xffF3F3F3),
+ endIndent: 15.w,
+ indent: 15.w,
+ thickness: 0.4,
+ ),
+ SizedBox(height: 5.w),
+ Row(
+ children: [
+ SizedBox(width: 15.w),
+ text(
+ SCAppLocalizations.of(
+ context,
+ )!.redEnvelopeAmount("${resData.totalAmount}"),
+ fontWeight: FontWeight.w600,
+ textColor: Colors.white70,
+ fontSize: 13.sp,
+ ),
+ Spacer(),
+ resData.status == 2
+ ? Row(
+ children: [
+ Image.asset(
+ _strategy.getSCMessageChatPageGoldCoinIcon(),
+ height: 15.w,
+ ),
+ text(
+ "${resData.totalAmount ?? 0}",
+ fontWeight: FontWeight.w400,
+ textColor: Color(0xffFFF836),
+ fontSize: 14.sp,
+ ),
+ ],
+ )
+ : Container(),
+ SizedBox(width: 15.w),
+ ],
+ ),
+ SizedBox(height: 8.w),
+ resData.status == 2
+ ? Row(
+ mainAxisAlignment: MainAxisAlignment.start,
+ crossAxisAlignment: CrossAxisAlignment.center,
+ children: [
+ SizedBox(width: 20.w),
+ netImage(
+ url: resData.receiverInfo?.avatar ?? "",
+ shape: BoxShape.circle,
+ width: 45.w,
+ height: 45.w,
+ ),
+ SizedBox(width: 10.w),
+ Column(
+ crossAxisAlignment: CrossAxisAlignment.start,
+ children: [
+ Row(
+ children: [
+ Container(
+ height: 18.w,
+ constraints: BoxConstraints(maxWidth: 120.w),
+ child:
+ (resData.receiverInfo?.nickName?.length ??
+ 0) >
+ 12
+ ? Marquee(
+ text:
+ resData.receiverInfo?.nickName ??
+ "",
+ style: TextStyle(
+ fontSize: 14.sp,
+ color: Colors.white,
+ fontWeight: FontWeight.w600,
+ decoration: TextDecoration.none,
+ ),
+ scrollAxis: Axis.horizontal,
+ crossAxisAlignment:
+ CrossAxisAlignment.start,
+ blankSpace: 20.0,
+ velocity: 40.0,
+ pauseAfterRound: Duration(seconds: 1),
+ accelerationDuration: Duration(
+ seconds: 1,
+ ),
+ accelerationCurve: Curves.easeOut,
+ decelerationDuration: Duration(
+ milliseconds: 500,
+ ),
+ decelerationCurve: Curves.easeOut,
+ )
+ : Text(
+ resData.receiverInfo?.nickName ?? "",
+ maxLines: 1,
+ overflow: TextOverflow.ellipsis,
+ style: TextStyle(
+ fontSize: 14.sp,
+ color: Colors.white,
+ fontWeight: FontWeight.w600,
+ decoration: TextDecoration.none,
+ ),
+ ),
+ ),
+ SizedBox(width: 5.w),
+ ],
+ ),
+ SizedBox(height: 5.w),
+ Row(
+ children: [
+ text(
+ SCMDateUtils.formatDateTime3(
+ DateTime.fromMillisecondsSinceEpoch(
+ resData.grabbedAt ?? 0,
+ ),
+ ),
+ fontWeight: FontWeight.w600,
+ textColor: Colors.white70,
+ fontSize: 13.sp,
+ ),
+ ],
+ ),
+ ],
+ ),
+ ],
+ )
+ : (resData.status == 1
+ ? Row(
+ mainAxisAlignment: MainAxisAlignment.center,
+ children: [
+ text(
+ SCAppLocalizations.of(
+ context,
+ )!.redEnvelopeNotYetClaimed,
+ fontWeight: FontWeight.w600,
+ textColor: Colors.white,
+ fontSize: 15.sp,
+ ),
+ ],
+ )
+ : Container()),
+ SizedBox(height: 18.w),
+ ],
+ ),
+ );
+ },
+ );
+ }
+
+ _buildPackTips(SCUserRedPacketSendRes? resData) {
+ //状态:1-待领取 2-已领取 3-已过期
+ if (resData?.status == 2) {
+ if ("${resData?.receiverInfo?.userId}" ==
+ AccountStorage().getCurrentUser()?.userProfile?.id) {
+ return Container(
+ width: ScreenUtil().screenWidth * 0.6,
+ child: Text.rich(
+ TextSpan(
+ children: [
+ TextSpan(
+ text: SCAppLocalizations.of(
+ context,
+ )!.youAccepted(resData?.senderInfo?.nickName ?? ""),
+ style: TextStyle(
+ fontSize: 12.sp,
+ color: Colors.black26,
+ fontWeight: FontWeight.bold,
+ ),
+ ),
+ TextSpan(
+ text: SCAppLocalizations.of(context)!.redEnvelope,
+ style: TextStyle(
+ fontSize: 12.sp,
+ color: Color(0xffFF7759),
+ fontWeight: FontWeight.w600,
+ ),
+ ),
+ TextSpan(
+ text: ".",
+ style: TextStyle(
+ fontSize: 12.sp,
+ color: Color(0xffFF7759),
+ fontWeight: FontWeight.bold,
+ ),
+ ),
+ ],
+ ),
+ ),
+ );
+ } else if ("${resData?.senderInfo?.userId}" ==
+ AccountStorage().getCurrentUser()?.userProfile?.id) {
+ return Container(
+ width: ScreenUtil().screenWidth * 0.6,
+ child: Text.rich(
+ TextSpan(
+ children: [
+ TextSpan(
+ text: SCAppLocalizations.of(
+ context,
+ )!.acceptedYour(resData?.receiverInfo?.nickName ?? ""),
+ style: TextStyle(
+ fontSize: 12.sp,
+ color: Colors.black26,
+ fontWeight: FontWeight.bold,
+ ),
+ ),
+ TextSpan(
+ text: SCAppLocalizations.of(context)!.redEnvelope,
+ style: TextStyle(
+ fontSize: 12.sp,
+ color: Color(0xffFF7759),
+ fontWeight: FontWeight.w600,
+ ),
+ ),
+ TextSpan(
+ text: ".",
+ style: TextStyle(
+ fontSize: 12.sp,
+ color: Color(0xffFF7759),
+ fontWeight: FontWeight.bold,
+ ),
+ ),
+ ],
+ ),
+ ),
+ );
+ }
+ }
+ return Container();
+ }
+}
+
+// class MySpecialTextSpanBuilder extends SpecialTextSpanBuilder {
+// /// whether show background for @somebody
+// MySpecialTextSpanBuilder();
+//
+// @override
+// TextSpan build(String data, {TextStyle? textStyle, onTap}) {
+// var textSpan = super.build(data, textStyle: textStyle, onTap: onTap);
+// return textSpan;
+// }
+//
+// @override
+// SpecialText? createSpecialText(
+// String flag, {
+// TextStyle? textStyle,
+// SpecialTextGestureTapCallback? onTap,
+// required int index,
+// }) {
+// if (flag == null || flag == "") return null;
+//
+// ///index is end index of start flag, so text start index should be index-(flag.length-1)
+// if (textStyle != null) {
+// if (isStart(flag, EmojiText.flag)) {
+// return EmojiText(textStyle, start: index - (EmojiText.flag.length - 1));
+// }
+// }
+// return null;
+// }
+// }
+
+// class EmojiText extends SpecialText {
+// EmojiText(TextStyle textStyle, {required this.start})
+// : super(EmojiText.flag, ']', textStyle);
+// static const String flag = '[';
+// final int start;
+//
+// @override
+// InlineSpan finishText() {
+// String key = toString();
+// key = key.replaceAll("[", "");
+// key = key.replaceAll("]", "");
+// int index;
+// try {
+// index = int.parse(key);
+// } catch (e) {
+// return TextSpan(text: toString(), style: textStyle);
+// }
+//
+// ///https://github.com/flutter/flutter/issues/42086
+// /// widget span is not working on web
+// if (index <= 113) {
+// //fontsize id define image height
+// //size = 30.0/26.0 * fontSize
+// double size = 16.w;
+//
+// ///fontSize 26 and text height =30.0
+// //final double fontSize = 26.0;
+// return ImageSpan(
+// AssetImage("sc_images/msg/emoji/$key.png"),
+// actualText: key,
+// imageWidth: textStyle!.fontSize!,
+// imageHeight: textStyle!.fontSize!,
+// start: start,
+// fit: BoxFit.fill,
+// margin: const EdgeInsets.only(left: 2.0, top: 2.0, right: 2.0),
+// );
+// }
+//
+// return TextSpan(text: toString(), style: textStyle);
+// }
+// }
diff --git a/lib/modules/chat/noti/message_notifcation_page.dart b/lib/modules/chat/noti/message_notifcation_page.dart
new file mode 100644
index 0000000..d48cd75
--- /dev/null
+++ b/lib/modules/chat/noti/message_notifcation_page.dart
@@ -0,0 +1,294 @@
+import 'dart:convert';
+
+import 'package:extended_text/extended_text.dart';
+import 'package:flutter/cupertino.dart';
+import 'package:flutter/material.dart';
+import 'package:flutter_screenutil/flutter_screenutil.dart';
+import 'package:provider/provider.dart';
+import 'package:pull_to_refresh/pull_to_refresh.dart';
+
+import 'package:yumi/app_localizations.dart';
+import 'package:yumi/ui_kit/components/appbar/socialchat_appbar.dart';
+import 'package:yumi/ui_kit/components/sc_compontent.dart';
+import 'package:yumi/app/constants/sc_screen.dart';
+import 'package:yumi/app/routes/sc_fluro_navigator.dart';
+import 'package:yumi/shared/tools/sc_date_utils.dart';
+import 'package:yumi/shared/data_sources/sources/repositories/sc_user_repository_impl.dart';
+import 'package:yumi/shared/business_logic/models/res/sc_public_message_page_res.dart';
+import 'package:yumi/services/audio/rtm_manager.dart';
+import 'package:yumi/modules/index/main_route.dart';
+import 'package:yumi/app/constants/sc_global_config.dart';
+import 'package:yumi/app/config/business_logic_strategy.dart';
+
+class MessageNotifcationPage extends StatefulWidget {
+ @override
+ _MessageNotifcationPageState createState() => _MessageNotifcationPageState();
+}
+
+class _MessageNotifcationPageState extends State {
+ List records = [];
+ num index = 1;
+ final RefreshController _refreshController = RefreshController();
+ final ScrollController _scrollController = ScrollController();
+ RtmProvider? rtmProvider;
+
+ BusinessLogicStrategy get _strategy => SCGlobalConfig.businessLogicStrategy;
+
+ @override
+ void initState() {
+ super.initState();
+ rtmProvider = Provider.of(context, listen: false);
+ rtmProvider?.onNewNotifcationMessageCurrentConversationListener =
+ _onNewMessage;
+ loadData();
+ }
+
+ @override
+ void dispose() {
+ rtmProvider?.onNewNotifcationMessageCurrentConversationListener = null;
+ super.dispose();
+ }
+
+ _onNewMessage(Records? message) async {
+ if (message == null) {
+ return;
+ }
+
+ int? index;
+ for (var element in records) {
+ if (element.id == message.id) {
+ index = records.indexOf(element);
+ continue;
+ }
+ }
+ if (index != null) {
+ records.removeAt(index);
+ records.insert(index, message);
+ } else {
+ records.insert(0, message);
+ }
+ _scrollController.jumpTo(0.0);
+ setState(() {});
+ }
+
+ @override
+ Widget build(BuildContext context) {
+ return Stack(
+ children: [
+ Image.asset(
+ _strategy.getSCMessageChatPageRoomSettingBackground(),
+ width: ScreenUtil().screenWidth,
+ height: ScreenUtil().screenHeight,
+ fit: BoxFit.fill,
+ ),
+ Scaffold(
+ backgroundColor: Colors.transparent,
+ resizeToAvoidBottomInset: false,
+ appBar: SocialChatStandardAppBar(
+ title: SCAppLocalizations.of(context)!.notifcation,
+ actions: [],
+ ),
+ body: SafeArea(
+ top: false,
+ child: SmartRefresher(
+ enablePullDown: false,
+ enablePullUp: true,
+ onLoading: () async {
+ index = index + 1;
+ loadData();
+ },
+ footer: CustomFooter(
+ height: 1,
+ builder: (context, mode) {
+ return SizedBox(
+ height: 1,
+ width: 1,
+ child: SizedBox(height: 1, width: 1),
+ );
+ },
+ ),
+ controller: _refreshController,
+ child:
+ records.isNotEmpty
+ ? Container(
+ child: CustomScrollView(
+ shrinkWrap: records.length > 3 ? false : true,
+ controller: _scrollController,
+ reverse: true,
+ physics: const ClampingScrollPhysics(),
+ // 禁用回弹效果
+ slivers: [
+ SliverList(
+ delegate: SliverChildBuilderDelegate(
+ (c, i) => _MessageItem(message: records[i]),
+ childCount: records.length,
+ ),
+ ),
+ ],
+ ),
+ )
+ : mainEmpty(),
+ ),
+ ),
+ ),
+ ],
+ );
+ }
+
+ void loadData() {
+ SCAccountRepository().publicMessagePage("notification", index, 30).then((
+ result,
+ ) {
+ var list = result.records ?? [];
+ if (list.isNotEmpty) {
+ records.addAll(list);
+ if (list.length == 30) {
+ _refreshController.loadComplete();
+ } else {
+ _refreshController.loadNoData();
+ }
+ } else {
+ _refreshController.loadNoData();
+ }
+ setState(() {});
+ _scrollController.jumpTo(0.0);
+ });
+ }
+}
+
+class _MessageItem extends StatelessWidget {
+ final Records message;
+ late BuildContext context;
+
+ _MessageItem({required this.message});
+
+ @override
+ Widget build(BuildContext context) {
+ this.context = context;
+ print('status:${message.status}');
+ String time = SCMDateUtils.formatMessageTime(
+ context,
+ DateTime.fromMillisecondsSinceEpoch(int.parse(message.createdAt ?? "0")),
+ );
+ return Container(
+ margin: EdgeInsets.symmetric(horizontal: 15.w, vertical: 8.w),
+ child: Column(
+ children: [
+ Container(
+ margin: EdgeInsets.only(bottom: 12.w),
+ child: Row(
+ children: [
+ Spacer(),
+ Container(
+ decoration: BoxDecoration(
+ color: Colors.black12,
+ borderRadius: BorderRadius.all(Radius.circular(height(13))),
+ ),
+ alignment: Alignment.center,
+ padding: EdgeInsets.symmetric(
+ horizontal: width(15),
+ vertical: 8.w,
+ ),
+ child: Text(
+ time,
+ style: TextStyle(
+ fontSize: sp(12),
+ color: Colors.white,
+ fontWeight: FontWeight.w400,
+ decoration: TextDecoration.none,
+ height: 1,
+ ),
+ ),
+ ),
+ Spacer(),
+ ],
+ ),
+ ),
+ _msg(message),
+ ],
+ ),
+ );
+ }
+
+ _msg(Records message) {
+ return GestureDetector(
+ child: Container(
+ alignment: AlignmentDirectional.centerStart,
+ decoration: BoxDecoration(
+ color: Color(0xff18F2B1).withOpacity(0.1),
+ borderRadius: BorderRadius.all(Radius.circular(8)),
+ ),
+ padding: EdgeInsets.all(8.0.w),
+ child: Column(
+ children: [
+ Row(
+ children: [
+ SizedBox(width: 5.w),
+ Expanded(
+ child: ExtendedText(
+ message.title ?? "",
+ overflow: TextOverflow.ellipsis,
+ maxLines: 2,
+ // specialTextSpanBuilder: MySpecialTextSpanBuilder(),
+ style: TextStyle(
+ fontSize: sp(16),
+ color: Colors.white,
+ fontWeight: FontWeight.bold,
+ ),
+ ),
+ ),
+ SizedBox(width: 5.w),
+ ],
+ ),
+ message.imageUrl != null && message.imageUrl!.isNotEmpty
+ ? GestureDetector(
+ child: Container(
+ margin: EdgeInsets.all(5.w),
+ child: netImage(
+ url: message.imageUrl ?? "",
+ fit: BoxFit.contain,
+ borderRadius: BorderRadius.all(Radius.circular(8)),
+ ),
+ ),
+ onTap: () {
+ String encodedUrls = Uri.encodeComponent(
+ jsonEncode([message.imageUrl]),
+ );
+ SCNavigatorUtils.push(
+ context,
+ "${SCMainRoute.imagePreview}?imageUrls=$encodedUrls&initialIndex=0",
+ );
+ },
+ )
+ : Container(),
+ Row(
+ children: [
+ SizedBox(width: 5.w),
+ Expanded(
+ child: ExtendedText(
+ message.content ?? "",
+ // specialTextSpanBuilder: MySpecialTextSpanBuilder(),
+ style: TextStyle(fontSize: sp(14), color: Colors.white),
+ ),
+ ),
+ SizedBox(width: 5.w),
+ ],
+ ),
+ ],
+ ),
+ ),
+ onTap: () {
+ if (message.extraData != null && message.extraData?.link != null) {
+ if (message.extraData!.link!.startsWith("http") ||
+ message.extraData!.link!.startsWith("https")) {
+ SCNavigatorUtils.push(
+ context,
+ "${SCMainRoute.webViewPage}?url=${Uri.encodeComponent(message.extraData?.link ?? "")}&showTitle=false",
+ replace: false,
+ );
+ }
+ }
+ },
+ );
+ }
+}
diff --git a/lib/modules/chat/system/message_system_page.dart b/lib/modules/chat/system/message_system_page.dart
new file mode 100644
index 0000000..eda3470
--- /dev/null
+++ b/lib/modules/chat/system/message_system_page.dart
@@ -0,0 +1,1172 @@
+import 'dart:convert';
+import 'package:extended_image/extended_image.dart'
+ show ExtendedImage, ExtendedRawImage, ExtendedImageState, LoadState;
+import 'package:extended_text/extended_text.dart';
+import 'package:flutter/cupertino.dart';
+import 'package:flutter/material.dart';
+import 'package:flutter/services.dart';
+import 'package:flutter_screenutil/flutter_screenutil.dart';
+import 'package:flutter_smart_dialog/flutter_smart_dialog.dart';
+import 'package:yumi/ui_kit/components/sc_compontent.dart';
+import 'package:yumi/ui_kit/components/text/sc_text.dart';
+import 'package:yumi/app/routes/sc_fluro_navigator.dart';
+import 'package:yumi/shared/tools/sc_system_message_utils.dart';
+import 'package:yumi/shared/data_sources/sources/repositories/sc_user_repository_impl.dart';
+import 'package:provider/provider.dart';
+import 'package:pull_to_refresh/pull_to_refresh.dart';
+import 'package:tencent_cloud_chat_sdk/enum/message_elem_type.dart';
+import 'package:tencent_cloud_chat_sdk/enum/message_status.dart';
+import 'package:tencent_cloud_chat_sdk/models/v2_tim_callback.dart';
+import 'package:tencent_cloud_chat_sdk/models/v2_tim_conversation.dart';
+import 'package:tencent_cloud_chat_sdk/models/v2_tim_custom_elem.dart';
+import 'package:tencent_cloud_chat_sdk/models/v2_tim_message.dart';
+import 'package:tencent_cloud_chat_sdk/models/v2_tim_text_elem.dart';
+import 'package:tencent_cloud_chat_sdk/models/v2_tim_value_callback.dart';
+import 'package:tencent_cloud_chat_sdk/tencent_im_sdk_plugin.dart';
+
+import 'package:yumi/app_localizations.dart';
+import 'package:yumi/ui_kit/components/appbar/socialchat_appbar.dart';
+import 'package:yumi/ui_kit/components/dialog/dialog_base.dart';
+import 'package:yumi/ui_kit/components/sc_tts.dart';
+import 'package:yumi/ui_kit/theme/socialchat_theme.dart';
+import 'package:yumi/app/constants/sc_screen.dart';
+import 'package:yumi/shared/tools/sc_date_utils.dart';
+import 'package:yumi/services/general/sc_app_general_manager.dart';
+import 'package:yumi/services/audio/rtm_manager.dart';
+import 'package:yumi/services/auth/user_profile_manager.dart';
+import 'package:yumi/modules/store/store_route.dart';
+import 'package:yumi/app/constants/sc_global_config.dart';
+import 'package:yumi/app/config/business_logic_strategy.dart';
+
+import '../../../shared/data_sources/models/enum/sc_sysytem_message_type.dart';
+import '../../../shared/business_logic/models/res/sc_system_invit_message_res.dart';
+
+class MessageSystemPage extends StatefulWidget {
+ final V2TimConversation? conversation;
+ final bool shrinkWrap;
+
+ //是否是房间内聊天界面。
+ final bool inRoom;
+
+ const MessageSystemPage({
+ Key? key,
+ this.conversation,
+ this.shrinkWrap = false,
+ this.inRoom = false,
+ }) : super(key: key);
+
+ @override
+ _MessageSystemPageState createState() => _MessageSystemPageState();
+}
+
+class _MessageSystemPageState extends State {
+ final ScrollController _scrollController = ScrollController();
+ final RefreshController _refreshController = RefreshController();
+ RtmProvider? rtmProvider;
+ V2TimConversation? currentConversation;
+ List currentConversationMessageList = [];
+
+ BusinessLogicStrategy get _strategy => SCGlobalConfig.businessLogicStrategy;
+
+ @override
+ void initState() {
+ super.initState();
+ rtmProvider = Provider.of(context, listen: false);
+ currentConversation = widget.conversation;
+ rtmProvider?.onNewMessageCurrentConversationListener = _onNewMessage;
+ loadMsg();
+ }
+
+ @override
+ void dispose() {
+ rtmProvider?.onNewMessageCurrentConversationListener = null;
+ super.dispose();
+ }
+
+ Future loadMsg() async {
+ V2TimValueCallback> v2timValueCallback =
+ await TencentImSDKPlugin.v2TIMManager
+ .getMessageManager()
+ .getC2CHistoryMessageList(
+ userID: currentConversation!.userID!,
+ count: 100,
+ lastMsgID: null,
+ );
+ List messages = v2timValueCallback.data!;
+ // List messages = await FTIM.getMessageManager().getMessages(conversation: currentConversation);
+ print("messages : ${messages?.length ?? 0}");
+ currentConversationMessageList ??= [];
+ currentConversationMessageList?.clear();
+
+ for (var msg in messages) {
+ if (!msg.isSelf! && msg.isPeerRead!) {
+ TencentImSDKPlugin.v2TIMManager
+ .getMessageManager()
+ .sendMessageReadReceipts(messageIDList: [msg.msgID!]);
+ }
+ }
+ currentConversationMessageList.insertAll(0, messages ?? []);
+ setState(() {});
+ _scrollController.jumpTo(0.0);
+ }
+
+ _onNewMessage(V2TimMessage? message, {String? msgId}) async {
+ if (message == null) {
+ return;
+ }
+ if (message.userID != currentConversation?.userID) return;
+
+ int? index;
+ for (var element in currentConversationMessageList) {
+ if (msgId != null) {
+ if (msgId == element.msgID) {
+ element.status = MessageStatus.V2TIM_MSG_STATUS_SEND_FAIL;
+ setState(() {});
+ continue;
+ }
+ } else {
+ if (element.msgID == message.msgID) {
+ index = currentConversationMessageList.indexOf(element);
+ continue;
+ }
+ }
+ }
+ if (msgId != null) {
+ return;
+ }
+ if (index != null) {
+ currentConversationMessageList.removeAt(index!);
+ currentConversationMessageList.insert(index!, message);
+ } else {
+ currentConversationMessageList.insert(0, message);
+ }
+ await TencentImSDKPlugin.v2TIMManager
+ .getMessageManager()
+ .markC2CMessageAsRead(userID: currentConversation!.userID!);
+ //发送已读回执
+ await TencentImSDKPlugin.v2TIMManager
+ .getMessageManager()
+ .sendMessageReadReceipts(messageIDList: [message.msgID!]);
+ setState(() {});
+ // await FTIM.getContactManager().setReadMessage(currentConversation);
+ }
+
+ @override
+ Widget build(BuildContext context) {
+ return Stack(
+ children: [
+ Image.asset(
+ _strategy.getSCMessageChatPageRoomSettingBackground(),
+ width: ScreenUtil().screenWidth,
+ height: ScreenUtil().screenHeight,
+ fit: BoxFit.fill,
+ ),
+ Scaffold(
+ backgroundColor: Colors.transparent,
+ resizeToAvoidBottomInset: false,
+ appBar: SocialChatStandardAppBar(
+ title: SCAppLocalizations.of(context)!.system,
+ actions: [],
+ ),
+ body: SafeArea(top: false, child: _msgList()),
+ ),
+ ],
+ );
+ }
+
+ Widget _msgList() {
+ print('xiaoxiliebiao:${currentConversationMessageList.length}');
+ return SmartRefresher(
+ enablePullDown: false,
+ enablePullUp: true,
+ onLoading: () async {
+ print('onLoading');
+ if (currentConversationMessageList.isNotEmpty) {
+ // 拉取单聊历史消息
+ // 首次拉取,lastMsgID 设置为 null
+ // 再次拉取时,lastMsgID 可以使用返回的消息列表中的最后一条消息的id
+ V2TimValueCallback> v2timValueCallback =
+ await TencentImSDKPlugin.v2TIMManager
+ .getMessageManager()
+ .getC2CHistoryMessageList(
+ userID: currentConversation!.userID ?? "",
+ count: 30,
+ lastMsgID: currentConversationMessageList.last.msgID,
+ );
+ List messages =
+ v2timValueCallback.data as List;
+ print('加载前:${currentConversationMessageList.length}');
+ currentConversationMessageList.addAll(messages);
+ print('加载后:${currentConversationMessageList.length}');
+ if (messages.length == 30) {
+ _refreshController.loadComplete();
+ } else {
+ _refreshController.loadNoData();
+ }
+ } else {
+ _refreshController.loadNoData();
+ }
+ setState(() {});
+ },
+ footer: CustomFooter(
+ height: 1,
+ builder: (context, mode) {
+ return SizedBox(
+ height: 1,
+ width: 1,
+ child: SizedBox(height: 1, width: 1),
+ );
+ },
+ ),
+ controller: _refreshController,
+ child: Container(
+ child: CustomScrollView(
+ shrinkWrap: currentConversationMessageList.length > 10 ? false : true,
+ controller: _scrollController,
+ reverse: true,
+ physics: const ClampingScrollPhysics(),
+ // 禁用回弹效果
+ slivers: [
+ SliverList(
+ delegate: SliverChildBuilderDelegate(
+ (c, i) => _MessageItem(
+ message: currentConversationMessageList[i],
+ preMessage:
+ i < currentConversationMessageList.length - 1
+ ? currentConversationMessageList[i + 1]
+ : null,
+ currentConversationMessageList:
+ currentConversationMessageList,
+ updateCall: () {
+ setState(() {});
+ },
+ ),
+ childCount: currentConversationMessageList.length,
+ ),
+ ),
+ ],
+ ),
+ ),
+ );
+ }
+}
+
+class _MessageItem extends StatelessWidget {
+ final V2TimMessage message;
+ final V2TimMessage? preMessage;
+ List currentConversationMessageList = [];
+ Function updateCall;
+
+ ///上一条
+ late BuildContext context;
+
+ _MessageItem({
+ required this.message,
+ this.preMessage,
+ required this.currentConversationMessageList,
+ required this.updateCall,
+ });
+
+ @override
+ Widget build(BuildContext context) {
+ this.context = context;
+ bool showTime = true;
+ int timestamp = (message.timestamp ?? 0) * 1000;
+ int preTimestamp = (preMessage?.timestamp ?? 0) * 1000;
+ if (preMessage != null) {
+ ///5分钟以内 不显示
+ // print('timestamp:$timestamp===preTimestamp:${preTimestamp}');
+ if (DateTime.fromMillisecondsSinceEpoch(timestamp)
+ .difference(DateTime.fromMillisecondsSinceEpoch(preTimestamp))
+ .inMilliseconds <
+ 1000 * 60 * 5) {
+ showTime = false;
+ }
+ }
+ String time = SCMDateUtils.formatMessageTime(
+ context,
+ DateTime.fromMillisecondsSinceEpoch(timestamp ?? 0),
+ );
+ String noticeType = "";
+ String tagHead = "";
+ if (message.elemType == MessageElemType.V2TIM_ELEM_TYPE_CUSTOM) {
+ V2TimCustomElem customElem = message.customElem!;
+ String content = customElem.data ?? "";
+ final data = jsonDecode(content);
+ noticeType = data["noticeType"];
+ if (noticeType == SCSysytemMessageType.CP_LOVE_LETTER.name) {
+ var bean = SCSystemInvitMessageRes.fromJson(jsonDecode(data["content"]));
+ tagHead = bean.userAvatar ?? "";
+ }
+ }
+ print('status:${message.status}');
+ return Container(
+ margin: EdgeInsets.symmetric(horizontal: 15.w, vertical: 8.w),
+ child: Column(
+ crossAxisAlignment: CrossAxisAlignment.start,
+ // textDirection: message.isSelf ? TextDirection.rtl : TextDirection.ltr,
+ children: [
+ Visibility(
+ visible: showTime,
+ child: Container(
+ margin: EdgeInsets.only(bottom: 12.w),
+ child: Row(
+ children: [
+ Spacer(),
+ Container(
+ alignment: Alignment.center,
+ padding: EdgeInsets.symmetric(
+ horizontal: width(15),
+ vertical: 8.w,
+ ),
+ decoration: BoxDecoration(
+ color: Colors.black12,
+ borderRadius: BorderRadius.all(
+ Radius.circular(height(13)),
+ ),
+ ),
+ child: Text(
+ time,
+ style: TextStyle(
+ fontSize: sp(12),
+ color: Colors.white,
+ fontWeight: FontWeight.w400,
+ decoration: TextDecoration.none,
+ height: 1,
+ ),
+ ),
+ ),
+ Spacer(),
+ ],
+ ),
+ ),
+ ),
+ Row(
+ mainAxisSize: MainAxisSize.min,
+ crossAxisAlignment: CrossAxisAlignment.center,
+ textDirection:
+ message.isSelf! ? TextDirection.rtl : TextDirection.ltr,
+ children: [
+ GestureDetector(
+ behavior: HitTestBehavior.opaque,
+ onTap: () {},
+ child:
+ noticeType == SCSysytemMessageType.CP_LOVE_LETTER.name &&
+ tagHead.isNotEmpty
+ ? netImage(
+ url: tagHead,
+ width: 45.w,
+ shape: BoxShape.circle,
+ )
+ : ExtendedImage.asset(
+ SCGlobalConfig.businessLogicStrategy.getMessagePageSystemMessageIcon(),
+ width: 45.w,
+ shape: BoxShape.circle,
+ fit: BoxFit.cover,
+ ),
+ ),
+ // 他人消息的阴影间隔是10dp
+ Container(width: 8.w),
+ Expanded(
+ child: Row(
+ textDirection: TextDirection.ltr,
+ children: [
+ Expanded(
+ child: Container(
+ alignment: AlignmentDirectional.topStart,
+ margin: EdgeInsets.only(top: 4.w),
+ child: _msg(),
+ ),
+ ),
+ ],
+ ),
+ ),
+ ],
+ ),
+ ],
+ ),
+ );
+ }
+
+ _msg() {
+ return _text();
+ }
+
+ ///文本消息
+ _text() {
+ String content = "";
+ if (message.elemType == MessageElemType.V2TIM_ELEM_TYPE_TEXT) {
+ V2TimTextElem textElem = message.textElem!;
+ content = textElem.text ?? "";
+ } else if (message.elemType == MessageElemType.V2TIM_ELEM_TYPE_IMAGE) {
+ content = SCAppLocalizations.of(context)!.image;
+ } else if (message.elemType == MessageElemType.V2TIM_ELEM_TYPE_VIDEO) {
+ content = SCAppLocalizations.of(context)!.video;
+ } else if (message.elemType == MessageElemType.V2TIM_ELEM_TYPE_SOUND) {
+ content = SCAppLocalizations.of(context)!.sound;
+ } else if (message.elemType == MessageElemType.V2TIM_ELEM_TYPE_CUSTOM) {
+ V2TimCustomElem customElem = message.customElem!;
+ content = customElem.data ?? "";
+ final data = jsonDecode(content);
+ String type = data["noticeType"];
+ if (type == SCSysytemMessageType.GIVE_AWAY_PROPS.name) {
+ String title = data["title"] ?? "";
+ String expand = data["expand"] ?? "";
+ return Builder(
+ builder: (ct) {
+ return GestureDetector(
+ child: Container(
+ decoration: BoxDecoration(
+ color: Color(0xff18F2B1).withOpacity(0.1),
+ borderRadius: BorderRadius.only(
+ topLeft: Radius.circular(0),
+ topRight: Radius.circular(8.w),
+ bottomLeft: Radius.circular(8.w),
+ bottomRight: Radius.circular(8),
+ ),
+ ),
+ padding: EdgeInsets.all(8.0.w),
+ child: Column(
+ children: [
+ text(
+ SCAppLocalizations.of(context)!.propMessagePrompt,
+ maxLines: 1,
+ // specialTextSpanBuilder: MySpecialTextSpanBuilder(),
+ fontSize: sp(16),
+ textColor: Colors.white,
+ fontWeight: FontWeight.bold,
+ ),
+ ExtendedText(
+ data["content"],
+ // specialTextSpanBuilder: MySpecialTextSpanBuilder(),
+ style: TextStyle(fontSize: sp(14), color: Colors.white),
+ ),
+ expand.isNotEmpty
+ ? Row(
+ children: [
+ SizedBox(width: 10.w),
+ netImage(
+ url: expand,
+ width: 45.w,
+ height: 45.w,
+ fit: BoxFit.contain,
+ ),
+ ],
+ )
+ : Container(),
+ ],
+ ),
+ ),
+ onTap: () {
+ if (title.isNotEmpty) {
+ var dTitle = jsonDecode(title);
+ String propType = dTitle["propType"] ?? "";
+ if ("ACTIVITY" == propType ||
+ "ADMINISTRSCOR" == propType ||
+ "ACHIEVEMENT" == propType) {
+
+ }else {
+ SCNavigatorUtils.push(
+ context,
+ StoreRoute.bags,
+ replace: false,
+ );
+ }
+ } else {
+ SCNavigatorUtils.push(context, StoreRoute.bags, replace: false);
+ }
+ },
+ onLongPress: () {
+ _showMsgItemMenu(ct, "");
+ },
+ );
+ },
+ );
+ } else if (type == SCSysytemMessageType.AGENT_SEND_INVITE_HOST.name) {
+ return SCSystemMessageUtils.buildAgentSendInviteHostMessage(
+ data,
+ (ct, content) {
+ _showMsgItemMenu(ct, content);
+ },
+ (String id) {
+ rejectOpt(id, type);
+ },
+ (String id) {
+ acceptOpt(id, type);
+ },
+ context,
+ );
+ } else if (type == SCSysytemMessageType.BD_SEND_INVITE_AGENT.name) {
+ return SCSystemMessageUtils.buildBdSendInviteAgentMessage(
+ data,
+ (ct, content) {
+ _showMsgItemMenu(ct, content);
+ },
+ (String id) {
+ rejectOpt(id, type);
+ },
+ (String id) {
+ acceptOpt(id, type);
+ },
+ context,
+ );
+ } else if (type == SCSysytemMessageType.BD_LEADER_INVITE_BD.name) {
+ return SCSystemMessageUtils.buildBdLeaderInviteBdMessage(
+ data,
+ (ct, content) {
+ _showMsgItemMenu(ct, content);
+ },
+ (String id) {
+ rejectOpt(id, type);
+ },
+ (String id) {
+ acceptOpt(id, type);
+ },
+ context,
+ );
+ } else if (type == SCSysytemMessageType.BD_LEADER_INVITE_BD_LEADER.name) {
+ return SCSystemMessageUtils.buildBdLeaderInviteBdLeaderMessage(
+ data,
+ (ct, content) {
+ _showMsgItemMenu(ct, content);
+ },
+ (String id) {
+ rejectOpt(id, type);
+ },
+ (String id) {
+ acceptOpt(id, type);
+ },
+ context,
+ );
+ } else if (type == SCSysytemMessageType.ADMIN_INVITE_RECHARGE_AGENT.name) {
+ return SCSystemMessageUtils.buildAdminInviteRechargeAgentMessage(
+ data,
+ (ct, content) {
+ _showMsgItemMenu(ct, content);
+ },
+ (String id) {
+ rejectOpt(id, type);
+ },
+ (String id) {
+ acceptOpt(id, type);
+ },
+ context,
+ );
+ } else if (type == SCSysytemMessageType.CP_BUILD.name) {
+ return SCSystemMessageUtils.buildCPBuildMessage(
+ data,
+ (ct, content) {
+ _showMsgItemMenu(ct, content);
+ },
+ (String id) {
+ rejectOpt(id, type);
+ },
+ (String id) {
+ acceptOpt(id, type);
+ },
+ context,
+ );
+ } else if (type == SCSysytemMessageType.CP_LOVE_LETTER.name) {
+ return SCSystemMessageUtils.buildCPLoveLetterMessage(data, (ct, content) {
+ _showMsgItemMenu(ct, content);
+ }, context);
+ } else if (type == SCSysytemMessageType.USER_COINS_RECEIVED.name) {
+ return SCSystemMessageUtils.buildUserCoinsReceivedMessage(data, (
+ ct,
+ content,
+ ) {
+ _showMsgItemMenu(ct, content);
+ }, context);
+ } else if (type == SCSysytemMessageType.COIN_SELLER_COINS_RECEIVED.name) {
+ return SCSystemMessageUtils.buildUserCoinsReceivedMessage(data, (
+ ct,
+ content,
+ ) {
+ _showMsgItemMenu(ct, content);
+ }, context);
+ } else if (type == SCSysytemMessageType.USER_SPECIAL_AUDIT_RESULTS.name) {
+ if (data["content"] != null) {
+ return Builder(
+ builder: (ct) {
+ return GestureDetector(
+ onLongPress: () {
+ _showMsgItemMenu(ct, "");
+ },
+ onTap: () {},
+ child: Container(
+ decoration: BoxDecoration(
+ color: Colors.white,
+ boxShadow: [
+ BoxShadow(blurRadius: 2.w, color: Colors.black26),
+ ],
+ borderRadius: BorderRadius.only(
+ topLeft: Radius.circular(0),
+ topRight: Radius.circular(8.w),
+ bottomLeft: Radius.circular(8.w),
+ bottomRight: Radius.circular(8),
+ ),
+ ),
+ padding: EdgeInsets.all(8.0.w),
+ child: ExtendedText(
+ data["content"],
+ // specialTextSpanBuilder: MySpecialTextSpanBuilder(),
+ style: TextStyle(fontSize: sp(14), color: Colors.black54),
+ ),
+ ),
+ );
+ },
+ );
+ }
+ } else if (type == SCSysytemMessageType.USER_FOLLOW.name) {
+ String expand = data["expand"] ?? "";
+ if (data["content"] != null) {
+ var bean = SCSystemInvitMessageRes.fromJson(
+ jsonDecode(data["content"]),
+ );
+ return Builder(
+ builder: (ct) {
+ return GestureDetector(
+ onLongPress: () {
+ _showMsgItemMenu(ct, "");
+ },
+ child: Container(
+ decoration: BoxDecoration(
+ color: Colors.white,
+ boxShadow: [
+ BoxShadow(blurRadius: 2.w, color: Colors.black26),
+ ],
+ borderRadius: BorderRadius.only(
+ topLeft: Radius.circular(0),
+ topRight: Radius.circular(8.w),
+ bottomLeft: Radius.circular(8.w),
+ bottomRight: Radius.circular(8),
+ ),
+ ),
+ padding: EdgeInsets.all(8.0.w),
+ child: Column(
+ children: [
+ Row(
+ children: [
+ head(url: bean.userAvatar ?? "", width: 65.w),
+ Column(
+ crossAxisAlignment: CrossAxisAlignment.start,
+ children: [
+ Row(
+ children: [
+ netImage(
+ url:
+ Provider.of(
+ context,
+ listen: false,
+ )
+ .findCountryByName(
+ bean.countryName ?? "",
+ )
+ ?.nationalFlag ??
+ "",
+ borderRadius: BorderRadius.all(
+ Radius.circular(3.w),
+ ),
+ width: 19.w,
+ height: 14.w,
+ ),
+ SizedBox(width: 3.w),
+ Container(
+ constraints: BoxConstraints(
+ maxWidth: 160.w,
+ ),
+ child: text(
+ bean.userNickname ?? "",
+ fontWeight: FontWeight.bold,
+ textColor: Colors.black,
+ fontSize: 16.sp,
+ ),
+ ),
+ ],
+ ),
+ GestureDetector(
+ child: Container(
+ padding: EdgeInsets.symmetric(vertical: 8.w),
+ decoration: BoxDecoration(
+ image: DecorationImage(
+ image: AssetImage(
+ SCGlobalConfig.businessLogicStrategy.getIdBackgroundImage(bean.account != bean.actualAccount),
+ ),
+ fit: BoxFit.fitWidth,
+ ),
+ ),
+ child: Row(
+ textDirection: TextDirection.ltr,
+ children: [
+ SizedBox(width: 38.w),
+ text(
+ bean.actualAccount ?? "",
+ fontSize: 12.sp,
+ textColor: Colors.white,
+ fontWeight: FontWeight.bold,
+ ),
+ SizedBox(width: 5.w),
+ Image.asset(
+ SCGlobalConfig.businessLogicStrategy.getCopyIdIcon(),
+ width: 12.w,
+ height: 12.w,
+ ),
+ SizedBox(width: 8.w),
+ ],
+ ),
+ ),
+ onTap: () {
+ Clipboard.setData(
+ ClipboardData(
+ text: bean.actualAccount ?? "",
+ ),
+ );
+ SCTts.show(
+ SCAppLocalizations.of(
+ context,
+ )!.copiedToClipboard,
+ );
+ },
+ ),
+ ],
+ ),
+ ],
+ ),
+ SizedBox(height: 3.w),
+ GestureDetector(
+ child: Container(
+ alignment: AlignmentDirectional.center,
+ height: 25.w,
+ width: 65.w,
+ decoration: BoxDecoration(
+ color: Color(0xffB464FF),
+ borderRadius: BorderRadius.all(
+ Radius.circular(15.0),
+ ),
+ ),
+ child: text(
+ SCAppLocalizations.of(context)!.follow,
+ fontSize: 14.sp,
+ fontWeight: FontWeight.w600,
+ textColor: Colors.white,
+ ),
+ ),
+ onTap: () {
+ SCAccountRepository().followNew(expand).then((result) {
+ SCTts.show(SCAppLocalizations.of(context)!.followSucc);
+ });
+ },
+ ),
+ Divider(
+ color: Colors.black12,
+ thickness: 0.5,
+ height: 28.w,
+ ),
+ ExtendedText(
+ SCAppLocalizations.of(context)!.followedYou,
+ // specialTextSpanBuilder: MySpecialTextSpanBuilder(),
+ style: TextStyle(
+ fontSize: sp(14),
+ color: Colors.black54,
+ ),
+ ),
+ SizedBox(height: 5.w),
+ ],
+ ),
+ ),
+ );
+ },
+ );
+ }
+ } else if (type == SCSysytemMessageType.VIOLSCION_WARNING.name) {
+ if (data["content"] != null) {
+ return Builder(
+ builder: (ct) {
+ return GestureDetector(
+ onLongPress: () {
+ _showMsgItemMenu(ct, "");
+ },
+ onTap: () {},
+ child: Container(
+ decoration: BoxDecoration(
+ color: Colors.white,
+ boxShadow: [
+ BoxShadow(blurRadius: 2.w, color: Colors.black26),
+ ],
+ borderRadius: BorderRadius.only(
+ topLeft: Radius.circular(0),
+ topRight: Radius.circular(8.w),
+ bottomLeft: Radius.circular(8.w),
+ bottomRight: Radius.circular(8),
+ ),
+ ),
+ padding: EdgeInsets.all(8.0.w),
+ child: ExtendedText(
+ data["content"],
+ // specialTextSpanBuilder: MySpecialTextSpanBuilder(),
+ style: TextStyle(fontSize: sp(14), color: Colors.black54),
+ ),
+ ),
+ );
+ },
+ );
+ }
+ } else if (type == SCSysytemMessageType.VIOLSCION_ADJUST.name) {
+ if (data["content"] != null) {
+ return Builder(
+ builder: (ct) {
+ return GestureDetector(
+ onLongPress: () {
+ _showMsgItemMenu(ct, "");
+ },
+ onTap: () {},
+ child: Container(
+ decoration: BoxDecoration(
+ color: Colors.white,
+ boxShadow: [
+ BoxShadow(blurRadius: 2.w, color: Colors.black26),
+ ],
+ borderRadius: BorderRadius.only(
+ topLeft: Radius.circular(0),
+ topRight: Radius.circular(8.w),
+ bottomLeft: Radius.circular(8.w),
+ bottomRight: Radius.circular(8),
+ ),
+ ),
+ padding: EdgeInsets.all(8.0.w),
+ child: ExtendedText(
+ data["content"],
+ // specialTextSpanBuilder: MySpecialTextSpanBuilder(),
+ style: TextStyle(fontSize: sp(14), color: Colors.black54),
+ ),
+ ),
+ );
+ },
+ );
+ }
+ }
+ if (content.isEmpty) {
+ if (customElem.extension == 'sendGift') {
+ content = SCAppLocalizations.of(context)!.gift2;
+ } else {
+ content = SCAppLocalizations.of(context)!.receivedAMessage;
+ }
+ }
+ }
+
+ return Builder(
+ builder: (ct) {
+ return GestureDetector(
+ onLongPress: () {
+ _showMsgItemMenu(ct, "");
+ },
+ child: Container(
+ decoration: BoxDecoration(
+ color: Colors.white,
+ boxShadow: [BoxShadow(blurRadius: 2.w, color: Colors.black26)],
+ borderRadius: BorderRadius.only(
+ topLeft: Radius.circular(0),
+ topRight: Radius.circular(8.w),
+ bottomLeft: Radius.circular(8.w),
+ bottomRight: Radius.circular(8),
+ ),
+ ),
+ padding: EdgeInsets.all(8.0.w),
+ child: ExtendedText(
+ content,
+ // specialTextSpanBuilder: MySpecialTextSpanBuilder(),
+ style: TextStyle(fontSize: sp(14), color: Colors.black54),
+ ),
+ ),
+ );
+ },
+ );
+ }
+
+ void _showMsgItemMenu(BuildContext ct, String content) {
+ SmartDialog.showAttach(
+ tag: "showMsgItemMenu",
+ targetContext: ct,
+ alignment: Alignment.topCenter,
+ maskColor: Colors.transparent,
+ animationType: SmartAnimationType.fade,
+ scalePointBuilder: (selfSize) => Offset(selfSize.width, 10),
+ builder: (_) {
+ return Container(
+ margin: EdgeInsets.only(bottom: 10.w),
+ decoration: BoxDecoration(
+ color: Color(0xffdcdddf),
+ borderRadius: BorderRadius.circular(10),
+ ),
+ padding: EdgeInsets.symmetric(horizontal: 10.w, vertical: 5.w),
+ child: Row(
+ mainAxisSize: MainAxisSize.min,
+ children: [
+ GestureDetector(
+ behavior: HitTestBehavior.opaque,
+ onTap: () {
+ SmartDialog.dismiss(tag: "showMsgItemMenu");
+ _delete();
+ },
+ child: Container(
+ margin: EdgeInsets.symmetric(horizontal: 8.w),
+ child: Column(
+ children: [
+ Image.asset(
+ SCGlobalConfig.businessLogicStrategy.getSCMessageChatPageMessageMenuDeleteIcon(),
+ width: 20.w,
+ ),
+ SizedBox(height: 3.w),
+ text(
+ SCAppLocalizations.of(context)!.delete,
+ fontSize: 12.sp,
+ textColor: Color(0xff777777),
+ ),
+ ],
+ ),
+ ),
+ ),
+ ],
+ ),
+ );
+ },
+ );
+ }
+
+ ///删除消息
+ void _delete() {
+ SmartDialog.show(
+ tag: "showDeleteDialog",
+ alignment: Alignment.bottomCenter,
+ debounce: true,
+ animationType: SmartAnimationType.fade,
+ builder: (_) {
+ return SafeArea(
+ child: Container(
+ height: 168.w,
+ decoration: BoxDecoration(
+ color: Colors.white,
+ borderRadius: BorderRadius.only(
+ topLeft: Radius.circular(8.0),
+ topRight: Radius.circular(8.0),
+ ),
+ ),
+ child: Column(
+ children: [
+ SizedBox(height: 10.w),
+ Row(
+ mainAxisAlignment: MainAxisAlignment.center,
+ children: [
+ text(
+ SCAppLocalizations.of(context)!.tips,
+ fontSize: 16.sp,
+ textColor: Colors.black,
+ fontWeight: FontWeight.bold,
+ ),
+ ],
+ ),
+ SizedBox(height: 5.w),
+ Divider(height: height(1), color: SocialChatTheme.dividerColor),
+ GestureDetector(
+ child: Container(
+ padding: EdgeInsets.symmetric(vertical: 10.w),
+ color: Colors.transparent,
+ child: Row(
+ mainAxisAlignment: MainAxisAlignment.center,
+ children: [
+ text(
+ SCAppLocalizations.of(context)!.deleteFromMyDevice,
+ fontSize: 14.sp,
+ textColor: Colors.black,
+ ),
+ ],
+ ),
+ ),
+ onTap: () async {
+ V2TimCallback deleteMessageFromLocalStorage =
+ await TencentImSDKPlugin.v2TIMManager
+ .getMessageManager()
+ .deleteMessageFromLocalStorage(
+ msgID: message.msgID ?? "",
+ );
+ if (deleteMessageFromLocalStorage.code == 0) {
+ //删除成功
+ int index = 0;
+ for (var value in currentConversationMessageList) {
+ if (value.msgID == message.msgID) {
+ break;
+ }
+ index = index + 1;
+ }
+ currentConversationMessageList.removeAt(index);
+ updateCall();
+ SmartDialog.dismiss(tag: "showDeleteDialog");
+ }
+ },
+ ),
+ Divider(height: height(1), color: SocialChatTheme.dividerColor),
+ GestureDetector(
+ onTap: () async {
+ V2TimCallback deleteMessageFromLocalStorage =
+ await TencentImSDKPlugin.v2TIMManager
+ .getMessageManager()
+ .deleteMessages(msgIDs: [message.msgID ?? ""]);
+ if (deleteMessageFromLocalStorage.code == 0) {
+ //删除成功
+ int index = 0;
+ for (var value in currentConversationMessageList) {
+ if (value.msgID == message.msgID) {
+ break;
+ }
+ index = index + 1;
+ }
+ currentConversationMessageList.removeAt(index);
+ updateCall();
+ SmartDialog.dismiss(tag: "showDeleteDialog");
+ }
+ },
+ child: Container(
+ padding: EdgeInsets.symmetric(vertical: 10.w),
+ color: Colors.transparent,
+ child: Row(
+ mainAxisAlignment: MainAxisAlignment.center,
+ children: [
+ text(
+ SCAppLocalizations.of(context)!.deleteOnAllDevices,
+ fontSize: 14.sp,
+ textColor: Colors.black,
+ ),
+ ],
+ ),
+ ),
+ ),
+ Divider(height: height(1), color: SocialChatTheme.dividerColor),
+ GestureDetector(
+ onTap: () async {
+ SmartDialog.dismiss(tag: "showDeleteDialog");
+ },
+ child: Container(
+ padding: EdgeInsets.symmetric(vertical: 10.w),
+ color: Colors.transparent,
+ child: Row(
+ mainAxisAlignment: MainAxisAlignment.center,
+ children: [
+ text(
+ SCAppLocalizations.of(context)!.cancel,
+ fontSize: 14.sp,
+ textColor: Colors.black,
+ ),
+ ],
+ ),
+ ),
+ ),
+ ],
+ ),
+ ),
+ );
+ },
+ );
+ }
+
+ void acceptOpt(String id, String type) {
+ SmartDialog.show(
+ tag: "showConfirmDialog",
+ alignment: Alignment.center,
+ debounce: true,
+ animationType: SmartAnimationType.fade,
+ builder: (_) {
+ return MsgDialog(
+ title: SCAppLocalizations.of(context)!.tips,
+ msg: SCAppLocalizations.of(context)!.confirmAcceptTheInvitation,
+ btnText: SCAppLocalizations.of(context)!.confirm,
+ onEnsure: () async {
+ if (type == SCSysytemMessageType.AGENT_SEND_INVITE_HOST.name) {
+ Provider.of(
+ context,
+ listen: false,
+ ).inviteHostOpt(context, id, "1");
+ } else if (type == SCSysytemMessageType.BD_SEND_INVITE_AGENT.name) {
+ Provider.of