Skip to content

Commit

Permalink
feat: Add app info to settings
Browse files Browse the repository at this point in the history
  • Loading branch information
holzeis committed Jan 22, 2024
1 parent 110d1ae commit 33196c2
Show file tree
Hide file tree
Showing 9 changed files with 279 additions and 17 deletions.
14 changes: 14 additions & 0 deletions webapp/build.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,23 @@
use std::fs;
use std::process::Command;

fn main() {
// ensure that the directory exists which needs to be embedded in our binary
let directory_path = "./frontend/build/web";
if fs::create_dir_all(directory_path).is_err() {
std::process::exit(1);
}

let output = Command::new("git")
.args(["rev-parse", "HEAD"])
.output()
.expect("To be able to get commit hash");
let git_hash = String::from_utf8(output.stdout).expect("To be a valid string");
let output = Command::new("git")
.args(["rev-parse", "--abbrev-ref", "HEAD"])
.output()
.expect("To be able to get branch name");
let branch_name = String::from_utf8(output.stdout).expect("To be a valid string");
println!("cargo:rustc-env=COMMIT_HASH={}", git_hash);
println!("cargo:rustc-env=BRANCH_NAME={}", branch_name);
}
2 changes: 1 addition & 1 deletion webapp/frontend/lib/common/scaffold_with_nav.dart
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ class _ScaffoldWithNestedNavigation extends State<ScaffoldWithNestedNavigation>
@override
void initState() {
super.initState();
context.read<VersionService>().fetchVersion().then((v) => setState(() => version = v));
context.read<VersionService>().fetchVersion().then((v) => setState(() => version = v.version));
context.read<WalletService>().getBalance().then((b) => setState(() => balance = b));
}

Expand Down
17 changes: 11 additions & 6 deletions webapp/frontend/lib/common/version_service.dart
Original file line number Diff line number Diff line change
@@ -1,17 +1,22 @@
import 'package:flutter/cupertino.dart';
import 'package:http/http.dart' as http;
import 'dart:convert';

class Version {
final String version;
final String commitHash;
final String branch;

const Version({required this.version});
const Version({required this.version, required this.commitHash, required this.branch});

factory Version.fromJson(Map<String, dynamic> json) {
return switch (json) {
{
'version': String version,
'commit_hash': String commitHash,
'branch': String branch,
} =>
Version(version: version),
Version(version: version, commitHash: commitHash, branch: branch),
_ => throw const FormatException('Failed to load version.'),
};
}
Expand All @@ -20,7 +25,7 @@ class Version {
class VersionService {
const VersionService();

Future<String> fetchVersion() async {
Future<Version> fetchVersion() async {
// TODO(holzeis): this should come from the config
const port = "3001";
const host = "localhost";
Expand All @@ -29,12 +34,12 @@ class VersionService {
final response = await http.get(Uri.http('$host:$port', '/api/version'));

if (response.statusCode == 200) {
return Version.fromJson(jsonDecode(response.body) as Map<String, dynamic>).version;
return Version.fromJson(jsonDecode(response.body) as Map<String, dynamic>);
} else {
return 'unknown';
throw FlutterError("Failed to fetch version");
}
} catch (e) {
return "unknown";
return throw FlutterError("Failed to fetch version. $e");
}
}
}
4 changes: 3 additions & 1 deletion webapp/frontend/lib/main.dart
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import 'package:flutter/material.dart';
import 'package:get_10101/common/version_service.dart';
import 'package:get_10101/logger/logger.dart';
import 'package:get_10101/routes.dart';
import 'package:get_10101/settings/settings_service.dart';
import 'package:get_10101/wallet/wallet_service.dart';
import 'package:provider/provider.dart';

Expand All @@ -15,7 +16,8 @@ void main() {

var providers = [
Provider(create: (context) => const VersionService()),
Provider(create: (context) => const WalletService())
Provider(create: (context) => const WalletService()),
Provider(create: (context) => const SettingsService())
];
runApp(MultiProvider(providers: providers, child: const TenTenOneApp()));
}
Expand Down
160 changes: 160 additions & 0 deletions webapp/frontend/lib/settings/app_info_screen.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,160 @@
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:get_10101/common/color.dart';
import 'package:get_10101/common/snack_bar.dart';
import 'package:get_10101/common/version_service.dart';
import 'package:get_10101/settings/settings_service.dart';
import 'package:provider/provider.dart';

class AppInfoScreen extends StatefulWidget {
const AppInfoScreen({super.key});

@override
State<AppInfoScreen> createState() => _AppInfoScreenState();
}

class _AppInfoScreenState extends State<AppInfoScreen> {
EdgeInsets margin = const EdgeInsets.all(10);

String _version = "";
String _nodeId = "";
String _commit = "not available";
String _branch = "not available";

@override
void initState() {
Future.wait<dynamic>([
context.read<VersionService>().fetchVersion(),
context.read<SettingsService>().getNodeId()
]).then((value) {
final version = value[0];
final nodeId = value[1];

setState(() {
_commit = version.commitHash;
_branch = version.branch;
_version = version.version;
_nodeId = nodeId;
});
});

super.initState();
}

@override
Widget build(BuildContext context) {
return Scaffold(
body: Container(
padding: const EdgeInsets.only(top: 20, left: 10, right: 10),
child: Column(
children: [
Column(
children: [
Container(
margin: const EdgeInsets.only(top: 20, left: 10, right: 10, bottom: 10),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
const Text(
"NODE INFO",
style: TextStyle(color: Colors.grey, fontSize: 17),
),
const SizedBox(
height: 10,
),
Container(
decoration: BoxDecoration(
color: Colors.white, borderRadius: BorderRadius.circular(15)),
child: moreInfo(context,
title: "Node Id", info: _nodeId, showCopyButton: true))
],
),
),
Container(
margin: const EdgeInsets.all(10),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
const Text(
"BUILD INFO",
style: TextStyle(color: Colors.grey, fontSize: 18),
),
const SizedBox(
height: 10,
),
Container(
decoration: BoxDecoration(
color: Colors.white, borderRadius: BorderRadius.circular(15)),
child: Column(
children: [
moreInfo(context, title: "Version", info: _version),
moreInfo(context,
title: "Commit Hash", info: _commit, showCopyButton: true),
moreInfo(context,
title: "Branch", info: _branch, showCopyButton: kDebugMode)
],
))
],
),
),
],
),
const SizedBox(height: 10)
],
)),
);
}
}

