// import 'package:crypto_font_icons/crypto_font_icons.dart'; import 'package:crypto_font_icons/crypto_font_icons.dart'; import 'package:external_app_launcher/external_app_launcher.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:faucethub/game_page.dart'; import 'package:flutter/material.dart'; import 'package:flutter/rendering.dart'; import 'package:font_awesome_flutter/font_awesome_flutter.dart'; import 'Backend/helpers.dart'; class HomePage extends StatefulWidget { const HomePage({Key? key}) : super(key: key); @override State createState() => _HomePageState(); } int selectedBotNavIndex = 0; String daysLeft = ""; class _HomePageState extends State { 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)), ), Card( margin: EdgeInsets.all(12), child: Container( padding: EdgeInsets.all(10), child: Column( children: [ Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Text("Earnings", style: TextStyle( fontSize: 20, fontWeight: FontWeight.bold)), InkWell(child: Icon(Icons.arrow_forward_outlined,size:25), onTap: (){ selectedBotNavIndex=2; setState(() { }); },) ], ), Padding( padding: const EdgeInsets.all(8.0), child: Column( mainAxisSize: MainAxisSize.max, mainAxisAlignment: MainAxisAlignment.spaceAround, children: [ SizedBox(height: 20,), Text("Previously Earned", style: TextStyle( fontSize: 25, fontWeight: FontWeight.bold)), Text('\$0', style: TextStyle(fontSize: 20)), SizedBox(height: 20,), Text("This Seasons", style: TextStyle( fontSize: 25, fontWeight: FontWeight.bold)), Text('~ \$${Hoarder.currentEarnings.toStringAsFixed(2)}', style: TextStyle(fontSize: 18)) ], ), ), ], ), ), ), // HomeCard( // child: Container( // padding: EdgeInsets.symmetric(vertical: 50), // child: Column( // mainAxisSize: MainAxisSize.max, // mainAxisAlignment: MainAxisAlignment.spaceAround, // children: [ // Text("Previously earned", style:TextStyle(fontSize: 25, fontWeight: FontWeight.bold)), // Text('\$6.9'), // Text("This Seasons'",style: TextStyle(fontSize: 25, fontWeight: FontWeight.bold)), // Text('\$2.3') // ], // ) // // child: Text( // // "\$6.90", // // style: TextStyle(fontSize: 50), // // ), // ), // title: "Earnings"), HomeCard( title: "Seasonal Challenges $daysLeft", child: Container( child: Column( children: [ (Hoarder.Challenges.length > 0) ? 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'])); }) ]); }) : Container( padding: EdgeInsets.all(30), child: Text("Not linked to any games")) ], ), )), // 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 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: [ Container( alignment: Alignment.center, padding: EdgeInsets.fromLTRB(0, 0, 0, 20), child: Text("FH ID : ${Brain.UserJson['id']}"), ), 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: () async { // showLinkGameDialog(context, Brain.LinkedGamesJson[index]); // await LaunchApp.openApp( // androidPackageName: Brain.LinkedGamesJson[index]['link'], // // openStore: false // ); String code = Brain.LinkedGamesJson[index]['code']; Navigator.push( context, MaterialPageRoute(builder: (context) => GamePage(code)), ); }, 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]); String code = Brain.NonLinkedGamesJson[index]['code']; return InkWell( onTap: () async { Navigator.push( context, MaterialPageRoute(builder: (context) => GamePage(code)), ); // showLinkGameDialog(context, Brain.NonLinkedGamesJson[index]); // try { // ///checks if the app is installed on your mobile device // String id = Brain.NonLinkedGamesJson[index]['link']; // Debug.Log(id); // bool isInstalled = await DeviceApps.isAppInstalled(id); // if (isInstalled) { // DeviceApps.openApp(id); // } else { // ///if the app is not installed it lunches google play store so you can install it from there // // launchUrl(Uri(path: "market://details?id=" +Brain.NonLinkedGamesJson[index]['link']),mode: LaunchMode.externalApplication,); // // try{launch("market://details?id=" +Brain.NonLinkedGamesJson[index]['link']);}catch(e){ // launch("https://play.google.com/store/apps/details?id=$id"); // // } // } // } 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']), trailing: Icon( Helpers.GetIconForCrypto( Brain.NonLinkedGamesJson[index]['coin']), size: 17, ), ), ); }) ], ), ), ); } 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 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(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(); }, ) ]); }); } }