UI changes, Logs viewer

version bumped to 0.2.0
This commit is contained in:
Mercurio 2023-11-10 18:29:45 +01:00
parent c0a8012357
commit 9e1e60492e
4 changed files with 227 additions and 15 deletions

147
lib/LogsPage.dart Normal file
View file

@ -0,0 +1,147 @@
import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;
import 'package:shared_preferences/shared_preferences.dart';
import 'package:OpenshockCompanion/settings_page.dart' show SettingsPage;
class LogsPage extends StatefulWidget {
const LogsPage({Key? key}) : super(key: key);
@override
_LogsPageState createState() => _LogsPageState();
}
class _LogsPageState extends State<LogsPage> {
List<Map<String, dynamic>> logs = [];
@override
void initState() {
super.initState();
fetchLogs();
}
Future<void> fetchLogs() async {
final SharedPreferences prefs = await SharedPreferences.getInstance();
final apiKey = prefs.getString('apiKey');
final shockerId = prefs.getString('shockerId');
if (apiKey == null || shockerId == null) {
// Handle missing API key or shockerId
return;
}
final url = 'https://api.shocklink.net/1/shockers/$shockerId/logs?offset=0&limit=30';
final response = await http.get(Uri.parse(url), headers: {
'accept': 'application/json',
'OpenShockToken': apiKey,
});
if (response.statusCode == 200) {
final jsonData = json.decode(response.body);
if (jsonData['data'] != null) {
setState(() {
logs = List<Map<String, dynamic>>.from(jsonData['data']);
});
}
} else {
// Handle API request error
}
}
Future<void> _handleRefresh() async {
await fetchLogs();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Logs'),
),
body: RefreshIndicator(
onRefresh: _handleRefresh,
child: Scrollbar(
thumbVisibility: true,
child: Padding(
padding: const EdgeInsets.all(16.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
const Text('Logs'),
Expanded(
child: SingleChildScrollView(
child: DataTable(
columns: const [
DataColumn(label: Text('Name')),
DataColumn(label: Text('Intensity')),
DataColumn(label: Text('Duration (s)')),
],
rows: logs.map((log) {
final controlledBy = log['controlledBy'] as Map<String, dynamic>?;
// Add null check for controlledBy
if (controlledBy != null) {
final name = controlledBy['name'] as String?;
final intensity = log['intensity'] as int?;
final duration = (log['duration'] as int?)! / 1000; // Convert to seconds
// Add null checks for name and intensity
if (name != null && intensity != null) {
return DataRow(
cells: [
DataCell(Text(name)),
DataCell(Text(intensity.toString())),
DataCell(Text(duration.toString())),
],
);
}
}
return const DataRow(cells: []);
}).toList(),
),
),
),
],
),
),
),
),
bottomNavigationBar: BottomNavigationBar(
items: const [
BottomNavigationBarItem(
icon: Icon(Icons.home),
label: 'Home',
),
BottomNavigationBarItem(
icon: Icon(Icons.settings),
label: 'Settings',
),
BottomNavigationBarItem(
icon: Icon(Icons.list),
label: 'Logs',
),
],
currentIndex: 2, // Set the current index to 2 for the Logs page
onTap: (index) {
if (index == 0) {
// Navigate back to the main page
Navigator.popUntil(context, (route) => route.isFirst);
} else if (index == 1) {
// Navigate to the Settings page
Navigator.push(
context,
MaterialPageRoute(builder: (context) => const SettingsPage()),
);
}
},
selectedItemColor: const Color.fromARGB(255, 211, 187, 255), // or any color you prefer
unselectedItemColor: Theme.of(context).textTheme.bodySmall?.color,
showUnselectedLabels: true,
selectedLabelStyle: const TextStyle(fontWeight: FontWeight.bold),
),
);
}
}

View file

