511 lines
18 KiB
Dart
511 lines
18 KiB
Dart
// import 'package:crypto_font_icons/crypto_font_icons.dart';
|
|
import 'package:crypto_font_icons/crypto_font_icons.dart';
|
|
import 'package:device_apps/device_apps.dart';
|
|
import 'package:faucethub/Backend/DebugHelper.dart';
|
|
import 'package:faucethub/Backend/Dialogs.dart';
|
|
import 'package:faucethub/Backend/Encryptor.dart';
|
|
import 'package:faucethub/Backend/brains.dart';
|
|
import 'package:faucethub/Backend/hoarder.dart';
|
|
import 'package:faucethub/Backend/login_mgr.dart';
|
|
import 'package:flutter/material.dart';
|
|
import 'package:flutter/rendering.dart';
|
|
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
|
|
import 'package:url_launcher/url_launcher.dart';
|
|
import 'Backend/helpers.dart';
|
|
|
|
class HomePage extends StatefulWidget {
|
|
const HomePage({Key? key}) : super(key: key);
|
|
|
|
@override
|
|
State<HomePage> createState() => _HomePageState();
|
|
}
|
|
|
|
int selectedBotNavIndex = 0;
|
|
String daysLeft = "";
|
|
class _HomePageState extends State<HomePage> {
|
|
bool looping =false;
|
|
@override
|
|
void initState() {
|
|
// TODO: implement initState
|
|
super.initState();
|
|
loop();
|
|
}
|
|
|
|
void loop() async{
|
|
looping=true;
|
|
|
|
while(looping){
|
|
await Hoarder.FetchChallenges();
|
|
DateTime now = DateTime.now();
|
|
DateTime nextMonth = DateTime(now.year,now.month);
|
|
|
|
daysLeft = "${nextMonth.difference(now).inDays} Days Remaining";
|
|
setState(() {
|
|
|
|
});
|
|
|
|
await Future.delayed(const Duration(seconds: 30));
|
|
}
|
|
}
|
|
|
|
@override
|
|
void dispose() {
|
|
// TODO: implement dispose
|
|
super.dispose();
|
|
|
|
looping=false;
|
|
}
|
|
|
|
Widget HomeWidget() {
|
|
final ScrollController _firstController = ScrollController();
|
|
return SingleChildScrollView(
|
|
child: Column(
|
|
crossAxisAlignment: CrossAxisAlignment.stretch,
|
|
children: [
|
|
Container(
|
|
padding: EdgeInsets.all(20),
|
|
child: Text("Welcome ${Brain.DisplayName},",
|
|
style: TextStyle(fontSize: 20, fontWeight: FontWeight.bold)),
|
|
),
|
|
HomeCard(
|
|
child: Container(
|
|
padding: EdgeInsets.symmetric(vertical: 50),
|
|
child: Text(
|
|
"\$6.90",
|
|
style: TextStyle(fontSize: 50),
|
|
),
|
|
),
|
|
title: "Earnings"),
|
|
HomeCard(
|
|
title: "Seasonal Challenges - $daysLeft",
|
|
child: Container(
|
|
child: Column(
|
|
children: [
|
|
|
|
ListView.builder(
|
|
physics: NeverScrollableScrollPhysics(),
|
|
shrinkWrap: true,
|
|
itemCount: Hoarder.Challenges.length,
|
|
itemBuilder: (BuildContext context, int index) {
|
|
dynamic gameJson = Helpers.GetGameFromCode(Hoarder.Challenges[index][0]['game'] ?? 'spaceio');
|
|
return ChallengesList(gameName: gameJson['name'], coin: gameJson['coin'], challengesInfo: [
|
|
ListView.builder(
|
|
physics: NeverScrollableScrollPhysics(),
|
|
shrinkWrap: true,
|
|
itemCount: Hoarder.Challenges[index].length,
|
|
itemBuilder: (BuildContext context, int index2) {
|
|
return ChallengeProgress(Hoarder.Challenges[index][index2]['name'], int.parse(Hoarder.Challenges[index][index2]['total']), int.parse(Hoarder.Challenges[index][index2]['current']), int.parse(Hoarder.Challenges[index][index2]['reward']));
|
|
}
|
|
)
|
|
]);
|
|
}
|
|
)
|
|
],
|
|
),
|
|
)
|
|
),
|
|
// HomeCard(
|
|
// title: "Featured Games",
|
|
// child: SizedBox(
|
|
// height: 110,
|
|
// child: Scrollbar(
|
|
// thumbVisibility: true,
|
|
// controller: _firstController,
|
|
// child: ListView.builder(
|
|
// scrollDirection: Axis.horizontal,
|
|
// controller: _firstController,
|
|
// itemCount: Hoarder.FeaturedGames.length,
|
|
// itemBuilder: (BuildContext context, int index) {
|
|
// Debug.Log(Hoarder.FeaturedGames[index]);
|
|
// return InkWell(
|
|
// onTap: () {},
|
|
// child: Card(
|
|
// child: ClipRRect(
|
|
// borderRadius: BorderRadius.circular(12),
|
|
// child: Image.network(
|
|
// Hoarder.FeaturedGames[index]['icon'],
|
|
// width: 100,
|
|
// height: 100),
|
|
// ),
|
|
// ),
|
|
// );
|
|
// }),
|
|
// ),
|
|
// ),
|
|
// ),
|
|
// HomeCard(
|
|
// child: SizedBox(
|
|
// height: 250,
|
|
// ),
|
|
// title: "Top Players"),
|
|
],
|
|
),
|
|
);
|
|
}
|
|
|
|
Widget ChallengesList({required String gameName, required String coin, required List<Widget> challengesInfo}){
|
|
return Card(
|
|
color: Colors.black12,
|
|
child: Container(
|
|
padding: EdgeInsets.all(10),
|
|
child: Column(
|
|
children: [
|
|
Row(mainAxisAlignment: MainAxisAlignment.spaceBetween, mainAxisSize: MainAxisSize.max,children:[
|
|
Text(gameName, style:TextStyle(fontSize: 18, fontWeight: FontWeight.bold)),
|
|
Row(
|
|
children: [
|
|
FaIcon(Helpers.GetIconForCrypto(coin)),
|
|
Text(" $coin"),
|
|
],
|
|
)
|
|
]),
|
|
SizedBox(height: 10,),
|
|
Container(
|
|
padding: const EdgeInsets.all(8.0),
|
|
child: Column(
|
|
children: challengesInfo,
|
|
),
|
|
),
|
|
|
|
],
|
|
),
|
|
),
|
|
);
|
|
}
|
|
|
|
Widget ChallengeProgress(String title, int total, int current, int reward,
|
|
{String prefix = ""}){
|
|
return Container(
|
|
child: Column(
|
|
crossAxisAlignment: CrossAxisAlignment.start,
|
|
mainAxisSize: MainAxisSize.max,
|
|
children: [
|
|
Row(
|
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
|
mainAxisSize: MainAxisSize.max,
|
|
children: [
|
|
Text(title, textAlign: TextAlign.left,),
|
|
Text("$reward Sats",style: TextStyle(fontWeight: FontWeight.bold,color: (total <= current) ? Colors.green : Colors.grey,fontSize: 15))
|
|
],
|
|
),
|
|
const SizedBox(height: 5,),
|
|
Row(
|
|
children: [
|
|
Expanded(child: LinearProgressIndicator(value: current/total, color: Colors.green,)),
|
|
SizedBox(width:60,child: Text("$current / $total $prefix",textAlign: TextAlign.end,style:TextStyle(fontSize: 12,color: (total <= current) ? Colors.green : Colors.white)))
|
|
],
|
|
),
|
|
const SizedBox(height: 12,),
|
|
|
|
]
|
|
),
|
|
);
|
|
}
|
|
|
|
Widget GamesWidget() {
|
|
final ScrollController scrollController = ScrollController();
|
|
return Container(
|
|
padding: EdgeInsets.fromLTRB(20, 20, 0, 20),
|
|
child: SingleChildScrollView(
|
|
physics: ScrollPhysics(),
|
|
child: Column(
|
|
crossAxisAlignment: CrossAxisAlignment.start,
|
|
children: <Widget>[
|
|
Text(
|
|
"Linked",
|
|
style: TextStyle(fontSize: 20, fontWeight: FontWeight.bold),
|
|
),
|
|
SizedBox(
|
|
height: 5,
|
|
),
|
|
ListView.builder(
|
|
physics: NeverScrollableScrollPhysics(),
|
|
shrinkWrap: true,
|
|
controller: scrollController,
|
|
itemCount: Brain.LinkedGamesJson.length,
|
|
itemBuilder: (BuildContext context, int index) {
|
|
// Debug.Log(Hoarder.LinkedGamesJson[index]);
|
|
return InkWell(
|
|
onTap: () {
|
|
showLinkGameDialog(context, Brain.LinkedGamesJson[index]);
|
|
},
|
|
child: ListTile(
|
|
leading: ClipRRect(
|
|
borderRadius: BorderRadius.circular(12),
|
|
child: Image.network(Brain.LinkedGamesJson[index]['icon'],
|
|
width: 50, height: 50),
|
|
),
|
|
title: Text(Brain.LinkedGamesJson[index]['name']),
|
|
subtitle: Text(Brain.LinkedGamesJson[index]['description']),
|
|
trailing: Row(
|
|
mainAxisSize: MainAxisSize.min,
|
|
children: [
|
|
Icon(
|
|
Helpers.GetIconForCrypto(
|
|
Brain.LinkedGamesJson[index]['coin']),
|
|
size: 17,
|
|
),
|
|
SizedBox(
|
|
width: 2,
|
|
),
|
|
Text("0.00004000"),
|
|
],
|
|
),
|
|
),
|
|
);
|
|
}),
|
|
SizedBox(
|
|
height: 20,
|
|
),
|
|
Text(
|
|
"Not Linked",
|
|
style: TextStyle(fontSize: 20, fontWeight: FontWeight.bold),
|
|
),
|
|
SizedBox(
|
|
height: 5,
|
|
),
|
|
ListView.builder(
|
|
physics: NeverScrollableScrollPhysics(),
|
|
shrinkWrap: true,
|
|
controller: scrollController,
|
|
itemCount: Brain.NonLinkedGamesJson.length,
|
|
itemBuilder: (BuildContext context, int index) {
|
|
// Debug.Log(Hoarder.NonLinkedGamesJson[index]);
|
|
return InkWell(
|
|
onTap: () async{
|
|
// showLinkGameDialog(context, Brain.NonLinkedGamesJson[index]);
|
|
try {
|
|
///checks if the app is installed on your mobile device
|
|
bool isInstalled = await DeviceApps.isAppInstalled('si.modula.android.instantheartrate');
|
|
if (isInstalled) {
|
|
DeviceApps.openApp("si.modula.android.instantheartrate");
|
|
} else {
|
|
///if the app is not installed it lunches google play store so you can install it from there
|
|
launch("market://details?id=" +"si.modula.android.instantheartrate");
|
|
}
|
|
} catch (e) {
|
|
print(e);
|
|
}
|
|
},
|
|
child: ListTile(
|
|
leading: ClipRRect(
|
|
borderRadius: BorderRadius.circular(12),
|
|
child: Image.network(Brain.NonLinkedGamesJson[index]['icon'],
|
|
width: 50, height: 50),
|
|
),
|
|
title: Text(Brain.NonLinkedGamesJson[index]['name']),
|
|
subtitle: Text(Brain.NonLinkedGamesJson[index]['description']),
|
|
),
|
|
);
|
|
})
|
|
],
|
|
),
|
|
),
|
|
);
|
|
}
|
|
|
|
Widget WalletWidget() {
|
|
final ScrollController scrollController = ScrollController();
|
|
return Container(
|
|
padding: EdgeInsets.all(10),
|
|
child:
|
|
Container( child: Column(children: [
|
|
HomeCard(child: Container(
|
|
child: ListTile(
|
|
leading: FaIcon(FontAwesomeIcons.solidCircleUser,size: 60,),
|
|
title: Text(Brain.Username),
|
|
subtitle: Text("Total Earnings : \$42.69"),
|
|
trailing: IconButton(icon: Icon(Icons.settings), onPressed: () { selectedBotNavIndex=3;setState(() {
|
|
|
|
}); },),
|
|
)
|
|
), title: "Your Account", showMore: false),
|
|
Row(mainAxisAlignment: MainAxisAlignment.center, mainAxisSize: MainAxisSize.max,children: [
|
|
Expanded(child: MaterialButton(onPressed: (){}, child: Text("Withdraw"),color: Colors.green, ))
|
|
],),
|
|
SizedBox(height: 30,),
|
|
Text("Sort by",style: TextStyle(fontSize: 12),),
|
|
DefaultTabController(length: 2, child: Column(
|
|
mainAxisSize: MainAxisSize.min,
|
|
children: [
|
|
|
|
TabBar(
|
|
tabs:[Tab(text: "Currency",),Tab(text: "Games",)]
|
|
),
|
|
|
|
Container(
|
|
padding: EdgeInsets.all(10),
|
|
//Add this to give height
|
|
constraints: BoxConstraints.expand(height: 250),
|
|
child: TabBarView(children: [
|
|
Container(
|
|
child: Column(
|
|
|
|
children: [
|
|
CurrencyListItem("BTC", "0.0004000 = \$1.20"),
|
|
CurrencyListItem("ETH", "0.0004000 = \$0.50"),
|
|
CurrencyListItem("XRP", "0.0004000 = \$0.20"),
|
|
CurrencyListItem("DOGE", "0.0004000 = \$0.020")
|
|
|
|
],
|
|
)
|
|
),
|
|
Container(
|
|
child: Column(
|
|
children: [
|
|
GameListItem(Hoarder.GamesJson[0], "0.0004000 = \$1.20"),
|
|
GameListItem(Hoarder.GamesJson[1], "0.0004000 = \$1.20"),
|
|
GameListItem(Hoarder.GamesJson[2], "0.0004000 = \$1.20"),
|
|
|
|
],
|
|
)
|
|
),
|
|
]),
|
|
),
|
|
|
|
],
|
|
))
|
|
],)));
|
|
}
|
|
|
|
Widget SettingsWidget() {
|
|
final ScrollController scrollController = ScrollController();
|
|
return Container(
|
|
padding: EdgeInsets.symmetric(vertical: 20,horizontal: 10),
|
|
child:
|
|
SingleChildScrollView(physics: ScrollPhysics(), child: Column(children: [
|
|
Text("Settings", style: TextStyle(fontSize: 25,fontWeight: FontWeight.bold),),
|
|
SizedBox(height: 20,),
|
|
ListTile()
|
|
],)));
|
|
}
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
List<Widget> bodyOptions = [
|
|
HomeWidget(),
|
|
GamesWidget(),
|
|
WalletWidget(),
|
|
SettingsWidget()
|
|
];
|
|
|
|
return SafeArea(
|
|
child: Scaffold(
|
|
// appBar: AppBar(title: Text('Faucet Hub'),),
|
|
|
|
body: bodyOptions.elementAt(selectedBotNavIndex),
|
|
bottomNavigationBar: BottomNavigationBar(
|
|
enableFeedback: true,
|
|
selectedItemColor: Colors.green,
|
|
unselectedItemColor: Colors.grey,
|
|
elevation: 20,
|
|
items: const <BottomNavigationBarItem>[
|
|
BottomNavigationBarItem(icon: Icon(Icons.home), label: "Home"),
|
|
BottomNavigationBarItem(
|
|
icon: Icon(Icons.videogame_asset), label: "Games"),
|
|
BottomNavigationBarItem(
|
|
icon: Icon(Icons.account_balance_wallet), label: "Wallet"),
|
|
BottomNavigationBarItem(
|
|
icon: Icon(Icons.settings), label: "Settings"),
|
|
],
|
|
currentIndex: selectedBotNavIndex,
|
|
onTap: onBotNavTapped,
|
|
)),
|
|
);
|
|
}
|
|
|
|
static Widget HomeCard(
|
|
{bool showMore = false, required Widget child, required String title}) {
|
|
return Padding(
|
|
padding: const EdgeInsets.all(8.0),
|
|
child: Card(
|
|
child: Container(
|
|
padding: EdgeInsets.symmetric(horizontal: 5, vertical: 10),
|
|
child: Column(children: [
|
|
Padding(
|
|
padding: const EdgeInsets.fromLTRB(8, 0, 8, 8),
|
|
child: Row(
|
|
mainAxisSize: MainAxisSize.max,
|
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
|
children: [
|
|
Text(
|
|
title,
|
|
style: TextStyle(
|
|
fontSize: 17, fontWeight: FontWeight.bold),
|
|
),
|
|
(showMore) ? InkWell(
|
|
child: Icon(Icons.arrow_right_alt),
|
|
onTap: () {},
|
|
) : Container()
|
|
],
|
|
),
|
|
),
|
|
child
|
|
]))));
|
|
}
|
|
|
|
Widget CurrencyListItem(String currencyName, String value){
|
|
return Container(padding: EdgeInsets.all(5),
|
|
child: Row(mainAxisSize: MainAxisSize.max,mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
|
children: [
|
|
Row(mainAxisSize: MainAxisSize.min, children: [Icon(Helpers.GetIconForCrypto(currencyName)),SizedBox(width: 10,), Text(currencyName)],),
|
|
Text(value)
|
|
],),
|
|
);
|
|
}
|
|
|
|
Widget GameListItem(dynamic Game, String value){
|
|
return Container(padding: EdgeInsets.all(5),
|
|
child: Row(mainAxisSize: MainAxisSize.max,mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
|
children: [
|
|
Row(mainAxisSize: MainAxisSize.min, children: [ Icon(Helpers.GetIconForCrypto(Game['coin'])),SizedBox(width: 10,), Text(Game['name'])],),
|
|
Text(value)
|
|
],),
|
|
);
|
|
}
|
|
|
|
void onBotNavTapped(int value) {
|
|
selectedBotNavIndex = value;
|
|
setState(() {});
|
|
}
|
|
TextEditingController manualLinkInput = TextEditingController();
|
|
void showLinkGameDialog(BuildContext context, dynamic Game) {
|
|
Debug.Log("Showing custom dialog");
|
|
|
|
showDialog(
|
|
context: context,
|
|
builder: (BuildContext context){
|
|
return AlertDialog(
|
|
title: Text("Link game - ${Game['name']}"),
|
|
content: Column(
|
|
mainAxisSize: MainAxisSize.min,
|
|
children: [
|
|
Text("Enter user id in-game to Link this game to the Faucet Hub"),
|
|
TextField(controller: manualLinkInput,
|
|
decoration: InputDecoration(
|
|
hintText: 'User ID'
|
|
))
|
|
],
|
|
),
|
|
actions: [
|
|
TextButton(child:Text("Link"), onPressed: (){
|
|
String input = manualLinkInput.text;
|
|
manualLinkInput.clear();
|
|
|
|
if(input.length< 2){
|
|
Dialogs.showAlertDialog(context, "Failed", "Invalid User ID");
|
|
return;
|
|
}
|
|
int userId = Encryptor.stringToInt(input);
|
|
if(userId < 0){ return;}
|
|
|
|
print("Init link to id $userId");
|
|
},),
|
|
TextButton(child:Text("Cancel"), onPressed: (){ manualLinkInput.clear(); Navigator.of(context).pop(); },)
|
|
]
|
|
);
|
|
}
|
|
);
|
|
}
|
|
}
|