Widget moreInfo(BuildContext context,
{required String title, required String info, bool showCopyButton = false}) {
return Container(
padding: const EdgeInsets.all(15),
child: Row(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
title,
style:
const TextStyle(fontSize: 17, fontWeight: FontWeight.w400, color: Colors.black),
),
const SizedBox(height: 7),
showCopyButton
? SizedBox(
width: 400,
child: Text(
info,
softWrap: true,
maxLines: 4,
style: TextStyle(
fontSize: 18, fontWeight: FontWeight.w300, color: Colors.grey.shade700),
))
: const SizedBox()
],
),
showCopyButton
? GestureDetector(
onTap: () async {
showSnackBar(ScaffoldMessenger.of(context), "Copied $info");
await Clipboard.setData(ClipboardData(text: info));
},
child: Icon(
Icons.copy,
size: 17,
color: tenTenOnePurple.shade800,
),
)
: Text(
info,
style: TextStyle(
fontSize: 18, fontWeight: FontWeight.w300, color: Colors.grey.shade700),
)
],
),
);
}
66 changes: 57 additions & 9 deletions webapp/frontend/lib/settings/settings_screen.dart
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
import 'package:flutter/material.dart';
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
import 'package:get_10101/common/color.dart';
import 'package:get_10101/settings/app_info_screen.dart';

class SettingsScreen extends StatefulWidget {
static const route = "/settings";
Expand All @@ -9,17 +12,62 @@ class SettingsScreen extends StatefulWidget {
State<SettingsScreen> createState() => _SettingsScreenState();
}

class _SettingsScreenState extends State<SettingsScreen> {
class _SettingsScreenState extends State<SettingsScreen> with SingleTickerProviderStateMixin {
late final _tabController = TabController(length: 3, vsync: this);

@override
Widget build(BuildContext context) {
return const Column(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
Text(
'Settings Screen',
),
],
return SizedBox(
width: 500,
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
TabBar(
unselectedLabelColor: Colors.black,
labelColor: tenTenOnePurple,
tabs: const [
Tab(
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Icon(FontAwesomeIcons.info, size: 20),
SizedBox(width: 10),
Text("App Info")
],
)),
Tab(
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Icon(Icons.balance_outlined, size: 20),
SizedBox(width: 10),
Text("Channel")
],
),
),
Tab(
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Icon(FontAwesomeIcons.seedling, size: 20),
SizedBox(width: 10),
Text("Backup")
],
),
),
],
controller: _tabController,
indicatorSize: TabBarIndicatorSize.tab,
),
Expanded(
child: TabBarView(
controller: _tabController,
children: const [AppInfoScreen(), Text("Channel"), Text("Backup")],
),
),
],
),
);
}
}
23 changes: 23 additions & 0 deletions webapp/frontend/lib/settings/settings_service.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import 'package:http/http.dart' as http;

class SettingsService {
const SettingsService();

Future<String> getNodeId() async {
// TODO(holzeis): this should come from the config
const port = "3001";
const host = "localhost";

try {
final response = await http.get(Uri.http('$host:$port', '/api/node'));

if (response.statusCode == 200) {
return response.body;
} else {
return "unknown";
}
} catch (e) {
return "unknown";
}
}
}
8 changes: 8 additions & 0 deletions webapp/src/api.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,11 +37,15 @@ where
#[derive(Serialize)]
pub struct Version {
version: String,
commit_hash: String,
branch: String,
}

pub async fn version() -> Json<Version> {
Json(Version {
version: env!("CARGO_PKG_VERSION").to_string(),
commit_hash: env!("COMMIT_HASH").to_string(),
branch: env!("BRANCH_NAME").to_string(),
})
}

Expand Down Expand Up @@ -131,3 +135,7 @@ pub async fn send_payment(params: Json<Payment>) -> Result<(), AppError> {

Ok(())
}

pub async fn get_node_id() -> impl IntoResponse {
ln_dlc::get_node_pubkey().to_string()
}
Loading

0 comments on commit 33196c2

Please sign in to comment.