clean up git status and show for enabled coins only

This commit is contained in:
julian 2024-05-24 12:01:48 -06:00
parent e3e5bf63e3
commit 1a078955c9
3 changed files with 523 additions and 767 deletions

View file

@ -8,142 +8,29 @@
*
*/
import 'dart:convert';
import 'package:flutter/gestures.dart';
import 'package:flutter/material.dart';
import 'package:flutter_libepiccash/git_versions.dart' as EPIC_VERSIONS;
import 'package:flutter_libmonero/git_versions.dart' as MONERO_VERSIONS;
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:lelantus/git_versions.dart' as FIRO_VERSIONS;
import 'package:package_info_plus/package_info_plus.dart';
import '../../../networking/http.dart';
import '../../../services/tor_service.dart';
import 'package:url_launcher/url_launcher.dart';
import '../../../app_config.dart';
import '../../../themes/stack_colors.dart';
import '../../../utilities/logger.dart';
import '../../../utilities/prefs.dart';
import '../../../utilities/git_status.dart';
import '../../../utilities/text_styles.dart';
import '../../../wallets/crypto_currency/crypto_currency.dart';
import '../../../widgets/background.dart';
import '../../../widgets/custom_buttons/app_bar_icon_button.dart';
import '../../../widgets/custom_buttons/blue_text_button.dart';
import '../../../widgets/rounded_white_container.dart';
import 'package:url_launcher/url_launcher.dart';
const kGithubAPI = "https://api.github.com";
const kGithubSearch = "/search/commits";
const kGithubHead = "/repos";
enum CommitStatus { isHead, isOldCommit, notACommit, notLoaded }
Future<bool> doesCommitExist(
String organization,
String project,
String commit,
) async {
Logging.instance.log("doesCommitExist", level: LogLevel.Info);
// final Client client = Client();
HTTP client = HTTP();
try {
final uri = Uri.parse(
"$kGithubAPI$kGithubHead/$organization/$project/commits/$commit");
final commitQuery = await client.get(
url: uri,
headers: {'Content-Type': 'application/json'},
proxyInfo: Prefs.instance.useTor
? TorService.sharedInstance.getProxyInfo()
: null,
);
final response = jsonDecode(commitQuery.body.toString());
Logging.instance.log("doesCommitExist $project $commit", // $response",
level: LogLevel.Info);
bool isThereCommit;
try {
isThereCommit = response['sha'] == commit;
Logging.instance.log(
"$commit isThereCommit=$isThereCommit",
level: LogLevel.Info,
);
return isThereCommit;
} catch (_) {
return false;
}
} catch (e, s) {
Logging.instance.log("$e $s", level: LogLevel.Error);
return false;
}
}
Future<bool> isHeadCommit(
String organization,
String project,
String branch,
String commit,
) async {
Logging.instance.log("doesCommitExist", level: LogLevel.Info);
HTTP client = HTTP();
try {
final uri = Uri.parse(
"$kGithubAPI$kGithubHead/$organization/$project/commits/$branch");
final commitQuery = await client.get(
url: uri,
headers: {'Content-Type': 'application/json'},
proxyInfo: Prefs.instance.useTor
? TorService.sharedInstance.getProxyInfo()
: null,
);
final response = jsonDecode(commitQuery.body.toString());
Logging.instance.log(
"isHeadCommit $project $commit $branch", //$response",
level: LogLevel.Info,
);
bool isHead;
try {
isHead = response['sha'] == commit;
Logging.instance.log(
"$commit isHead=$isHead",
level: LogLevel.Info,
);
return isHead;
} catch (_) {
return false;
}
} catch (e, s) {
Logging.instance.log("$e $s", level: LogLevel.Error);
return false;
}
}
class AboutView extends ConsumerWidget {
const AboutView({Key? key}) : super(key: key);
const AboutView({super.key});
static const String routeName = "/about";
@override
Widget build(BuildContext context, WidgetRef ref) {
String firoCommit = FIRO_VERSIONS.getPluginVersion();
String epicCashCommit = EPIC_VERSIONS.getPluginVersion();
String moneroCommit = MONERO_VERSIONS.getPluginVersion();
List<Future> futureFiroList = [
doesCommitExist("cypherstack", "flutter_liblelantus", firoCommit),
isHeadCommit("cypherstack", "flutter_liblelantus", "main", firoCommit),
];
Future commitFiroFuture = Future.wait(futureFiroList);
List<Future> futureEpicList = [
doesCommitExist("cypherstack", "flutter_libepiccash", epicCashCommit),
isHeadCommit(
"cypherstack", "flutter_libepiccash", "main", epicCashCommit),
];
Future commitEpicFuture = Future.wait(futureEpicList);
List<Future> futureMoneroList = [
doesCommitExist("cypherstack", "flutter_libmonero", moneroCommit),
isHeadCommit("cypherstack", "flutter_libmonero", "main", moneroCommit),
];
Future commitMoneroFuture = Future.wait(futureMoneroList);
return Background(
child: Scaffold(
backgroundColor: Theme.of(context).extension<StackColors>()!.background,
@ -271,60 +158,24 @@ class AboutView extends ConsumerWidget {
);
},
),
const SizedBox(
height: 12,
),
FutureBuilder(
future: commitFiroFuture,
builder:
(context, AsyncSnapshot<dynamic> snapshot) {
bool commitExists = false;
bool isHead = false;
if (AppConfig.coins.whereType<Firo>().isNotEmpty)
const SizedBox(
height: 12,
),
if (AppConfig.coins.whereType<Firo>().isNotEmpty)
FutureBuilder(
future: GitStatus.getFiroCommitStatus(),
builder: (
context,
AsyncSnapshot<CommitStatus> snapshot,
) {
CommitStatus stateOfCommit =
CommitStatus.notLoaded;
if (snapshot.connectionState ==
ConnectionState.done &&
snapshot.hasData) {
commitExists = snapshot.data![0] as bool;
isHead = snapshot.data![1] as bool;
if (commitExists && isHead) {
stateOfCommit = CommitStatus.isHead;
} else if (commitExists) {
stateOfCommit = CommitStatus.isOldCommit;
} else {
stateOfCommit = CommitStatus.notACommit;
}
}
TextStyle indicationStyle =
STextStyles.itemSubtitle(context);
switch (stateOfCommit) {
case CommitStatus.isHead:
indicationStyle =
STextStyles.itemSubtitle(context)
.copyWith(
color: Theme.of(context)
.extension<StackColors>()!
.accentColorGreen);
break;
case CommitStatus.isOldCommit:
indicationStyle =
STextStyles.itemSubtitle(context)
.copyWith(
color: Theme.of(context)
.extension<StackColors>()!
.accentColorYellow);
break;
case CommitStatus.notACommit:
indicationStyle =
STextStyles.itemSubtitle(context)
.copyWith(
color: Theme.of(context)
.extension<StackColors>()!
.accentColorRed);
break;
default:
break;
stateOfCommit = snapshot.data!;
}
return RoundedWhiteContainer(
child: Column(
@ -339,68 +190,37 @@ class AboutView extends ConsumerWidget {
height: 4,
),
SelectableText(
firoCommit,
style: indicationStyle,
GitStatus.firoCommit,
style: GitStatus.styleForStatus(
stateOfCommit,
context,
),
),
],
),
);
}),
const SizedBox(
height: 12,
),
FutureBuilder(
future: commitEpicFuture,
builder:
(context, AsyncSnapshot<dynamic> snapshot) {
bool commitExists = false;
bool isHead = false;
},
),
if (AppConfig.coins.whereType<Epiccash>().isNotEmpty)
const SizedBox(
height: 12,
),
if (AppConfig.coins.whereType<Epiccash>().isNotEmpty)
FutureBuilder(
future: GitStatus.getEpicCommitStatus(),
builder: (
context,
AsyncSnapshot<CommitStatus> snapshot,
) {
CommitStatus stateOfCommit =
CommitStatus.notLoaded;
if (snapshot.connectionState ==
ConnectionState.done &&
snapshot.hasData) {
commitExists = snapshot.data![0] as bool;
isHead = snapshot.data![1] as bool;
if (commitExists && isHead) {
stateOfCommit = CommitStatus.isHead;
} else if (commitExists) {
stateOfCommit = CommitStatus.isOldCommit;
} else {
stateOfCommit = CommitStatus.notACommit;
}
}
TextStyle indicationStyle =
STextStyles.itemSubtitle(context);
switch (stateOfCommit) {
case CommitStatus.isHead:
indicationStyle =
STextStyles.itemSubtitle(context)
.copyWith(
color: Theme.of(context)
.extension<StackColors>()!
.accentColorGreen);
break;
case CommitStatus.isOldCommit:
indicationStyle =
STextStyles.itemSubtitle(context)
.copyWith(
color: Theme.of(context)
.extension<StackColors>()!
.accentColorYellow);
break;
case CommitStatus.notACommit:
indicationStyle =
STextStyles.itemSubtitle(context)
.copyWith(
color: Theme.of(context)
.extension<StackColors>()!
.accentColorRed);
break;
default:
break;
stateOfCommit = snapshot.data!;
}
return RoundedWhiteContainer(
child: Column(
crossAxisAlignment:
@ -414,67 +234,35 @@ class AboutView extends ConsumerWidget {
height: 4,
),
SelectableText(
epicCashCommit,
style: indicationStyle,
GitStatus.epicCashCommit,
style: GitStatus.styleForStatus(
stateOfCommit,
context,
),
),
],
),
);
}),
const SizedBox(
height: 12,
),
FutureBuilder(
future: commitMoneroFuture,
builder:
(context, AsyncSnapshot<dynamic> snapshot) {
bool commitExists = false;
bool isHead = false;
},
),
if (AppConfig.coins.whereType<Monero>().isNotEmpty)
const SizedBox(
height: 12,
),
if (AppConfig.coins.whereType<Monero>().isNotEmpty)
FutureBuilder(
future: GitStatus.getMoneroCommitStatus(),
builder: (
context,
AsyncSnapshot<CommitStatus> snapshot,
) {
CommitStatus stateOfCommit =
CommitStatus.notLoaded;
if (snapshot.connectionState ==
ConnectionState.done &&
snapshot.hasData) {
commitExists = snapshot.data![0] as bool;
isHead = snapshot.data![1] as bool;
if (commitExists && isHead) {
stateOfCommit = CommitStatus.isHead;
} else if (commitExists) {
stateOfCommit = CommitStatus.isOldCommit;
} else {
stateOfCommit = CommitStatus.notACommit;
}
}
TextStyle indicationStyle =
STextStyles.itemSubtitle(context);
switch (stateOfCommit) {
case CommitStatus.isHead:
indicationStyle =
STextStyles.itemSubtitle(context)
.copyWith(
color: Theme.of(context)
.extension<StackColors>()!
.accentColorGreen);
break;
case CommitStatus.isOldCommit:
indicationStyle =
STextStyles.itemSubtitle(context)
.copyWith(
color: Theme.of(context)
.extension<StackColors>()!
.accentColorYellow);
break;
case CommitStatus.notACommit:
indicationStyle =
STextStyles.itemSubtitle(context)
.copyWith(
color: Theme.of(context)
.extension<StackColors>()!
.accentColorRed);
break;
default:
break;
stateOfCommit = snapshot.data!;
}
return RoundedWhiteContainer(
child: Column(
@ -489,13 +277,17 @@ class AboutView extends ConsumerWidget {
height: 4,
),
SelectableText(
moneroCommit,
style: indicationStyle,
GitStatus.moneroCommit,
style: GitStatus.styleForStatus(
stateOfCommit,
context,
),
),
],
),
);
}),
},
),
const SizedBox(
height: 12,
),
@ -522,32 +314,34 @@ class AboutView extends ConsumerWidget {
],
),
),
const SizedBox(
height: 12,
),
RoundedWhiteContainer(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
"Tezos functionality",
style: STextStyles.titleBold12(context),
),
const SizedBox(
height: 4,
),
CustomTextButton(
text: "Powered by TzKT API",
onTap: () {
launchUrl(
Uri.parse("https://tzkt.io"),
mode: LaunchMode.externalApplication,
);
},
),
],
if (AppConfig.coins.whereType<Tezos>().isNotEmpty)
const SizedBox(
height: 12,
),
if (AppConfig.coins.whereType<Tezos>().isNotEmpty)
RoundedWhiteContainer(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
"Tezos functionality",
style: STextStyles.titleBold12(context),
),
const SizedBox(
height: 4,
),
CustomTextButton(
text: "Powered by TzKT API",
onTap: () {
launchUrl(
Uri.parse("https://tzkt.io"),
mode: LaunchMode.externalApplication,
);
},
),
],
),
),
),
const SizedBox(
height: 12,
),
@ -558,8 +352,9 @@ class AboutView extends ConsumerWidget {
style: STextStyles.label(context),
children: [
const TextSpan(
text:
"By using Stack Wallet, you agree to the "),
text:
"By using ${AppConfig.appName}, you agree to the ",
),
TextSpan(
text: "Terms of service",
style: STextStyles.richLink(context),
@ -567,7 +362,8 @@ class AboutView extends ConsumerWidget {
..onTap = () {
launchUrl(
Uri.parse(
"https://stackwallet.com/terms-of-service.html"),
"https://stackwallet.com/terms-of-service.html",
),
mode: LaunchMode.externalApplication,
);
},
@ -580,7 +376,8 @@ class AboutView extends ConsumerWidget {
..onTap = () {
launchUrl(
Uri.parse(
"https://stackwallet.com/privacy-policy.html"),
"https://stackwallet.com/privacy-policy.html",
),
mode: LaunchMode.externalApplication,
);
},

View file

@ -8,105 +8,21 @@
*
*/
import 'dart:convert';
import 'package:flutter/gestures.dart';
import 'package:flutter/material.dart';
import 'package:flutter_libepiccash/git_versions.dart' as EPIC_VERSIONS;
import 'package:flutter_libmonero/git_versions.dart' as MONERO_VERSIONS;
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:http/http.dart';
import 'package:lelantus/git_versions.dart' as FIRO_VERSIONS;
import 'package:package_info_plus/package_info_plus.dart';
import 'package:url_launcher/url_launcher.dart';
import '../../../app_config.dart';
import '../../../themes/stack_colors.dart';
import '../../../utilities/logger.dart';
import '../../../utilities/git_status.dart';
import '../../../utilities/text_styles.dart';
import '../../../wallets/crypto_currency/crypto_currency.dart';
import '../../../widgets/custom_buttons/blue_text_button.dart';
import '../../../widgets/desktop/desktop_app_bar.dart';
import '../../../widgets/desktop/desktop_scaffold.dart';
import '../../../widgets/rounded_white_container.dart';
import 'package:url_launcher/url_launcher.dart';
const kGithubAPI = "https://api.github.com";
const kGithubSearch = "/search/commits";
const kGithubHead = "/repos";
enum CommitStatus { isHead, isOldCommit, notACommit, notLoaded }
Future<bool> doesCommitExist(
String organization,
String project,
String commit,
) async {
Logging.instance.log("doesCommitExist", level: LogLevel.Info);
final Client client = Client();
try {
final uri = Uri.parse(
"$kGithubAPI$kGithubHead/$organization/$project/commits/$commit",
);
final commitQuery = await client.get(
uri,
headers: {'Content-Type': 'application/json'},
);
final response = jsonDecode(commitQuery.body.toString());
Logging.instance.log(
"doesCommitExist $project $commit $response",
level: LogLevel.Info,
);
bool isThereCommit;
try {
isThereCommit = response['sha'] == commit;
Logging.instance
.log("isThereCommit $isThereCommit", level: LogLevel.Info);
return isThereCommit;
} catch (e, s) {
return false;
}
} catch (e, s) {
Logging.instance.log("$e $s", level: LogLevel.Error);
return false;
}
}
Future<bool> isHeadCommit(
String organization,
String project,
String branch,
String commit,
) async {
Logging.instance.log("doesCommitExist", level: LogLevel.Info);
final Client client = Client();
try {
final uri = Uri.parse(
"$kGithubAPI$kGithubHead/$organization/$project/commits/$branch",
);
final commitQuery = await client.get(
uri,
headers: {'Content-Type': 'application/json'},
);
final response = jsonDecode(commitQuery.body.toString());
Logging.instance.log(
"isHeadCommit $project $commit $branch $response",
level: LogLevel.Info,
);
bool isHead;
try {
isHead = response['sha'] == commit;
Logging.instance.log("isHead $isHead", level: LogLevel.Info);
return isHead;
} catch (e, s) {
return false;
}
} catch (e, s) {
Logging.instance.log("$e $s", level: LogLevel.Error);
return false;
}
}
class DesktopAboutView extends ConsumerWidget {
const DesktopAboutView({super.key});
@ -115,30 +31,6 @@ class DesktopAboutView extends ConsumerWidget {
@override
Widget build(BuildContext context, WidgetRef ref) {
final String firoCommit = FIRO_VERSIONS.getPluginVersion();
final String epicCashCommit = EPIC_VERSIONS.getPluginVersion();
final String moneroCommit = MONERO_VERSIONS.getPluginVersion();
final List<Future<bool>> futureFiroList = [
doesCommitExist("cypherstack", "flutter_liblelantus", firoCommit),
isHeadCommit("cypherstack", "flutter_liblelantus", "main", firoCommit),
];
final Future<void> commitFiroFuture = Future.wait(futureFiroList);
final List<Future<bool>> futureEpicList = [
doesCommitExist("cypherstack", "flutter_libepiccash", epicCashCommit),
isHeadCommit(
"cypherstack",
"flutter_libepiccash",
"main",
epicCashCommit,
),
];
final Future<void> commitEpicFuture = Future.wait(futureEpicList);
final List<Future<bool>> futureMoneroList = [
doesCommitExist("cypherstack", "flutter_libmonero", moneroCommit),
isHeadCommit("cypherstack", "flutter_libmonero", "main", moneroCommit),
];
final Future<void> commitMoneroFuture = Future.wait(futureMoneroList);
debugPrint("BUILD: $runtimeType");
return DesktopScaffold(
background: Theme.of(context).extension<StackColors>()!.background,
@ -158,6 +50,7 @@ class DesktopAboutView extends ConsumerWidget {
),
),
body: Column(
mainAxisSize: MainAxisSize.min,
children: [
Padding(
padding: const EdgeInsets.fromLTRB(24, 10, 24, 35),
@ -165,11 +58,10 @@ class DesktopAboutView extends ConsumerWidget {
children: [
Expanded(
child: RoundedWhiteContainer(
width: 929,
height: 451,
child: Padding(
padding: const EdgeInsets.only(left: 10, top: 10),
child: Column(
mainAxisSize: MainAxisSize.min,
// mainAxisAlignment: MainAxisAlignment.start,
children: [
Row(
@ -253,6 +145,8 @@ class DesktopAboutView extends ConsumerWidget {
padding:
const EdgeInsets.only(right: 10, bottom: 10),
child: Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
FutureBuilder(
future: PackageInfo.fromPlatform(),
@ -273,12 +167,16 @@ class DesktopAboutView extends ConsumerWidget {
}
return Column(
mainAxisSize: MainAxisSize.min,
mainAxisAlignment:
MainAxisAlignment.spaceBetween,
crossAxisAlignment:
CrossAxisAlignment.start,
children: [
Row(
children: [
Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment:
CrossAxisAlignment.start,
children: [
@ -309,9 +207,10 @@ class DesktopAboutView extends ConsumerWidget {
],
),
const SizedBox(
width: 400,
width: 64,
),
Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment:
CrossAxisAlignment.start,
children: [
@ -347,6 +246,7 @@ class DesktopAboutView extends ConsumerWidget {
Row(
children: [
Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment:
CrossAxisAlignment.start,
children: [
@ -376,341 +276,187 @@ class DesktopAboutView extends ConsumerWidget {
),
],
),
const SizedBox(
width: 350,
),
FutureBuilder(
future: commitFiroFuture,
builder: (
context,
AsyncSnapshot<dynamic> snapshot,
) {
bool commitExists = false;
bool isHead = false;
CommitStatus stateOfCommit =
CommitStatus.notLoaded;
if (snapshot.connectionState ==
ConnectionState.done &&
snapshot.hasData) {
commitExists =
snapshot.data![0] as bool;
isHead =
snapshot.data![1] as bool;
if (commitExists && isHead) {
stateOfCommit =
CommitStatus.isHead;
} else if (commitExists) {
stateOfCommit = CommitStatus
.isOldCommit;
} else {
stateOfCommit =
CommitStatus.notACommit;
}
}
TextStyle indicationStyle =
STextStyles.itemSubtitle(
context,
);
switch (stateOfCommit) {
case CommitStatus.isHead:
indicationStyle =
STextStyles
.itemSubtitle(
context,
).copyWith(
color: Theme.of(
context,
)
.extension<
StackColors>()!
.accentColorGreen,
);
break;
case CommitStatus.isOldCommit:
indicationStyle =
STextStyles
.itemSubtitle(
context,
).copyWith(
color: Theme.of(
context,
)
.extension<
StackColors>()!
.accentColorYellow,
);
break;
case CommitStatus.notACommit:
indicationStyle =
STextStyles
.itemSubtitle(
context,
).copyWith(
color: Theme.of(
context,
)
.extension<
StackColors>()!
.accentColorRed,
);
break;
default:
break;
}
return Column(
crossAxisAlignment:
CrossAxisAlignment.start,
children: [
Text(
"Firo Build Commit",
style: STextStyles
.desktopTextExtraExtraSmall(
context,
).copyWith(
color: Theme.of(
context,
)
.extension<
StackColors>()!
.textDark,
),
),
const SizedBox(
height: 2,
),
SelectableText(
firoCommit,
style: indicationStyle,
),
],
);
},
),
],
),
const SizedBox(height: 35),
Row(
const SizedBox(height: 32),
Wrap(
spacing: 64,
runSpacing: 32,
children: [
FutureBuilder(
future: commitEpicFuture,
builder: (
context,
AsyncSnapshot<dynamic> snapshot,
) {
bool commitExists = false;
bool isHead = false;
CommitStatus stateOfCommit =
CommitStatus.notLoaded;
if (snapshot.connectionState ==
ConnectionState.done &&
snapshot.hasData) {
commitExists =
snapshot.data![0] as bool;
isHead =
snapshot.data![1] as bool;
if (commitExists && isHead) {
stateOfCommit =
CommitStatus.isHead;
} else if (commitExists) {
stateOfCommit = CommitStatus
.isOldCommit;
} else {
stateOfCommit =
CommitStatus.notACommit;
}
}
TextStyle indicationStyle =
STextStyles.itemSubtitle(
if (AppConfig.coins
.whereType<Firo>()
.isNotEmpty)
FutureBuilder(
future: GitStatus
.getFiroCommitStatus(),
builder: (
context,
);
switch (stateOfCommit) {
case CommitStatus.isHead:
indicationStyle =
STextStyles
.itemSubtitle(
context,
).copyWith(
color: Theme.of(
context,
)
.extension<
StackColors>()!
.accentColorGreen,
);
break;
case CommitStatus.isOldCommit:
indicationStyle =
STextStyles
.itemSubtitle(
context,
).copyWith(
color: Theme.of(
context,
)
.extension<
StackColors>()!
.accentColorYellow,
);
break;
case CommitStatus.notACommit:
indicationStyle =
STextStyles
.itemSubtitle(
context,
).copyWith(
color: Theme.of(
context,
)
.extension<
StackColors>()!
.accentColorRed,
);
break;
default:
break;
}
return Column(
crossAxisAlignment:
CrossAxisAlignment.start,
children: [
Text(
"Epic Cash Build Commit",
style: STextStyles
.desktopTextExtraExtraSmall(
context,
).copyWith(
color: Theme.of(
context,
)
.extension<
StackColors>()!
.textDark,
),
),
const SizedBox(
height: 2,
),
SelectableText(
epicCashCommit,
style: indicationStyle,
),
],
);
},
),
const SizedBox(
width: 105,
),
FutureBuilder(
future: commitMoneroFuture,
builder: (
context,
AsyncSnapshot<dynamic> snapshot,
) {
bool commitExists = false;
bool isHead = false;
CommitStatus stateOfCommit =
CommitStatus.notLoaded;
AsyncSnapshot<CommitStatus>
snapshot,
) {
CommitStatus stateOfCommit =
CommitStatus.notLoaded;
if (snapshot.connectionState ==
ConnectionState.done &&
snapshot.hasData) {
commitExists =
snapshot.data![0] as bool;
isHead =
snapshot.data![1] as bool;
if (commitExists && isHead) {
if (snapshot.connectionState ==
ConnectionState
.done &&
snapshot.hasData) {
stateOfCommit =
CommitStatus.isHead;
} else if (commitExists) {
stateOfCommit = CommitStatus
.isOldCommit;
} else {
stateOfCommit =
CommitStatus.notACommit;
snapshot.data!;
}
}
TextStyle indicationStyle =
STextStyles.itemSubtitle(
context,
);
switch (stateOfCommit) {
case CommitStatus.isHead:
indicationStyle =
STextStyles
.itemSubtitle(
context,
).copyWith(
color: Theme.of(
context,
)
.extension<
StackColors>()!
.accentColorGreen,
);
break;
case CommitStatus.isOldCommit:
indicationStyle =
STextStyles
.itemSubtitle(
context,
).copyWith(
color: Theme.of(
context,
)
.extension<
StackColors>()!
.accentColorYellow,
);
break;
case CommitStatus.notACommit:
indicationStyle =
STextStyles
.itemSubtitle(
context,
).copyWith(
color: Theme.of(
context,
)
.extension<
StackColors>()!
.accentColorRed,
);
break;
default:
break;
}
return Column(
crossAxisAlignment:
CrossAxisAlignment.start,
children: [
Text(
"Monero Build Commit",
style: STextStyles
.desktopTextExtraExtraSmall(
context,
).copyWith(
color: Theme.of(
return Column(
mainAxisSize:
MainAxisSize.min,
crossAxisAlignment:
CrossAxisAlignment
.start,
children: [
Text(
"Firo Build Commit",
style: STextStyles
.desktopTextExtraExtraSmall(
context,
)
.extension<
StackColors>()!
.textDark,
).copyWith(
color: Theme.of(
context,
)
.extension<
StackColors>()!
.textDark,
),
),
),
const SizedBox(
height: 2,
),
SelectableText(
moneroCommit,
style: indicationStyle,
),
],
);
},
),
const SizedBox(
height: 2,
),
SelectableText(
GitStatus.firoCommit,
style: GitStatus
.styleForStatus(
stateOfCommit,
context,
),
),
],
);
},
),
if (AppConfig.coins
.whereType<Epiccash>()
.isNotEmpty)
FutureBuilder(
future: GitStatus
.getEpicCommitStatus(),
builder: (
context,
AsyncSnapshot<CommitStatus>
snapshot,
) {
CommitStatus stateOfCommit =
CommitStatus.notLoaded;
if (snapshot.connectionState ==
ConnectionState
.done &&
snapshot.hasData) {
stateOfCommit =
snapshot.data!;
}
return Column(
mainAxisSize:
MainAxisSize.min,
crossAxisAlignment:
CrossAxisAlignment
.start,
children: [
Text(
"Epic Cash Build Commit",
style: STextStyles
.desktopTextExtraExtraSmall(
context,
).copyWith(
color: Theme.of(
context,
)
.extension<
StackColors>()!
.textDark,
),
),
const SizedBox(
height: 2,
),
SelectableText(
GitStatus
.epicCashCommit,
style: GitStatus
.styleForStatus(
stateOfCommit,
context,
),
),
],
);
},
),
if (AppConfig.coins
.whereType<Monero>()
.isNotEmpty)
FutureBuilder(
future: GitStatus
.getMoneroCommitStatus(),
builder: (
context,
AsyncSnapshot<CommitStatus>
snapshot,
) {
CommitStatus stateOfCommit =
CommitStatus.notLoaded;
if (snapshot.connectionState ==
ConnectionState
.done &&
snapshot.hasData) {
stateOfCommit =
snapshot.data!;
}
return Column(
mainAxisSize:
MainAxisSize.min,
crossAxisAlignment:
CrossAxisAlignment
.start,
children: [
Text(
"Monero Build Commit",
style: STextStyles
.desktopTextExtraExtraSmall(
context,
).copyWith(
color: Theme.of(
context,
)
.extension<
StackColors>()!
.textDark,
),
),
const SizedBox(
height: 2,
),
SelectableText(
GitStatus.moneroCommit,
style: GitStatus
.styleForStatus(
stateOfCommit,
context,
),
),
],
);
},
),
],
),
const SizedBox(height: 35),
@ -741,32 +487,39 @@ class DesktopAboutView extends ConsumerWidget {
),
],
),
const SizedBox(height: 25),
Row(
children: [
Text(
"Tezos functionality:",
style: STextStyles
.desktopTextExtraExtraSmall(
context,
).copyWith(
color: Theme.of(context)
.extension<StackColors>()!
.textDark,
if (AppConfig.coins
.whereType<Tezos>()
.isNotEmpty)
const SizedBox(height: 25),
if (AppConfig.coins
.whereType<Tezos>()
.isNotEmpty)
Row(
children: [
Text(
"Tezos functionality:",
style: STextStyles
.desktopTextExtraExtraSmall(
context,
).copyWith(
color: Theme.of(context)
.extension<StackColors>()!
.textDark,
),
),
),
CustomTextButton(
text: "Powered by TzKT API",
onTap: () {
launchUrl(
Uri.parse("https://tzkt.io"),
mode: LaunchMode
.externalApplication,
);
},
),
],
),
CustomTextButton(
text: "Powered by TzKT API",
onTap: () {
launchUrl(
Uri.parse(
"https://tzkt.io"),
mode: LaunchMode
.externalApplication,
);
},
),
],
),
],
);
},

View file

@ -0,0 +1,206 @@
import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:flutter_libepiccash/git_versions.dart' as epic_versions;
import 'package:flutter_libmonero/git_versions.dart' as monero_versions;
import 'package:http/http.dart';
import 'package:lelantus/git_versions.dart' as firo_versions;
import '../../../themes/stack_colors.dart';
import '../../../utilities/logger.dart';
import '../../../utilities/text_styles.dart';
const kGithubAPI = "https://api.github.com";
const kGithubSearch = "/search/commits";
const kGithubHead = "/repos";
enum CommitStatus { isHead, isOldCommit, notACommit, notLoaded }
abstract class GitStatus {
static String get firoCommit => firo_versions.getPluginVersion();
static String get epicCashCommit => epic_versions.getPluginVersion();
static String get moneroCommit => monero_versions.getPluginVersion();
static CommitStatus? _cachedFiroStatus;
static Future<CommitStatus> getFiroCommitStatus() async {
if (_cachedFiroStatus != null) {
return _cachedFiroStatus!;
}
final List<bool> results = await Future.wait([
_doesCommitExist("cypherstack", "flutter_liblelantus", firoCommit),
_isHeadCommit("cypherstack", "flutter_liblelantus", "main", firoCommit),
]);
final commitExists = results[0];
final commitIsHead = results[1];
if (commitExists && commitIsHead) {
_cachedFiroStatus = CommitStatus.isHead;
} else if (commitExists) {
_cachedFiroStatus = CommitStatus.isOldCommit;
} else {
_cachedFiroStatus = CommitStatus.notACommit;
}
return _cachedFiroStatus!;
}
static CommitStatus? _cachedEpicStatus;
static Future<CommitStatus> getEpicCommitStatus() async {
if (_cachedEpicStatus != null) {
return _cachedEpicStatus!;
}
final List<bool> results = await Future.wait([
_doesCommitExist("cypherstack", "flutter_libepiccash", epicCashCommit),
_isHeadCommit(
"cypherstack",
"flutter_libepiccash",
"main",
epicCashCommit,
),
]);
final commitExists = results[0];
final commitIsHead = results[1];
if (commitExists && commitIsHead) {
_cachedEpicStatus = CommitStatus.isHead;
} else if (commitExists) {
_cachedEpicStatus = CommitStatus.isOldCommit;
} else {
_cachedEpicStatus = CommitStatus.notACommit;
}
return _cachedEpicStatus!;
}
static CommitStatus? _cachedMoneroStatus;
static Future<CommitStatus> getMoneroCommitStatus() async {
if (_cachedMoneroStatus != null) {
return _cachedMoneroStatus!;
}
final List<bool> results = await Future.wait([
_doesCommitExist("cypherstack", "flutter_libmonero", moneroCommit),
_isHeadCommit("cypherstack", "flutter_libmonero", "main", moneroCommit),
]);
final commitExists = results[0];
final commitIsHead = results[1];
if (commitExists && commitIsHead) {
_cachedMoneroStatus = CommitStatus.isHead;
} else if (commitExists) {
_cachedMoneroStatus = CommitStatus.isOldCommit;
} else {
_cachedMoneroStatus = CommitStatus.notACommit;
}
return _cachedMoneroStatus!;
}
static TextStyle styleForStatus(CommitStatus status, BuildContext context) {
final Color color;
switch (status) {
case CommitStatus.isHead:
color = Theme.of(
context,
).extension<StackColors>()!.accentColorGreen;
break;
case CommitStatus.isOldCommit:
color = Theme.of(
context,
).extension<StackColors>()!.accentColorYellow;
break;
case CommitStatus.notACommit:
color = Theme.of(
context,
).extension<StackColors>()!.accentColorRed;
break;
default:
return STextStyles.itemSubtitle(
context,
);
}
return STextStyles.itemSubtitle(
context,
).copyWith(color: color);
}
static Future<bool> _doesCommitExist(
String organization,
String project,
String commit,
) async {
Logging.instance.log("doesCommitExist", level: LogLevel.Info);
final Client client = Client();
try {
final uri = Uri.parse(
"$kGithubAPI$kGithubHead/$organization/$project/commits/$commit",
);
final commitQuery = await client.get(
uri,
headers: {'Content-Type': 'application/json'},
);
final response = jsonDecode(commitQuery.body.toString());
Logging.instance.log(
"doesCommitExist $project $commit $response",
level: LogLevel.Info,
);
bool isThereCommit;
try {
isThereCommit = response['sha'] == commit;
Logging.instance
.log("isThereCommit $isThereCommit", level: LogLevel.Info);
return isThereCommit;
} catch (e, s) {
return false;
}
} catch (e, s) {
Logging.instance.log("$e $s", level: LogLevel.Error);
return false;
}
}
static Future<bool> _isHeadCommit(
String organization,
String project,
String branch,
String commit,
) async {
Logging.instance.log("doesCommitExist", level: LogLevel.Info);
final Client client = Client();
try {
final uri = Uri.parse(
"$kGithubAPI$kGithubHead/$organization/$project/commits/$branch",
);
final commitQuery = await client.get(
uri,
headers: {'Content-Type': 'application/json'},
);
final response = jsonDecode(commitQuery.body.toString());
Logging.instance.log(
"isHeadCommit $project $commit $branch $response",
level: LogLevel.Info,
);
bool isHead;
try {
isHead = response['sha'] == commit;
Logging.instance.log("isHead $isHead", level: LogLevel.Info);
return isHead;
} catch (e, s) {
return false;
}
} catch (e, s) {
Logging.instance.log("$e $s", level: LogLevel.Error);
return false;
}
}
}