first final test
This commit is contained in:
parent
8cde87b914
commit
575243e959
|
|
@ -76,9 +76,14 @@ android {
|
||||||
shrinkResources false
|
shrinkResources false
|
||||||
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
|
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
|
||||||
}
|
}
|
||||||
|
|
||||||
|
debug {
|
||||||
|
signingConfig signingConfigs.release
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
flutter {
|
flutter {
|
||||||
source '../..'
|
source '../..'
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -7,17 +7,113 @@
|
||||||
"client": [
|
"client": [
|
||||||
{
|
{
|
||||||
"client_info": {
|
"client_info": {
|
||||||
"mobilesdk_app_id": "1:581103504002:android:896e4d41aad9180318829b",
|
"mobilesdk_app_id": "1:581103504002:android:d12a150d3d54570418829b",
|
||||||
|
"android_client_info": {
|
||||||
|
"package_name": "com.example.hoshan"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"oauth_client": [
|
||||||
|
{
|
||||||
|
"client_id": "581103504002-kb0klg3vds4qcnt5cc348d402l803jh8.apps.googleusercontent.com",
|
||||||
|
"client_type": 1,
|
||||||
|
"android_info": {
|
||||||
|
"package_name": "com.example.hoshan",
|
||||||
|
"certificate_hash": "4fea29f5e9872705f5d86af453b1d77fd4134260"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"client_id": "581103504002-dhn875p11up9ae7k6l5r1kdqs71ap3qf.apps.googleusercontent.com",
|
||||||
|
"client_type": 3
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"api_key": [
|
||||||
|
{
|
||||||
|
"current_key": "AIzaSyDi2WRiOSEws1alpLitxX0zsX14rT71aPk"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"services": {
|
||||||
|
"appinvite_service": {
|
||||||
|
"other_platform_oauth_client": [
|
||||||
|
{
|
||||||
|
"client_id": "581103504002-dhn875p11up9ae7k6l5r1kdqs71ap3qf.apps.googleusercontent.com",
|
||||||
|
"client_type": 3
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"client_id": "581103504002-2e454pgr7fes6b94ptbt82rpfldehedq.apps.googleusercontent.com",
|
||||||
|
"client_type": 2,
|
||||||
|
"ios_info": {
|
||||||
|
"bundle_id": "com.example.hoshan"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"client_info": {
|
||||||
|
"mobilesdk_app_id": "1:581103504002:android:8983465e8b4f637d18829b",
|
||||||
"android_client_info": {
|
"android_client_info": {
|
||||||
"package_name": "com.houshan.basa"
|
"package_name": "com.houshan.basa"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"oauth_client": [
|
||||||
|
{
|
||||||
|
"client_id": "581103504002-mugog6e0d224snhmoen4t01g91m4corc.apps.googleusercontent.com",
|
||||||
|
"client_type": 1,
|
||||||
|
"android_info": {
|
||||||
|
"package_name": "com.houshan.basa",
|
||||||
|
"certificate_hash": "5f7bdab9d1978fa6ba4bb89ba17cfddb41aa7bdb"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"client_id": "581103504002-qc5f48octc7274mr3n4hgam3fr5pejd3.apps.googleusercontent.com",
|
||||||
|
"client_type": 1,
|
||||||
|
"android_info": {
|
||||||
|
"package_name": "com.houshan.basa",
|
||||||
|
"certificate_hash": "df8e828db30cabed5c68362c0a67f760610046ee"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"client_id": "581103504002-dhn875p11up9ae7k6l5r1kdqs71ap3qf.apps.googleusercontent.com",
|
||||||
|
"client_type": 3
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"api_key": [
|
||||||
|
{
|
||||||
|
"current_key": "AIzaSyDi2WRiOSEws1alpLitxX0zsX14rT71aPk"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"services": {
|
||||||
|
"appinvite_service": {
|
||||||
|
"other_platform_oauth_client": [
|
||||||
|
{
|
||||||
|
"client_id": "581103504002-dhn875p11up9ae7k6l5r1kdqs71ap3qf.apps.googleusercontent.com",
|
||||||
|
"client_type": 3
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"client_id": "581103504002-2e454pgr7fes6b94ptbt82rpfldehedq.apps.googleusercontent.com",
|
||||||
|
"client_type": 2,
|
||||||
|
"ios_info": {
|
||||||
|
"bundle_id": "com.example.hoshan"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"client_info": {
|
||||||
|
"mobilesdk_app_id": "1:581103504002:android:896e4d41aad9180318829b",
|
||||||
|
"android_client_info": {
|
||||||
|
"package_name": "com.houshan.hoshan"
|
||||||
|
}
|
||||||
|
},
|
||||||
"oauth_client": [
|
"oauth_client": [
|
||||||
{
|
{
|
||||||
"client_id": "581103504002-jqptfhs4cpgqngckh8g6kisd25jhfp35.apps.googleusercontent.com",
|
"client_id": "581103504002-jqptfhs4cpgqngckh8g6kisd25jhfp35.apps.googleusercontent.com",
|
||||||
"client_type": 1,
|
"client_type": 1,
|
||||||
"android_info": {
|
"android_info": {
|
||||||
"package_name": "com.houshan.basa",
|
"package_name": "com.houshan.hoshan",
|
||||||
"certificate_hash": "b64c77112af5000772d60fbe05138e873f6fc118"
|
"certificate_hash": "b64c77112af5000772d60fbe05138e873f6fc118"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
@ -25,7 +121,7 @@
|
||||||
"client_id": "581103504002-t6a9nuq2nnbdjj71s2inc70p4fikl921.apps.googleusercontent.com",
|
"client_id": "581103504002-t6a9nuq2nnbdjj71s2inc70p4fikl921.apps.googleusercontent.com",
|
||||||
"client_type": 1,
|
"client_type": 1,
|
||||||
"android_info": {
|
"android_info": {
|
||||||
"package_name": "com.houshan.basa",
|
"package_name": "com.houshan.hoshan",
|
||||||
"certificate_hash": "5f7bdab9d1978fa6ba4bb89ba17cfddb41aa7bdb"
|
"certificate_hash": "5f7bdab9d1978fa6ba4bb89ba17cfddb41aa7bdb"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -35,6 +35,15 @@
|
||||||
<category android:name="android.intent.category.LAUNCHER"/>
|
<category android:name="android.intent.category.LAUNCHER"/>
|
||||||
</intent-filter>
|
</intent-filter>
|
||||||
<meta-data android:name="flutter_deeplinking_enabled" android:value="true"/>
|
<meta-data android:name="flutter_deeplinking_enabled" android:value="true"/>
|
||||||
|
<intent-filter android:autoVerify="true">
|
||||||
|
<action android:name="android.intent.action.VIEW"/>
|
||||||
|
<category android:name="android.intent.category.DEFAULT"/>
|
||||||
|
<category android:name="android.intent.category.BROWSABLE"/>
|
||||||
|
|
||||||
|
<data android:scheme="https" android:host="basaweb.houshan.ai" />
|
||||||
|
<data android:scheme="http" android:host="basaweb.houshan.ai" />
|
||||||
|
</intent-filter>
|
||||||
|
|
||||||
<intent-filter android:autoVerify="true">
|
<intent-filter android:autoVerify="true">
|
||||||
<action android:name="android.intent.action.VIEW"/>
|
<action android:name="android.intent.action.VIEW"/>
|
||||||
<category android:name="android.intent.category.DEFAULT"/>
|
<category android:name="android.intent.category.DEFAULT"/>
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,5 @@
|
||||||
|
<svg width="18" height="18" viewBox="0 0 18 18" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<path d="M9.04492 12.375V8.625" stroke="#3D3D3D" stroke-miterlimit="10" stroke-linecap="round" stroke-linejoin="round"/>
|
||||||
|
<path d="M10.875 10.5H7.125" stroke="#3D3D3D" stroke-miterlimit="10" stroke-linecap="round" stroke-linejoin="round"/>
|
||||||
|
<path d="M16.5 8.25V12.75C16.5 15.75 15.75 16.5 12.75 16.5H5.25C2.25 16.5 1.5 15.75 1.5 12.75V5.25C1.5 2.25 2.25 1.5 5.25 1.5H6.375C7.5 1.5 7.7475 1.83 8.175 2.4L9.3 3.9C9.585 4.275 9.75 4.5 10.5 4.5H12.75C15.75 4.5 16.5 5.25 16.5 8.25Z" stroke="#3D3D3D" stroke-miterlimit="10"/>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 622 B |
|
|
@ -362,6 +362,10 @@ class $AssetsIconBulkGen {
|
||||||
class $AssetsIconGifGen {
|
class $AssetsIconGifGen {
|
||||||
const $AssetsIconGifGen();
|
const $AssetsIconGifGen();
|
||||||
|
|
||||||
|
/// File path: assets/icon/gif/33.gif
|
||||||
|
AssetGenImage get a33 =>
|
||||||
|
const AssetGenImage('assets/icon/gif/33.gif', size: Size(640.0, 360.0));
|
||||||
|
|
||||||
/// File path: assets/icon/gif/alpha.gif
|
/// File path: assets/icon/gif/alpha.gif
|
||||||
AssetGenImage get alpha => const AssetGenImage('assets/icon/gif/alpha.gif');
|
AssetGenImage get alpha => const AssetGenImage('assets/icon/gif/alpha.gif');
|
||||||
|
|
||||||
|
|
@ -445,6 +449,7 @@ class $AssetsIconGifGen {
|
||||||
|
|
||||||
/// List of all assets
|
/// List of all assets
|
||||||
List<AssetGenImage> get values => [
|
List<AssetGenImage> get values => [
|
||||||
|
a33,
|
||||||
alpha,
|
alpha,
|
||||||
bell,
|
bell,
|
||||||
beta,
|
beta,
|
||||||
|
|
@ -534,6 +539,18 @@ class $AssetsIconNavbarsGen {
|
||||||
class $AssetsIconOutlineGen {
|
class $AssetsIconOutlineGen {
|
||||||
const $AssetsIconOutlineGen();
|
const $AssetsIconOutlineGen();
|
||||||
|
|
||||||
|
/// File path: assets/icon/outline/Houshan features.svg
|
||||||
|
SvgGenImage get houshanFeatures => const SvgGenImage(
|
||||||
|
'assets/icon/outline/Houshan features.svg',
|
||||||
|
size: Size(32.0, 33.0),
|
||||||
|
);
|
||||||
|
|
||||||
|
/// File path: assets/icon/outline/add family.svg
|
||||||
|
SvgGenImage get addFamily => const SvgGenImage(
|
||||||
|
'assets/icon/outline/add family.svg',
|
||||||
|
size: Size(32.0, 33.0),
|
||||||
|
);
|
||||||
|
|
||||||
/// File path: assets/icon/outline/add.svg
|
/// File path: assets/icon/outline/add.svg
|
||||||
SvgGenImage get add =>
|
SvgGenImage get add =>
|
||||||
const SvgGenImage('assets/icon/outline/add.svg', size: Size(24.0, 24.0));
|
const SvgGenImage('assets/icon/outline/add.svg', size: Size(24.0, 24.0));
|
||||||
|
|
@ -550,6 +567,12 @@ class $AssetsIconOutlineGen {
|
||||||
size: Size(24.0, 24.0),
|
size: Size(24.0, 24.0),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
/// File path: assets/icon/outline/arrow-left.svg
|
||||||
|
SvgGenImage get arrowLeft => const SvgGenImage(
|
||||||
|
'assets/icon/outline/arrow-left.svg',
|
||||||
|
size: Size(24.0, 24.0),
|
||||||
|
);
|
||||||
|
|
||||||
/// File path: assets/icon/outline/arrow-right.svg
|
/// File path: assets/icon/outline/arrow-right.svg
|
||||||
SvgGenImage get arrowRight => const SvgGenImage(
|
SvgGenImage get arrowRight => const SvgGenImage(
|
||||||
'assets/icon/outline/arrow-right.svg',
|
'assets/icon/outline/arrow-right.svg',
|
||||||
|
|
@ -596,6 +619,12 @@ class $AssetsIconOutlineGen {
|
||||||
size: Size(19.0, 19.0),
|
size: Size(19.0, 19.0),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
/// File path: assets/icon/outline/carbon_pedestrian-family.svg
|
||||||
|
SvgGenImage get carbonPedestrianFamily => const SvgGenImage(
|
||||||
|
'assets/icon/outline/carbon_pedestrian-family.svg',
|
||||||
|
size: Size(32.0, 32.0),
|
||||||
|
);
|
||||||
|
|
||||||
/// File path: assets/icon/outline/card-add.svg
|
/// File path: assets/icon/outline/card-add.svg
|
||||||
SvgGenImage get cardAdd => const SvgGenImage(
|
SvgGenImage get cardAdd => const SvgGenImage(
|
||||||
'assets/icon/outline/card-add.svg',
|
'assets/icon/outline/card-add.svg',
|
||||||
|
|
@ -630,6 +659,12 @@ class $AssetsIconOutlineGen {
|
||||||
size: Size(16.0, 17.0),
|
size: Size(16.0, 17.0),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
/// File path: assets/icon/outline/close-circle.svg
|
||||||
|
SvgGenImage get closeCircle => const SvgGenImage(
|
||||||
|
'assets/icon/outline/close-circle.svg',
|
||||||
|
size: Size(24.0, 24.0),
|
||||||
|
);
|
||||||
|
|
||||||
/// File path: assets/icon/outline/coin.svg
|
/// File path: assets/icon/outline/coin.svg
|
||||||
SvgGenImage get coin =>
|
SvgGenImage get coin =>
|
||||||
const SvgGenImage('assets/icon/outline/coin.svg', size: Size(25.0, 25.0));
|
const SvgGenImage('assets/icon/outline/coin.svg', size: Size(25.0, 25.0));
|
||||||
|
|
@ -692,6 +727,10 @@ class $AssetsIconOutlineGen {
|
||||||
size: Size(16.0, 16.0),
|
size: Size(16.0, 16.0),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
/// File path: assets/icon/outline/edit.svg
|
||||||
|
SvgGenImage get edit =>
|
||||||
|
const SvgGenImage('assets/icon/outline/edit.svg', size: Size(24.0, 24.0));
|
||||||
|
|
||||||
/// File path: assets/icon/outline/element-plus.svg
|
/// File path: assets/icon/outline/element-plus.svg
|
||||||
SvgGenImage get elementPlus => const SvgGenImage(
|
SvgGenImage get elementPlus => const SvgGenImage(
|
||||||
'assets/icon/outline/element-plus.svg',
|
'assets/icon/outline/element-plus.svg',
|
||||||
|
|
@ -722,6 +761,18 @@ class $AssetsIconOutlineGen {
|
||||||
size: Size(16.0, 17.0),
|
size: Size(16.0, 17.0),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
/// File path: assets/icon/outline/family.svg
|
||||||
|
SvgGenImage get family => const SvgGenImage(
|
||||||
|
'assets/icon/outline/family.svg',
|
||||||
|
size: Size(328.0, 115.0),
|
||||||
|
);
|
||||||
|
|
||||||
|
/// File path: assets/icon/outline/familyMembers.svg
|
||||||
|
SvgGenImage get familyMembers => const SvgGenImage(
|
||||||
|
'assets/icon/outline/familyMembers.svg',
|
||||||
|
size: Size(30.0, 29.0),
|
||||||
|
);
|
||||||
|
|
||||||
/// File path: assets/icon/outline/filter.svg
|
/// File path: assets/icon/outline/filter.svg
|
||||||
SvgGenImage get filter => const SvgGenImage(
|
SvgGenImage get filter => const SvgGenImage(
|
||||||
'assets/icon/outline/filter.svg',
|
'assets/icon/outline/filter.svg',
|
||||||
|
|
@ -734,6 +785,12 @@ class $AssetsIconOutlineGen {
|
||||||
size: Size(16.0, 16.0),
|
size: Size(16.0, 16.0),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
/// File path: assets/icon/outline/folder-add.svg
|
||||||
|
SvgGenImage get folderAdd => const SvgGenImage(
|
||||||
|
'assets/icon/outline/folder-add.svg',
|
||||||
|
size: Size(18.0, 18.0),
|
||||||
|
);
|
||||||
|
|
||||||
/// File path: assets/icon/outline/gallery-add.svg
|
/// File path: assets/icon/outline/gallery-add.svg
|
||||||
SvgGenImage get galleryAdd => const SvgGenImage(
|
SvgGenImage get galleryAdd => const SvgGenImage(
|
||||||
'assets/icon/outline/gallery-add.svg',
|
'assets/icon/outline/gallery-add.svg',
|
||||||
|
|
@ -746,6 +803,12 @@ class $AssetsIconOutlineGen {
|
||||||
size: Size(18.0, 18.0),
|
size: Size(18.0, 18.0),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
/// File path: assets/icon/outline/gift 2.svg
|
||||||
|
SvgGenImage get gift2 => const SvgGenImage(
|
||||||
|
'assets/icon/outline/gift 2.svg',
|
||||||
|
size: Size(86.0, 88.0),
|
||||||
|
);
|
||||||
|
|
||||||
/// File path: assets/icon/outline/gift.svg
|
/// File path: assets/icon/outline/gift.svg
|
||||||
SvgGenImage get gift =>
|
SvgGenImage get gift =>
|
||||||
const SvgGenImage('assets/icon/outline/gift.svg', size: Size(24.0, 24.0));
|
const SvgGenImage('assets/icon/outline/gift.svg', size: Size(24.0, 24.0));
|
||||||
|
|
@ -786,6 +849,12 @@ class $AssetsIconOutlineGen {
|
||||||
size: Size(16.0, 16.0),
|
size: Size(16.0, 16.0),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
/// File path: assets/icon/outline/ion_infinite.svg
|
||||||
|
SvgGenImage get ionInfinite => const SvgGenImage(
|
||||||
|
'assets/icon/outline/ion_infinite.svg',
|
||||||
|
size: Size(32.0, 32.0),
|
||||||
|
);
|
||||||
|
|
||||||
/// File path: assets/icon/outline/lamp-charge.svg
|
/// File path: assets/icon/outline/lamp-charge.svg
|
||||||
SvgGenImage get lampCharge => const SvgGenImage(
|
SvgGenImage get lampCharge => const SvgGenImage(
|
||||||
'assets/icon/outline/lamp-charge.svg',
|
'assets/icon/outline/lamp-charge.svg',
|
||||||
|
|
@ -918,6 +987,10 @@ class $AssetsIconOutlineGen {
|
||||||
size: Size(24.0, 24.0),
|
size: Size(24.0, 24.0),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
/// File path: assets/icon/outline/send.svg
|
||||||
|
SvgGenImage get send =>
|
||||||
|
const SvgGenImage('assets/icon/outline/send.svg', size: Size(16.0, 16.0));
|
||||||
|
|
||||||
/// File path: assets/icon/outline/setting.svg
|
/// File path: assets/icon/outline/setting.svg
|
||||||
SvgGenImage get setting => const SvgGenImage(
|
SvgGenImage get setting => const SvgGenImage(
|
||||||
'assets/icon/outline/setting.svg',
|
'assets/icon/outline/setting.svg',
|
||||||
|
|
@ -952,6 +1025,12 @@ class $AssetsIconOutlineGen {
|
||||||
SvgGenImage get stop =>
|
SvgGenImage get stop =>
|
||||||
const SvgGenImage('assets/icon/outline/stop.svg', size: Size(24.0, 24.0));
|
const SvgGenImage('assets/icon/outline/stop.svg', size: Size(24.0, 24.0));
|
||||||
|
|
||||||
|
/// File path: assets/icon/outline/streamline_coins-stack.svg
|
||||||
|
SvgGenImage get streamlineCoinsStack => const SvgGenImage(
|
||||||
|
'assets/icon/outline/streamline_coins-stack.svg',
|
||||||
|
size: Size(32.0, 32.0),
|
||||||
|
);
|
||||||
|
|
||||||
/// File path: assets/icon/outline/sun.svg
|
/// File path: assets/icon/outline/sun.svg
|
||||||
SvgGenImage get sun =>
|
SvgGenImage get sun =>
|
||||||
const SvgGenImage('assets/icon/outline/sun.svg', size: Size(18.0, 18.0));
|
const SvgGenImage('assets/icon/outline/sun.svg', size: Size(18.0, 18.0));
|
||||||
|
|
@ -992,6 +1071,12 @@ class $AssetsIconOutlineGen {
|
||||||
size: Size(16.0, 16.0),
|
size: Size(16.0, 16.0),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
/// File path: assets/icon/outline/trashPopup.svg
|
||||||
|
SvgGenImage get trashPopup => const SvgGenImage(
|
||||||
|
'assets/icon/outline/trashPopup.svg',
|
||||||
|
size: Size(48.0, 48.0),
|
||||||
|
);
|
||||||
|
|
||||||
/// File path: assets/icon/outline/verify.svg
|
/// File path: assets/icon/outline/verify.svg
|
||||||
SvgGenImage get verify => const SvgGenImage(
|
SvgGenImage get verify => const SvgGenImage(
|
||||||
'assets/icon/outline/verify.svg',
|
'assets/icon/outline/verify.svg',
|
||||||
|
|
@ -1010,17 +1095,32 @@ class $AssetsIconOutlineGen {
|
||||||
size: Size(16.0, 16.0),
|
size: Size(16.0, 16.0),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
/// File path: assets/icon/outline/wallet.svg
|
||||||
|
SvgGenImage get wallet => const SvgGenImage(
|
||||||
|
'assets/icon/outline/wallet.svg',
|
||||||
|
size: Size(32.0, 33.0),
|
||||||
|
);
|
||||||
|
|
||||||
/// File path: assets/icon/outline/warning-2.svg
|
/// File path: assets/icon/outline/warning-2.svg
|
||||||
SvgGenImage get warning2 => const SvgGenImage(
|
SvgGenImage get warning2 => const SvgGenImage(
|
||||||
'assets/icon/outline/warning-2.svg',
|
'assets/icon/outline/warning-2.svg',
|
||||||
size: Size(24.0, 25.0),
|
size: Size(24.0, 25.0),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
/// File path: assets/icon/outline/warning.svg
|
||||||
|
SvgGenImage get warning => const SvgGenImage(
|
||||||
|
'assets/icon/outline/warning.svg',
|
||||||
|
size: Size(32.0, 33.0),
|
||||||
|
);
|
||||||
|
|
||||||
/// List of all assets
|
/// List of all assets
|
||||||
List<SvgGenImage> get values => [
|
List<SvgGenImage> get values => [
|
||||||
|
houshanFeatures,
|
||||||
|
addFamily,
|
||||||
add,
|
add,
|
||||||
archiveTick,
|
archiveTick,
|
||||||
arrowFlashRight,
|
arrowFlashRight,
|
||||||
|
arrowLeft,
|
||||||
arrowRight,
|
arrowRight,
|
||||||
assistant,
|
assistant,
|
||||||
bitcoinRefresh,
|
bitcoinRefresh,
|
||||||
|
|
@ -1029,12 +1129,14 @@ class $AssetsIconOutlineGen {
|
||||||
calendarEdit,
|
calendarEdit,
|
||||||
call,
|
call,
|
||||||
camera,
|
camera,
|
||||||
|
carbonPedestrianFamily,
|
||||||
cardAdd,
|
cardAdd,
|
||||||
cardPos,
|
cardPos,
|
||||||
characters,
|
characters,
|
||||||
chart,
|
chart,
|
||||||
chat,
|
chat,
|
||||||
clock,
|
clock,
|
||||||
|
closeCircle,
|
||||||
coin,
|
coin,
|
||||||
copy,
|
copy,
|
||||||
courthouse,
|
courthouse,
|
||||||
|
|
@ -1046,15 +1148,20 @@ class $AssetsIconOutlineGen {
|
||||||
documentText,
|
documentText,
|
||||||
download,
|
download,
|
||||||
edit2,
|
edit2,
|
||||||
|
edit,
|
||||||
elementPlus,
|
elementPlus,
|
||||||
emojiHappy,
|
emojiHappy,
|
||||||
emptyWalletTick,
|
emptyWalletTick,
|
||||||
emptyWallet,
|
emptyWallet,
|
||||||
eraser,
|
eraser,
|
||||||
|
family,
|
||||||
|
familyMembers,
|
||||||
filter,
|
filter,
|
||||||
flag2,
|
flag2,
|
||||||
|
folderAdd,
|
||||||
galleryAdd,
|
galleryAdd,
|
||||||
ghost,
|
ghost,
|
||||||
|
gift2,
|
||||||
gift,
|
gift,
|
||||||
globalSearch,
|
globalSearch,
|
||||||
hat,
|
hat,
|
||||||
|
|
@ -1063,6 +1170,7 @@ class $AssetsIconOutlineGen {
|
||||||
idea,
|
idea,
|
||||||
import,
|
import,
|
||||||
infoCircle,
|
infoCircle,
|
||||||
|
ionInfinite,
|
||||||
lampCharge,
|
lampCharge,
|
||||||
library,
|
library,
|
||||||
like,
|
like,
|
||||||
|
|
@ -1087,12 +1195,14 @@ class $AssetsIconOutlineGen {
|
||||||
profileUserDoual,
|
profileUserDoual,
|
||||||
profile,
|
profile,
|
||||||
searchNormal,
|
searchNormal,
|
||||||
|
send,
|
||||||
setting,
|
setting,
|
||||||
share,
|
share,
|
||||||
shieldTick,
|
shieldTick,
|
||||||
smsTracking,
|
smsTracking,
|
||||||
stopCircle,
|
stopCircle,
|
||||||
stop,
|
stop,
|
||||||
|
streamlineCoinsStack,
|
||||||
sun,
|
sun,
|
||||||
tickCircle,
|
tickCircle,
|
||||||
tickSquare,
|
tickSquare,
|
||||||
|
|
@ -1100,10 +1210,13 @@ class $AssetsIconOutlineGen {
|
||||||
toolBox,
|
toolBox,
|
||||||
translate,
|
translate,
|
||||||
trash,
|
trash,
|
||||||
|
trashPopup,
|
||||||
verify,
|
verify,
|
||||||
videoPlay,
|
videoPlay,
|
||||||
voiceCricle,
|
voiceCricle,
|
||||||
|
wallet,
|
||||||
warning2,
|
warning2,
|
||||||
|
warning,
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1130,6 +1243,12 @@ class $AssetsIconSocialGen {
|
||||||
class $AssetsImageBoardingsGen {
|
class $AssetsImageBoardingsGen {
|
||||||
const $AssetsImageBoardingsGen();
|
const $AssetsImageBoardingsGen();
|
||||||
|
|
||||||
|
/// File path: assets/image/boardings/AI Houshan.svg
|
||||||
|
SvgGenImage get aIHoushan => const SvgGenImage(
|
||||||
|
'assets/image/boardings/AI Houshan.svg',
|
||||||
|
size: Size(328.0, 88.0),
|
||||||
|
);
|
||||||
|
|
||||||
/// File path: assets/image/boardings/drei.png
|
/// File path: assets/image/boardings/drei.png
|
||||||
AssetGenImage get drei => const AssetGenImage(
|
AssetGenImage get drei => const AssetGenImage(
|
||||||
'assets/image/boardings/drei.png',
|
'assets/image/boardings/drei.png',
|
||||||
|
|
@ -1167,7 +1286,7 @@ class $AssetsImageBoardingsGen {
|
||||||
);
|
);
|
||||||
|
|
||||||
/// List of all assets
|
/// List of all assets
|
||||||
List<AssetGenImage> get values => [drei, eins, funf, sechs, vier, zwei];
|
List<dynamic> get values => [aIHoushan, drei, eins, funf, sechs, vier, zwei];
|
||||||
}
|
}
|
||||||
|
|
||||||
class $AssetsImageEmptyGen {
|
class $AssetsImageEmptyGen {
|
||||||
|
|
@ -1191,6 +1310,12 @@ class $AssetsImageEmptyGen {
|
||||||
size: Size(347.0, 433.0),
|
size: Size(347.0, 433.0),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
/// File path: assets/image/empty/empty state 1 1.png
|
||||||
|
AssetGenImage get emptyState11 => const AssetGenImage(
|
||||||
|
'assets/image/empty/empty state 1 1.png',
|
||||||
|
size: Size(328.0, 351.0),
|
||||||
|
);
|
||||||
|
|
||||||
/// File path: assets/image/empty/empty-text-underline.svg
|
/// File path: assets/image/empty/empty-text-underline.svg
|
||||||
SvgGenImage get emptyTextUnderline => const SvgGenImage(
|
SvgGenImage get emptyTextUnderline => const SvgGenImage(
|
||||||
'assets/image/empty/empty-text-underline.svg',
|
'assets/image/empty/empty-text-underline.svg',
|
||||||
|
|
@ -1226,6 +1351,7 @@ class $AssetsImageEmptyGen {
|
||||||
amount,
|
amount,
|
||||||
assistant,
|
assistant,
|
||||||
connection,
|
connection,
|
||||||
|
emptyState11,
|
||||||
emptyTextUnderline,
|
emptyTextUnderline,
|
||||||
inbox,
|
inbox,
|
||||||
messages,
|
messages,
|
||||||
|
|
|
||||||
|
|
@ -180,20 +180,20 @@ class Routes {
|
||||||
navigatorKey: navigatorKey,
|
navigatorKey: navigatorKey,
|
||||||
redirect: (context, state) async {
|
redirect: (context, state) async {
|
||||||
final uri = state.uri;
|
final uri = state.uri;
|
||||||
if (uri.scheme == 'houshan' && uri.host == 'auth') {
|
|
||||||
final token = uri.queryParameters['token'];
|
final token = uri.queryParameters['token'];
|
||||||
if (token != null && token.isNotEmpty) {
|
final hasToken = token != null && token.isNotEmpty;
|
||||||
|
|
||||||
|
final isCustomScheme = uri.scheme == 'houshan' && uri.host == 'auth';
|
||||||
|
|
||||||
|
if (hasToken) {
|
||||||
|
if (isCustomScheme || kIsWeb || uri.path == '/') {
|
||||||
if (kDebugMode) {
|
if (kDebugMode) {
|
||||||
print('Deep link token received: ${token.substring(0, 20)}...');
|
print('✅ Login Token Detected: ${token.substring(0, 10)}...');
|
||||||
}
|
}
|
||||||
await AuthTokenStorage.setToken(token);
|
await AuthTokenStorage.setToken(token);
|
||||||
await OnBoardingStorage
|
await OnBoardingStorage.setAsSeen();
|
||||||
.setAsSeen();
|
|
||||||
showOnBoarding = false;
|
showOnBoarding = false;
|
||||||
if (kDebugMode) {
|
|
||||||
print('Token saved. Redirecting to main...');
|
|
||||||
}
|
|
||||||
|
|
||||||
return main;
|
return main;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -211,7 +211,7 @@ class Routes {
|
||||||
return auth;
|
return auth;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (state.matchedLocation == auth) {
|
if (state.uri.path == auth) {
|
||||||
if (context.read<UserInfoCubit>().state is UserInfoFail) return null;
|
if (context.read<UserInfoCubit>().state is UserInfoFail) return null;
|
||||||
if (AuthTokenStorage.getToken().isNotEmpty ||
|
if (AuthTokenStorage.getToken().isNotEmpty ||
|
||||||
(UserInfoCubit.userInfoModel.login != null &&
|
(UserInfoCubit.userInfoModel.login != null &&
|
||||||
|
|
@ -219,7 +219,7 @@ class Routes {
|
||||||
return main;
|
return main;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (state.matchedLocation == home && kIsWeb) {
|
if (state.uri.path == home && kIsWeb) {
|
||||||
if (UserInfoCubit.userInfoModel.login == null) {
|
if (UserInfoCubit.userInfoModel.login == null) {
|
||||||
return main;
|
return main;
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -250,7 +250,6 @@ class Routes {
|
||||||
try {
|
try {
|
||||||
showOnBoarding = state.extra as bool;
|
showOnBoarding = state.extra as bool;
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
// Check if onboarding was already seen
|
|
||||||
showOnBoarding = !OnBoardingStorage.hasSeen();
|
showOnBoarding = !OnBoardingStorage.hasSeen();
|
||||||
if (kDebugMode) {
|
if (kDebugMode) {
|
||||||
print('Error get Args: $e');
|
print('Error get Args: $e');
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,8 @@
|
||||||
|
// ignore_for_file: avoid_print
|
||||||
|
|
||||||
import 'package:firebase_messaging/firebase_messaging.dart';
|
import 'package:firebase_messaging/firebase_messaging.dart';
|
||||||
import 'package:flutter/foundation.dart';
|
import 'package:flutter/foundation.dart';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter/services.dart';
|
import 'package:flutter/services.dart';
|
||||||
import 'package:go_router/go_router.dart';
|
import 'package:go_router/go_router.dart';
|
||||||
import 'package:hoshan/core/routes/route_generator.dart';
|
import 'package:hoshan/core/routes/route_generator.dart';
|
||||||
|
|
@ -16,27 +19,44 @@ class FirebasApi {
|
||||||
static Future<void> initialNotifications() async {
|
static Future<void> initialNotifications() async {
|
||||||
await refreshToken();
|
await refreshToken();
|
||||||
|
|
||||||
|
try {
|
||||||
|
await _firebaseMessaging.subscribeToTopic('all_users').timeout(
|
||||||
|
const Duration(seconds: 10),
|
||||||
|
onTimeout: () {
|
||||||
|
print('⏰ Subscribe to topic timed out - continuing anyway');
|
||||||
|
},
|
||||||
|
);
|
||||||
|
print('✅ Subscribed to topic: all_users');
|
||||||
|
} catch (e) {
|
||||||
|
print('❌ Failed to subscribe to topic (app will continue): $e');
|
||||||
|
}
|
||||||
|
|
||||||
initPushNotification();
|
initPushNotification();
|
||||||
}
|
}
|
||||||
|
|
||||||
static Future refreshToken() async {
|
static Future refreshToken() async {
|
||||||
await _firebaseMessaging.requestPermission();
|
try {
|
||||||
|
print('🔄 Start getting FCM Token...');
|
||||||
|
await _firebaseMessaging.requestPermission();
|
||||||
|
|
||||||
fcmToken = await _firebaseMessaging.getToken();
|
fcmToken = await _firebaseMessaging.getToken().timeout(
|
||||||
|
const Duration(seconds: 10),
|
||||||
|
onTimeout: () {
|
||||||
|
print('⏰ FCM Token request timed out - continuing without token');
|
||||||
|
return null;
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
final packageInfo = await PackageInfo.fromPlatform();
|
final packageInfo = await PackageInfo.fromPlatform();
|
||||||
final packageName = packageInfo.packageName;
|
final packageName = packageInfo.packageName;
|
||||||
|
|
||||||
if (kDebugMode) {
|
|
||||||
print('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━');
|
print('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━');
|
||||||
print('📦 Package Name: $packageName');
|
print('📦 Package Name: $packageName');
|
||||||
print('📱 FCM Token for Firebase:');
|
print('🔥 Firebase Initialized Successfully');
|
||||||
print('$fcmToken');
|
print('📱 FCM Token: $fcmToken');
|
||||||
print('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━');
|
|
||||||
print('');
|
|
||||||
print('✅ Copy this token and use it in Firebase Console:');
|
|
||||||
print(' Cloud Messaging → Send test message');
|
|
||||||
print('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━');
|
print('━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━');
|
||||||
|
} catch (e) {
|
||||||
|
print('❌ ERROR Getting Token (app will continue): $e');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -67,5 +87,23 @@ class FirebasApi {
|
||||||
static Future initPushNotification() async {
|
static Future initPushNotification() async {
|
||||||
FirebaseMessaging.instance.getInitialMessage().then(handleMessage);
|
FirebaseMessaging.instance.getInitialMessage().then(handleMessage);
|
||||||
FirebaseMessaging.onMessageOpenedApp.listen(handleMessage);
|
FirebaseMessaging.onMessageOpenedApp.listen(handleMessage);
|
||||||
|
FirebaseMessaging.onMessage.listen((RemoteMessage message) {
|
||||||
|
if (message.notification != null) {
|
||||||
|
if (navigatorKey.currentContext != null) {
|
||||||
|
ScaffoldMessenger.of(navigatorKey.currentContext!).showSnackBar(
|
||||||
|
SnackBar(
|
||||||
|
content: Text(
|
||||||
|
message.notification!.title != null
|
||||||
|
? '${message.notification!.title}\n${message.notification!.body}'
|
||||||
|
: '${message.notification!.body}',
|
||||||
|
textDirection: TextDirection.rtl,
|
||||||
|
),
|
||||||
|
behavior: SnackBarBehavior.floating,
|
||||||
|
showCloseIcon: true,
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,16 +1,19 @@
|
||||||
class CreditModel {
|
class CreditModel {
|
||||||
final int? credit;
|
final int? credit;
|
||||||
final int? freeCredit;
|
final int? freeCredit;
|
||||||
|
final int? giftCredit;
|
||||||
|
|
||||||
CreditModel({this.credit, this.freeCredit});
|
CreditModel({this.credit, this.freeCredit, this.giftCredit});
|
||||||
|
|
||||||
CreditModel copyWith({
|
CreditModel copyWith({
|
||||||
int? credit,
|
int? credit,
|
||||||
int? freeCredit,
|
int? freeCredit,
|
||||||
|
int? giftCredit,
|
||||||
}) {
|
}) {
|
||||||
return CreditModel(
|
return CreditModel(
|
||||||
credit: credit ?? this.credit,
|
credit: credit ?? this.credit,
|
||||||
freeCredit: freeCredit ?? this.freeCredit,
|
freeCredit: freeCredit ?? this.freeCredit,
|
||||||
|
giftCredit: giftCredit ?? this.giftCredit,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -57,6 +57,22 @@ class DefaultFirebaseOptions {
|
||||||
storageBucket: 'hoshan-42d9f.appspot.com',
|
storageBucket: 'hoshan-42d9f.appspot.com',
|
||||||
);
|
);
|
||||||
|
|
||||||
|
static const FirebaseOptions androidHoushan = FirebaseOptions(
|
||||||
|
apiKey: 'AIzaSyDi2WRiOSEws1alpLitxX0zsX14rT71aPk',
|
||||||
|
appId: '1:581103504002:android:8983465e8b4f637d18829b',
|
||||||
|
messagingSenderId: '581103504002',
|
||||||
|
projectId: 'hoshan-42d9f',
|
||||||
|
storageBucket: 'hoshan-42d9f.appspot.com',
|
||||||
|
);
|
||||||
|
|
||||||
|
static const FirebaseOptions androidHoushanMain = FirebaseOptions(
|
||||||
|
apiKey: 'AIzaSyDi2WRiOSEws1alpLitxX0zsX14rT71aPk',
|
||||||
|
appId: '1:581103504002:android:896e4d41aad9180318829b',
|
||||||
|
messagingSenderId: '581103504002',
|
||||||
|
projectId: 'hoshan-42d9f',
|
||||||
|
storageBucket: 'hoshan-42d9f.appspot.com',
|
||||||
|
);
|
||||||
|
|
||||||
static const FirebaseOptions ios = FirebaseOptions(
|
static const FirebaseOptions ios = FirebaseOptions(
|
||||||
apiKey: 'AIzaSyAENpjFJ2VeVQEt3_Iud9gfqLvuffb7EUI',
|
apiKey: 'AIzaSyAENpjFJ2VeVQEt3_Iud9gfqLvuffb7EUI',
|
||||||
appId: '1:581103504002:ios:4e51253f750a0fc818829b',
|
appId: '1:581103504002:ios:4e51253f750a0fc818829b',
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,5 @@
|
||||||
|
// ignore_for_file: avoid_print
|
||||||
|
|
||||||
import 'package:firebase_core/firebase_core.dart';
|
import 'package:firebase_core/firebase_core.dart';
|
||||||
import 'package:firebase_messaging/firebase_messaging.dart';
|
import 'package:firebase_messaging/firebase_messaging.dart';
|
||||||
import 'package:flutter/foundation.dart';
|
import 'package:flutter/foundation.dart';
|
||||||
|
|
@ -30,50 +32,88 @@ import 'package:hoshan/ui/screens/tools/bloc/tools_bloc.dart';
|
||||||
import 'package:hoshan/ui/theme/cubit/theme_mode_cubit.dart';
|
import 'package:hoshan/ui/theme/cubit/theme_mode_cubit.dart';
|
||||||
import 'package:hoshan/ui/theme/my_custom_scroll_behavior.dart';
|
import 'package:hoshan/ui/theme/my_custom_scroll_behavior.dart';
|
||||||
import 'package:hoshan/ui/theme/theme.dart';
|
import 'package:hoshan/ui/theme/theme.dart';
|
||||||
|
import 'package:package_info_plus/package_info_plus.dart';
|
||||||
import 'package:sentry_flutter/sentry_flutter.dart';
|
import 'package:sentry_flutter/sentry_flutter.dart';
|
||||||
import 'package:url_strategy/url_strategy.dart';
|
import 'package:url_strategy/url_strategy.dart';
|
||||||
|
|
||||||
@pragma('vm:entry-point')
|
@pragma('vm:entry-point')
|
||||||
Future<void> _onBackgroundMessage(RemoteMessage message) async {}
|
Future<void> _onBackgroundMessage(RemoteMessage message) async {
|
||||||
|
debugPrint("Handling a background message: ${message.messageId}");
|
||||||
|
}
|
||||||
|
|
||||||
void main() async {
|
void main() async {
|
||||||
setPathUrlStrategy();
|
setPathUrlStrategy();
|
||||||
WidgetsFlutterBinding.ensureInitialized();
|
WidgetsFlutterBinding.ensureInitialized();
|
||||||
|
|
||||||
// 1. Wrap SharedPreferences in try-catch
|
|
||||||
try {
|
try {
|
||||||
await SharedPreferencesHelper.initial();
|
await SharedPreferencesHelper.initial();
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
debugPrint("Error initializing SharedPreferences: $e");
|
debugPrint("Error initializing SharedPreferences: $e");
|
||||||
}
|
}
|
||||||
|
|
||||||
// 2. Wrap Tapsell in try-catch (High probability of crash here)
|
|
||||||
try {
|
try {
|
||||||
await TapsellService.initialize();
|
await TapsellService.initialize();
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
debugPrint("Error initializing Tapsell: $e");
|
debugPrint("Error initializing Tapsell: $e");
|
||||||
}
|
}
|
||||||
|
|
||||||
// 3. Firebase Initialization
|
print('🚀 Starting Firebase Initialization...');
|
||||||
try {
|
try {
|
||||||
FirebaseMessaging.onBackgroundMessage(_onBackgroundMessage);
|
FirebaseMessaging.onBackgroundMessage(_onBackgroundMessage);
|
||||||
await Firebase.initializeApp(
|
|
||||||
options: DefaultFirebaseOptions.currentPlatform);
|
FirebaseOptions options = DefaultFirebaseOptions.currentPlatform;
|
||||||
FirebasApi.initialNotifications();
|
|
||||||
} catch (e) {
|
if (defaultTargetPlatform == TargetPlatform.android) {
|
||||||
debugPrint('Error initializing Firebase: $e');
|
print('🤖 Platform is Android, checking package info...');
|
||||||
|
final packageInfo = await PackageInfo.fromPlatform();
|
||||||
|
print("📦 RUNNING WITH PACKAGE: ${packageInfo.packageName}");
|
||||||
|
|
||||||
|
if (packageInfo.packageName == 'com.houshan.basa') {
|
||||||
|
options = DefaultFirebaseOptions.androidHoushan;
|
||||||
|
print("🔥 Using 'androidHoushan' options (Basa)");
|
||||||
|
} else if (packageInfo.packageName == 'com.houshan.hoshan') {
|
||||||
|
options = DefaultFirebaseOptions.androidHoushanMain;
|
||||||
|
print("🔥 Using 'androidHoushanMain' options (Main)");
|
||||||
|
} else {
|
||||||
|
print("⚠️ Unknown package name, using default options");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Firebase.apps.isEmpty) {
|
||||||
|
print('⏳ Calling Firebase.initializeApp...');
|
||||||
|
try {
|
||||||
|
await Firebase.initializeApp(options: options);
|
||||||
|
print('✅ Firebase.initializeApp completed.');
|
||||||
|
} catch (e) {
|
||||||
|
print('⚠️ Firebase.initializeApp failed: $e');
|
||||||
|
if (e.toString().contains('duplicate-app')) {
|
||||||
|
print('ℹ️ Ignoring duplicate-app error and continuing...');
|
||||||
|
} else {
|
||||||
|
rethrow;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
print('ℹ️ Firebase already initialized. Skipping initialization.');
|
||||||
|
}
|
||||||
|
|
||||||
|
print('⏳ Calling FirebasApi.initialNotifications()...');
|
||||||
|
await FirebasApi.initialNotifications();
|
||||||
|
} catch (e, stack) {
|
||||||
|
print('❌❌ Error initializing Firebase: $e');
|
||||||
|
print(stack);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 4. Downloader Initialization
|
|
||||||
try {
|
try {
|
||||||
if (!kIsWeb) {
|
if (!kIsWeb) {
|
||||||
await FlutterDownloader.initialize(debug: true, ignoreSsl: true);
|
await FlutterDownloader.initialize(debug: true, ignoreSsl: true);
|
||||||
|
print('✅ FlutterDownloader initialized');
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
debugPrint('Error initializing FlutterDownloader: $e');
|
debugPrint('Error initializing FlutterDownloader: $e');
|
||||||
}
|
}
|
||||||
|
|
||||||
// Run App
|
// Run App
|
||||||
|
print('✅✅ Main initialization completed! Starting app...');
|
||||||
if (kReleaseMode) {
|
if (kReleaseMode) {
|
||||||
await SentryFlutter.init((options) {
|
await SentryFlutter.init((options) {
|
||||||
options.dsn =
|
options.dsn =
|
||||||
|
|
@ -81,11 +121,11 @@ void main() async {
|
||||||
|
|
||||||
options.sendDefaultPii = true;
|
options.sendDefaultPii = true;
|
||||||
},
|
},
|
||||||
// Init your App.
|
|
||||||
appRunner: () => runApp(mainApp()));
|
appRunner: () => runApp(mainApp()));
|
||||||
} else {
|
} else {
|
||||||
runApp(mainApp());
|
runApp(mainApp());
|
||||||
}
|
}
|
||||||
|
print('🚀🚀 App started successfully!');
|
||||||
}
|
}
|
||||||
|
|
||||||
MultiBlocProvider mainApp() {
|
MultiBlocProvider mainApp() {
|
||||||
|
|
|
||||||
|
|
@ -51,11 +51,17 @@ class _AuthPageState extends State<AuthPage> {
|
||||||
if (!kIsWeb) {
|
if (!kIsWeb) {
|
||||||
final appLinks = AppLinks();
|
final appLinks = AppLinks();
|
||||||
_linkSubscription = appLinks.uriLinkStream.listen((uri) async {
|
_linkSubscription = appLinks.uriLinkStream.listen((uri) async {
|
||||||
if (uri.scheme == 'houshan' && uri.host == 'auth') {
|
print('🔔 AuthPage Listener Received URI: $uri'); // Debug Log
|
||||||
|
|
||||||
|
final isCustomScheme = uri.scheme == 'houshan' && uri.host == 'auth';
|
||||||
|
final isWebLink = (uri.scheme == 'https' || uri.scheme == 'http') &&
|
||||||
|
uri.host == 'basaweb.houshan.ai';
|
||||||
|
|
||||||
|
if (isCustomScheme || isWebLink) {
|
||||||
final token = uri.queryParameters['token'];
|
final token = uri.queryParameters['token'];
|
||||||
if (token != null && token.isNotEmpty) {
|
if (token != null && token.isNotEmpty) {
|
||||||
if (kDebugMode) {
|
if (kDebugMode) {
|
||||||
print('Deep link received while app open: $token');
|
print('Deep link received: $uri');
|
||||||
}
|
}
|
||||||
await AuthTokenStorage.setToken(token);
|
await AuthTokenStorage.setToken(token);
|
||||||
await OnBoardingStorage.setAsSeen();
|
await OnBoardingStorage.setAsSeen();
|
||||||
|
|
|
||||||
|
|
@ -28,7 +28,7 @@ class _GiftCodeScreenState extends State<GiftCodeScreen> {
|
||||||
listener: (context, state) async {
|
listener: (context, state) async {
|
||||||
if (state is CheckCodeSucceess) {
|
if (state is CheckCodeSucceess) {
|
||||||
await context.read<UserInfoCubit>().getUserInfo();
|
await context.read<UserInfoCubit>().getUserInfo();
|
||||||
context.go(Routes.giftCredit,
|
context.go(Routes.home,
|
||||||
extra: HomeArgs(message: state.message, freeCredit: 50));
|
extra: HomeArgs(message: state.message, freeCredit: 50));
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
@ -105,7 +105,7 @@ class _GiftCodeScreenState extends State<GiftCodeScreen> {
|
||||||
onPressed: () async {
|
onPressed: () async {
|
||||||
if (state is CheckCodeLoading) return;
|
if (state is CheckCodeLoading) return;
|
||||||
await context.read<UserInfoCubit>().getUserInfo();
|
await context.read<UserInfoCubit>().getUserInfo();
|
||||||
context.go(Routes.giftCredit,
|
context.go(Routes.home,
|
||||||
extra: HomeArgs(freeCredit: 50));
|
extra: HomeArgs(freeCredit: 50));
|
||||||
},
|
},
|
||||||
child: Text(
|
child: Text(
|
||||||
|
|
|
||||||
|
|
@ -96,7 +96,7 @@ class _VerificationScreenState extends State<VerificationScreen> {
|
||||||
context.read<AuthScreensCubit>().changeState(AuthScreens.code);
|
context.read<AuthScreensCubit>().changeState(AuthScreens.code);
|
||||||
} else {
|
} else {
|
||||||
await context.read<UserInfoCubit>().getUserInfo();
|
await context.read<UserInfoCubit>().getUserInfo();
|
||||||
context.go(Routes.giftCredit);
|
context.go(Routes.home);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -58,6 +58,9 @@ class MessagesBloc extends Bloc<MessagesEvent, MessagesState> {
|
||||||
if (event is AddMessage) {
|
if (event is AddMessage) {
|
||||||
final updatedList = List<Messages>.from(state.messages);
|
final updatedList = List<Messages>.from(state.messages);
|
||||||
updatedList.add(event.message);
|
updatedList.add(event.message);
|
||||||
|
if (kDebugMode) {
|
||||||
|
print('📨 AddMessage: Total messages = ${updatedList.length}, Role = ${event.message.role}, File = ${event.message.file?.name}');
|
||||||
|
}
|
||||||
emit(MessagesSuccess(messages: updatedList)); // Copy the current state
|
emit(MessagesSuccess(messages: updatedList)); // Copy the current state
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
File diff suppressed because it is too large
Load Diff
|
|
@ -54,7 +54,6 @@ class ReceiveMessageCubit extends Cubit<ReceiveMessageState> {
|
||||||
AiResponseModel aiResponseModel = AiResponseModel();
|
AiResponseModel aiResponseModel = AiResponseModel();
|
||||||
await scrollToEnd();
|
await scrollToEnd();
|
||||||
try {
|
try {
|
||||||
// Call your streaming message function and yield states accordingly
|
|
||||||
await for (String message in request.tool!
|
await for (String message in request.tool!
|
||||||
? ChatbotRepository.sendMessageTool(request)
|
? ChatbotRepository.sendMessageTool(request)
|
||||||
: ChatbotRepository.sendMessage(request)) {
|
: ChatbotRepository.sendMessage(request)) {
|
||||||
|
|
@ -78,7 +77,7 @@ class ReceiveMessageCubit extends Cubit<ReceiveMessageState> {
|
||||||
|
|
||||||
for (String json in jsonStrings) {
|
for (String json in jsonStrings) {
|
||||||
json = json.replaceAll(
|
json = json.replaceAll(
|
||||||
RegExp(r'[{}"]'), ''); // Remove braces and quotes
|
RegExp(r'[{}"]'), '');
|
||||||
List<String> pairs = json.split(', ');
|
List<String> pairs = json.split(', ');
|
||||||
for (String pair in pairs) {
|
for (String pair in pairs) {
|
||||||
if (pair.contains('chat_id:')) {
|
if (pair.contains('chat_id:')) {
|
||||||
|
|
@ -94,10 +93,10 @@ class ReceiveMessageCubit extends Cubit<ReceiveMessageState> {
|
||||||
pair.replaceAll('human_message_id: ', '');
|
pair.replaceAll('human_message_id: ', '');
|
||||||
} else if (pair.contains('credit:')) {
|
} else if (pair.contains('credit:')) {
|
||||||
jsonMap['credit'] = pair.replaceAll('credit: ', '');
|
jsonMap['credit'] = pair.replaceAll('credit: ', '');
|
||||||
} else if (pair.contains('credit:')) {
|
|
||||||
jsonMap['credit'] = pair.replaceAll('credit: ', '');
|
|
||||||
} else if (pair.contains('free:')) {
|
} else if (pair.contains('free:')) {
|
||||||
jsonMap['free'] = pair.replaceAll('free: ', '');
|
jsonMap['free'] = pair.replaceAll('free: ', '');
|
||||||
|
} else if (pair.contains('gift:')) {
|
||||||
|
jsonMap['gift'] = pair.replaceAll('gift: ', '');
|
||||||
} else if (pair.contains('human_message_created_at:')) {
|
} else if (pair.contains('human_message_created_at:')) {
|
||||||
jsonMap['human_message_created_at'] =
|
jsonMap['human_message_created_at'] =
|
||||||
pair.replaceAll('human_message_created_at: ', '');
|
pair.replaceAll('human_message_created_at: ', '');
|
||||||
|
|
@ -122,8 +121,16 @@ class ReceiveMessageCubit extends Cubit<ReceiveMessageState> {
|
||||||
final res = AiResponseModel.fromJson(jsonMap);
|
final res = AiResponseModel.fromJson(jsonMap);
|
||||||
|
|
||||||
if (res.content != null) {
|
if (res.content != null) {
|
||||||
result += res.content ?? ''; // Add each content to the list
|
result += res.content ?? '';
|
||||||
if (!(res.content!.startsWith('http'))) {
|
if (res.content!.startsWith('http')) {
|
||||||
|
if (res.content!.isImage()) {
|
||||||
|
emit(ReceiveMessageOnResponsing(text: 'در حال آمادهسازی تصویر'));
|
||||||
|
} else if (res.content!.isAudio()) {
|
||||||
|
emit(ReceiveMessageOnResponsing(text: 'در حال آمادهسازی صوت'));
|
||||||
|
} else if (res.content!.isDocument()) {
|
||||||
|
emit(ReceiveMessageOnResponsing(text: 'در حال آمادهسازی فایل'));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
emit(ReceiveMessageOnResponsing(text: result));
|
emit(ReceiveMessageOnResponsing(text: result));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -138,10 +145,14 @@ class ReceiveMessageCubit extends Cubit<ReceiveMessageState> {
|
||||||
content: result.isEmpty ? res.content : result,
|
content: result.isEmpty ? res.content : result,
|
||||||
freeCredit: res.freeCredit,
|
freeCredit: res.freeCredit,
|
||||||
humanMessageId: res.humanMessageId);
|
humanMessageId: res.humanMessageId);
|
||||||
// Yield the received message line by line
|
|
||||||
}
|
}
|
||||||
await scrollToEnd();
|
await scrollToEnd();
|
||||||
|
|
||||||
|
if (aiResponseModel.content != null &&
|
||||||
|
aiResponseModel.content!.startsWith('http')) {
|
||||||
|
await Future.delayed(const Duration(milliseconds: 500));
|
||||||
|
}
|
||||||
|
|
||||||
if (aiResponseModel.error ?? true) {
|
if (aiResponseModel.error ?? true) {
|
||||||
emit(ReceiveMessageOnFail(
|
emit(ReceiveMessageOnFail(
|
||||||
oldHumanMessageId: request.messageId ?? '',
|
oldHumanMessageId: request.messageId ?? '',
|
||||||
|
|
|
||||||
|
|
@ -126,6 +126,20 @@ class _PhotoChatPageState extends State<PhotoChatPage> {
|
||||||
.state is MediaGResponseLoading) {
|
.state is MediaGResponseLoading) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
context.read<MessagesBloc>().add(AddMessage(
|
||||||
|
message: Messages(
|
||||||
|
file: image.xFile,
|
||||||
|
content: [
|
||||||
|
Content(
|
||||||
|
imageUrl: FileUrl(
|
||||||
|
url: image.xFile.path))
|
||||||
|
],
|
||||||
|
createdAt: DateTime.now()
|
||||||
|
.toIso8601String(),
|
||||||
|
id: 'hero',
|
||||||
|
role: 'user')));
|
||||||
|
|
||||||
context.read<MediaGResponseCubit>().request(
|
context.read<MediaGResponseCubit>().request(
|
||||||
SendMessageModel(
|
SendMessageModel(
|
||||||
ghost: isGhost.value,
|
ghost: isGhost.value,
|
||||||
|
|
@ -164,11 +178,30 @@ class _PhotoChatPageState extends State<PhotoChatPage> {
|
||||||
.state is MediaGResponseLoading) {
|
.state is MediaGResponseLoading) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
final query = _query.text;
|
||||||
|
|
||||||
|
if (query.isNotEmpty) {
|
||||||
|
context.read<MessagesBloc>().add(
|
||||||
|
AddMessage(
|
||||||
|
message: Messages(
|
||||||
|
query: query,
|
||||||
|
content: [
|
||||||
|
Content(
|
||||||
|
type: 'text',
|
||||||
|
text: query)
|
||||||
|
],
|
||||||
|
createdAt: DateTime.now()
|
||||||
|
.toIso8601String(),
|
||||||
|
id: 'hero',
|
||||||
|
role: 'user')));
|
||||||
|
}
|
||||||
|
|
||||||
context.read<MediaGResponseCubit>().request(
|
context.read<MediaGResponseCubit>().request(
|
||||||
SendMessageModel(
|
SendMessageModel(
|
||||||
messageId: DateTime.now()
|
messageId: DateTime.now()
|
||||||
.toIso8601String(),
|
.toIso8601String(),
|
||||||
query: _query.text,
|
query: query,
|
||||||
botId: widget.chatArgs.bot.id,
|
botId: widget.chatArgs.bot.id,
|
||||||
ghost: isGhost.value,
|
ghost: isGhost.value,
|
||||||
id: chatId));
|
id: chatId));
|
||||||
|
|
@ -255,22 +288,50 @@ class _PhotoChatPageState extends State<PhotoChatPage> {
|
||||||
child: CircularProgressIndicator(),
|
child: CircularProgressIndicator(),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
// if (state is MessagesSuccess) {
|
|
||||||
final m = mState.messages;
|
final m = mState.messages;
|
||||||
List<List<Messages>> allMessages = groupMessages(m);
|
List<List<Messages>> allMessages = groupMessages(m);
|
||||||
// فیلتر کردن گروههایی که حداقل یک پیام با image_url دارند
|
|
||||||
List<List<Messages>> messages = allMessages.where((group) {
|
List<List<Messages>> messages = ptp
|
||||||
return group.any((msg) =>
|
? allMessages.where((group) {
|
||||||
msg.content?.any((c) => c.imageUrl != null) ?? false);
|
return group.any((msg) =>
|
||||||
}).toList();
|
msg.content?.any((c) => c.imageUrl != null) ??
|
||||||
|
false);
|
||||||
|
}).toList()
|
||||||
|
: allMessages;
|
||||||
|
|
||||||
return BlocConsumer<MediaGResponseCubit, MediaGResponseState>(
|
return BlocConsumer<MediaGResponseCubit, MediaGResponseState>(
|
||||||
listener: (context, state) async {
|
listener: (context, state) async {
|
||||||
if (state is MediaGResponseSucess) {
|
if (state is MediaGResponseSucess) {
|
||||||
|
final messages =
|
||||||
|
context.read<MessagesBloc>().state.messages;
|
||||||
|
final heroMessage = messages.firstWhere(
|
||||||
|
(m) => m.id == 'hero',
|
||||||
|
orElse: () => Messages(id: null, role: 'user'),
|
||||||
|
);
|
||||||
|
|
||||||
|
if (heroMessage.id != null) {
|
||||||
|
context
|
||||||
|
.read<MessagesBloc>()
|
||||||
|
.add(DeleteMessageWithId(messageId: 'hero'));
|
||||||
|
}
|
||||||
|
|
||||||
context.read<MessagesBloc>().add(AddMessage(
|
context.read<MessagesBloc>().add(AddMessage(
|
||||||
message: Messages(
|
message: Messages(
|
||||||
query: state.query,
|
query: state.query,
|
||||||
file: state.file,
|
file: state.file,
|
||||||
|
content: state.file != null
|
||||||
|
? [
|
||||||
|
Content(
|
||||||
|
imageUrl:
|
||||||
|
FileUrl(url: state.file!.path))
|
||||||
|
]
|
||||||
|
: state.query != null &&
|
||||||
|
state.query!.isNotEmpty
|
||||||
|
? [
|
||||||
|
Content(
|
||||||
|
type: 'text', text: state.query)
|
||||||
|
]
|
||||||
|
: null,
|
||||||
createdAt: DateTime.now().toIso8601String(),
|
createdAt: DateTime.now().toIso8601String(),
|
||||||
error: state.response.error,
|
error: state.response.error,
|
||||||
id: state.response.humanMessageId,
|
id: state.response.humanMessageId,
|
||||||
|
|
@ -300,11 +361,16 @@ class _PhotoChatPageState extends State<PhotoChatPage> {
|
||||||
|
|
||||||
chatId = state.response.chatId;
|
chatId = state.response.chatId;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (state is MediaGResponseFail) {
|
||||||
|
context
|
||||||
|
.read<MessagesBloc>()
|
||||||
|
.add(DeleteMessageWithId(messageId: 'hero'));
|
||||||
|
}
|
||||||
},
|
},
|
||||||
builder: (context, state) {
|
builder: (context, state) {
|
||||||
final newMaxSize = messages.length + 1;
|
final newMaxSize = messages.length + 1;
|
||||||
|
|
||||||
// استفاده از postFrameCallback برای جلوگیری از setState در build
|
|
||||||
if (maxSize.value != newMaxSize) {
|
if (maxSize.value != newMaxSize) {
|
||||||
WidgetsBinding.instance.addPostFrameCallback((_) {
|
WidgetsBinding.instance.addPostFrameCallback((_) {
|
||||||
if (mounted) {
|
if (mounted) {
|
||||||
|
|
@ -318,7 +384,6 @@ class _PhotoChatPageState extends State<PhotoChatPage> {
|
||||||
return ListView(
|
return ListView(
|
||||||
physics: const BouncingScrollPhysics(),
|
physics: const BouncingScrollPhysics(),
|
||||||
children: [
|
children: [
|
||||||
// Bot info section
|
|
||||||
Column(
|
Column(
|
||||||
children: [
|
children: [
|
||||||
const SizedBox(
|
const SizedBox(
|
||||||
|
|
@ -497,7 +562,6 @@ class _PhotoChatPageState extends State<PhotoChatPage> {
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
// Messages list
|
|
||||||
...messages.asMap().entries.map((entry) {
|
...messages.asMap().entries.map((entry) {
|
||||||
final index = entry.key;
|
final index = entry.key;
|
||||||
final ms = entry.value;
|
final ms = entry.value;
|
||||||
|
|
@ -545,30 +609,59 @@ class _PhotoChatPageState extends State<PhotoChatPage> {
|
||||||
16)),
|
16)),
|
||||||
child: AspectRatio(
|
child: AspectRatio(
|
||||||
aspectRatio: 3 / 4,
|
aspectRatio: 3 / 4,
|
||||||
child: user!.file != null
|
child: Stack(
|
||||||
? ClipRRect(
|
fit: StackFit.expand,
|
||||||
borderRadius:
|
children: [
|
||||||
BorderRadius
|
user!.file != null
|
||||||
.circular(
|
? ClipRRect(
|
||||||
12),
|
borderRadius:
|
||||||
child: CustomeImage(
|
BorderRadius
|
||||||
src: user
|
.circular(
|
||||||
.file!.path,
|
12),
|
||||||
fit: BoxFit.cover,
|
child:
|
||||||
))
|
CustomeImage(
|
||||||
: ImageNetwork(
|
src: user
|
||||||
width:
|
.file!
|
||||||
double.infinity,
|
.path,
|
||||||
height:
|
fit: BoxFit
|
||||||
double.infinity,
|
.cover,
|
||||||
radius: 12,
|
))
|
||||||
showHero: true,
|
: ImageNetwork(
|
||||||
url: user
|
width: double
|
||||||
.content
|
.infinity,
|
||||||
?.first
|
height: double
|
||||||
.imageUrl
|
.infinity,
|
||||||
?.url ??
|
radius: 12,
|
||||||
''),
|
showHero: true,
|
||||||
|
url: user
|
||||||
|
.content
|
||||||
|
?.first
|
||||||
|
.imageUrl
|
||||||
|
?.url ??
|
||||||
|
''),
|
||||||
|
if (user.id == 'hero')
|
||||||
|
Container(
|
||||||
|
decoration:
|
||||||
|
BoxDecoration(
|
||||||
|
color: Colors
|
||||||
|
.black
|
||||||
|
.withOpacity(
|
||||||
|
0.5),
|
||||||
|
borderRadius:
|
||||||
|
BorderRadius
|
||||||
|
.circular(
|
||||||
|
12),
|
||||||
|
),
|
||||||
|
child: Center(
|
||||||
|
child:
|
||||||
|
CircularProgressIndicator(
|
||||||
|
color: Colors
|
||||||
|
.white,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
after: Container(
|
after: Container(
|
||||||
|
|
@ -684,52 +777,83 @@ class _PhotoChatPageState extends State<PhotoChatPage> {
|
||||||
?.url ??
|
?.url ??
|
||||||
''),
|
''),
|
||||||
)
|
)
|
||||||
: Padding(
|
: Stack(
|
||||||
padding:
|
children: [
|
||||||
const EdgeInsets.all(
|
Padding(
|
||||||
16.0),
|
padding:
|
||||||
child: Directionality(
|
const EdgeInsets
|
||||||
textDirection:
|
.all(16.0),
|
||||||
TextDirection.rtl,
|
child: Directionality(
|
||||||
child: Scrollbar(
|
textDirection:
|
||||||
thumbVisibility: true,
|
TextDirection
|
||||||
trackVisibility: true,
|
.rtl,
|
||||||
interactive: true,
|
child: Scrollbar(
|
||||||
controller:
|
thumbVisibility:
|
||||||
yourScrollController,
|
true,
|
||||||
radius: const Radius
|
trackVisibility:
|
||||||
.circular(16),
|
true,
|
||||||
child:
|
interactive: true,
|
||||||
SingleChildScrollView(
|
controller:
|
||||||
controller:
|
yourScrollController,
|
||||||
yourScrollController,
|
radius:
|
||||||
physics:
|
const Radius
|
||||||
const BouncingScrollPhysics(),
|
.circular(
|
||||||
child: Padding(
|
16),
|
||||||
padding:
|
|
||||||
const EdgeInsets
|
|
||||||
.only(
|
|
||||||
left:
|
|
||||||
8.0),
|
|
||||||
child:
|
child:
|
||||||
SelectableText(
|
SingleChildScrollView(
|
||||||
user.query ??
|
controller:
|
||||||
'',
|
yourScrollController,
|
||||||
|
physics:
|
||||||
|
const BouncingScrollPhysics(),
|
||||||
|
child: Padding(
|
||||||
|
padding:
|
||||||
|
const EdgeInsets
|
||||||
|
.only(
|
||||||
|
left:
|
||||||
|
8.0),
|
||||||
|
child:
|
||||||
|
SelectableText(
|
||||||
|
user.query ??
|
||||||
|
'',
|
||||||
|
|
||||||
style:
|
style: AppTextStyles
|
||||||
AppTextStyles
|
|
||||||
.body4
|
.body4
|
||||||
.copyWith(
|
.copyWith(
|
||||||
color: Colors
|
color: Colors
|
||||||
.white,
|
.white,
|
||||||
|
),
|
||||||
|
// overflow: TextOverflow.ellipsis,
|
||||||
|
// textAlign: TextAlign.justify,
|
||||||
|
),
|
||||||
),
|
),
|
||||||
// overflow: TextOverflow.ellipsis,
|
|
||||||
// textAlign: TextAlign.justify,
|
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
if (user.id == 'hero')
|
||||||
|
Positioned.fill(
|
||||||
|
child: Container(
|
||||||
|
decoration:
|
||||||
|
BoxDecoration(
|
||||||
|
color: Colors
|
||||||
|
.black
|
||||||
|
.withOpacity(
|
||||||
|
0.5),
|
||||||
|
borderRadius:
|
||||||
|
BorderRadius
|
||||||
|
.circular(
|
||||||
|
12),
|
||||||
|
),
|
||||||
|
child: Center(
|
||||||
|
child:
|
||||||
|
CircularProgressIndicator(
|
||||||
|
color: Colors
|
||||||
|
.white,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
|
|
|
||||||
|
|
@ -316,7 +316,6 @@ class _TtaPageState extends State<VideoChatPage> {
|
||||||
1 +
|
1 +
|
||||||
(state is MediaGResponseLoading ? 1 : 0);
|
(state is MediaGResponseLoading ? 1 : 0);
|
||||||
|
|
||||||
// استفاده از postFrameCallback برای جلوگیری از setState در build
|
|
||||||
if (maxSize.value != newMaxSize) {
|
if (maxSize.value != newMaxSize) {
|
||||||
WidgetsBinding.instance.addPostFrameCallback((_) {
|
WidgetsBinding.instance.addPostFrameCallback((_) {
|
||||||
if (mounted) {
|
if (mounted) {
|
||||||
|
|
@ -653,7 +652,7 @@ class _TtaPageState extends State<VideoChatPage> {
|
||||||
BorderRadius.circular(
|
BorderRadius.circular(
|
||||||
12),
|
12),
|
||||||
child: ChatVideoPlayer(
|
child: ChatVideoPlayer(
|
||||||
src: ai?.content?.first
|
src: ai.content?.first
|
||||||
.videoUrl?.url ??
|
.videoUrl?.url ??
|
||||||
'',
|
'',
|
||||||
custome:
|
custome:
|
||||||
|
|
|
||||||
|
|
@ -15,7 +15,7 @@ class PostsCubit extends Cubit<PostsState> {
|
||||||
// Disabled enabled.json check - always show posts
|
// Disabled enabled.json check - always show posts
|
||||||
// try {
|
// try {
|
||||||
// final check = await CoursesServices.dio.get('/enabled.json');
|
// final check = await CoursesServices.dio.get('/enabled.json');
|
||||||
// print('🟢 enabled.json: ${check.data}');
|
// print('<EFBFBD> enabled.json: ${check.data}');
|
||||||
// if (check.data == false) {
|
// if (check.data == false) {
|
||||||
// emit(PostsFail());
|
// emit(PostsFail());
|
||||||
// return;
|
// return;
|
||||||
|
|
|
||||||
|
|
@ -32,7 +32,6 @@ import 'package:hoshan/ui/theme/colors.dart';
|
||||||
import 'package:hoshan/ui/theme/cubit/theme_mode_cubit.dart';
|
import 'package:hoshan/ui/theme/cubit/theme_mode_cubit.dart';
|
||||||
import 'package:hoshan/ui/theme/responsive.dart';
|
import 'package:hoshan/ui/theme/responsive.dart';
|
||||||
import 'package:hoshan/ui/theme/text.dart';
|
import 'package:hoshan/ui/theme/text.dart';
|
||||||
import 'package:hoshan/ui/widgets/ai_Banner.dart';
|
|
||||||
import 'package:hoshan/ui/widgets/components/bot/bot_grid_card.dart';
|
import 'package:hoshan/ui/widgets/components/bot/bot_grid_card.dart';
|
||||||
import 'package:hoshan/ui/widgets/components/bot/bot_grid_card_placeholder.dart';
|
import 'package:hoshan/ui/widgets/components/bot/bot_grid_card_placeholder.dart';
|
||||||
import 'package:hoshan/ui/widgets/components/bot/tool_card.dart';
|
import 'package:hoshan/ui/widgets/components/bot/tool_card.dart';
|
||||||
|
|
|
||||||
|
|
@ -31,8 +31,10 @@ class _SplashPageState extends State<SplashPage> {
|
||||||
@override
|
@override
|
||||||
void initState() {
|
void initState() {
|
||||||
super.initState();
|
super.initState();
|
||||||
|
print('🎯 SplashPage: initState called');
|
||||||
|
|
||||||
WidgetsBinding.instance.addPostFrameCallback((_) async {
|
WidgetsBinding.instance.addPostFrameCallback((_) async {
|
||||||
|
print('🎯 SplashPage: PostFrameCallback started');
|
||||||
bool hasDeepLink = false;
|
bool hasDeepLink = false;
|
||||||
if (!kIsWeb) {
|
if (!kIsWeb) {
|
||||||
try {
|
try {
|
||||||
|
|
@ -92,11 +94,14 @@ class _SplashPageState extends State<SplashPage> {
|
||||||
|
|
||||||
if (!hasDeepLink) {
|
if (!hasDeepLink) {
|
||||||
String authToken = AuthTokenStorage.getToken();
|
String authToken = AuthTokenStorage.getToken();
|
||||||
|
print('🎯 SplashPage: Auth token = ${authToken.isEmpty ? "EMPTY" : "EXISTS"}');
|
||||||
if (mounted) {
|
if (mounted) {
|
||||||
if (authToken.isEmpty) {
|
if (authToken.isEmpty) {
|
||||||
|
print('🎯 SplashPage: Navigating to auth page');
|
||||||
FirebasApi.deleteToken();
|
FirebasApi.deleteToken();
|
||||||
context.go(Routes.auth);
|
context.go(Routes.auth);
|
||||||
} else {
|
} else {
|
||||||
|
print('🎯 SplashPage: Getting user info');
|
||||||
context.read<UserInfoCubit>().getUserInfo();
|
context.read<UserInfoCubit>().getUserInfo();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -10,23 +10,16 @@ class FamilyBanner extends StatelessWidget {
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
|
final hasParent = UserInfoCubit.userInfoModel.parent != null;
|
||||||
|
|
||||||
|
if (hasParent) {
|
||||||
|
return const SizedBox.shrink();
|
||||||
|
}
|
||||||
|
|
||||||
return Padding(
|
return Padding(
|
||||||
padding: const EdgeInsets.all(16.0),
|
padding: const EdgeInsets.all(16.0),
|
||||||
child: GestureDetector(
|
child: GestureDetector(
|
||||||
onTap: () {
|
onTap: () {
|
||||||
final hasParent = UserInfoCubit.userInfoModel.parent != null;
|
|
||||||
|
|
||||||
if (hasParent) {
|
|
||||||
ScaffoldMessenger.of(context).showSnackBar(
|
|
||||||
const SnackBar(
|
|
||||||
content: Text(
|
|
||||||
'شما عضو یک خانواده هستید و نمیتوانید خانواده جدید اضافه کنید',
|
|
||||||
),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
Navigator.push(
|
Navigator.push(
|
||||||
context,
|
context,
|
||||||
MaterialPageRoute(
|
MaterialPageRoute(
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue