WT1.1.4 build 45 android fb, iap
This commit is contained in:
parent
f3cc241f65
commit
4bd1950ffd
@ -78,5 +78,7 @@ dependencies {
|
|||||||
implementation 'com.google.firebase:firebase-analytics:18.0.0'
|
implementation 'com.google.firebase:firebase-analytics:18.0.0'
|
||||||
implementation 'com.facebook.android:facebook-login:5.15.3'
|
implementation 'com.facebook.android:facebook-login:5.15.3'
|
||||||
implementation 'com.android.support:multidex:1.0.3'
|
implementation 'com.android.support:multidex:1.0.3'
|
||||||
|
def billing_version = "3.0.0"
|
||||||
|
implementation "com.android.billingclient:billing:$billing_version"
|
||||||
}
|
}
|
||||||
sourceCompatibility = '1.8'
|
sourceCompatibility = '1.8'
|
@ -50,12 +50,12 @@
|
|||||||
android:value="2" />
|
android:value="2" />
|
||||||
|
|
||||||
<meta-data android:name="com.facebook.sdk.ApplicationId"
|
<meta-data android:name="com.facebook.sdk.ApplicationId"
|
||||||
android:value="@string/app_name"/>
|
android:value="@string/facebook_app_id"/>
|
||||||
|
|
||||||
<activity android:name="com.facebook.FacebookActivity"
|
<activity android:name="com.facebook.FacebookActivity"
|
||||||
android:configChanges=
|
android:configChanges=
|
||||||
"keyboard|keyboardHidden|screenLayout|screenSize|orientation"
|
"keyboard|keyboardHidden|screenLayout|screenSize|orientation"
|
||||||
android:label="WorkoutTest" />
|
android:label="@string/app_name" />
|
||||||
<activity
|
<activity
|
||||||
android:name="com.facebook.CustomTabActivity"
|
android:name="com.facebook.CustomTabActivity"
|
||||||
android:exported="true">
|
android:exported="true">
|
||||||
|
200
asset/data/promotion_codes-month.csv
Normal file
200
asset/data/promotion_codes-month.csv
Normal file
@ -0,0 +1,200 @@
|
|||||||
|
Promotion code
|
||||||
|
- A7DXXDNMKXU0KUJAEW70PRF
|
||||||
|
2HLKJ93QP0TTGYFB4EL383L
|
||||||
|
VDZBBGVMUUZ9PF2HTPG7PJ8
|
||||||
|
V7RF0U3H6T0CY5LXX6AH7A4
|
||||||
|
D63MQ1JPW6BQ4P0ZQM9UNQV
|
||||||
|
ZDT7SSQB01FG4LCE67APADL
|
||||||
|
U6953FSGRD54HYSAP27BQSA
|
||||||
|
P0EHCGYHBM8PCVDY3AETGBY
|
||||||
|
RUQX8TPKLT83WZ102EQ18B6
|
||||||
|
LZ7MD5N30VQ6RD13J7NXHLL
|
||||||
|
02FR52AH4WSANVMFGNQLBHX
|
||||||
|
NLT4166PUJYW6ARAX76VK6Z
|
||||||
|
TT6J3EBD56YZEK5T7R48ZB7
|
||||||
|
PJ9APMP07V716P0MZQ1QQZ4
|
||||||
|
1LAEA5MAVZCQ6Q6V746VWHA
|
||||||
|
UR80FUSC88S4ZM6D7F2LAHX
|
||||||
|
QGSTE9Z6T4ZTBR7D18ENZZE
|
||||||
|
42F6RJ8UC0JGTJ3J3SPAW51
|
||||||
|
Y1Z3S9D375EW5QG0KDWHRN5
|
||||||
|
5KSKAP7JMSZB8KFWQCNJ2EP
|
||||||
|
RFPKVGG2HUTLJDS293SK7T5
|
||||||
|
6AH8L8V6ZDXRFDGWLD7XC1R
|
||||||
|
L34MAXPGWBPHHEDRJ6J56Y2
|
||||||
|
ZHD36F0FSPQ0302UG9JG4SJ
|
||||||
|
A534UX0580PET9ZLRJGSJBN
|
||||||
|
H8DZKTCYBXX3Y03UGQFVFFL
|
||||||
|
2EN7JH4A3KCJB2H49WBT4NX
|
||||||
|
XKP4HLPL738ZWAHH0DFPV73
|
||||||
|
QA980ELAHDVJKAAALCSX3EC
|
||||||
|
RRXA7TKYR8T0GRUS7QEBMU6
|
||||||
|
3E9K4YZ4JG6UM9A03LQYX8Z
|
||||||
|
YTYYQE4B1HNCAPVEWHAHBYN
|
||||||
|
TAUZRSDGB8HT4JHWT04R0T0
|
||||||
|
2APA0FT1DH0XM35PESM7YX0
|
||||||
|
CVLTAJM0NF1GX46FEYCKXR1
|
||||||
|
A8GH58V40TSC6L86ECWRNBT
|
||||||
|
QJ37ENK3TK3FTZA250DGS02
|
||||||
|
TJJWKUMBQRPTT8VWZDF4W9X
|
||||||
|
CM6DDDUYVCGSGXZ36D5N6WW
|
||||||
|
AZMUZ9EPL0JBHYKGRK3MCK0
|
||||||
|
12MV9LC4BE4KGEDEW5X2MEM
|
||||||
|
41F0GRVWJSLEAUAY0ALUN1V
|
||||||
|
PPPHG266FFF6QBGJSL8WBDF
|
||||||
|
MGP71PUFZ6NKLPP4VF8DS3T
|
||||||
|
LXA6SH75WZ8KY4BEUV0S85U
|
||||||
|
447FRJGYW2902PLLXZYTRAU
|
||||||
|
D9EMMELU70PXZ8AKUZ56WCZ
|
||||||
|
CZ4VPRSD6RFCGRDM1SVU2BH
|
||||||
|
1ZTL14ZD7GHVB6B0NQMTCX5
|
||||||
|
SA5W6ABBE74VUJV077C9A7E
|
||||||
|
WB9EMATS4DHY3N2QL8WPXGB
|
||||||
|
XQ368K414VJVVAS4G0EBT7C
|
||||||
|
KGXV8WTQZ39WUUFYUJQXS1Y
|
||||||
|
KW9920H2TDVJG9M6WVH2MBZ
|
||||||
|
EZUSXBLAT69K7MBYUULPSUY
|
||||||
|
3ZW2R3HFQB0GT27253L530Q
|
||||||
|
WNWUYXYZZLVT5EK5NH4UMB7
|
||||||
|
7WSV8KB1DH5XEBE9ZBTVSVF
|
||||||
|
0Q3USEXJDRN219V66275B4H
|
||||||
|
U6LKPXG16Z83A1RA320P0U6
|
||||||
|
PAV3UQXD61NR528X1GND42R
|
||||||
|
6NNZ9MVWZESFPHV0VBQBMNN
|
||||||
|
BD2XLH4HKJWCGPY9C1AJGNW
|
||||||
|
RQTLUQ1ZZJZBET76071WT89
|
||||||
|
RBKQRGP9E6QGUX3KAJXF20K
|
||||||
|
UGM5QUE0EXKEBE2A75ECNSM
|
||||||
|
N2P0H1LFS2YEKX64D2PWDN7
|
||||||
|
P6VJLEAKABRGFVR4T5DH1X5
|
||||||
|
TJ815RNL5A460XJG4THR9JL
|
||||||
|
YL0XY8R2TBTP5N5F9S3VWSV
|
||||||
|
DU32C5H5U4GLT0509DS9G2K
|
||||||
|
9DXV8W7QU9L63EY7XJVYTQ7
|
||||||
|
UXNLD05CKKX20YKKNLVJ4BS
|
||||||
|
VYDMRWTW5FJ76XGLSML71QU
|
||||||
|
MBJJHEJPTRY2HQXLLPJ51XR
|
||||||
|
XM63E19C75AJUBHH98D7W6C
|
||||||
|
PTAU2W57H36U9U547UUND9G
|
||||||
|
F1MZVKQ0Q4186X2JAPKW4RP
|
||||||
|
MJRP26W2QM6XKUJDKFXX6AY
|
||||||
|
AFN2GK30M9XNAPCF6GA1PZY
|
||||||
|
GMYZDKLK428WS94GYHSW97U
|
||||||
|
WVJHNTJE2USGWYAUB2G2ZNK
|
||||||
|
DPYWSJETW05X990Z0U2MWBS
|
||||||
|
S8U1061Q6LRZNGWHTGJ04U0
|
||||||
|
HTLC06BVKKBKS7SBVK26J45
|
||||||
|
A91PFKAHJMMXFTAHRUB9ENK
|
||||||
|
KXPJ0AV2QURS3T9Z3HR0RN8
|
||||||
|
V24WFCGMMQ1X38EUXXAVCGW
|
||||||
|
263NEVRL247Q3D82PU5SFDK
|
||||||
|
Z4QPPMN3J2T12VTGFVEZ2K7
|
||||||
|
29F4W2RCAWRMK9P7KWRQ0WK
|
||||||
|
LHJEC87AM9TRC0C0JX3XLGX
|
||||||
|
PFSML2E11VJEB9GJ9SR1T36
|
||||||
|
ZECQPLLUVX3QR61WMUX42HA
|
||||||
|
K8MJAX3THB3FCWZT9VB2GSV
|
||||||
|
HV4NHY2E3YJ836HH5KKU9Z1
|
||||||
|
H6VN3YCXJYL5KR63QNGUX1C
|
||||||
|
MDLNPC7H171QQN2C4SU0MZ7
|
||||||
|
48HAF1RBHFWC2H8ZUHU8MGG
|
||||||
|
48Z1MS05VFAB5ZKDEYB17TA
|
||||||
|
V5LGP8113UJJ1SEWC5B5GTE
|
||||||
|
RR5FP5CY1JB2WB9KY0YRKJR
|
||||||
|
AYGQQN8FFPGY557PG6VGTTK
|
||||||
|
PXT14ECUUR2MYP7XH9LYUQ6
|
||||||
|
FED9VS405XMWYHW2P14NGJN
|
||||||
|
V5NBC31P2B1A9D536ERVBYH
|
||||||
|
AUHL02U2UDZY9N25Z0QE9C8
|
||||||
|
JLSRMKPW82XY5EALCPT1P7G
|
||||||
|
JM2BQUT9ZM3DNMDLVPATZGP
|
||||||
|
C26KUVKFHL0VJ03H95G6F2Q
|
||||||
|
LBLDHBEA63LH8S97SBLLA2C
|
||||||
|
GYNB2CCAU6QLGW79N2UJ4UT
|
||||||
|
1KPWT2JNULPBE3B9H8FC8NL
|
||||||
|
EPDC7FRE705861ZMRJ71BV4
|
||||||
|
9E0CDJTDCG5HD7C2LWPFDS7
|
||||||
|
D72UZ0B4EUBZE8C9ZNX7XVP
|
||||||
|
W2S98ZA8BW5NJ7RKHBSEE7P
|
||||||
|
HMCV6KNUVY3Q4WGM3ZVRKNY
|
||||||
|
U0BQEC40RZ5CDLQH26PP4YT
|
||||||
|
MTLLSJJN4LQVRS7JFL2Y2K6
|
||||||
|
Z0G8BJ8NS9U8HYBHN3N99AE
|
||||||
|
9J14SSRZAMZ31DG1ZXNVNNV
|
||||||
|
WPS91QFT25LT7YXVYPG75BP
|
||||||
|
G3A4HNEVT5CH077FWZZUK88
|
||||||
|
QDKUWSRJR5K6Z97C4ZUGTWH
|
||||||
|
5YZTDJ1J85QXZH6TXX3TDDQ
|
||||||
|
ZM500MPBGWU0F2VHQQUKZ5T
|
||||||
|
TTF0R47WTKWPJT4LATUKWHQ
|
||||||
|
JS5A5F0RCZRVB971F2LE2HS
|
||||||
|
1D8A1XVA3SKFCFWRSXQYRFV
|
||||||
|
K3LE2X4GAL1MYPR9RY9EN6G
|
||||||
|
24X5VZDJD3YZUABYW6YSVSC
|
||||||
|
9C3R9XDFL24D7CTZMFH2CMN
|
||||||
|
VX4B1HLX8VFZS2MPNN094TZ
|
||||||
|
4Z7EKRK9YC3T130V0QWMKWL
|
||||||
|
8AXQF15N9VESKNQRVXMGG87
|
||||||
|
79T0R5HWKK91LUKJ0PMNDCB
|
||||||
|
YG5ZGFAAWC9ZD8SM1HARLBL
|
||||||
|
BMD30152E4L9WUL0Q5V7AF3
|
||||||
|
R40VFDKQH0SVB3DJK170ZAZ
|
||||||
|
D74L2A1KJED72TZ3DWVH8ZP
|
||||||
|
0WT613SN6Y4K3J2G77D0EUT
|
||||||
|
W7EH5EV6KZ5T8TA0DRSYCED
|
||||||
|
U8HDE2HVB09ZB9TN4KAEAPR
|
||||||
|
JV75U798X715X36PN2PE0D3
|
||||||
|
UUD5YAN2J2UXG15LBHHCP7G
|
||||||
|
W1W9C458C72XM1ULP1BVXPR
|
||||||
|
LR0UF5R33VN4DZPJUGQA0CY
|
||||||
|
A9WFKNJAW5K0D1SJNVY2DAW
|
||||||
|
UZ8TNXA91J8GASZEG3GXZQM
|
||||||
|
05DZ47KFJKPW6FRTJB1408J
|
||||||
|
37XQMR4EJ7RLDDDD3PZWWXY
|
||||||
|
NVGJTTW0GZCYKC07BDVQHVR
|
||||||
|
7MK2P0CJRR4DNVLY0K564T4
|
||||||
|
L4S2NBED58K86MK7C9Y42ZT
|
||||||
|
LMB4TR1HPB3C6F6HDWKJ4A2
|
||||||
|
NRTFR3Q4K4EDHH8WM2ADAKA
|
||||||
|
QLPLCN13Z2HC8ELBJ2HWZWR
|
||||||
|
KCWQE1KNVC3KW7XZGRVAU5Q
|
||||||
|
69GSLNNEC0N3FU4CA09EEGE
|
||||||
|
LQLPJR7VXCNGQZHZXM3Q09E
|
||||||
|
ZABXFHVGNKMBSF1KZD1JYGD
|
||||||
|
MH29T4T2BQW3BCU6BEZVNWB
|
||||||
|
SG0FS4R1W2TSG6V7ZU00UVD
|
||||||
|
5R99FUV2X6DU0QQFMACMV37
|
||||||
|
AMPHQR8S0Q5D85XFZXS9WM8
|
||||||
|
AU1325QFCDMD92BVJ1UNKUB
|
||||||
|
R9X4QMJ11NA9THEXPSCFCES
|
||||||
|
5MPD73H81E0ND5PAF9QTTA1
|
||||||
|
R7UGAY5BBNP7PFBUK9F0UB2
|
||||||
|
PLRAMYCRMTM8ENT7LDXZG4R
|
||||||
|
U4MJ3WGBZ4P04G14C0VPF1T
|
||||||
|
CFNQEFSUEKN1FLN9LMF5T7W
|
||||||
|
JBNZREJAFVY82LMU09H59NH
|
||||||
|
FH641QN4A5R139B1XDVR95H
|
||||||
|
71WJ7TL1SGBR1X4HK01RB3A
|
||||||
|
53SQJPFBWWM2QPHD7B5Y1D9
|
||||||
|
HP56RB9QH0N0KFQDXDFJN4J
|
||||||
|
YFNL1WXSLQLBGY8H6H7SQKZ
|
||||||
|
N0K4B0CRE8XGFQ6R2J258XE
|
||||||
|
6E4MMLDN7PKYKVBC5HY84UB
|
||||||
|
LH4B02LJE3V4QWNBC92P36T
|
||||||
|
46K1R5XQJ8DNFL2S9PSVE05
|
||||||
|
KTNP7KXY8P3BH4GJCBCHAW6
|
||||||
|
WFEX4UK60WTQDJSNQ2BSJRM
|
||||||
|
LMVKNTH5SVTV4B6LNNZW3H8
|
||||||
|
CWGQBAF6AZ82NU8U47MKE7Q
|
||||||
|
WNYXQQX0WEEVQTF8JH690S1
|
||||||
|
5WJA3TF43HKWSBUUNB9F1A5
|
||||||
|
CL78PV3T9JTFDNF1Y9CA9YS
|
||||||
|
NZPF8XE8562BCPQ3E4BLMCT
|
||||||
|
HHZBNN0US3LG1MUR6A7U1L4
|
||||||
|
40ZS9086PMMYHEZZCMD8E19
|
||||||
|
LJZXQ3JX5LNSBLDA3B2HAZZ
|
||||||
|
2KG86G8HC09KQ6AG3NP658C
|
||||||
|
KEW6N6ANMUABGEP6YPEAHH2
|
||||||
|
V2TGMTNW2PKSSCR9J7V0GU8
|
||||||
|
X40UEV1PEN3FJY7WXVS3M57
|
||||||
|
QXYMX3Q8J48KN0SSMKK6F7V
|
|
101
asset/data/promotion_codes-yb.csv
Normal file
101
asset/data/promotion_codes-yb.csv
Normal file
@ -0,0 +1,101 @@
|
|||||||
|
Promotion code
|
||||||
|
-- KJM6GH5NTDDW12VDWK3D7AU
|
||||||
|
-- 0CZG2AWS41G29VD2S1C3FBQ
|
||||||
|
9H499GCQKXKEPMWTE6NYJ4L
|
||||||
|
09KHJXX8Y4AE3A4DPZSCZB0
|
||||||
|
HT7GJR81R2Q5XWGD81E0ZY1
|
||||||
|
ZJNPW2ACQQQVJDPDNG1JYYR
|
||||||
|
Q8BTA7DTADKF0S7YR8F6EKM
|
||||||
|
ECZRD2BU74JL3T94ZD04C4Z
|
||||||
|
NMLGBZP92MN9VH15FH4PJJK
|
||||||
|
PSUPGVX1BFPDAM5BPCS3FQQ
|
||||||
|
40PJBGMGJR0UHLEWBNWF32U
|
||||||
|
W7N5D66YFKNNRXE6CJNXDT7
|
||||||
|
A1Y1V52C3WLUXFFL4F42LVZ
|
||||||
|
FM7EZK3HH6TN5YE702Z9AM5
|
||||||
|
D5YSSBDF982P88YBGUNLFWF
|
||||||
|
JCY6JHSXGP3XVT471GS32TB
|
||||||
|
RMAH0VTA38WGR0YECTE6H09
|
||||||
|
DTLSFDX7ZAA4HPEJJCKEZF5
|
||||||
|
P8ZR8821XMNTMFN66DYG825
|
||||||
|
THHUYPZ17EV00G2NM84EJWR
|
||||||
|
E7ZHT83XN6KCXPQ3KRXCL0D
|
||||||
|
R8BDSFN2F4GLNZU2V5QMSFF
|
||||||
|
7VWXPULDVL9LGM7TZRKCBQP
|
||||||
|
BD4UA5YKAV29CA8GN014RDQ
|
||||||
|
4W8GX1EKCVEH17SYZ9MFX85
|
||||||
|
SZ8DL9G6SCMCHMS7JA7HCDT
|
||||||
|
D383P1Y0RCN5M49G454XJ4G
|
||||||
|
7DC9FKU6PLYL7ARNL9FUMBX
|
||||||
|
80RFXJF8ZHC6S4X592BTDR1
|
||||||
|
VXJ9T0CGE2RLPSCRHGVDLK8
|
||||||
|
W7LGSSRMEGGLDDT568WBMUT
|
||||||
|
Q5RG5QTLG0N285KAD43QGNN
|
||||||
|
QUYKWTNZ9MBQ1EL49WS2FB6
|
||||||
|
GEQSQ8W0SHDK52RJTHBS45E
|
||||||
|
DZNBW0L2M6MF8JCKVT15SM9
|
||||||
|
KHL0A6MKBY4WF4KGYVSEXU9
|
||||||
|
HWEVEH5QS74RD06XGSXUP4R
|
||||||
|
CF1HCXMYWNT0GEK757DR7QJ
|
||||||
|
38NSEXPC1XG573M6FVPU1DS
|
||||||
|
RZ1QJ6TA68N0SPUT0FM6TYR
|
||||||
|
SRHCQJ4ANJKLHH9WV127VTU
|
||||||
|
RYD0XV94L770S9W1RW22AZY
|
||||||
|
EM6TWEC71ATHZRU159H577W
|
||||||
|
BZPJDHBUA0F37ULKUYKX3MD
|
||||||
|
SL5PSDXWFKMWRSB1VTVK982
|
||||||
|
H630F22CDLKGTE7128ZSR7V
|
||||||
|
FXP9FC311KSFDX87KA7NDNS
|
||||||
|
4ZQX57DTQ82T7B2A113RRA2
|
||||||
|
GF0X3UK29CRPFUSMTKJY7VJ
|
||||||
|
AHSZLDVUCDMXXC840DDERCX
|
||||||
|
T9C5PVP0AMS48UW88L9Q1BQ
|
||||||
|
G6SKQQK9EAVJF1TM4J2SK4H
|
||||||
|
3Y00PYF2QKRQN4ZNZVWERGH
|
||||||
|
QCSEMNG7G0704UHE93KENLH
|
||||||
|
MUB9P4Y1F5VLPTSGRT6E1ED
|
||||||
|
KE9EC1JH63LBX79BHX1WQFH
|
||||||
|
PD16F8BZZRC94TFJRQ3L3PG
|
||||||
|
ANQDQ2KJTVQQTYXPAUELB1S
|
||||||
|
RAXT8YFK3LAALY0HLWX9KAQ
|
||||||
|
4CR33PYZZ7RGKWDTCFD9XVK
|
||||||
|
NWV7CJX6AG78NR7769D190Y
|
||||||
|
EC490NHL19NZV0GF76TLQXQ
|
||||||
|
9E42VMUFB13NU6N8QGL2TYT
|
||||||
|
ED99UQ1VFVJSHPGXC8ERAEA
|
||||||
|
XZU9XZK7RKL8GRTFS5LUDXD
|
||||||
|
677FF9GZVHEYWC13N5HGSGD
|
||||||
|
NJVAWAYGEZAL6JCVB0D43CD
|
||||||
|
CJ4JGJZQW5JVLN5BDGKGLT6
|
||||||
|
VHB93V8U4ASWS78ZUYZCN19
|
||||||
|
3JGM2U3EPZ8MW4TBZW7H53G
|
||||||
|
2FYZ7G4JRWEMZMDPQQSJUTV
|
||||||
|
5E3C44SU9R3YLBJDGR3GQM8
|
||||||
|
S1X2HWGFDDL61A48EY777DU
|
||||||
|
5MHRAX98UTQQ372ANJ3WJB0
|
||||||
|
X5C7UB37VQ3R4PFT38FDAA5
|
||||||
|
PFG41S3LRSXPQ9ZFMKFTGDQ
|
||||||
|
TRXZU2HEVR1TPXXQEGNU611
|
||||||
|
0C4ZVMKCHVJVKASB78X6CYL
|
||||||
|
ZVHV1LA2JZXD90CEP375W8R
|
||||||
|
R9TGDA50REYPP4FKCF9GK6H
|
||||||
|
DGDYA7XVR0SLX6CWWMSVVDB
|
||||||
|
65XLN0P4LBQ6J81VJ1JD0CH
|
||||||
|
RYV7SZLD8B6N92QA8V4PT5N
|
||||||
|
RDK07CND4QR8QRCWNZMEMJA
|
||||||
|
NKNJ09BPS7M4E4CJ4H3WUX7
|
||||||
|
554X7A7Z0F4MPS8NX8H5GLG
|
||||||
|
5XQZ5L9Y8BTB2C4DRQKDW53
|
||||||
|
9T9KK0DUQQL7Z3H19HCFM4C
|
||||||
|
ZBF62Y2PF1M5T2B69PEKECR
|
||||||
|
DVG93BR8BVT0DW3V10USX3H
|
||||||
|
4DUQ0CAMF0S08YBVWTG4Z6Y
|
||||||
|
0EC19Q18NTVE1S8NN7EWFSQ
|
||||||
|
L9617J33F5GU2LRK4HQ0AY3
|
||||||
|
D8MHJSK6E86QCLFYFBMJ63K
|
||||||
|
AJ8ZQK2SYGK6YK4ZWAJPV5H
|
||||||
|
WL7NJ28NRYQ4J36F13HX65W
|
||||||
|
VP5MTQZB78ZGJ5SKUQYJ67Y
|
||||||
|
6DL9WDQ3U1A8A9Z30B05KZL
|
||||||
|
VXF8A7QMEQCLQAY9P7B5EZA
|
||||||
|
KCNPFPUHRFXPZWCACFQ8YW6
|
|
101
asset/data/promotion_codes_ya.csv
Normal file
101
asset/data/promotion_codes_ya.csv
Normal file
@ -0,0 +1,101 @@
|
|||||||
|
Promotion code
|
||||||
|
DULPYTPABG7Y51GYL6A8Z72
|
||||||
|
8A8PH0M87ESVL2YTMXXFVKJ
|
||||||
|
8X2976ZLFR61SP85NGVK0AA
|
||||||
|
8CDC60CU9HLBNJEQ9F2QPC7
|
||||||
|
VSHTMHLJTBAV731JX52MNQ4
|
||||||
|
C302XQN62ZU8F27BQ1RBGT9
|
||||||
|
6FDAGQVCGZQSCA56XXA08DM
|
||||||
|
KK0KBEUGWW3521NA31GV3T4
|
||||||
|
PAT2TF5A44RAMD883ECHYCG
|
||||||
|
CGRHCDVKA9Z8D7RXV97BRPY
|
||||||
|
E1FQ4V968KYEU6JDQ8TQEAT
|
||||||
|
NEH6BUEAT9UCHAX1QJD0CJJ
|
||||||
|
QHLBD3GN473MHT30QAAD0U8
|
||||||
|
2XK0LYH77U6EUQ3NM8M2U1C
|
||||||
|
CG6C3H6BK4RZAFS9WF46YU0
|
||||||
|
BY6Y07P0AYT5TH2VQ8X267N
|
||||||
|
9C5VW5X5DHHKJ8Q40ZM81EG
|
||||||
|
P5Y8K895CP4AVBYVDCG5D60
|
||||||
|
T5S0M4LN7SAX27B4RKDGKQ3
|
||||||
|
6G34MCK50FNLZ8ZUTWLF5AJ
|
||||||
|
JZD22RSD7WRKXLP8EDBWH4U
|
||||||
|
7V4WT93MFY03AB76NJH8SXJ
|
||||||
|
CY4VKZ74MYUEM3KTGL0LHLT
|
||||||
|
XP4U1930D44QAUUEM16PLCT
|
||||||
|
U5M7FPV2MHUA6VEJN2XWVKY
|
||||||
|
D6EC4QWWXDYUULAW8QT8AHF
|
||||||
|
LJ4NJAY7KCM25WT0A25BPN6
|
||||||
|
K6SQLF2C9APJBZF04BRDNH2
|
||||||
|
1C8L76C512HBULG3NQUA84K
|
||||||
|
H1VR3131G5G2ARSLGVMM4GF
|
||||||
|
7AHJ0EB97PA4XY1GLTVTTHN
|
||||||
|
AUWZGVK4ULY52210Y8ULD30
|
||||||
|
D0JY0HW6MLHAPCKBQTMVFQ3
|
||||||
|
TSE722BT94HNSY3GRV28UN1
|
||||||
|
H8Q1EAYYS5JDX2KU4J3P344
|
||||||
|
U3K5S83M1ULR0ETL8XFJ8VJ
|
||||||
|
XEG86F51SXXY5P2HZG49H58
|
||||||
|
8HFS2KE099XZMHYEDEQN84Z
|
||||||
|
3GUH12E4V5RYV9J8ZMBETZ8
|
||||||
|
DHKTFWBNJ7R1CXV2E41K3CK
|
||||||
|
49KK8J5Y1K2LPERB6G09P9M
|
||||||
|
VXYYBTMLPXAY4EGUENVLAZR
|
||||||
|
5AHZGKA02K4717MD2A94EPJ
|
||||||
|
7DGNRVD16Q2GP5N9XL3Y0EG
|
||||||
|
7LG8U55NRA6TKRT3VPY1RME
|
||||||
|
S8RY3KSDJPMW0Y26VEC4RVG
|
||||||
|
WS043ADBZ4HHZ57U9SZRXUP
|
||||||
|
K7YET0Q249XNFH7NX8GX575
|
||||||
|
UEJCE8CMDSUKJNBTVN9NUBA
|
||||||
|
UDQA1SY0L9FRHZBKR8GHWEN
|
||||||
|
XM4K7S04G018P3NQHS8TV2Y
|
||||||
|
9LJT7CSYTMJALZ6L7TUGP3R
|
||||||
|
SRN1UNBW6BSAYUFFJ7MQ690
|
||||||
|
7XHX75BCBMK5R1WKHDFJX2P
|
||||||
|
RULRS8H8LKFZY8VVMRRD8DM
|
||||||
|
N1Y3DSPBCC6CZTKP5NUMZ1D
|
||||||
|
H4RAWV8Z8ZCS80QQMQ39AN9
|
||||||
|
URF18Q5GTQ0A5WJG0MUCJ5G
|
||||||
|
QPBHN1B2JNQB2THW2NWDMS5
|
||||||
|
C6N0Z1D7SA7H9HLABSA2W5Q
|
||||||
|
31CQANBKBPPUZ8FLHCYJ2WB
|
||||||
|
GHGJV049LN066UYM239K4SV
|
||||||
|
4NDWC74YQJKFJZHSHP6N4YG
|
||||||
|
904EM94E8VEFLWWLT10W7C8
|
||||||
|
HRLLGB3QHCW8PG75XWL9CV8
|
||||||
|
SHEYF4F7B5F6LGLWGXYMBKV
|
||||||
|
WABU07E42Z3FK2V06XLDQDC
|
||||||
|
40KX6L2T1R839HWQHF8UWWU
|
||||||
|
Q8XAXGQEZ2V847WMYKCV91A
|
||||||
|
LK1MV8G85EV51XA43HVW5AA
|
||||||
|
U5HB1KMVS1AUD21YE4ZXDS5
|
||||||
|
5Y5SKU4MP2QGTUPKG3LEL8K
|
||||||
|
FC8VS4S0SZ1VJUH4SNDKAQ4
|
||||||
|
WUS35TBS78VWS4SSJQPG502
|
||||||
|
2FZQLEF358H0LA2HGQAB57W
|
||||||
|
KQVC3CHDNPDR1ADVDNAZDCH
|
||||||
|
0AFT33YM8X7RTXT07KVVN21
|
||||||
|
GP2M6QAM3G18MBC2ZYD73RL
|
||||||
|
GFKSN039H70CYT70JM81SKQ
|
||||||
|
2ECADR3TXBJ2CUWF6WKDF7L
|
||||||
|
U2V944D5TB4TZXG6JCD003P
|
||||||
|
PHG6QP4YT5TJZ75F58QADQ8
|
||||||
|
GUVJVYANS8HPWQHMTNGHXGA
|
||||||
|
USAL3QBLYWPCC0JXDQGK263
|
||||||
|
V5M18UT9L2Q3EZ095TUAPQX
|
||||||
|
W3UCUV9WW5HEG4UBX1M0U58
|
||||||
|
YBSM2K271EJHJ23CSD6HS04
|
||||||
|
HT8RFH4TMX9LJVA3FJDNRCG
|
||||||
|
9HDPRJHG15E5275PDKXAFB7
|
||||||
|
R95YEGEU7U8DR6DQUYMBKTH
|
||||||
|
3LCXQ54B24GH4K5WU6G3DU9
|
||||||
|
NHHTHNT2C42CARLX2RLFMUS
|
||||||
|
WB5EW890X513DLFEW0QZX5M
|
||||||
|
WDB6FSAFZ8JXLPKUF2JLWRB
|
||||||
|
346AWN92NCYTK12NNV1SYMK
|
||||||
|
V0TQG3F0XYBDPU946C13LMQ
|
||||||
|
SA4HAPXW1TPVAFCG5P9H6Q3
|
||||||
|
SMJJE6RY9W6Q6HWHEL7YSHU
|
||||||
|
AHA16TP02C6NS83A8DSA9B2
|
||||||
|
NSJVXY2H026YQB3ZJMZLY2E
|
|
@ -9,7 +9,7 @@
|
|||||||
"Logout": "Logout",
|
"Logout": "Logout",
|
||||||
"Tests": "Tests",
|
"Tests": "Tests",
|
||||||
"Change Language": "Change Language",
|
"Change Language": "Change Language",
|
||||||
"Password too short": "Password too short (at least 6 characters)",
|
"Password too short": "Password too short (at least 9 characters)",
|
||||||
"Please type an email address": "Please type an email address",
|
"Please type an email address": "Please type an email address",
|
||||||
"Exception: Please accept our data policy":"Please accept our data policy",
|
"Exception: Please accept our data policy":"Please accept our data policy",
|
||||||
"Please accept our data protection policy. For more information please click on 'Privacy'":"Please accept our data protection policy. For more information please click on 'Privacy'",
|
"Please accept our data protection policy. For more information please click on 'Privacy'":"Please accept our data protection policy. For more information please click on 'Privacy'",
|
||||||
@ -27,6 +27,8 @@
|
|||||||
"Please log in": "Please log in",
|
"Please log in": "Please log in",
|
||||||
"Exception: Customer does not exist or the password is wrong": "The email does not exist or the password is wrong",
|
"Exception: Customer does not exist or the password is wrong": "The email does not exist or the password is wrong",
|
||||||
"Exception: Customer exists": "The email address has been registered already",
|
"Exception: Customer exists": "The email address has been registered already",
|
||||||
|
"Exception: Please type an email address": "Please type an email address",
|
||||||
|
"Exception: Password too short": "Password too short (at least 9 characters)",
|
||||||
"There is an error: during registration:": "There is an error: during registration:",
|
"There is an error: during registration:": "There is an error: during registration:",
|
||||||
"Please select an exercise": "Please select an exercise",
|
"Please select an exercise": "Please select an exercise",
|
||||||
"Cardio": "Cardio",
|
"Cardio": "Cardio",
|
||||||
@ -162,7 +164,7 @@
|
|||||||
"Edit My Custom Plan": "Edit My Custom Plan",
|
"Edit My Custom Plan": "Edit My Custom Plan",
|
||||||
"Suggested Training Plan": "Suggested Training Plan",
|
"Suggested Training Plan": "Suggested Training Plan",
|
||||||
"My Special Plan": "My Special Plan",
|
"My Special Plan": "My Special Plan",
|
||||||
"Star's Exercise Plan":"Star's Exercise Plan",
|
"Star's Exercise Plan":"Celeb Exercise Plan",
|
||||||
"My Trainee's Plan": "My Trainee's Plan",
|
"My Trainee's Plan": "My Trainee's Plan",
|
||||||
"Execute My Trainee's Training Plan": "Execute My Trainee's Training Plan",
|
"Execute My Trainee's Training Plan": "Execute My Trainee's Training Plan",
|
||||||
|
|
||||||
|
@ -9,7 +9,7 @@
|
|||||||
"Login": "Bejelentkezés",
|
"Login": "Bejelentkezés",
|
||||||
"Logout": "Kijelentkezés",
|
"Logout": "Kijelentkezés",
|
||||||
"Change Language": "Nyelv",
|
"Change Language": "Nyelv",
|
||||||
"Password too short": "A jelszó min. 6 karakterből álljon",
|
"Password too short": "A jelszó min. 9 karakterből álljon",
|
||||||
"Please type an email address": "Kérlek írj be egy email címet",
|
"Please type an email address": "Kérlek írj be egy email címet",
|
||||||
"SignUp": "Regisztráció",
|
"SignUp": "Regisztráció",
|
||||||
"Exception: Please accept our data policy":"Kérlek fogadd el az adatvédelmi szabályzatunkat",
|
"Exception: Please accept our data policy":"Kérlek fogadd el az adatvédelmi szabályzatunkat",
|
||||||
@ -29,6 +29,8 @@
|
|||||||
"Customer does not exist or the password is wrong": "A felhasználó nem létezik vagy a jelszó rossz.",
|
"Customer does not exist or the password is wrong": "A felhasználó nem létezik vagy a jelszó rossz.",
|
||||||
"The email does not exist or the password is wrong": "A felhasználó nem létezik vagy a jelszó rossz.",
|
"The email does not exist or the password is wrong": "A felhasználó nem létezik vagy a jelszó rossz.",
|
||||||
"Exception: Facebook login was not successful": "Facebook bejelentkezés sikertelen",
|
"Exception: Facebook login was not successful": "Facebook bejelentkezés sikertelen",
|
||||||
|
"Exception: Please type an email address": "Kérlek írj be egy email címet",
|
||||||
|
"Exception: Password too short": "A jelszó min. 9 karakterből álljon",
|
||||||
"Exception: You have a previous Facebook login operation in progress":"Az előző bejelentkezés még folyamatban van.",
|
"Exception: You have a previous Facebook login operation in progress":"Az előző bejelentkezés még folyamatban van.",
|
||||||
"Exception: Facebook login cancelled":"Facebook bejelentkezés megszakítva ",
|
"Exception: Facebook login cancelled":"Facebook bejelentkezés megszakítva ",
|
||||||
"Exception: Facebook login failed":"Facebook bejelentkezés sikertelen",
|
"Exception: Facebook login failed":"Facebook bejelentkezés sikertelen",
|
||||||
|
@ -15,6 +15,7 @@
|
|||||||
97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FD1CF9000F007C117D /* Assets.xcassets */; };
|
97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FD1CF9000F007C117D /* Assets.xcassets */; };
|
||||||
BB69292B2521AF45001FBA4C /* Launch Screen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = BB69292A2521AF45001FBA4C /* Launch Screen.storyboard */; };
|
BB69292B2521AF45001FBA4C /* Launch Screen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = BB69292A2521AF45001FBA4C /* Launch Screen.storyboard */; };
|
||||||
BB81345024BB4BE10078D9A4 /* GoogleService-Info.plist in Resources */ = {isa = PBXBuildFile; fileRef = BB81344F24BB4BE10078D9A4 /* GoogleService-Info.plist */; };
|
BB81345024BB4BE10078D9A4 /* GoogleService-Info.plist in Resources */ = {isa = PBXBuildFile; fileRef = BB81344F24BB4BE10078D9A4 /* GoogleService-Info.plist */; };
|
||||||
|
BB8D3BFA25A8CBFE00BF29FE /* AuthenticationServices.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = BB8D3BF925A8CBFE00BF29FE /* AuthenticationServices.framework */; };
|
||||||
/* End PBXBuildFile section */
|
/* End PBXBuildFile section */
|
||||||
|
|
||||||
/* Begin PBXCopyFilesBuildPhase section */
|
/* Begin PBXCopyFilesBuildPhase section */
|
||||||
@ -48,6 +49,7 @@
|
|||||||
BB43773E2540715900D74BFA /* Runner.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = Runner.entitlements; sourceTree = "<group>"; };
|
BB43773E2540715900D74BFA /* Runner.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = Runner.entitlements; sourceTree = "<group>"; };
|
||||||
BB69292A2521AF45001FBA4C /* Launch Screen.storyboard */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; path = "Launch Screen.storyboard"; sourceTree = "<group>"; };
|
BB69292A2521AF45001FBA4C /* Launch Screen.storyboard */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; path = "Launch Screen.storyboard"; sourceTree = "<group>"; };
|
||||||
BB81344F24BB4BE10078D9A4 /* GoogleService-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "GoogleService-Info.plist"; sourceTree = "<group>"; };
|
BB81344F24BB4BE10078D9A4 /* GoogleService-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "GoogleService-Info.plist"; sourceTree = "<group>"; };
|
||||||
|
BB8D3BF925A8CBFE00BF29FE /* AuthenticationServices.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AuthenticationServices.framework; path = System/Library/Frameworks/AuthenticationServices.framework; sourceTree = SDKROOT; };
|
||||||
D5EDDC52125075FB9E21AD35 /* Pods-Runner.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.debug.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"; sourceTree = "<group>"; };
|
D5EDDC52125075FB9E21AD35 /* Pods-Runner.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.debug.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"; sourceTree = "<group>"; };
|
||||||
F39E6E227EB942E5663A6086 /* Pods-Runner.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.release.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"; sourceTree = "<group>"; };
|
F39E6E227EB942E5663A6086 /* Pods-Runner.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.release.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"; sourceTree = "<group>"; };
|
||||||
/* End PBXFileReference section */
|
/* End PBXFileReference section */
|
||||||
@ -57,6 +59,7 @@
|
|||||||
isa = PBXFrameworksBuildPhase;
|
isa = PBXFrameworksBuildPhase;
|
||||||
buildActionMask = 2147483647;
|
buildActionMask = 2147483647;
|
||||||
files = (
|
files = (
|
||||||
|
BB8D3BFA25A8CBFE00BF29FE /* AuthenticationServices.framework in Frameworks */,
|
||||||
42B6B159AF35AFB6DE777DFB /* Pods_Runner.framework in Frameworks */,
|
42B6B159AF35AFB6DE777DFB /* Pods_Runner.framework in Frameworks */,
|
||||||
);
|
);
|
||||||
runOnlyForDeploymentPostprocessing = 0;
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
@ -77,6 +80,7 @@
|
|||||||
3ADC50290ED054951FAC1F56 /* Frameworks */ = {
|
3ADC50290ED054951FAC1F56 /* Frameworks */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
|
BB8D3BF925A8CBFE00BF29FE /* AuthenticationServices.framework */,
|
||||||
09BD889296C5C90D989820C8 /* Pods_Runner.framework */,
|
09BD889296C5C90D989820C8 /* Pods_Runner.framework */,
|
||||||
);
|
);
|
||||||
name = Frameworks;
|
name = Frameworks;
|
||||||
|
@ -4,5 +4,7 @@
|
|||||||
<dict>
|
<dict>
|
||||||
<key>aps-environment</key>
|
<key>aps-environment</key>
|
||||||
<string>development</string>
|
<string>development</string>
|
||||||
|
<key>com.apple.developer.authentication-services.autofill-credential-provider</key>
|
||||||
|
<true/>
|
||||||
</dict>
|
</dict>
|
||||||
</plist>
|
</plist>
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
|
import 'dart:io';
|
||||||
import 'dart:math';
|
import 'dart:math';
|
||||||
|
|
||||||
import 'package:aitrainer_app/model/cache.dart';
|
import 'package:aitrainer_app/model/cache.dart';
|
||||||
@ -6,6 +7,7 @@ import 'package:aitrainer_app/model/product.dart';
|
|||||||
import 'package:aitrainer_app/model/product_test.dart';
|
import 'package:aitrainer_app/model/product_test.dart';
|
||||||
import 'package:aitrainer_app/service/logging.dart';
|
import 'package:aitrainer_app/service/logging.dart';
|
||||||
import 'package:aitrainer_app/service/product_test_service.dart';
|
import 'package:aitrainer_app/service/product_test_service.dart';
|
||||||
|
import 'package:aitrainer_app/util/platform_purchase.dart';
|
||||||
import 'package:bloc/bloc.dart';
|
import 'package:bloc/bloc.dart';
|
||||||
import 'package:equatable/equatable.dart';
|
import 'package:equatable/equatable.dart';
|
||||||
import 'package:flurry/flurry.dart';
|
import 'package:flurry/flurry.dart';
|
||||||
@ -26,20 +28,46 @@ class SalesBloc extends Bloc<SalesEvent, SalesState> with Logging {
|
|||||||
try {
|
try {
|
||||||
if (event is SalesLoad) {
|
if (event is SalesLoad) {
|
||||||
yield SalesLoading();
|
yield SalesLoading();
|
||||||
Flurry.logEvent("SalesPageOpen");
|
//Flurry.logEvent("SalesPageOpen");
|
||||||
|
await PlatformPurchaseApi().initPurchasePlatformState();
|
||||||
this.getProductSet();
|
this.getProductSet();
|
||||||
yield SalesReady();
|
yield SalesReady();
|
||||||
} else if (event is SalesPurchase) {
|
} else if (event is SalesPurchase) {
|
||||||
final int productId = event.productId;
|
final int productId = event.productId;
|
||||||
trace("Requesting purchase for" + productId.toString());
|
trace("Requesting purchase for" + productId.toString());
|
||||||
Flurry.logEvent("PurchaseRequest");
|
//Flurry.logEvent("PurchaseRequest");
|
||||||
//PlatformPurchaseApi().requestPurchase(null);
|
PlatformPurchaseApi().purchase(getSelectedProduct(productId));
|
||||||
}
|
}
|
||||||
} on Exception catch (ex) {
|
} on Exception catch (ex) {
|
||||||
yield SalesError(message: ex.toString());
|
yield SalesError(message: ex.toString());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Product getSelectedProduct(int productId) {
|
||||||
|
Product prod;
|
||||||
|
for (var product in this.product2Display) {
|
||||||
|
if (product.productId == productId) {
|
||||||
|
prod = product;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return prod;
|
||||||
|
}
|
||||||
|
|
||||||
|
String getLocalizedPrice(String productId) {
|
||||||
|
String price = "";
|
||||||
|
for (var product in PlatformPurchaseApi().getIAPItems()) {
|
||||||
|
if (Platform.isAndroid) {
|
||||||
|
print("PlatformProduct " + product.toString());
|
||||||
|
if (productId == product.productId) {
|
||||||
|
price = product.localizedPrice;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return price;
|
||||||
|
}
|
||||||
|
|
||||||
void getProductSet() {
|
void getProductSet() {
|
||||||
int productId = 0;
|
int productId = 0;
|
||||||
this.tests = Cache().productTests;
|
this.tests = Cache().productTests;
|
||||||
@ -51,7 +79,7 @@ class SalesBloc extends Bloc<SalesEvent, SalesState> with Logging {
|
|||||||
trace("Previous ProductTest: " + tests[0].toJson().toString());
|
trace("Previous ProductTest: " + tests[0].toJson().toString());
|
||||||
productId = tests[0].productId;
|
productId = tests[0].productId;
|
||||||
for (var elem in Cache().products) {
|
for (var elem in Cache().products) {
|
||||||
Product product = elem as Product;
|
final Product product = elem as Product;
|
||||||
if (product.productId == productId) {
|
if (product.productId == productId) {
|
||||||
productSet = product.productSet;
|
productSet = product.productSet;
|
||||||
break;
|
break;
|
||||||
@ -63,8 +91,11 @@ class SalesBloc extends Bloc<SalesEvent, SalesState> with Logging {
|
|||||||
trace("ProductSet: " + productSet.toString());
|
trace("ProductSet: " + productSet.toString());
|
||||||
for (var elem in Cache().products) {
|
for (var elem in Cache().products) {
|
||||||
Product product = elem as Product;
|
Product product = elem as Product;
|
||||||
|
|
||||||
if (product.productSet == productSet) {
|
if (product.productSet == productSet) {
|
||||||
productId = product.productId;
|
productId = product.productId;
|
||||||
|
final String platformProductId = Platform.isAndroid ? product.productIdAndroid : product.productIdIos;
|
||||||
|
product.localizedPrice = getLocalizedPrice(platformProductId);
|
||||||
product2Display.add(product);
|
product2Display.add(product);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -76,7 +107,7 @@ class SalesBloc extends Bloc<SalesEvent, SalesState> with Logging {
|
|||||||
productTest.productId = productId;
|
productTest.productId = productId;
|
||||||
productTest.customerId = Cache().userLoggedIn.customerId;
|
productTest.customerId = Cache().userLoggedIn.customerId;
|
||||||
productTest.dateView = DateTime.now();
|
productTest.dateView = DateTime.now();
|
||||||
ProductTestApi().saveProductTest(productTest);
|
//ProductTestApi().saveProductTest(productTest);
|
||||||
Cache().productTests.add(productTest);
|
//Cache().productTests.add(productTest);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -28,7 +28,6 @@ class SessionBloc extends Bloc<SessionEvent, SessionState> with Logging {
|
|||||||
// ignore: close_sinks
|
// ignore: close_sinks
|
||||||
SettingsBloc settingsBloc = event.settingsBloc;
|
SettingsBloc settingsBloc = event.settingsBloc;
|
||||||
await session.fetchSessionAndNavigate();
|
await session.fetchSessionAndNavigate();
|
||||||
await PlatformPurchaseApi().initPurchasePlatformState();
|
|
||||||
String lang = AppLanguage().appLocal.languageCode;
|
String lang = AppLanguage().appLocal.languageCode;
|
||||||
log("Change lang to $lang");
|
log("Change lang to $lang");
|
||||||
settingsBloc.add(SettingsChangeLanguage(language: lang));
|
settingsBloc.add(SettingsChangeLanguage(language: lang));
|
||||||
|
@ -105,7 +105,7 @@ class Cache with Logging {
|
|||||||
LinkedHashMap<String, int> _badges = LinkedHashMap();
|
LinkedHashMap<String, int> _badges = LinkedHashMap();
|
||||||
|
|
||||||
List deviceLanguages;
|
List deviceLanguages;
|
||||||
String startPage;
|
String startPage = "home";
|
||||||
String testEnvironment;
|
String testEnvironment;
|
||||||
bool liveServer = true;
|
bool liveServer = true;
|
||||||
bool hasHardware = false;
|
bool hasHardware = false;
|
||||||
|
@ -12,6 +12,7 @@ class Product {
|
|||||||
String productIdAndroid;
|
String productIdAndroid;
|
||||||
double priceIos;
|
double priceIos;
|
||||||
double priceAndroid;
|
double priceAndroid;
|
||||||
|
String localizedPrice;
|
||||||
|
|
||||||
Product.fromJson(Map json) {
|
Product.fromJson(Map json) {
|
||||||
this.productId = json['productId'];
|
this.productId = json['productId'];
|
||||||
|
@ -10,6 +10,7 @@ import 'package:aitrainer_app/service/exercise_tree_service.dart';
|
|||||||
import 'package:aitrainer_app/service/exercisetype_service.dart';
|
import 'package:aitrainer_app/service/exercisetype_service.dart';
|
||||||
import 'package:aitrainer_app/service/logging.dart';
|
import 'package:aitrainer_app/service/logging.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter/services.dart';
|
||||||
|
|
||||||
class Antagonist {
|
class Antagonist {
|
||||||
static String chest = "Chest";
|
static String chest = "Chest";
|
||||||
@ -47,6 +48,19 @@ class WorkoutTreeRepository with Logging {
|
|||||||
Antagonist.calf: Antagonist.calfNr
|
Antagonist.calf: Antagonist.calfNr
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Future<String> _buildImage(String imageUrl) async {
|
||||||
|
String assetImage = 'asset/menu/' + imageUrl.substring(7);
|
||||||
|
//print("Loading image " + assetImage);
|
||||||
|
return rootBundle.load(assetImage).then((value) {
|
||||||
|
return assetImage;
|
||||||
|
}).catchError((_) {
|
||||||
|
String imagePath = assetImage.substring(10);
|
||||||
|
String url = Cache.mediaUrl + 'images' + imagePath;
|
||||||
|
//print("Exception: " + assetImage + " will be loaded from the network " + url);
|
||||||
|
return url;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
Future<void> createTree() async {
|
Future<void> createTree() async {
|
||||||
isEnglish = AppLanguage().appLocal == Locale('en');
|
isEnglish = AppLanguage().appLocal == Locale('en');
|
||||||
log("** Start creating tree on lang: " + AppLanguage().appLocal.languageCode);
|
log("** Start creating tree on lang: " + AppLanguage().appLocal.languageCode);
|
||||||
@ -65,7 +79,7 @@ class WorkoutTreeRepository with Logging {
|
|||||||
//log(" -- TreeItem " + treeItem.toJson().toString() + " active " + treeItem.active.toString());
|
//log(" -- TreeItem " + treeItem.toJson().toString() + " active " + treeItem.active.toString());
|
||||||
if (treeItem.active == true) {
|
if (treeItem.active == true) {
|
||||||
String treeName = isEnglish ? treeItem.name : treeItem.nameTranslation;
|
String treeName = isEnglish ? treeItem.name : treeItem.nameTranslation;
|
||||||
String assetImage = 'asset/menu/' + treeItem.imageUrl.substring(7);
|
//String assetImage = await _buildImage(treeItem.imageUrl);
|
||||||
|
|
||||||
bool is1RM = treeItem.name == 'One Rep Max' ? true : false;
|
bool is1RM = treeItem.name == 'One Rep Max' ? true : false;
|
||||||
if (is1RM == false && treeItem.parentId != 0) {
|
if (is1RM == false && treeItem.parentId != 0) {
|
||||||
@ -86,7 +100,7 @@ class WorkoutTreeRepository with Logging {
|
|||||||
treeItem.treeId,
|
treeItem.treeId,
|
||||||
treeItem.parentId,
|
treeItem.parentId,
|
||||||
treeName,
|
treeName,
|
||||||
assetImage,
|
treeItem.imageUrl,
|
||||||
Colors.white,
|
Colors.white,
|
||||||
30,
|
30,
|
||||||
false,
|
false,
|
||||||
@ -104,11 +118,11 @@ class WorkoutTreeRepository with Logging {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
exerciseTypes.forEach((exerciseType) {
|
exerciseTypes.forEach((exerciseType) async {
|
||||||
if (!(exerciseType.imageUrl.isEmpty || exerciseType.name.isEmpty || exerciseType.nameTranslation.isEmpty) &&
|
if (!(exerciseType.imageUrl.isEmpty || exerciseType.name.isEmpty || exerciseType.nameTranslation.isEmpty) &&
|
||||||
exerciseType.active == true) {
|
exerciseType.active == true) {
|
||||||
String exerciseTypeName = isEnglish ? exerciseType.name : exerciseType.nameTranslation;
|
String exerciseTypeName = isEnglish ? exerciseType.name : exerciseType.nameTranslation;
|
||||||
String assetImage = 'asset/menu/' + exerciseType.imageUrl.substring(7);
|
//String assetImage = await _buildImage(exerciseType.imageUrl); //'asset/menu/' + exerciseType.imageUrl.substring(7);
|
||||||
if (exerciseType.parents.isNotEmpty) {
|
if (exerciseType.parents.isNotEmpty) {
|
||||||
exerciseType.parents.forEach((parentId) {
|
exerciseType.parents.forEach((parentId) {
|
||||||
bool is1RM = this.isParent1RM(parentId);
|
bool is1RM = this.isParent1RM(parentId);
|
||||||
@ -117,8 +131,21 @@ class WorkoutTreeRepository with Logging {
|
|||||||
if (isEndurance) exerciseType.setAbility(ExerciseAbility.endurance);
|
if (isEndurance) exerciseType.setAbility(ExerciseAbility.endurance);
|
||||||
bool isRunning = this.isParentRunning(parentId);
|
bool isRunning = this.isParentRunning(parentId);
|
||||||
if (isRunning) exerciseType.setAbility(ExerciseAbility.running);
|
if (isRunning) exerciseType.setAbility(ExerciseAbility.running);
|
||||||
WorkoutMenuTree menuItem = WorkoutMenuTree(exerciseType.exerciseTypeId, parentId, exerciseTypeName, assetImage, Colors.white,
|
WorkoutMenuTree menuItem = WorkoutMenuTree(
|
||||||
24, true, exerciseType.exerciseTypeId, exerciseType, exerciseType.base, is1RM, isEndurance, isRunning, exerciseType.name);
|
exerciseType.exerciseTypeId,
|
||||||
|
parentId,
|
||||||
|
exerciseTypeName,
|
||||||
|
exerciseType.imageUrl,
|
||||||
|
Colors.white,
|
||||||
|
24,
|
||||||
|
true,
|
||||||
|
exerciseType.exerciseTypeId,
|
||||||
|
exerciseType,
|
||||||
|
exerciseType.base,
|
||||||
|
is1RM,
|
||||||
|
isEndurance,
|
||||||
|
isRunning,
|
||||||
|
exerciseType.name);
|
||||||
this.tree[exerciseType.name] = menuItem;
|
this.tree[exerciseType.name] = menuItem;
|
||||||
//log("WorkoutMenuTree item " + menuItem.toJson().toString());
|
//log("WorkoutMenuTree item " + menuItem.toJson().toString());
|
||||||
/* log("ExerciseType in Menu item " +
|
/* log("ExerciseType in Menu item " +
|
||||||
|
@ -3,6 +3,7 @@ import 'dart:convert';
|
|||||||
import 'package:aitrainer_app/model/cache.dart';
|
import 'package:aitrainer_app/model/cache.dart';
|
||||||
import 'package:aitrainer_app/model/exercise_tree.dart';
|
import 'package:aitrainer_app/model/exercise_tree.dart';
|
||||||
import 'package:aitrainer_app/model/exercise_tree_parents.dart';
|
import 'package:aitrainer_app/model/exercise_tree_parents.dart';
|
||||||
|
import 'package:flutter/services.dart';
|
||||||
import 'api.dart';
|
import 'api.dart';
|
||||||
|
|
||||||
class ExerciseTreeApi {
|
class ExerciseTreeApi {
|
||||||
@ -15,10 +16,28 @@ class ExerciseTreeApi {
|
|||||||
|
|
||||||
exerciseTree = await getExerciseTreeParents(exerciseTree);
|
exerciseTree = await getExerciseTreeParents(exerciseTree);
|
||||||
|
|
||||||
|
if (exerciseTree != null) {
|
||||||
|
exerciseTree.forEach((element) async {
|
||||||
|
element.imageUrl = await _buildImage(element.imageUrl);
|
||||||
|
});
|
||||||
|
}
|
||||||
Cache().setExerciseTree(exerciseTree);
|
Cache().setExerciseTree(exerciseTree);
|
||||||
return exerciseTree;
|
return exerciseTree;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Future<String> _buildImage(String imageUrl) async {
|
||||||
|
String assetImage = 'asset/menu/' + imageUrl.substring(7);
|
||||||
|
//print("Loading image " + assetImage);
|
||||||
|
return rootBundle.load(assetImage).then((value) {
|
||||||
|
return assetImage;
|
||||||
|
}).catchError((_) {
|
||||||
|
String imagePath = assetImage.substring(10);
|
||||||
|
String url = Cache.mediaUrl + 'images' + imagePath;
|
||||||
|
//print("Exception: " + assetImage + " will be loaded from the network " + url);
|
||||||
|
return url;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
Future<List<ExerciseTree>> getExerciseTreeParents(List<ExerciseTree> exerciseTree) async {
|
Future<List<ExerciseTree>> getExerciseTreeParents(List<ExerciseTree> exerciseTree) async {
|
||||||
List<ExerciseTree> copyList = this._copyList(exerciseTree);
|
List<ExerciseTree> copyList = this._copyList(exerciseTree);
|
||||||
|
|
||||||
|
@ -3,6 +3,7 @@ import 'package:aitrainer_app/model/cache.dart';
|
|||||||
import 'package:aitrainer_app/model/exercise_type.dart';
|
import 'package:aitrainer_app/model/exercise_type.dart';
|
||||||
import 'package:aitrainer_app/service/api.dart';
|
import 'package:aitrainer_app/service/api.dart';
|
||||||
import 'package:aitrainer_app/service/logging.dart';
|
import 'package:aitrainer_app/service/logging.dart';
|
||||||
|
import 'package:flutter/services.dart';
|
||||||
|
|
||||||
class ExerciseTypeApi with Logging {
|
class ExerciseTypeApi with Logging {
|
||||||
final APIClient _client = new APIClient();
|
final APIClient _client = new APIClient();
|
||||||
@ -11,10 +12,31 @@ class ExerciseTypeApi with Logging {
|
|||||||
final body = await _client.get("exercise_type", "");
|
final body = await _client.get("exercise_type", "");
|
||||||
final Iterable json = jsonDecode(body);
|
final Iterable json = jsonDecode(body);
|
||||||
final List<ExerciseType> exerciseTypes = json.map((exerciseType) => ExerciseType.fromJson(exerciseType)).toList();
|
final List<ExerciseType> exerciseTypes = json.map((exerciseType) => ExerciseType.fromJson(exerciseType)).toList();
|
||||||
|
if (exerciseTypes != null) {
|
||||||
|
exerciseTypes.forEach((element) async {
|
||||||
|
element.imageUrl = await _buildImage(element.imageUrl);
|
||||||
|
});
|
||||||
|
}
|
||||||
Cache().setExerciseTypes(exerciseTypes);
|
Cache().setExerciseTypes(exerciseTypes);
|
||||||
return exerciseTypes;
|
return exerciseTypes;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Future<String> _buildImage(String imageUrl) async {
|
||||||
|
if (imageUrl.length > 8) {
|
||||||
|
String assetImage = 'asset/menu/' + imageUrl.substring(7);
|
||||||
|
return rootBundle.load(assetImage).then((value) {
|
||||||
|
return assetImage;
|
||||||
|
}).catchError((_) {
|
||||||
|
String imagePath = assetImage.substring(10);
|
||||||
|
String url = Cache.mediaUrl + 'images' + imagePath;
|
||||||
|
//print("Exception: " + assetImage + " will be loaded from the network " + url);
|
||||||
|
return url;
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
return imageUrl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Future<void> saveExerciseType(ExerciseType exerciseType) async {
|
Future<void> saveExerciseType(ExerciseType exerciseType) async {
|
||||||
String body = JsonEncoder().convert(exerciseType.toJson());
|
String body = JsonEncoder().convert(exerciseType.toJson());
|
||||||
log(" ===== saving exerciseType id: " + exerciseType.exerciseTypeId.toString() + ":" + body);
|
log(" ===== saving exerciseType id: " + exerciseType.exerciseTypeId.toString() + ":" + body);
|
||||||
|
@ -35,6 +35,12 @@ class FirebaseApi with Logging {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Future<String> signInEmail(String email, String password) async {
|
Future<String> signInEmail(String email, String password) async {
|
||||||
|
if (email == null) {
|
||||||
|
throw Exception("Please type an email address");
|
||||||
|
}
|
||||||
|
if (password == null) {
|
||||||
|
throw Exception("Password too short");
|
||||||
|
}
|
||||||
String rc = SIGN_IN_OK;
|
String rc = SIGN_IN_OK;
|
||||||
try {
|
try {
|
||||||
userCredential = await FirebaseAuth.instance.signInWithEmailAndPassword(email: email, password: password);
|
userCredential = await FirebaseAuth.instance.signInWithEmailAndPassword(email: email, password: password);
|
||||||
|
@ -1,5 +1,8 @@
|
|||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
|
import 'dart:io';
|
||||||
|
|
||||||
|
import 'package:aitrainer_app/model/cache.dart';
|
||||||
|
import 'package:aitrainer_app/model/product.dart';
|
||||||
import 'package:aitrainer_app/service/logging.dart';
|
import 'package:aitrainer_app/service/logging.dart';
|
||||||
import 'package:flutter_inapp_purchase/flutter_inapp_purchase.dart';
|
import 'package:flutter_inapp_purchase/flutter_inapp_purchase.dart';
|
||||||
|
|
||||||
@ -11,10 +14,14 @@ class PlatformPurchaseApi with Logging {
|
|||||||
StreamSubscription _conectionSubscription;
|
StreamSubscription _conectionSubscription;
|
||||||
String _platformVersion = 'Unknown';
|
String _platformVersion = 'Unknown';
|
||||||
List<IAPItem> _items = [];
|
List<IAPItem> _items = [];
|
||||||
|
List getIAPItems() => _items;
|
||||||
List<PurchasedItem> _purchases = [];
|
List<PurchasedItem> _purchases = [];
|
||||||
|
|
||||||
final List<String> _productLists = List();
|
final List<String> _productList = List();
|
||||||
/* Platform.isAndroid
|
|
||||||
|
List getProductList() => _productList;
|
||||||
|
|
||||||
|
/* Platform.isAndroid
|
||||||
? [
|
? [
|
||||||
'android.test.purchased',
|
'android.test.purchased',
|
||||||
'point_1000',
|
'point_1000',
|
||||||
@ -22,7 +29,7 @@ class PlatformPurchaseApi with Logging {
|
|||||||
'android.test.canceled',
|
'android.test.canceled',
|
||||||
]
|
]
|
||||||
: ['com.cooni.point1000', 'com.cooni.point5000'];
|
: ['com.cooni.point1000', 'com.cooni.point5000'];
|
||||||
*/
|
*/
|
||||||
|
|
||||||
factory PlatformPurchaseApi() {
|
factory PlatformPurchaseApi() {
|
||||||
return _singleton;
|
return _singleton;
|
||||||
@ -30,27 +37,32 @@ class PlatformPurchaseApi with Logging {
|
|||||||
|
|
||||||
PlatformPurchaseApi._internal();
|
PlatformPurchaseApi._internal();
|
||||||
|
|
||||||
void close() {
|
Future<void> close() async {
|
||||||
if (_conectionSubscription != null) {
|
if (_conectionSubscription != null) {
|
||||||
_conectionSubscription.cancel();
|
_conectionSubscription.cancel();
|
||||||
_conectionSubscription = null;
|
_conectionSubscription = null;
|
||||||
}
|
}
|
||||||
|
await FlutterInappPurchase.instance.endConnection;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Platform messages are asynchronous, so we initialize in an async method.
|
// Platform messages are asynchronous, so we initialize in an async method.
|
||||||
Future<void> initPurchasePlatformState() async {
|
Future<void> initPurchasePlatformState() async {
|
||||||
|
if (_productList.length > 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
log(" --- Init PurchasePlatform");
|
||||||
String platformVersion;
|
String platformVersion;
|
||||||
// Platform messages may fail, so we use a try/catch PlatformException.
|
// Platform messages may fail, so we use a try/catch PlatformException.
|
||||||
try {
|
try {
|
||||||
platformVersion = await FlutterInappPurchase.instance.platformVersion;
|
platformVersion = await FlutterInappPurchase.instance.platformVersion;
|
||||||
} on Exception {
|
} on Exception {
|
||||||
platformVersion = 'Failed to get platform version for InAppPurchase.';
|
platformVersion = 'Failed to get platform version for InAppPurchase.';
|
||||||
log(platformVersion);
|
log("PlatformVersion" + platformVersion);
|
||||||
}
|
}
|
||||||
|
|
||||||
// prepare
|
// prepare
|
||||||
var result = await FlutterInappPurchase.instance.initConnection;
|
var result = await FlutterInappPurchase.instance.initConnection;
|
||||||
log('result: $result');
|
log(' FlutterInappPurchase init result: $result');
|
||||||
|
|
||||||
_platformVersion = platformVersion;
|
_platformVersion = platformVersion;
|
||||||
|
|
||||||
@ -73,15 +85,57 @@ class PlatformPurchaseApi with Logging {
|
|||||||
_purchaseErrorSubscription = FlutterInappPurchase.purchaseError.listen((purchaseError) {
|
_purchaseErrorSubscription = FlutterInappPurchase.purchaseError.listen((purchaseError) {
|
||||||
log('purchase-error: $purchaseError');
|
log('purchase-error: $purchaseError');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
getSubscriptions();
|
||||||
|
}
|
||||||
|
|
||||||
|
void getSubscriptions() {
|
||||||
|
Cache().products.forEach((element) {
|
||||||
|
Product product = element as Product;
|
||||||
|
if (Platform.isAndroid) {
|
||||||
|
if (product.productIdAndroid != null && product.productIdAndroid.isNotEmpty) {
|
||||||
|
_productList.add(product.productIdAndroid);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (product.productIdIos != null && product.productIdIos.isNotEmpty) {
|
||||||
|
_productList.add(product.productIdIos);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
_productList.forEach((element) {
|
||||||
|
print(element);
|
||||||
|
});
|
||||||
|
_getSubscription();
|
||||||
|
}
|
||||||
|
|
||||||
|
void purchase(Product product) {
|
||||||
|
if (product == null) {
|
||||||
|
throw Exception("No product to purchase");
|
||||||
|
}
|
||||||
|
String productId = Platform.isAndroid ? product.productIdAndroid : product.productIdIos;
|
||||||
|
IAPItem selected;
|
||||||
|
for (var item in _items) {
|
||||||
|
if (item.productId == productId) {
|
||||||
|
selected = item;
|
||||||
|
log("Item to purchase: " + item.toString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (selected != null) {
|
||||||
|
requestPurchase(selected);
|
||||||
|
} else {
|
||||||
|
throw Exception("product " + productId + " not defined in the PlatformStore");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void requestPurchase(IAPItem item) {
|
void requestPurchase(IAPItem item) {
|
||||||
//FlutterInappPurchase.instance.requestPurchase(item.productId);
|
//FlutterInappPurchase.instance.requestPurchase(item.productId);
|
||||||
FlutterInappPurchase.instance.requestPurchase("WT_monthly");
|
FlutterInappPurchase.instance.requestPurchase(item.productId);
|
||||||
}
|
}
|
||||||
|
|
||||||
Future _getProduct() async {
|
Future _getSubscription() async {
|
||||||
List<IAPItem> items = await FlutterInappPurchase.instance.getProducts(_productLists);
|
List<IAPItem> items = await FlutterInappPurchase.instance.getSubscriptions(_productList);
|
||||||
for (var item in items) {
|
for (var item in items) {
|
||||||
log('${item.toString()}');
|
log('${item.toString()}');
|
||||||
this._items.add(item);
|
this._items.add(item);
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
import 'package:aitrainer_app/bloc/sales/sales_bloc.dart';
|
import 'package:aitrainer_app/bloc/sales/sales_bloc.dart';
|
||||||
|
import 'package:aitrainer_app/service/logging.dart';
|
||||||
import 'package:aitrainer_app/util/trans.dart';
|
import 'package:aitrainer_app/util/trans.dart';
|
||||||
import 'package:aitrainer_app/widgets/app_bar_min.dart';
|
import 'package:aitrainer_app/widgets/app_bar_min.dart';
|
||||||
import 'package:aitrainer_app/widgets/sales_button.dart';
|
import 'package:aitrainer_app/widgets/sales_button.dart';
|
||||||
@ -8,121 +9,122 @@ import 'package:google_fonts/google_fonts.dart';
|
|||||||
import 'package:modal_progress_hud/modal_progress_hud.dart';
|
import 'package:modal_progress_hud/modal_progress_hud.dart';
|
||||||
|
|
||||||
// ignore: must_be_immutable
|
// ignore: must_be_immutable
|
||||||
class SalesPage extends StatelessWidget with Trans {
|
class SalesPage extends StatelessWidget with Trans, Logging {
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
setContext(context);
|
setContext(context);
|
||||||
return BlocProvider(
|
return Scaffold(
|
||||||
create: (context) => SalesBloc()..add(SalesLoad()),
|
appBar: AppBarMin(
|
||||||
child: BlocConsumer<SalesBloc, SalesState>(listener: (context, state) {
|
back: true,
|
||||||
if (state is SalesError) {
|
),
|
||||||
Scaffold.of(context).showSnackBar(
|
body: BlocProvider(
|
||||||
SnackBar(backgroundColor: Colors.orange, content: Text(state.message, style: TextStyle(color: Colors.white))));
|
create: (context) => SalesBloc()..add(SalesLoad()),
|
||||||
}
|
child: BlocConsumer<SalesBloc, SalesState>(listener: (context, state) {
|
||||||
}, builder: (context, state) {
|
if (state is SalesError) {
|
||||||
final salesBloc = BlocProvider.of<SalesBloc>(context);
|
log("Error: " + state.message);
|
||||||
return ModalProgressHUD(
|
Scaffold.of(context).showSnackBar(
|
||||||
child: salesWidget(salesBloc),
|
SnackBar(backgroundColor: Colors.orange, content: Text(state.message, style: TextStyle(color: Colors.white))));
|
||||||
inAsyncCall: state is SalesLoading,
|
}
|
||||||
opacity: 0.5,
|
}, builder: (context, state) {
|
||||||
color: Colors.black54,
|
final salesBloc = BlocProvider.of<SalesBloc>(context);
|
||||||
progressIndicator: CircularProgressIndicator(),
|
return ModalProgressHUD(
|
||||||
);
|
child: salesWidget(salesBloc),
|
||||||
}));
|
inAsyncCall: state is SalesLoading,
|
||||||
|
opacity: 0.5,
|
||||||
|
color: Colors.black54,
|
||||||
|
progressIndicator: CircularProgressIndicator(),
|
||||||
|
);
|
||||||
|
})));
|
||||||
}
|
}
|
||||||
|
|
||||||
Widget salesWidget(SalesBloc bloc) {
|
Widget salesWidget(SalesBloc bloc) {
|
||||||
final double mediaWidth = MediaQuery.of(context).size.width;
|
final double mediaWidth = MediaQuery.of(context).size.width;
|
||||||
final double imageWidth = (mediaWidth - 5) / 2;
|
final double imageWidth = (mediaWidth - 5) / 2;
|
||||||
return Scaffold(
|
return Container(
|
||||||
appBar: AppBarMin(
|
decoration: BoxDecoration(
|
||||||
back: true,
|
image: DecorationImage(
|
||||||
|
image: AssetImage('asset/image/WT_black_background.png'),
|
||||||
|
fit: BoxFit.cover,
|
||||||
|
alignment: Alignment.center,
|
||||||
|
),
|
||||||
),
|
),
|
||||||
body: Container(
|
child: CustomScrollView(scrollDirection: Axis.vertical, slivers: [
|
||||||
decoration: BoxDecoration(
|
SliverList(
|
||||||
image: DecorationImage(
|
delegate: SliverChildListDelegate([
|
||||||
image: AssetImage('asset/image/WT_black_background.png'),
|
Divider(),
|
||||||
fit: BoxFit.cover,
|
Container(
|
||||||
alignment: Alignment.center,
|
padding: EdgeInsets.only(left: 65, right: 65),
|
||||||
),
|
child: Text("Unleash Your Development Now!",
|
||||||
|
textAlign: TextAlign.center,
|
||||||
|
maxLines: 4,
|
||||||
|
softWrap: true,
|
||||||
|
style: GoogleFonts.archivoBlack(
|
||||||
|
fontSize: 30,
|
||||||
|
color: Colors.white,
|
||||||
|
shadows: <Shadow>[
|
||||||
|
Shadow(
|
||||||
|
offset: Offset(5.0, 5.0),
|
||||||
|
blurRadius: 12.0,
|
||||||
|
color: Colors.black54,
|
||||||
|
),
|
||||||
|
Shadow(
|
||||||
|
offset: Offset(-3.0, 3.0),
|
||||||
|
blurRadius: 12.0,
|
||||||
|
color: Colors.black54,
|
||||||
|
),
|
||||||
|
],
|
||||||
|
))),
|
||||||
|
Divider(),
|
||||||
|
Container(
|
||||||
|
padding: EdgeInsets.only(left: 45, right: 45),
|
||||||
|
child: Text("Learn about your development, enjoy AI-driven predictions of all of your skills and bodyparts.",
|
||||||
|
textAlign: TextAlign.left,
|
||||||
|
maxLines: 4,
|
||||||
|
softWrap: true,
|
||||||
|
style: GoogleFonts.inter(
|
||||||
|
fontSize: 16,
|
||||||
|
color: Colors.white,
|
||||||
|
))),
|
||||||
|
SizedBox(
|
||||||
|
height: 50,
|
||||||
),
|
),
|
||||||
child: CustomScrollView(scrollDirection: Axis.vertical, slivers: [
|
])),
|
||||||
SliverList(
|
SliverGrid(
|
||||||
delegate: SliverChildListDelegate([
|
delegate: SliverChildListDelegate(getButtons(bloc)),
|
||||||
Divider(),
|
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
|
||||||
Container(
|
crossAxisCount: 3,
|
||||||
padding: EdgeInsets.only(left: 65, right: 65),
|
mainAxisSpacing: 10.0,
|
||||||
child: Text("Unleash Your Development Now!",
|
crossAxisSpacing: 10.0,
|
||||||
textAlign: TextAlign.center,
|
childAspectRatio: 0.55,
|
||||||
maxLines: 4,
|
),
|
||||||
softWrap: true,
|
),
|
||||||
style: GoogleFonts.archivoBlack(
|
SliverList(
|
||||||
fontSize: 30,
|
delegate: SliverChildListDelegate([
|
||||||
color: Colors.white,
|
SizedBox(
|
||||||
shadows: <Shadow>[
|
height: 30,
|
||||||
Shadow(
|
),
|
||||||
offset: Offset(5.0, 5.0),
|
Container(
|
||||||
blurRadius: 12.0,
|
padding: EdgeInsets.only(left: 55, right: 55),
|
||||||
color: Colors.black54,
|
child: Text(
|
||||||
),
|
"Subscription Conditions",
|
||||||
Shadow(
|
style: GoogleFonts.inter(fontSize: 14, fontWeight: FontWeight.bold, color: Colors.white),
|
||||||
offset: Offset(-3.0, 3.0),
|
)),
|
||||||
blurRadius: 12.0,
|
Divider(),
|
||||||
color: Colors.black54,
|
Container(
|
||||||
),
|
padding: EdgeInsets.only(left: 55, right: 55),
|
||||||
],
|
child: Text(
|
||||||
))),
|
"Payment will be charged to your account. Subscription automatically renews unless auto-renew is turned off at least 24 hourse before the end of the current period",
|
||||||
Divider(),
|
style: GoogleFonts.inter(fontSize: 12, color: Colors.white),
|
||||||
Container(
|
)),
|
||||||
padding: EdgeInsets.only(left: 45, right: 45),
|
Divider(),
|
||||||
child: Text("Learn about your development, enjoy AI-driven predictions of all of your skills and bodyparts.",
|
Container(
|
||||||
textAlign: TextAlign.left,
|
padding: EdgeInsets.only(left: 55, right: 55),
|
||||||
maxLines: 4,
|
child: Text(
|
||||||
softWrap: true,
|
"Account will be charged for renewal within 24 hours prior to the end of the current period",
|
||||||
style: GoogleFonts.inter(
|
style: GoogleFonts.inter(fontSize: 12, color: Colors.white),
|
||||||
fontSize: 16,
|
)),
|
||||||
color: Colors.white,
|
])),
|
||||||
))),
|
]));
|
||||||
SizedBox(
|
|
||||||
height: 50,
|
|
||||||
),
|
|
||||||
])),
|
|
||||||
SliverGrid(
|
|
||||||
delegate: SliverChildListDelegate(getButtons(bloc)),
|
|
||||||
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
|
|
||||||
crossAxisCount: 3,
|
|
||||||
mainAxisSpacing: 10.0,
|
|
||||||
crossAxisSpacing: 10.0,
|
|
||||||
childAspectRatio: 0.55,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
SliverList(
|
|
||||||
delegate: SliverChildListDelegate([
|
|
||||||
SizedBox(
|
|
||||||
height: 30,
|
|
||||||
),
|
|
||||||
Container(
|
|
||||||
padding: EdgeInsets.only(left: 55, right: 55),
|
|
||||||
child: Text(
|
|
||||||
"Subscription Conditions",
|
|
||||||
style: GoogleFonts.inter(fontSize: 14, fontWeight: FontWeight.bold, color: Colors.white),
|
|
||||||
)),
|
|
||||||
Divider(),
|
|
||||||
Container(
|
|
||||||
padding: EdgeInsets.only(left: 55, right: 55),
|
|
||||||
child: Text(
|
|
||||||
"Payment will be charged to your account. Subscription automatically renews unless auto-renew is turned off at least 24 hourse before the end of the current period",
|
|
||||||
style: GoogleFonts.inter(fontSize: 12, color: Colors.white),
|
|
||||||
)),
|
|
||||||
Divider(),
|
|
||||||
Container(
|
|
||||||
padding: EdgeInsets.only(left: 55, right: 55),
|
|
||||||
child: Text(
|
|
||||||
"Account will be charged for renewal within 24 hours prior to the end of the current period",
|
|
||||||
style: GoogleFonts.inter(fontSize: 12, color: Colors.white),
|
|
||||||
)),
|
|
||||||
])),
|
|
||||||
])));
|
|
||||||
;
|
;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -141,7 +143,7 @@ class SalesPage extends StatelessWidget with Trans {
|
|||||||
}
|
}
|
||||||
Widget button = SalesButton(
|
Widget button = SalesButton(
|
||||||
title: title,
|
title: title,
|
||||||
price: element.description + interval,
|
price: element.localizedPrice,
|
||||||
desc1: "Development programs",
|
desc1: "Development programs",
|
||||||
desc2: "Suggestions based on your actual status",
|
desc2: "Suggestions based on your actual status",
|
||||||
desc3: "Special customized training plans",
|
desc3: "Special customized training plans",
|
||||||
|
@ -142,6 +142,9 @@ class _AppBarNav extends State<AppBarNav> with SingleTickerProviderStateMixin, C
|
|||||||
ExerciseRepository exerciseRepository = ExerciseRepository();
|
ExerciseRepository exerciseRepository = ExerciseRepository();
|
||||||
exerciseRepository.getBaseExerciseFinishedPercent();
|
exerciseRepository.getBaseExerciseFinishedPercent();
|
||||||
percent = Cache().getPercentExercises();
|
percent = Cache().getPercentExercises();
|
||||||
|
if (percent == null || percent == -1) {
|
||||||
|
percent = 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
int sizeExerciseList = Cache().getExercises() == null ? 0 : Cache().getExercises().length;
|
int sizeExerciseList = Cache().getExercises() == null ? 0 : Cache().getExercises().length;
|
||||||
if (sizeExerciseList == 0) {
|
if (sizeExerciseList == 0) {
|
||||||
|
@ -160,7 +160,7 @@ class _DialogPremiumState extends State<DialogPremium> with Trans {
|
|||||||
Align(
|
Align(
|
||||||
alignment: Alignment.center,
|
alignment: Alignment.center,
|
||||||
child: GestureDetector(
|
child: GestureDetector(
|
||||||
onTap: widget.onTap ?? widget.onTap,
|
onTap: () => Navigator.of(context).pushNamed("salesPage"),
|
||||||
child: Stack(
|
child: Stack(
|
||||||
alignment: Alignment.center,
|
alignment: Alignment.center,
|
||||||
children: [
|
children: [
|
||||||
|
@ -2,12 +2,14 @@ import 'package:aitrainer_app/bloc/session/session_bloc.dart';
|
|||||||
import 'package:aitrainer_app/bloc/settings/settings_bloc.dart';
|
import 'package:aitrainer_app/bloc/settings/settings_bloc.dart';
|
||||||
import 'package:aitrainer_app/model/cache.dart';
|
import 'package:aitrainer_app/model/cache.dart';
|
||||||
import 'package:aitrainer_app/service/logging.dart';
|
import 'package:aitrainer_app/service/logging.dart';
|
||||||
|
import 'package:aitrainer_app/util/platform_purchase.dart';
|
||||||
import 'package:aitrainer_app/view/login.dart';
|
import 'package:aitrainer_app/view/login.dart';
|
||||||
import 'package:aitrainer_app/view/menu_page.dart';
|
import 'package:aitrainer_app/view/menu_page.dart';
|
||||||
import 'package:aitrainer_app/view/registration.dart';
|
import 'package:aitrainer_app/view/registration.dart';
|
||||||
import 'package:flutter/cupertino.dart';
|
import 'package:flutter/cupertino.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter/scheduler.dart';
|
import 'package:flutter/scheduler.dart';
|
||||||
|
import 'package:flutter/semantics.dart';
|
||||||
import 'package:flutter/widgets.dart';
|
import 'package:flutter/widgets.dart';
|
||||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||||
import 'loading.dart';
|
import 'loading.dart';
|
||||||
@ -85,4 +87,10 @@ class _HomePageState extends State<AitrainerHome> with Logging {
|
|||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void dispose() async {
|
||||||
|
super.dispose();
|
||||||
|
await PlatformPurchaseApi().close();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -53,6 +53,8 @@ class ImageButton extends StatelessWidget {
|
|||||||
top = height - (style.fontSize - 5) * text.length - 2 * left < 0 ? height - 2 * style.fontSize - 22 : height - style.fontSize - 37;
|
top = height - (style.fontSize - 5) * text.length - 2 * left < 0 ? height - 2 * style.fontSize - 22 : height - style.fontSize - 37;
|
||||||
//print("Top: " + top.toStringAsFixed(0) + " length: " + ((style.fontSize - 5) * text.length).toString());
|
//print("Top: " + top.toStringAsFixed(0) + " length: " + ((style.fontSize - 5) * text.length).toString());
|
||||||
}
|
}
|
||||||
|
final double width = MediaQuery.of(context).size.width;
|
||||||
|
print("Mediawidth: " + width.toStringAsFixed(0));
|
||||||
return Stack(alignment: AlignmentDirectional.bottomStart, children: [
|
return Stack(alignment: AlignmentDirectional.bottomStart, children: [
|
||||||
FlatButton(
|
FlatButton(
|
||||||
child: image == null
|
child: image == null
|
||||||
@ -101,29 +103,12 @@ class ImageButton extends StatelessWidget {
|
|||||||
],
|
],
|
||||||
)),
|
)),
|
||||||
)),
|
)),
|
||||||
/* Positioned(
|
|
||||||
top: top,
|
|
||||||
left: left,
|
|
||||||
child: Container(
|
|
||||||
height: width - 2 * left,
|
|
||||||
width: width - 2 * left,
|
|
||||||
child: InkWell(
|
|
||||||
onTap: onTap ?? onTap,
|
|
||||||
child: Text(
|
|
||||||
text,
|
|
||||||
maxLines: 2,
|
|
||||||
style: style,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
color: Colors.transparent,
|
|
||||||
),
|
|
||||||
), */
|
|
||||||
Cache().hasPurchased
|
Cache().hasPurchased
|
||||||
? Offstage()
|
? Offstage()
|
||||||
: Stack(alignment: Alignment.topCenter, children: [
|
: Stack(alignment: Alignment.topCenter, children: [
|
||||||
Positioned(
|
Positioned(
|
||||||
top: 20,
|
top: 10,
|
||||||
left: 20,
|
left: (width / 2 - 30) / 2 - 75,
|
||||||
child: this.isLocked
|
child: this.isLocked
|
||||||
? GestureDetector(
|
? GestureDetector(
|
||||||
child: Image.asset(
|
child: Image.asset(
|
||||||
|
@ -8,12 +8,14 @@ import 'package:aitrainer_app/localization/app_localization.dart';
|
|||||||
import 'package:aitrainer_app/model/cache.dart';
|
import 'package:aitrainer_app/model/cache.dart';
|
||||||
import 'package:aitrainer_app/model/workout_menu_tree.dart';
|
import 'package:aitrainer_app/model/workout_menu_tree.dart';
|
||||||
import 'package:aitrainer_app/service/logging.dart';
|
import 'package:aitrainer_app/service/logging.dart';
|
||||||
|
import 'package:aitrainer_app/util/not_found_exception.dart';
|
||||||
import 'package:aitrainer_app/util/trans.dart';
|
import 'package:aitrainer_app/util/trans.dart';
|
||||||
import 'package:aitrainer_app/widgets/dialog_common.dart';
|
import 'package:aitrainer_app/widgets/dialog_common.dart';
|
||||||
import 'package:badges/badges.dart';
|
import 'package:badges/badges.dart';
|
||||||
import 'package:flutter/cupertino.dart';
|
import 'package:flutter/cupertino.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter/painting.dart';
|
import 'package:flutter/painting.dart';
|
||||||
|
import 'package:flutter/services.dart';
|
||||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||||
import 'package:google_fonts/google_fonts.dart';
|
import 'package:google_fonts/google_fonts.dart';
|
||||||
|
|
||||||
@ -331,30 +333,30 @@ class _MenuPageWidgetState extends State<MenuPageWidget> with Trans, Logging {
|
|||||||
return returnCode;
|
return returnCode;
|
||||||
}
|
}
|
||||||
|
|
||||||
dynamic _getButtonImage(WorkoutMenuTree workoutTree, double cWidth, double cHeight) {
|
Widget _getButtonImage(WorkoutMenuTree workoutTree, double cWidth, double cHeight) {
|
||||||
dynamic image;
|
Widget image;
|
||||||
try {
|
|
||||||
|
if (workoutTree.imageName.startsWith('https')) {
|
||||||
image = ClipRRect(
|
image = ClipRRect(
|
||||||
borderRadius: BorderRadius.circular(24),
|
borderRadius: BorderRadius.circular(24.0),
|
||||||
child: Image.asset(
|
child: Container(
|
||||||
workoutTree.imageName,
|
color: Colors.black87,
|
||||||
height: 210,
|
child: FadeInImage(
|
||||||
errorBuilder: (context, error, stackTrace) {
|
image: NetworkImage(workoutTree.imageName),
|
||||||
String url = Cache.mediaUrl + 'images/' + workoutTree.imageName.substring(11);
|
placeholder: AssetImage("asset/image/dots.gif"),
|
||||||
Widget image = FadeInImage.assetNetwork(
|
),
|
||||||
placeholder: 'asset/image/dots.gif',
|
|
||||||
image: url,
|
|
||||||
height: 210,
|
|
||||||
);
|
|
||||||
return image;
|
|
||||||
},
|
|
||||||
));
|
));
|
||||||
} on Exception catch (_) {
|
} else {
|
||||||
String url = Cache.mediaUrl + '/images/' + workoutTree.imageName;
|
image = Container(
|
||||||
image = FadeInImage.assetNetwork(
|
//width: cWidth - 30,
|
||||||
placeholder: 'asset/image/dots.gif',
|
//height: 210.0,
|
||||||
image: url,
|
decoration: BoxDecoration(
|
||||||
height: 210,
|
image: DecorationImage(
|
||||||
|
fit: BoxFit.cover,
|
||||||
|
image: AssetImage(workoutTree.imageName),
|
||||||
|
),
|
||||||
|
borderRadius: BorderRadius.all(Radius.circular(24.0)),
|
||||||
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -365,6 +367,7 @@ class _MenuPageWidgetState extends State<MenuPageWidget> with Trans, Logging {
|
|||||||
String badgeKey = workoutMenuTree.nameEnglish;
|
String badgeKey = workoutMenuTree.nameEnglish;
|
||||||
bool show = Cache().getBadges()[badgeKey] != null;
|
bool show = Cache().getBadges()[badgeKey] != null;
|
||||||
int counter = Cache().getBadges()[badgeKey] != null ? Cache().getBadges()[badgeKey] : 0;
|
int counter = Cache().getBadges()[badgeKey] != null ? Cache().getBadges()[badgeKey] : 0;
|
||||||
|
Widget buttonImage = _getButtonImage(workoutMenuTree, cWidth, cHeight);
|
||||||
return Badge(
|
return Badge(
|
||||||
padding: EdgeInsets.all(8),
|
padding: EdgeInsets.all(8),
|
||||||
position: BadgePosition.topEnd(top: 3, end: 3),
|
position: BadgePosition.topEnd(top: 3, end: 3),
|
||||||
@ -377,7 +380,11 @@ class _MenuPageWidgetState extends State<MenuPageWidget> with Trans, Logging {
|
|||||||
color: Colors.white,
|
color: Colors.white,
|
||||||
fontSize: 16,
|
fontSize: 16,
|
||||||
)),
|
)),
|
||||||
child: _getButtonImage(workoutMenuTree, cWidth, cHeight),
|
child: buttonImage == null
|
||||||
|
? Container(
|
||||||
|
color: Colors.red,
|
||||||
|
)
|
||||||
|
: buttonImage,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
16
pubspec.lock
16
pubspec.lock
@ -369,7 +369,21 @@ packages:
|
|||||||
name: flutter_facebook_auth
|
name: flutter_facebook_auth
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.0.2+2"
|
version: "2.0.0+1"
|
||||||
|
flutter_facebook_auth_platform_interface:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: flutter_facebook_auth_platform_interface
|
||||||
|
url: "https://pub.dartlang.org"
|
||||||
|
source: hosted
|
||||||
|
version: "1.0.1"
|
||||||
|
flutter_facebook_auth_web:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: flutter_facebook_auth_web
|
||||||
|
url: "https://pub.dartlang.org"
|
||||||
|
source: hosted
|
||||||
|
version: "1.0.6"
|
||||||
flutter_form_bloc:
|
flutter_form_bloc:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
|
@ -15,7 +15,7 @@ publish_to: 'none' # Remove this line if you wish to publish to pub.dev
|
|||||||
# In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion.
|
# In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion.
|
||||||
# Read more about iOS versioning at
|
# Read more about iOS versioning at
|
||||||
# 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
|
||||||
version: 1.1.3+44
|
version: 1.1.4+45
|
||||||
|
|
||||||
environment:
|
environment:
|
||||||
sdk: ">=2.7.0 <3.0.0"
|
sdk: ">=2.7.0 <3.0.0"
|
||||||
@ -55,7 +55,7 @@ dependencies:
|
|||||||
#firebase_analytics: ^6.2.0
|
#firebase_analytics: ^6.2.0
|
||||||
firebase_messaging: ^7.0.3
|
firebase_messaging: ^7.0.3
|
||||||
firebase_auth: ^0.18.3
|
firebase_auth: ^0.18.3
|
||||||
flutter_facebook_auth: ^1.0.2+2
|
flutter_facebook_auth: ^2.0.0+1
|
||||||
flurry: ^0.0.7
|
flurry: ^0.0.7
|
||||||
|
|
||||||
animated_widgets: ^1.0.6
|
animated_widgets: ^1.0.6
|
||||||
|
Loading…
Reference in New Issue
Block a user