Compare commits
No commits in common. "78c3a9516022ca0002282d6ea429ae1c21bd0128" and "a3f8db991d4a7bc876e0223912d647664ab3903a" have entirely different histories.
78c3a95160
...
a3f8db991d
@ -87,7 +87,6 @@ android {
|
|||||||
}
|
}
|
||||||
dependencies {
|
dependencies {
|
||||||
implementation("androidx.multidex:multidex:2.0.1")
|
implementation("androidx.multidex:multidex:2.0.1")
|
||||||
implementation("com.android.installreferrer:installreferrer:2.2")
|
|
||||||
// implementation(platform("com.google.firebase:firebase-bom:34.0.0"))
|
// implementation(platform("com.google.firebase:firebase-bom:34.0.0"))
|
||||||
// implementation("com.google.firebase:firebase-auth")
|
// implementation("com.google.firebase:firebase-auth")
|
||||||
// implementation("com.google.firebase:firebase-core:16.0.8")
|
// implementation("com.google.firebase:firebase-core:16.0.8")
|
||||||
|
|||||||
@ -1,83 +1,10 @@
|
|||||||
package com.org.yumiparty
|
package com.org.yumiparty
|
||||||
|
|
||||||
import com.android.installreferrer.api.InstallReferrerClient
|
|
||||||
import com.android.installreferrer.api.InstallReferrerStateListener
|
|
||||||
import io.flutter.embedding.android.FlutterActivity
|
import io.flutter.embedding.android.FlutterActivity
|
||||||
import io.flutter.embedding.engine.FlutterEngine
|
import io.flutter.embedding.engine.FlutterEngine
|
||||||
import io.flutter.plugin.common.MethodChannel
|
|
||||||
|
|
||||||
class MainActivity : FlutterActivity() {
|
class MainActivity : FlutterActivity() {
|
||||||
private var installReferrerClient: InstallReferrerClient? = null
|
|
||||||
|
|
||||||
override fun configureFlutterEngine(flutterEngine: FlutterEngine) {
|
override fun configureFlutterEngine(flutterEngine: FlutterEngine) {
|
||||||
super.configureFlutterEngine(flutterEngine) // 这行必须存在!
|
super.configureFlutterEngine(flutterEngine) // 这行必须存在!
|
||||||
MethodChannel(
|
|
||||||
flutterEngine.dartExecutor.binaryMessenger,
|
|
||||||
INSTALL_REFERRER_CHANNEL
|
|
||||||
).setMethodCallHandler { call, result ->
|
|
||||||
when (call.method) {
|
|
||||||
"getInstallReferrer" -> getInstallReferrer(result)
|
|
||||||
else -> result.notImplemented()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onDestroy() {
|
|
||||||
installReferrerClient?.endConnection()
|
|
||||||
installReferrerClient = null
|
|
||||||
super.onDestroy()
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun getInstallReferrer(result: MethodChannel.Result) {
|
|
||||||
val client = InstallReferrerClient.newBuilder(this).build()
|
|
||||||
installReferrerClient = client
|
|
||||||
var hasResponded = false
|
|
||||||
|
|
||||||
fun respondOnce(value: String?) {
|
|
||||||
if (hasResponded) return
|
|
||||||
hasResponded = true
|
|
||||||
result.success(value)
|
|
||||||
client.endConnection()
|
|
||||||
if (installReferrerClient === client) {
|
|
||||||
installReferrerClient = null
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fun respondError(errorCode: String, message: String?) {
|
|
||||||
if (hasResponded) return
|
|
||||||
hasResponded = true
|
|
||||||
result.error(errorCode, message, null)
|
|
||||||
client.endConnection()
|
|
||||||
if (installReferrerClient === client) {
|
|
||||||
installReferrerClient = null
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
client.startConnection(object : InstallReferrerStateListener {
|
|
||||||
override fun onInstallReferrerSetupFinished(responseCode: Int) {
|
|
||||||
when (responseCode) {
|
|
||||||
InstallReferrerClient.InstallReferrerResponse.OK -> {
|
|
||||||
try {
|
|
||||||
respondOnce(client.installReferrer.installReferrer)
|
|
||||||
} catch (e: Exception) {
|
|
||||||
respondError("INSTALL_REFERRER_ERROR", e.message)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else -> respondOnce(null)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onInstallReferrerServiceDisconnected() {
|
|
||||||
respondOnce(null)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
} catch (e: Exception) {
|
|
||||||
respondError("INSTALL_REFERRER_CONNECTION_ERROR", e.message)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
companion object {
|
|
||||||
private const val INSTALL_REFERRER_CHANNEL = "com.org.yumiparty/install_referrer"
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -308,7 +308,6 @@
|
|||||||
"ownerSendTheRedEnvelope": "أرسل مالك الغرفة عملات المكافأة.",
|
"ownerSendTheRedEnvelope": "أرسل مالك الغرفة عملات المكافأة.",
|
||||||
"rewardCoins": "عملات المكافأة:{1} عملة",
|
"rewardCoins": "عملات المكافأة:{1} عملة",
|
||||||
"signInRewardReceived": "تم تسجيل الدخول بنجاح. المكافأة: {1}",
|
"signInRewardReceived": "تم تسجيل الدخول بنجاح. المكافأة: {1}",
|
||||||
"registerRewardReceived": "تم استلام مكافأة التسجيل: {1}",
|
|
||||||
"lastWeekProgress": "تقدم الأسبوع الماضي",
|
"lastWeekProgress": "تقدم الأسبوع الماضي",
|
||||||
"currentProgress": "التقدم الحالي",
|
"currentProgress": "التقدم الحالي",
|
||||||
"coins2": "{1} عملات",
|
"coins2": "{1} عملات",
|
||||||
|
|||||||
@ -162,7 +162,6 @@
|
|||||||
"ownerSendTheRedEnvelope": "মালিক পুরস্কার কয়েন পাঠিয়েছেন।",
|
"ownerSendTheRedEnvelope": "মালিক পুরস্কার কয়েন পাঠিয়েছেন।",
|
||||||
"rewardCoins": "পুরস্কার কয়েন:{1} কয়েন",
|
"rewardCoins": "পুরস্কার কয়েন:{1} কয়েন",
|
||||||
"signInRewardReceived": "সাইন ইন সফল হয়েছে। পুরস্কার: {1}",
|
"signInRewardReceived": "সাইন ইন সফল হয়েছে। পুরস্কার: {1}",
|
||||||
"registerRewardReceived": "রেজিস্ট্রেশন পুরস্কার পাওয়া গেছে: {1}",
|
|
||||||
"lastWeekProgress": "গত সপ্তাহের অগ্রগতি",
|
"lastWeekProgress": "গত সপ্তাহের অগ্রগতি",
|
||||||
"redEnvelopeTips2": "*লাল খাম সময়সীমার মধ্যে দাবি না করলে, বাকি কয়েন প্রেরক ব্যবহারকারীকে ফেরত দেওয়া হবে।",
|
"redEnvelopeTips2": "*লাল খাম সময়সীমার মধ্যে দাবি না করলে, বাকি কয়েন প্রেরক ব্যবহারকারীকে ফেরত দেওয়া হবে।",
|
||||||
"goToRecharge": "রিচার্জ করতে যান",
|
"goToRecharge": "রিচার্জ করতে যান",
|
||||||
|
|||||||
@ -134,7 +134,6 @@
|
|||||||
"ownerSendTheRedEnvelope": "The owner sent reward coins.",
|
"ownerSendTheRedEnvelope": "The owner sent reward coins.",
|
||||||
"rewardCoins": "Reward coins:{1} coins",
|
"rewardCoins": "Reward coins:{1} coins",
|
||||||
"signInRewardReceived": "Signed in successfully. Reward: {1}",
|
"signInRewardReceived": "Signed in successfully. Reward: {1}",
|
||||||
"registerRewardReceived": "Registration reward received: {1}",
|
|
||||||
"lastWeekProgress": "Last week's progress",
|
"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.",
|
"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",
|
"goToRecharge": "Go to recharge",
|
||||||
|
|||||||
@ -123,7 +123,6 @@
|
|||||||
"ownerSendTheRedEnvelope": "Sahip ödül jettonlarını gönderdi.",
|
"ownerSendTheRedEnvelope": "Sahip ödül jettonlarını gönderdi.",
|
||||||
"rewardCoins": "Ödül jettonları:{1} jetton",
|
"rewardCoins": "Ödül jettonları:{1} jetton",
|
||||||
"signInRewardReceived": "Giriş başarılı. Ödül: {1}",
|
"signInRewardReceived": "Giriş başarılı. Ödül: {1}",
|
||||||
"registerRewardReceived": "Kayıt ödülü alındı: {1}",
|
|
||||||
"lastWeekProgress": "Geçen Haftanın İlerlemesi",
|
"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.",
|
"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",
|
"goToRecharge": "Yüklemeye Git",
|
||||||
|
|||||||
@ -502,7 +502,7 @@
|
|||||||
CLANG_ENABLE_MODULES = YES;
|
CLANG_ENABLE_MODULES = YES;
|
||||||
CODE_SIGN_IDENTITY = "Apple Development";
|
CODE_SIGN_IDENTITY = "Apple Development";
|
||||||
CODE_SIGN_STYLE = Automatic;
|
CODE_SIGN_STYLE = Automatic;
|
||||||
CURRENT_PROJECT_VERSION = 6;
|
CURRENT_PROJECT_VERSION = 5;
|
||||||
DEVELOPMENT_TEAM = S9X2AJ2US9;
|
DEVELOPMENT_TEAM = S9X2AJ2US9;
|
||||||
ENABLE_BITCODE = NO;
|
ENABLE_BITCODE = NO;
|
||||||
INFOPLIST_FILE = Runner/Info.plist;
|
INFOPLIST_FILE = Runner/Info.plist;
|
||||||
@ -511,7 +511,7 @@
|
|||||||
"$(inherited)",
|
"$(inherited)",
|
||||||
"@executable_path/Frameworks",
|
"@executable_path/Frameworks",
|
||||||
);
|
);
|
||||||
MARKETING_VERSION = 1.2.2;
|
MARKETING_VERSION = 1.2.1;
|
||||||
PRODUCT_BUNDLE_IDENTIFIER = com.org.yumiparty;
|
PRODUCT_BUNDLE_IDENTIFIER = com.org.yumiparty;
|
||||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||||
PROVISIONING_PROFILE_SPECIFIER = "";
|
PROVISIONING_PROFILE_SPECIFIER = "";
|
||||||
@ -693,7 +693,7 @@
|
|||||||
CODE_SIGN_ENTITLEMENTS = Runner/RunnerDebug.entitlements;
|
CODE_SIGN_ENTITLEMENTS = Runner/RunnerDebug.entitlements;
|
||||||
CODE_SIGN_IDENTITY = "Apple Development";
|
CODE_SIGN_IDENTITY = "Apple Development";
|
||||||
CODE_SIGN_STYLE = Automatic;
|
CODE_SIGN_STYLE = Automatic;
|
||||||
CURRENT_PROJECT_VERSION = 6;
|
CURRENT_PROJECT_VERSION = 5;
|
||||||
DEVELOPMENT_TEAM = F33K8VUZ62;
|
DEVELOPMENT_TEAM = F33K8VUZ62;
|
||||||
ENABLE_BITCODE = NO;
|
ENABLE_BITCODE = NO;
|
||||||
INFOPLIST_FILE = Runner/Info.plist;
|
INFOPLIST_FILE = Runner/Info.plist;
|
||||||
@ -702,7 +702,7 @@
|
|||||||
"$(inherited)",
|
"$(inherited)",
|
||||||
"@executable_path/Frameworks",
|
"@executable_path/Frameworks",
|
||||||
);
|
);
|
||||||
MARKETING_VERSION = 1.2.2;
|
MARKETING_VERSION = 1.2.1;
|
||||||
PRODUCT_BUNDLE_IDENTIFIER = com.org.yumiparty;
|
PRODUCT_BUNDLE_IDENTIFIER = com.org.yumiparty;
|
||||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||||
PROVISIONING_PROFILE_SPECIFIER = "";
|
PROVISIONING_PROFILE_SPECIFIER = "";
|
||||||
@ -722,7 +722,7 @@
|
|||||||
CODE_SIGN_ENTITLEMENTS = Runner/RunnerRelease.entitlements;
|
CODE_SIGN_ENTITLEMENTS = Runner/RunnerRelease.entitlements;
|
||||||
CODE_SIGN_IDENTITY = "Apple Development";
|
CODE_SIGN_IDENTITY = "Apple Development";
|
||||||
CODE_SIGN_STYLE = Automatic;
|
CODE_SIGN_STYLE = Automatic;
|
||||||
CURRENT_PROJECT_VERSION = 6;
|
CURRENT_PROJECT_VERSION = 5;
|
||||||
DEVELOPMENT_TEAM = F33K8VUZ62;
|
DEVELOPMENT_TEAM = F33K8VUZ62;
|
||||||
ENABLE_BITCODE = NO;
|
ENABLE_BITCODE = NO;
|
||||||
INFOPLIST_FILE = Runner/Info.plist;
|
INFOPLIST_FILE = Runner/Info.plist;
|
||||||
@ -731,7 +731,7 @@
|
|||||||
"$(inherited)",
|
"$(inherited)",
|
||||||
"@executable_path/Frameworks",
|
"@executable_path/Frameworks",
|
||||||
);
|
);
|
||||||
MARKETING_VERSION = 1.2.2;
|
MARKETING_VERSION = 1.2.1;
|
||||||
PRODUCT_BUNDLE_IDENTIFIER = com.org.yumiparty;
|
PRODUCT_BUNDLE_IDENTIFIER = com.org.yumiparty;
|
||||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||||
PROVISIONING_PROFILE_SPECIFIER = "";
|
PROVISIONING_PROFILE_SPECIFIER = "";
|
||||||
|
|||||||
@ -1612,9 +1612,6 @@ class SCAppLocalizations {
|
|||||||
String signInRewardReceived(String name) =>
|
String signInRewardReceived(String name) =>
|
||||||
translate('signInRewardReceived').replaceAll('{1}', name);
|
translate('signInRewardReceived').replaceAll('{1}', name);
|
||||||
|
|
||||||
String registerRewardReceived(String name) =>
|
|
||||||
translate('registerRewardReceived').replaceAll('{1}', name);
|
|
||||||
|
|
||||||
String deleteAccount2(String name) =>
|
String deleteAccount2(String name) =>
|
||||||
translate('deleteAccount2').replaceAll('{1}', name);
|
translate('deleteAccount2').replaceAll('{1}', name);
|
||||||
|
|
||||||
|
|||||||
@ -23,7 +23,6 @@ import 'package:yumi/services/auth/user_profile_manager.dart';
|
|||||||
import 'package:yumi/services/audio/rtc_manager.dart';
|
import 'package:yumi/services/audio/rtc_manager.dart';
|
||||||
import 'package:yumi/services/audio/rtm_manager.dart';
|
import 'package:yumi/services/audio/rtm_manager.dart';
|
||||||
import 'package:yumi/app/constants/sc_global_config.dart';
|
import 'package:yumi/app/constants/sc_global_config.dart';
|
||||||
import 'package:yumi/shared/tools/sc_install_referrer_utils.dart';
|
|
||||||
|
|
||||||
import '../../../shared/business_logic/usecases/sc_custom_filtering_textinput_formatter.dart';
|
import '../../../shared/business_logic/usecases/sc_custom_filtering_textinput_formatter.dart';
|
||||||
import '../../country/country_route.dart';
|
import '../../country/country_route.dart';
|
||||||
@ -54,7 +53,6 @@ class _SCEditProfilePageState extends State<SCEditProfilePage> {
|
|||||||
);
|
);
|
||||||
Provider.of<SCAppGeneralManager>(context, listen: false).selectCountryInfo =
|
Provider.of<SCAppGeneralManager>(context, listen: false).selectCountryInfo =
|
||||||
null;
|
null;
|
||||||
_fillInvitationCodeFromInstallReferrer();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
@ -531,22 +529,6 @@ class _SCEditProfilePageState extends State<SCEditProfilePage> {
|
|||||||
return eighteenYearsAgo;
|
return eighteenYearsAgo;
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> _fillInvitationCodeFromInstallReferrer() async {
|
|
||||||
final inviteCode = await SCInstallReferrerUtils.getInviteCode();
|
|
||||||
if (!mounted ||
|
|
||||||
inviteCode.isEmpty ||
|
|
||||||
invitationCodeController.text.trim().isNotEmpty) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
final normalizedInviteCode =
|
|
||||||
inviteCode.length > 10 ? inviteCode.substring(0, 10) : inviteCode;
|
|
||||||
invitationCodeController.value = TextEditingValue(
|
|
||||||
text: normalizedInviteCode,
|
|
||||||
selection: TextSelection.collapsed(offset: normalizedInviteCode.length),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
String? _preferNonEmpty(String? primary, String? fallback) {
|
String? _preferNonEmpty(String? primary, String? fallback) {
|
||||||
if (primary != null && primary.isNotEmpty) {
|
if (primary != null && primary.isNotEmpty) {
|
||||||
return primary;
|
return primary;
|
||||||
|
|||||||
@ -584,13 +584,6 @@ class _MessageItem extends StatelessWidget {
|
|||||||
) {
|
) {
|
||||||
_showMsgItemMenu(ct, content);
|
_showMsgItemMenu(ct, content);
|
||||||
}, context);
|
}, context);
|
||||||
} else if (_isRegisterRewardGrantedType(type)) {
|
|
||||||
return SCSystemMessageUtils.buildRegisterRewardGrantedMessage(data, (
|
|
||||||
ct,
|
|
||||||
content,
|
|
||||||
) {
|
|
||||||
_showMsgItemMenu(ct, content);
|
|
||||||
}, context);
|
|
||||||
} else if (type == SCSysytemMessageType.USER_SPECIAL_AUDIT_RESULTS.name) {
|
} else if (type == SCSysytemMessageType.USER_SPECIAL_AUDIT_RESULTS.name) {
|
||||||
if (data["content"] != null) {
|
if (data["content"] != null) {
|
||||||
return Builder(
|
return Builder(
|
||||||
@ -890,11 +883,6 @@ class _MessageItem extends StatelessWidget {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool _isRegisterRewardGrantedType(String type) {
|
|
||||||
return type.trim().toUpperCase().replaceAll(' ', '_') ==
|
|
||||||
SCSysytemMessageType.REGISTER_REWARD_GRANTED.name;
|
|
||||||
}
|
|
||||||
|
|
||||||
void _showMsgItemMenu(BuildContext ct, String content) {
|
void _showMsgItemMenu(BuildContext ct, String content) {
|
||||||
SmartDialog.showAttach(
|
SmartDialog.showAttach(
|
||||||
tag: "showMsgItemMenu",
|
tag: "showMsgItemMenu",
|
||||||
|
|||||||
@ -7,6 +7,7 @@ import 'package:yumi/app_localizations.dart';
|
|||||||
import 'package:yumi/modules/index/main_route.dart';
|
import 'package:yumi/modules/index/main_route.dart';
|
||||||
import 'package:yumi/modules/store/store_route.dart';
|
import 'package:yumi/modules/store/store_route.dart';
|
||||||
import 'package:yumi/modules/user/settings/settings_route.dart';
|
import 'package:yumi/modules/user/settings/settings_route.dart';
|
||||||
|
import 'package:yumi/modules/user/vip/vip_route.dart';
|
||||||
import 'package:yumi/modules/wallet/wallet_route.dart';
|
import 'package:yumi/modules/wallet/wallet_route.dart';
|
||||||
import 'package:yumi/services/auth/user_profile_manager.dart';
|
import 'package:yumi/services/auth/user_profile_manager.dart';
|
||||||
import 'package:yumi/shared/business_logic/models/res/sc_user_counter_res.dart';
|
import 'package:yumi/shared/business_logic/models/res/sc_user_counter_res.dart';
|
||||||
@ -15,7 +16,6 @@ import 'package:yumi/shared/data_sources/sources/repositories/sc_user_repository
|
|||||||
import 'package:yumi/ui_kit/components/sc_compontent.dart';
|
import 'package:yumi/ui_kit/components/sc_compontent.dart';
|
||||||
import 'package:yumi/ui_kit/components/sc_debounce_widget.dart';
|
import 'package:yumi/ui_kit/components/sc_debounce_widget.dart';
|
||||||
import 'package:yumi/ui_kit/widgets/id/sc_special_id_badge.dart';
|
import 'package:yumi/ui_kit/widgets/id/sc_special_id_badge.dart';
|
||||||
import 'package:yumi/ui_kit/widgets/svga/sc_svga_asset_widget.dart';
|
|
||||||
|
|
||||||
class MePage2 extends StatefulWidget {
|
class MePage2 extends StatefulWidget {
|
||||||
const MePage2({super.key});
|
const MePage2({super.key});
|
||||||
@ -25,10 +25,6 @@ class MePage2 extends StatefulWidget {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class _MePage2State extends State<MePage2> {
|
class _MePage2State extends State<MePage2> {
|
||||||
static const String _inviteActivityUrl =
|
|
||||||
'https://h5.haiyihy.com/app-invite/index.html';
|
|
||||||
static const double _inviteActivityHorizontalScale = 750 / 662;
|
|
||||||
|
|
||||||
Map<String, SCUserCounterRes> _counterMap = {};
|
Map<String, SCUserCounterRes> _counterMap = {};
|
||||||
|
|
||||||
@override
|
@override
|
||||||
@ -66,28 +62,6 @@ class _MePage2State extends State<MePage2> {
|
|||||||
} catch (_) {}
|
} catch (_) {}
|
||||||
}
|
}
|
||||||
|
|
||||||
void _openInviteActivity() {
|
|
||||||
final inviteActivityUrl = _appendToken(_inviteActivityUrl);
|
|
||||||
if (inviteActivityUrl.isEmpty) return;
|
|
||||||
|
|
||||||
SCNavigatorUtils.push(
|
|
||||||
context,
|
|
||||||
"${SCMainRoute.webViewPage}?url=${Uri.encodeComponent(inviteActivityUrl)}&showTitle=false",
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
String _appendToken(String url) {
|
|
||||||
final token = AccountStorage().getToken();
|
|
||||||
if (token.isEmpty) return url;
|
|
||||||
|
|
||||||
final uri = Uri.tryParse(url);
|
|
||||||
if (uri == null) return url;
|
|
||||||
|
|
||||||
final queryParameters = Map<String, String>.from(uri.queryParameters);
|
|
||||||
queryParameters['token'] = token;
|
|
||||||
return uri.replace(queryParameters: queryParameters).toString();
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return SafeArea(
|
return SafeArea(
|
||||||
@ -106,8 +80,8 @@ class _MePage2State extends State<MePage2> {
|
|||||||
SizedBox(height: 12.w),
|
SizedBox(height: 12.w),
|
||||||
_buildEntryRow(),
|
_buildEntryRow(),
|
||||||
SizedBox(height: 12.w),
|
SizedBox(height: 12.w),
|
||||||
_buildWalletCard(),
|
_buildWalletVipRow(),
|
||||||
_buildInviteActivityBanner(),
|
SizedBox(height: 12.w),
|
||||||
_buildMenuCard2(),
|
_buildMenuCard2(),
|
||||||
SizedBox(height: 12.w),
|
SizedBox(height: 12.w),
|
||||||
_buildMenuCard([
|
_buildMenuCard([
|
||||||
@ -254,12 +228,21 @@ class _MePage2State extends State<MePage2> {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Widget _buildWalletVipRow() {
|
||||||
|
return Row(
|
||||||
|
children: [
|
||||||
|
Expanded(child: _buildVipEntryCard()),
|
||||||
|
SizedBox(width: 10.w),
|
||||||
|
Expanded(child: _buildWalletCard()),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
Widget _buildWalletCard() {
|
Widget _buildWalletCard() {
|
||||||
return SCDebounceWidget(
|
return SCDebounceWidget(
|
||||||
onTap: () => SCNavigatorUtils.push(context, WalletRoute.recharge),
|
onTap: () => SCNavigatorUtils.push(context, WalletRoute.recharge),
|
||||||
child: Container(
|
child: Container(
|
||||||
width: double.infinity,
|
height: 68.w,
|
||||||
height: 90.w,
|
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
borderRadius: BorderRadius.circular(8.w),
|
borderRadius: BorderRadius.circular(8.w),
|
||||||
image: const DecorationImage(
|
image: const DecorationImage(
|
||||||
@ -267,44 +250,53 @@ class _MePage2State extends State<MePage2> {
|
|||||||
fit: BoxFit.fill,
|
fit: BoxFit.fill,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
padding: EdgeInsets.symmetric(horizontal: 12.w, vertical: 8.w),
|
padding: EdgeInsets.symmetric(horizontal: 10.w, vertical: 5.w),
|
||||||
child: Row(
|
child: Row(
|
||||||
children: [
|
children: [
|
||||||
Expanded(
|
Expanded(
|
||||||
child: Column(
|
child: Column(
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
mainAxisAlignment: MainAxisAlignment.center,
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
|
mainAxisSize: MainAxisSize.min,
|
||||||
children: [
|
children: [
|
||||||
Text(
|
Text(
|
||||||
SCAppLocalizations.of(context)!.wallet,
|
SCAppLocalizations.of(context)!.wallet,
|
||||||
|
maxLines: 1,
|
||||||
|
overflow: TextOverflow.ellipsis,
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
fontSize: 24.sp,
|
fontSize: 18.sp,
|
||||||
fontWeight: FontWeight.w800,
|
fontWeight: FontWeight.w800,
|
||||||
fontStyle: FontStyle.italic,
|
fontStyle: FontStyle.italic,
|
||||||
color: Colors.white,
|
color: Colors.white,
|
||||||
|
height: 1,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
SizedBox(height: 4.w),
|
SizedBox(height: 2.w),
|
||||||
Row(
|
Row(
|
||||||
children: [
|
children: [
|
||||||
Image.asset(
|
Image.asset(
|
||||||
'sc_images/general/sc_icon_jb.png',
|
'sc_images/general/sc_icon_wallet_coin.png',
|
||||||
width: 28.w,
|
width: 18.w,
|
||||||
height: 28.w,
|
height: 18.w,
|
||||||
),
|
),
|
||||||
SizedBox(width: 6.w),
|
SizedBox(width: 4.w),
|
||||||
Consumer<SocialChatUserProfileManager>(
|
Expanded(
|
||||||
builder: (context, ref, child) {
|
child: Consumer<SocialChatUserProfileManager>(
|
||||||
return Text(
|
builder: (context, ref, child) {
|
||||||
':${_balanceText(ref.myBalance)}',
|
return Text(
|
||||||
style: TextStyle(
|
':${_balanceText(ref.myBalance)}',
|
||||||
color: Colors.white,
|
maxLines: 1,
|
||||||
fontSize: 24.sp,
|
overflow: TextOverflow.ellipsis,
|
||||||
fontWeight: FontWeight.w700,
|
style: TextStyle(
|
||||||
fontStyle: FontStyle.italic,
|
color: Colors.white,
|
||||||
),
|
fontSize: 18.sp,
|
||||||
);
|
fontWeight: FontWeight.w700,
|
||||||
},
|
fontStyle: FontStyle.italic,
|
||||||
|
height: 1,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
@ -313,8 +305,8 @@ class _MePage2State extends State<MePage2> {
|
|||||||
),
|
),
|
||||||
Image.asset(
|
Image.asset(
|
||||||
'sc_images/index/sc_icon_wallet_icon.png',
|
'sc_images/index/sc_icon_wallet_icon.png',
|
||||||
width: 68.w,
|
width: 40.w,
|
||||||
height: 68.w,
|
height: 40.w,
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
@ -322,64 +314,101 @@ class _MePage2State extends State<MePage2> {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
Widget _buildInviteActivityBanner() {
|
Widget _buildVipEntryCard() {
|
||||||
return SCDebounceWidget(
|
return SCDebounceWidget(
|
||||||
onTap: _openInviteActivity,
|
onTap: () => SCNavigatorUtils.push(context, VipRoute.detail),
|
||||||
child: LayoutBuilder(
|
child: Container(
|
||||||
builder: (context, constraints) {
|
height: 68.w,
|
||||||
final width =
|
decoration: BoxDecoration(
|
||||||
constraints.maxWidth.isFinite
|
borderRadius: BorderRadius.circular(8.w),
|
||||||
? constraints.maxWidth
|
border: Border.all(color: const Color(0xFFFFD37A), width: 1.w),
|
||||||
: ScreenUtil().screenWidth - 20.w;
|
image: const DecorationImage(
|
||||||
final height = width / 5;
|
image: AssetImage('sc_images/vip/sc_vip_entry_bg.png'),
|
||||||
|
fit: BoxFit.fill,
|
||||||
return SizedBox(
|
),
|
||||||
width: width,
|
boxShadow: [
|
||||||
height: height,
|
BoxShadow(
|
||||||
child: Stack(
|
color: Colors.black.withValues(alpha: 0.18),
|
||||||
clipBehavior: Clip.none,
|
blurRadius: 10.w,
|
||||||
alignment: Alignment.center,
|
offset: Offset(0, 4.w),
|
||||||
children: [
|
|
||||||
Positioned.fill(
|
|
||||||
child: Transform(
|
|
||||||
alignment: Alignment.center,
|
|
||||||
transform: Matrix4.diagonal3Values(
|
|
||||||
_inviteActivityHorizontalScale,
|
|
||||||
1.0,
|
|
||||||
1.0,
|
|
||||||
),
|
|
||||||
child: SCSvgaAssetWidget(
|
|
||||||
assetPath: _inviteActivitySvgaAsset,
|
|
||||||
width: width,
|
|
||||||
height: height,
|
|
||||||
active: true,
|
|
||||||
loop: true,
|
|
||||||
fit: BoxFit.fill,
|
|
||||||
allowDrawingOverflow: true,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
),
|
||||||
);
|
],
|
||||||
},
|
),
|
||||||
|
clipBehavior: Clip.antiAlias,
|
||||||
|
child: Stack(
|
||||||
|
children: [
|
||||||
|
PositionedDirectional(
|
||||||
|
top: 12.w,
|
||||||
|
start: 14.w,
|
||||||
|
child: Text(
|
||||||
|
'VIP',
|
||||||
|
style: TextStyle(
|
||||||
|
color: Colors.white,
|
||||||
|
fontFamily: 'Source Han Sans SC',
|
||||||
|
fontSize: 16.sp,
|
||||||
|
fontWeight: FontWeight.w700,
|
||||||
|
height: 1,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
PositionedDirectional(
|
||||||
|
start: 13.w,
|
||||||
|
bottom: 10.w,
|
||||||
|
child: _buildVipLevelMark(5),
|
||||||
|
),
|
||||||
|
PositionedDirectional(
|
||||||
|
end: 2.w,
|
||||||
|
top: 8.w,
|
||||||
|
child: Image.asset(
|
||||||
|
'sc_images/vip/sc_vip_badge_5.png',
|
||||||
|
width: 52.w,
|
||||||
|
height: 52.w,
|
||||||
|
fit: BoxFit.contain,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
String get _inviteActivitySvgaAsset {
|
Widget _buildVipLevelMark(int level) {
|
||||||
switch (SCGlobalConfig.lang) {
|
return Row(
|
||||||
case 'ar':
|
mainAxisSize: MainAxisSize.min,
|
||||||
return 'sc_images/index/sc_invite_activity_rtl.svga';
|
crossAxisAlignment: CrossAxisAlignment.center,
|
||||||
case 'bn':
|
children: [
|
||||||
case 'fa':
|
Image.asset(
|
||||||
return 'sc_images/index/sc_invite_activity_fa.svga';
|
'sc_images/vip/sc_vip_letter_v.png',
|
||||||
case 'tr':
|
width: 18.1.w,
|
||||||
case 'pt':
|
height: 15.3.w,
|
||||||
return 'sc_images/index/sc_invite_activity_pt.svga';
|
fit: BoxFit.contain,
|
||||||
default:
|
),
|
||||||
return 'sc_images/index/sc_invite_activity.svga';
|
Image.asset(
|
||||||
}
|
'sc_images/vip/sc_vip_letter_i.png',
|
||||||
|
width: 8.3.w,
|
||||||
|
height: 15.3.w,
|
||||||
|
fit: BoxFit.contain,
|
||||||
|
),
|
||||||
|
Image.asset(
|
||||||
|
'sc_images/vip/sc_vip_letter_p.png',
|
||||||
|
width: 18.1.w,
|
||||||
|
height: 15.3.w,
|
||||||
|
fit: BoxFit.contain,
|
||||||
|
),
|
||||||
|
SizedBox(width: 3.w),
|
||||||
|
_buildVipLevelNumber(level),
|
||||||
|
],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Widget _buildVipLevelNumber(int level) {
|
||||||
|
return Image.asset(
|
||||||
|
'sc_images/vip/sc_vip_number_${level}_filled.png',
|
||||||
|
height: 15.247.w,
|
||||||
|
fit: BoxFit.fill,
|
||||||
|
color: const Color(0xFFFFD155),
|
||||||
|
colorBlendMode: BlendMode.srcIn,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
Widget _buildMenuCard2() {
|
Widget _buildMenuCard2() {
|
||||||
|
|||||||
@ -15,5 +15,4 @@ enum SCSysytemMessageType{
|
|||||||
CP_LOVE_LETTER,
|
CP_LOVE_LETTER,
|
||||||
USER_COINS_RECEIVED,
|
USER_COINS_RECEIVED,
|
||||||
COIN_SELLER_COINS_RECEIVED,
|
COIN_SELLER_COINS_RECEIVED,
|
||||||
REGISTER_REWARD_GRANTED,
|
|
||||||
}
|
}
|
||||||
@ -1,131 +0,0 @@
|
|||||||
import 'dart:io';
|
|
||||||
|
|
||||||
import 'package:flutter/foundation.dart';
|
|
||||||
import 'package:flutter/services.dart';
|
|
||||||
import 'package:yumi/shared/data_sources/sources/local/data_persistence.dart';
|
|
||||||
|
|
||||||
class SCInstallReferrerUtils {
|
|
||||||
static const MethodChannel _channel = MethodChannel(
|
|
||||||
'com.org.yumiparty/install_referrer',
|
|
||||||
);
|
|
||||||
static const String _cachedInviteCodeKey = 'install_referrer_invite_code';
|
|
||||||
static const String _cachedRawReferrerKey = 'install_referrer_raw';
|
|
||||||
|
|
||||||
static Future<String> getInviteCode() async {
|
|
||||||
final cachedInviteCode = DataPersistence.getString(_cachedInviteCodeKey);
|
|
||||||
if (cachedInviteCode.isNotEmpty) {
|
|
||||||
return cachedInviteCode;
|
|
||||||
}
|
|
||||||
|
|
||||||
final cachedRawReferrer = DataPersistence.getString(_cachedRawReferrerKey);
|
|
||||||
if (cachedRawReferrer.isNotEmpty) {
|
|
||||||
return extractInviteCode(cachedRawReferrer);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!Platform.isAndroid) {
|
|
||||||
return '';
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
final referrer = await _channel.invokeMethod<String>(
|
|
||||||
'getInstallReferrer',
|
|
||||||
);
|
|
||||||
if (referrer == null || referrer.trim().isEmpty) {
|
|
||||||
return '';
|
|
||||||
}
|
|
||||||
|
|
||||||
await DataPersistence.setString(_cachedRawReferrerKey, referrer);
|
|
||||||
final inviteCode = extractInviteCode(referrer);
|
|
||||||
if (inviteCode.isNotEmpty) {
|
|
||||||
await DataPersistence.setString(_cachedInviteCodeKey, inviteCode);
|
|
||||||
}
|
|
||||||
return inviteCode;
|
|
||||||
} on PlatformException catch (e) {
|
|
||||||
debugPrint('get install referrer failed: ${e.code} ${e.message}');
|
|
||||||
return '';
|
|
||||||
} catch (e) {
|
|
||||||
debugPrint('get install referrer failed: $e');
|
|
||||||
return '';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static String extractInviteCode(String referrer) {
|
|
||||||
return _extractInviteCode(referrer, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
static String _extractInviteCode(String input, int depth) {
|
|
||||||
if (depth > 4) {
|
|
||||||
return '';
|
|
||||||
}
|
|
||||||
|
|
||||||
final value = input.trim();
|
|
||||||
if (value.isEmpty) {
|
|
||||||
return '';
|
|
||||||
}
|
|
||||||
|
|
||||||
final params = _queryParameters(value);
|
|
||||||
final inviteCode = _inviteCodeFromParams(params);
|
|
||||||
if (inviteCode.isNotEmpty) {
|
|
||||||
return inviteCode;
|
|
||||||
}
|
|
||||||
|
|
||||||
final nestedReferrer = _nestedReferrerFromParams(params);
|
|
||||||
if (nestedReferrer != null && nestedReferrer.isNotEmpty) {
|
|
||||||
final nestedInviteCode = _extractInviteCode(nestedReferrer, depth + 1);
|
|
||||||
if (nestedInviteCode.isNotEmpty) {
|
|
||||||
return nestedInviteCode;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
final decodedValue = _decodeComponent(value);
|
|
||||||
if (decodedValue != value) {
|
|
||||||
return _extractInviteCode(decodedValue, depth + 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
return '';
|
|
||||||
}
|
|
||||||
|
|
||||||
static Map<String, String> _queryParameters(String value) {
|
|
||||||
final uri = Uri.tryParse(value);
|
|
||||||
if (uri != null && uri.hasQuery) {
|
|
||||||
return uri.queryParameters;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!value.contains('=')) {
|
|
||||||
return const {};
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
return Uri.splitQueryString(value);
|
|
||||||
} catch (_) {
|
|
||||||
return const {};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static String _inviteCodeFromParams(Map<String, String> params) {
|
|
||||||
for (final entry in params.entries) {
|
|
||||||
final key = entry.key.toLowerCase();
|
|
||||||
if (key == 'invite_code' || key == 'invitecode') {
|
|
||||||
return entry.value.trim();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return '';
|
|
||||||
}
|
|
||||||
|
|
||||||
static String? _nestedReferrerFromParams(Map<String, String> params) {
|
|
||||||
for (final entry in params.entries) {
|
|
||||||
if (entry.key.toLowerCase() == 'referrer') {
|
|
||||||
return entry.value;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
static String _decodeComponent(String value) {
|
|
||||||
try {
|
|
||||||
return Uri.decodeComponent(value);
|
|
||||||
} catch (_) {
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1425,243 +1425,4 @@ class SCSystemMessageUtils {
|
|||||||
}
|
}
|
||||||
return Container();
|
return Container();
|
||||||
}
|
}
|
||||||
|
|
||||||
static Widget buildRegisterRewardGrantedMessage(
|
|
||||||
data,
|
|
||||||
Function(BuildContext ct, String content) showMsgItemMenu,
|
|
||||||
BuildContext context,
|
|
||||||
) {
|
|
||||||
final content = _registerRewardGrantedContent(data, context);
|
|
||||||
return Builder(
|
|
||||||
builder: (ct) {
|
|
||||||
return GestureDetector(
|
|
||||||
onLongPress: () {
|
|
||||||
showMsgItemMenu(ct, content);
|
|
||||||
},
|
|
||||||
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,
|
|
||||||
style: TextStyle(fontSize: 14.sp, color: Colors.black54),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
},
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
static String _registerRewardGrantedContent(
|
|
||||||
dynamic data,
|
|
||||||
BuildContext context,
|
|
||||||
) {
|
|
||||||
final l10n = SCAppLocalizations.of(context)!;
|
|
||||||
final rewards =
|
|
||||||
_extractRegisterRewardItems(data)
|
|
||||||
.map((item) => _registerRewardItemLabel(l10n, item))
|
|
||||||
.where((item) => item.isNotEmpty)
|
|
||||||
.toList();
|
|
||||||
if (rewards.isNotEmpty) {
|
|
||||||
return l10n.registerRewardReceived(rewards.join(', '));
|
|
||||||
}
|
|
||||||
|
|
||||||
final plainContent = _plainRegisterRewardContent(data);
|
|
||||||
if (plainContent.isNotEmpty) {
|
|
||||||
return l10n.registerRewardReceived(plainContent);
|
|
||||||
}
|
|
||||||
return l10n.receiveSucc;
|
|
||||||
}
|
|
||||||
|
|
||||||
static List<dynamic> _extractRegisterRewardItems(dynamic value) {
|
|
||||||
final decoded = _decodeJsonValue(value);
|
|
||||||
if (decoded is List) {
|
|
||||||
return decoded;
|
|
||||||
}
|
|
||||||
if (decoded is Map) {
|
|
||||||
final nestedItems = _extractNestedRegisterRewardItems(decoded);
|
|
||||||
if (nestedItems.isNotEmpty) {
|
|
||||||
return nestedItems;
|
|
||||||
}
|
|
||||||
if (_looksLikeRewardItem(decoded)) {
|
|
||||||
return [decoded];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return const <dynamic>[];
|
|
||||||
}
|
|
||||||
|
|
||||||
static String _registerRewardItemLabel(
|
|
||||||
SCAppLocalizations l10n,
|
|
||||||
dynamic item,
|
|
||||||
) {
|
|
||||||
final decoded = _decodeJsonValue(item);
|
|
||||||
if (decoded is! Map) {
|
|
||||||
return _readPlainText(decoded);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!_looksLikeRewardItem(decoded)) {
|
|
||||||
final nestedItems = _extractNestedRegisterRewardItems(decoded);
|
|
||||||
if (nestedItems.isNotEmpty) {
|
|
||||||
return nestedItems
|
|
||||||
.map((item) => _registerRewardItemLabel(l10n, item))
|
|
||||||
.where((item) => item.isNotEmpty)
|
|
||||||
.join(', ');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
final type = _readPlainText(decoded['type']).trim().toUpperCase();
|
|
||||||
final detailType =
|
|
||||||
_readPlainText(decoded['detailType']).trim().toUpperCase();
|
|
||||||
final quantity = _rewardQuantity(decoded);
|
|
||||||
|
|
||||||
if (type == 'GOLD' ||
|
|
||||||
type == 'COIN' ||
|
|
||||||
type == 'COINS' ||
|
|
||||||
detailType == 'GOLD' ||
|
|
||||||
detailType == 'COIN' ||
|
|
||||||
detailType == 'COINS') {
|
|
||||||
return l10n.coins2(quantity.isEmpty ? '0' : quantity);
|
|
||||||
}
|
|
||||||
|
|
||||||
final name = _pickFirstNonEmpty([
|
|
||||||
_readPlainText(decoded['name']),
|
|
||||||
_readPlainText(decoded['badgeName']),
|
|
||||||
_readPlainText(decoded['remark']),
|
|
||||||
_readPlainText(decoded['title']),
|
|
||||||
_readPlainText(decoded['content']),
|
|
||||||
detailType,
|
|
||||||
type,
|
|
||||||
]);
|
|
||||||
if (name.isEmpty) {
|
|
||||||
return '';
|
|
||||||
}
|
|
||||||
|
|
||||||
final count = _asInt(decoded['quantity']);
|
|
||||||
if (count > 1) {
|
|
||||||
return '$name x$count';
|
|
||||||
}
|
|
||||||
return name;
|
|
||||||
}
|
|
||||||
|
|
||||||
static List<dynamic> _extractNestedRegisterRewardItems(
|
|
||||||
Map<dynamic, dynamic> value,
|
|
||||||
) {
|
|
||||||
const nestedKeys = [
|
|
||||||
'rewardItems',
|
|
||||||
'rewards',
|
|
||||||
'items',
|
|
||||||
'activityRewardProps',
|
|
||||||
'rewardConfig',
|
|
||||||
'propsGroup',
|
|
||||||
'propsGroups',
|
|
||||||
'data',
|
|
||||||
'content',
|
|
||||||
];
|
|
||||||
for (final key in nestedKeys) {
|
|
||||||
final items = _extractRegisterRewardItems(value[key]);
|
|
||||||
if (items.isNotEmpty) {
|
|
||||||
return items;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return const <dynamic>[];
|
|
||||||
}
|
|
||||||
|
|
||||||
static String _rewardQuantity(Map<dynamic, dynamic> item) {
|
|
||||||
final quantity = _asInt(item['quantity']);
|
|
||||||
if (quantity > 0) {
|
|
||||||
return quantity.toString();
|
|
||||||
}
|
|
||||||
return _pickFirstNonEmpty([
|
|
||||||
_readPlainText(item['amount']),
|
|
||||||
_readPlainText(item['content']),
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
|
|
||||||
static String _plainRegisterRewardContent(dynamic data) {
|
|
||||||
final decoded = _decodeJsonValue(data);
|
|
||||||
if (decoded is Map) {
|
|
||||||
return _pickFirstNonEmpty([
|
|
||||||
_readPlainText(decoded['message']),
|
|
||||||
_readPlainText(decoded['title']),
|
|
||||||
_readPlainText(decoded['content']),
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
return _readPlainText(decoded);
|
|
||||||
}
|
|
||||||
|
|
||||||
static dynamic _decodeJsonValue(dynamic value) {
|
|
||||||
if (value is! String) {
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
final text = value.trim();
|
|
||||||
if (!_looksLikeStructuredText(text)) {
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
return jsonDecode(text);
|
|
||||||
} catch (_) {
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool _looksLikeRewardItem(Map<dynamic, dynamic> value) {
|
|
||||||
const rewardKeys = [
|
|
||||||
'type',
|
|
||||||
'detailType',
|
|
||||||
'name',
|
|
||||||
'quantity',
|
|
||||||
'amount',
|
|
||||||
'remark',
|
|
||||||
'badgeName',
|
|
||||||
];
|
|
||||||
return rewardKeys.any(value.containsKey);
|
|
||||||
}
|
|
||||||
|
|
||||||
static String _pickFirstNonEmpty(List<String> values) {
|
|
||||||
for (final value in values) {
|
|
||||||
final text = value.trim();
|
|
||||||
if (text.isNotEmpty) {
|
|
||||||
return text;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return '';
|
|
||||||
}
|
|
||||||
|
|
||||||
static String _readPlainText(dynamic value) {
|
|
||||||
final text = _asString(value).trim();
|
|
||||||
if (text.isEmpty || _looksLikeStructuredText(text)) {
|
|
||||||
return '';
|
|
||||||
}
|
|
||||||
return text;
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool _looksLikeStructuredText(String value) {
|
|
||||||
final text = value.trimLeft();
|
|
||||||
return text.startsWith('{') || text.startsWith('[');
|
|
||||||
}
|
|
||||||
|
|
||||||
static String _asString(dynamic value) {
|
|
||||||
if (value == null) {
|
|
||||||
return '';
|
|
||||||
}
|
|
||||||
return value.toString();
|
|
||||||
}
|
|
||||||
|
|
||||||
static int _asInt(dynamic value) {
|
|
||||||
if (value is int) {
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
if (value is num) {
|
|
||||||
return value.toInt();
|
|
||||||
}
|
|
||||||
return int.tryParse(_asString(value)) ?? 0;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -37,7 +37,6 @@ class _RoomMenuDialogState extends State<RoomMenuDialog> {
|
|||||||
static const int _menuSound = 4;
|
static const int _menuSound = 4;
|
||||||
static const int _menuReport = 5;
|
static const int _menuReport = 5;
|
||||||
static const int _menuBackground = 6;
|
static const int _menuBackground = 6;
|
||||||
static bool get _showBackgroundFeature => false;
|
|
||||||
|
|
||||||
List<RoomMenu> items1 = [];
|
List<RoomMenu> items1 = [];
|
||||||
List<RoomMenu> items2 = [];
|
List<RoomMenu> items2 = [];
|
||||||
@ -120,8 +119,7 @@ class _RoomMenuDialogState extends State<RoomMenuDialog> {
|
|||||||
: "sc_icon_mic_open.png",
|
: "sc_icon_mic_open.png",
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
if (_showBackgroundFeature &&
|
if (Provider.of<RtcProvider>(context, listen: false).isFz()) {
|
||||||
Provider.of<RtcProvider>(context, listen: false).isFz()) {
|
|
||||||
items2.add(
|
items2.add(
|
||||||
RoomMenu(
|
RoomMenu(
|
||||||
_menuBackground,
|
_menuBackground,
|
||||||
|
|||||||
@ -210,10 +210,6 @@ class _SCSvgaAssetWidgetState extends State<SCSvgaAssetWidget>
|
|||||||
clearsAfterStop: widget.clearsAfterStop,
|
clearsAfterStop: widget.clearsAfterStop,
|
||||||
filterQuality: widget.filterQuality,
|
filterQuality: widget.filterQuality,
|
||||||
allowDrawingOverflow: widget.allowDrawingOverflow,
|
allowDrawingOverflow: widget.allowDrawingOverflow,
|
||||||
preferredSize:
|
|
||||||
widget.width != null && widget.height != null
|
|
||||||
? Size(widget.width!, widget.height!)
|
|
||||||
: null,
|
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|||||||
@ -16,7 +16,7 @@ publish_to: 'none' # Remove this line if you wish to publish to pub.dev
|
|||||||
# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html
|
# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html
|
||||||
# In Windows, build-name is used as the major, minor, and patch parts
|
# In Windows, build-name is used as the major, minor, and patch parts
|
||||||
# of the product and file versions while build-number is used as the build suffix.
|
# of the product and file versions while build-number is used as the build suffix.
|
||||||
version: 1.2.2+6
|
version: 1.2.1+5
|
||||||
|
|
||||||
|
|
||||||
environment:
|
environment:
|
||||||
|
|||||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -1,44 +0,0 @@
|
|||||||
import 'package:flutter_test/flutter_test.dart';
|
|
||||||
import 'package:yumi/shared/tools/sc_install_referrer_utils.dart';
|
|
||||||
|
|
||||||
void main() {
|
|
||||||
group('SCInstallReferrerUtils.extractInviteCode', () {
|
|
||||||
test('extracts invite code from decoded referrer', () {
|
|
||||||
expect(
|
|
||||||
SCInstallReferrerUtils.extractInviteCode(
|
|
||||||
'invite_code=LZSWI6GO&source=share',
|
|
||||||
),
|
|
||||||
'LZSWI6GO',
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
test('extracts invite code from encoded referrer', () {
|
|
||||||
expect(
|
|
||||||
SCInstallReferrerUtils.extractInviteCode(
|
|
||||||
'invite_code%3DLZSWI6GO%26source%3Dshare',
|
|
||||||
),
|
|
||||||
'LZSWI6GO',
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
test('extracts invite code from play store url', () {
|
|
||||||
expect(
|
|
||||||
SCInstallReferrerUtils.extractInviteCode(
|
|
||||||
'https://play.google.com/store/apps/details'
|
|
||||||
'?id=com.org.yumiparty'
|
|
||||||
'&referrer=invite_code%3DLZSWI6GO%26source%3Dshare',
|
|
||||||
),
|
|
||||||
'LZSWI6GO',
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
test('extracts invite code from camel case key', () {
|
|
||||||
expect(
|
|
||||||
SCInstallReferrerUtils.extractInviteCode(
|
|
||||||
'inviteCode=LZSWI6GO&source=share',
|
|
||||||
),
|
|
||||||
'LZSWI6GO',
|
|
||||||
);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
Loading…
x
Reference in New Issue
Block a user