Start implementing BugVault

This commit is contained in:
zontreck 2025-03-14 23:28:27 -07:00
parent 847fd65fae
commit db7130aca5
7 changed files with 261 additions and 121 deletions

View file

@ -0,0 +1,223 @@
import 'dart:async';
import 'dart:io';
import 'package:bugvault/Constants.dart';
import 'package:bugvault/FlutterConstants.dart';
import 'package:bugvault/SessionData.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter/widgets.dart';
import 'package:libac_dart/nbt/NbtIo.dart';
import 'package:libac_dart/nbt/impl/CompoundTag.dart';
import 'package:libacflutter/Constants.dart';
class BugVault extends StatefulWidget {
BugVault({super.key});
@override
State<StatefulWidget> createState() {
return BugVaultLoader();
}
}
class BugVaultLoader extends State<BugVault> {
@override
Widget build(BuildContext context) {
return MaterialApp(
routes: {"/": (ctx) => BugVaultLoadPage()},
theme: SessionData.g_bDarkMode ? ThemeData.dark() : ThemeData.light(),
);
}
}
class BugVaultLoadPage extends StatefulWidget {
BugVaultLoadPage({super.key});
@override
State<StatefulWidget> createState() {
return BugVaultLoadPageState();
}
}
class LoadStates {
static const READ_CONFIG = 1;
static const NO_CONFIG = 2;
static const CONFIG_LOADED = 4;
static const WAIT_READ = 8;
static const CONNECTING = 16;
static const LOGIN = 32;
}
class BugVaultLoadPageState extends State<BugVaultLoadPage> {
var g_dLoadProgress = 0.0;
var g_bFirstLoad = true;
var g_ixState = 0;
var g_sLoadMessage = "Please Wait...";
var g_sPageTitle = "BugVault - Loading...";
var g_cProgressBarColor = FlutterConstants.PROGRESS_BAR_COLOR;
TextEditingController USERNAME_CONTROLLER = TextEditingController();
TextEditingController URL_CONTROLLER = TextEditingController(
text: "bugs.zontreck.com",
);
TextEditingController PORT_CONTROLLER = TextEditingController(text: "8372");
@override
void didChangeDependencies() {
if (g_bFirstLoad) {
g_bFirstLoad = false;
// Schedule a timer that will get removed when we hit Progress 1.0
// TODO: When loading, we read a file from the application settings. That file should contain the last BugVault URL accessed. Alternatively, if the environment it is running on is WebJS, it should immediately call the backend to request data.
// NOTE: Data from backend is dependent on page and state. If accessing a bug report/feature request, it may be that the data requested is progress, assigned user, etc.
Timer.periodic(Duration(milliseconds: 150), (timer) async {
g_dLoadProgress += 0.01;
if (g_dLoadProgress >= 1.00) {
g_dLoadProgress = 1.0;
timer.cancel();
}
// STATE SPECIFIC
if (g_dLoadProgress > 0.05 &&
!(g_ixState & LoadStates.READ_CONFIG == LoadStates.READ_CONFIG)) {
g_ixState |= LoadStates.READ_CONFIG;
g_ixState |= LoadStates.WAIT_READ;
g_sLoadMessage = "Reading Configuration File...";
}
if (g_dLoadProgress > 0.10 &&
(g_ixState & LoadStates.WAIT_READ == LoadStates.WAIT_READ)) {
g_ixState = g_ixState & ~LoadStates.WAIT_READ;
File settings = File("settings.dat");
if (settings.existsSync()) {
g_ixState |= LoadStates.CONFIG_LOADED;
SessionData.g_nbtConfiguration =
await NbtIo.read("settings.dat") as CompoundTag;
} else
g_ixState |= LoadStates.NO_CONFIG;
}
if (g_dLoadProgress > 0.15 &&
(g_ixState & LoadStates.CONFIG_LOADED ==
LoadStates.CONFIG_LOADED)) {
g_sLoadMessage =
"Configuration Loaded... Connecting to last server...";
g_ixState = g_ixState & ~LoadStates.CONFIG_LOADED;
g_ixState |= LoadStates.CONNECTING;
}
if (g_dLoadProgress > 0.15 &&
(g_ixState & LoadStates.NO_CONFIG == LoadStates.NO_CONFIG)) {
g_sLoadMessage = "No configuration found... Please Login";
g_ixState = g_ixState & ~LoadStates.NO_CONFIG;
timer.cancel();
g_ixState |= LoadStates.LOGIN;
g_sPageTitle = "BugVault - Login";
g_cProgressBarColor = FlutterConstants.PROGRESS_BAR_WAIT;
}
// Refresh the state in app
setState(() {});
});
}
}
Widget GetLoginElements() {
return Column(
children: [
ListTile(
title: Text("Username"),
subtitle: Text(
"Your username on the server. Leave blank for anonymous access (if the server allows it)",
),
),
highlightTextField(USERNAME_CONTROLLER),
ListTile(
title: Text("URL"),
subtitle: Text(
"The URL to where the instance of BugVault is running",
),
),
Row(
children: [
Text("HOST / FQDN :"),
Expanded(child: highlightTextField(URL_CONTROLLER)),
Text("PORT :"),
Expanded(
child: highlightTextField(
PORT_CONTROLLER,
keyboardType: TextInputType.number,
),
),
],
),
ListTile(
title: Text("NOTICE"),
subtitle: Text(
"By logging in, or registering, you agree to any terms set forth by the service host. If an account does not exist, one will be created for you using the specified user name. \n\nThis application uses Passwordless Logins. \nIf this is your first time using BugVault, you may need to register a TOTP device for MFA. You'll also need to verify an email address. \nFor returning users, you will only be asked for the TOTP code. The email on file will only be used if you do not have access to the device with your TOTP code.",
),
),
],
);
}
Widget highlightTextField(
TextEditingController controller, {
TextInputType keyboardType = TextInputType.text,
}) {
return TextField(
controller: controller,
keyboardType: keyboardType,
inputFormatters: [
keyboardType == TextInputType.text
? FilteringTextInputFormatter.deny("")
: FilteringTextInputFormatter.digitsOnly,
],
decoration: InputDecoration(
focusedBorder: OutlineInputBorder(
borderSide: BorderSide(
color: FlutterConstants.INPUT_TEXTFIELD_SELECTED,
),
),
border: OutlineInputBorder(
borderSide: BorderSide(
color: FlutterConstants.INPUT_TEXTFIELD_NOT_SELECTED,
),
),
),
);
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(g_sPageTitle),
backgroundColor: LibACFlutterConstants.TITLEBAR_COLOR,
),
body: SingleChildScrollView(
child: Padding(
padding: EdgeInsets.all(8),
child: Column(
children: [
ListTile(title: Text(g_sLoadMessage)),
LinearProgressIndicator(
value: g_dLoadProgress,
minHeight: 20,
color: g_cProgressBarColor,
),
if (g_ixState & LoadStates.LOGIN == LoadStates.LOGIN)
GetLoginElements(),
],
),
),
),
);
}
}