@ -2,6 +2,7 @@ import 'package:flutter/material.dart';
import 'package:flutter/services.dart'; import 'package:flutter/services.dart';
import 'package:fluttertoast/fluttertoast.dart'; import 'package:fluttertoast/fluttertoast.dart';
import 'package:OpenshockCompanion/settings_page.dart' show SettingsPage; import 'package:OpenshockCompanion/settings_page.dart' show SettingsPage;
import 'package:OpenshockCompanion/LogsPage.dart' show LogsPage;
import 'package:OpenshockCompanion/api_handler.dart' show sendApiRequest; import 'package:OpenshockCompanion/api_handler.dart' show sendApiRequest;
import 'package:shared_preferences/shared_preferences.dart'; import 'package:shared_preferences/shared_preferences.dart';
@ -10,7 +11,7 @@ void main() {
} }
class MyApp extends StatelessWidget { class MyApp extends StatelessWidget {
const MyApp({super.key}); const MyApp({Key? key}) : super(key: key);
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
@ -36,7 +37,7 @@ class MyApp extends StatelessWidget {
} }
class SliderPage extends StatefulWidget { class SliderPage extends StatefulWidget {
const SliderPage({super.key}); const SliderPage({Key? key}) : super(key: key);
@override @override
_SliderPageState createState() => _SliderPageState(); _SliderPageState createState() => _SliderPageState();
@ -45,6 +46,7 @@ class SliderPage extends StatefulWidget {
class _SliderPageState extends State<SliderPage> { class _SliderPageState extends State<SliderPage> {
int intensityValue = 0; int intensityValue = 0;
int timeValue = 0; int timeValue = 0;
int currentIndex = 0;
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
@ -124,18 +126,49 @@ class _SliderPageState extends State<SliderPage> {
), ),
], ],
), ),
ElevatedButton(
child: const Text('Settings'),
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(builder: (context) => const SettingsPage()),
);
},
),
], ],
), ),
), ),
bottomNavigationBar: BottomNavigationBar(
currentIndex: currentIndex,
onTap: (index) {
setState(() {
currentIndex = index;
if (index == 0) {
// Home tab
} else if (index == 1) {
// Settings tab
Navigator.push(
context,
MaterialPageRoute(builder: (context) => const SettingsPage()),
);
} else if (index == 2) {
Navigator.push(
context,
MaterialPageRoute(builder: (context) => const LogsPage()),
);
}
});
},
items: const [
BottomNavigationBarItem(
icon: Icon(Icons.home),
label: 'Home',
),
BottomNavigationBarItem(
icon: Icon(Icons.settings),
label: 'Settings',
),
BottomNavigationBarItem(
icon: Icon(Icons.list),
label: 'Logs',
),
],
selectedItemColor: const Color.fromARGB(255, 211, 187, 255), // or any color you prefer
unselectedItemColor: Theme.of(context).textTheme.bodySmall?.color,
showUnselectedLabels: true,
selectedLabelStyle: const TextStyle(fontWeight: FontWeight.bold),
),
); );
} }

View file

@ -1,9 +1,9 @@
// settings_page.dart import 'package:OpenshockCompanion/LogsPage.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:shared_preferences/shared_preferences.dart'; import 'package:shared_preferences/shared_preferences.dart';
class SettingsPage extends StatefulWidget { class SettingsPage extends StatefulWidget {
const SettingsPage({super.key}); const SettingsPage({Key? key});
@override @override
_SettingsPageState createState() => _SettingsPageState(); _SettingsPageState createState() => _SettingsPageState();
@ -106,6 +106,38 @@ class _SettingsPageState extends State<SettingsPage> {
], ],
), ),
), ),
bottomNavigationBar: BottomNavigationBar(
items: const [
BottomNavigationBarItem(
icon: Icon(Icons.home),
label: 'Home',
),
BottomNavigationBarItem(
icon: Icon(Icons.settings),
label: 'Settings',
),
BottomNavigationBarItem(
icon: Icon(Icons.list),
label: 'Logs',
),
],
currentIndex: 1, // Set the current index to 1 for the Settings page
onTap: (index) {
if (index == 0) {
// Navigate back to the main page
Navigator.popUntil(context, (route) => route.isFirst);
} else if (index == 2) {
Navigator.push(
context,
MaterialPageRoute(builder: (context) => const LogsPage()),
);
}
},
selectedItemColor: const Color.fromARGB(255, 211, 187, 255), // or any color you prefer
unselectedItemColor: Theme.of(context).textTheme.caption?.color,
showUnselectedLabels: true,
selectedLabelStyle: TextStyle(fontWeight: FontWeight.bold),
),
); );
} }
} }

View file

@ -4,7 +4,7 @@ description: Companion app for managing openshock-compatible devices
# pub.dev using `flutter pub publish`. This is preferred for private packages. # pub.dev using `flutter pub publish`. This is preferred for private packages.
publish_to: 'none' # Remove this line if you wish to publish to pub.dev publish_to: 'none' # Remove this line if you wish to publish to pub.dev
version: 0.1.4 version: 0.2.0
environment: environment:
sdk: '>=3.1.2 <4.0.0' sdk: '>=3.1.2 <4.0.0'