FaucetHub/lib/home.dart
2023-05-19 23:23:42 +05:30

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(); },)
]
);
}
);
}
}