More tests, better functionality, the server serves the dashboard now on configurable ports. websocket stuff fixed, though I dont think data is really being sent / recieved...
This commit is contained in:
@@ -54,9 +54,7 @@ class _AchievementItem extends StatelessWidget {
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final achievedDate = achievement.achievedAt != null
|
||||
? DateTime.parse(achievement.achievedAt!)
|
||||
: null;
|
||||
final achievedDate = achievement.achievedAt;
|
||||
|
||||
return Padding(
|
||||
padding: const EdgeInsets.symmetric(vertical: 8),
|
||||
|
||||
@@ -191,7 +191,7 @@ class _UnclassifiedItemState extends State<_UnclassifiedItem> {
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final lastSeen = DateTime.parse(widget.app.lastSeen);
|
||||
final lastSeen = widget.app.lastSeen;
|
||||
|
||||
return Card(
|
||||
margin: const EdgeInsets.symmetric(vertical: 4),
|
||||
|
||||
@@ -54,7 +54,7 @@ class _ActivityItem extends StatelessWidget {
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final timestamp = DateTime.parse(activity.timestamp);
|
||||
final timestamp = activity.timestamp;
|
||||
final duration = Duration(seconds: activity.durationSeconds);
|
||||
|
||||
return Padding(
|
||||
@@ -66,7 +66,7 @@ class _ActivityItem extends StatelessWidget {
|
||||
height: 8,
|
||||
decoration: BoxDecoration(
|
||||
shape: BoxShape.circle,
|
||||
color: AppTheme.getActivityTypeColor(activity.type),
|
||||
color: AppTheme.getActivityTypeColor(activity.type ?? 'uncategorized'),
|
||||
),
|
||||
),
|
||||
const SizedBox(width: 12),
|
||||
@@ -75,13 +75,13 @@ class _ActivityItem extends StatelessWidget {
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
activity.application,
|
||||
activity.application ?? 'Unknown App',
|
||||
style: Theme.of(context).textTheme.bodyMedium?.copyWith(
|
||||
fontWeight: FontWeight.w500,
|
||||
),
|
||||
),
|
||||
Text(
|
||||
'${_capitalizeFirst(activity.type)} • ${_formatDuration(duration)} • ${_formatTime(timestamp)}',
|
||||
'${_capitalizeFirst(activity.type ?? 'uncategorized')} • ${_formatDuration(duration)} • ${_formatTime(timestamp)}',
|
||||
style: Theme.of(context).textTheme.bodySmall?.copyWith(
|
||||
color: Colors.grey.shade600,
|
||||
),
|
||||
@@ -94,8 +94,8 @@ class _ActivityItem extends StatelessWidget {
|
||||
);
|
||||
}
|
||||
|
||||
String _capitalizeFirst(String text) {
|
||||
if (text.isEmpty) return text;
|
||||
String _capitalizeFirst(String? text) {
|
||||
if (text == null || text.isEmpty) return 'Unknown';
|
||||
return text[0].toUpperCase() + text.substring(1);
|
||||
}
|
||||
|
||||
|
||||
@@ -6,10 +6,7 @@ import '../theme/app_theme.dart';
|
||||
class XPChart extends StatelessWidget {
|
||||
final List<StatsHistory> history;
|
||||
|
||||
const XPChart({
|
||||
super.key,
|
||||
required this.history,
|
||||
});
|
||||
const XPChart({super.key, required this.history});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
@@ -25,9 +22,7 @@ class XPChart extends StatelessWidget {
|
||||
const SizedBox(width: 8),
|
||||
Text(
|
||||
'XP Progress (7 Days)',
|
||||
style: Theme.of(context).textTheme.titleLarge?.copyWith(
|
||||
fontWeight: FontWeight.bold,
|
||||
),
|
||||
style: Theme.of(context).textTheme.titleLarge?.copyWith(fontWeight: FontWeight.bold),
|
||||
),
|
||||
],
|
||||
),
|
||||
@@ -36,13 +31,7 @@ class XPChart extends StatelessWidget {
|
||||
const SizedBox(height: 16),
|
||||
SizedBox(
|
||||
height: 300,
|
||||
child: history.isEmpty
|
||||
? const Center(
|
||||
child: CircularProgressIndicator(),
|
||||
)
|
||||
: LineChart(
|
||||
_buildChartData(),
|
||||
),
|
||||
child: history.isEmpty ? const Center(child: CircularProgressIndicator()) : LineChart(_buildChartData()),
|
||||
),
|
||||
],
|
||||
),
|
||||
@@ -53,7 +42,7 @@ class XPChart extends StatelessWidget {
|
||||
LineChartData _buildChartData() {
|
||||
final xpSpots = <FlSpot>[];
|
||||
final levelSpots = <FlSpot>[];
|
||||
|
||||
|
||||
for (int i = 0; i < history.length; i++) {
|
||||
xpSpots.add(FlSpot(i.toDouble(), history[i].xp.toDouble()));
|
||||
levelSpots.add(FlSpot(i.toDouble(), history[i].level.toDouble()));
|
||||
@@ -69,16 +58,10 @@ class XPChart extends StatelessWidget {
|
||||
horizontalInterval: maxXP / 5,
|
||||
verticalInterval: 1,
|
||||
getDrawingHorizontalLine: (value) {
|
||||
return FlLine(
|
||||
color: Colors.grey.shade300,
|
||||
strokeWidth: 1,
|
||||
);
|
||||
return FlLine(color: Colors.grey.shade300, strokeWidth: 1);
|
||||
},
|
||||
getDrawingVerticalLine: (value) {
|
||||
return FlLine(
|
||||
color: Colors.grey.shade300,
|
||||
strokeWidth: 1,
|
||||
);
|
||||
return FlLine(color: Colors.grey.shade300, strokeWidth: 1);
|
||||
},
|
||||
),
|
||||
titlesData: FlTitlesData(
|
||||
@@ -87,22 +70,16 @@ class XPChart extends StatelessWidget {
|
||||
sideTitles: SideTitles(
|
||||
showTitles: true,
|
||||
reservedSize: 40,
|
||||
interval: maxLevel / 4,
|
||||
// interval: 4,
|
||||
getTitlesWidget: (value, meta) {
|
||||
return Text(
|
||||
'L${value.toInt()}',
|
||||
style: const TextStyle(
|
||||
color: AppTheme.secondaryColor,
|
||||
fontWeight: FontWeight.bold,
|
||||
fontSize: 12,
|
||||
),
|
||||
'L${value.toInt() / 100}',
|
||||
style: const TextStyle(color: AppTheme.secondaryColor, fontWeight: FontWeight.bold, fontSize: 12),
|
||||
);
|
||||
},
|
||||
),
|
||||
),
|
||||
topTitles: const AxisTitles(
|
||||
sideTitles: SideTitles(showTitles: false),
|
||||
),
|
||||
topTitles: const AxisTitles(sideTitles: SideTitles(showTitles: false)),
|
||||
bottomTitles: AxisTitles(
|
||||
sideTitles: SideTitles(
|
||||
showTitles: true,
|
||||
@@ -116,11 +93,7 @@ class XPChart extends StatelessWidget {
|
||||
padding: const EdgeInsets.only(top: 8.0),
|
||||
child: Text(
|
||||
'${date.month}/${date.day}',
|
||||
style: const TextStyle(
|
||||
color: Colors.grey,
|
||||
fontWeight: FontWeight.bold,
|
||||
fontSize: 12,
|
||||
),
|
||||
style: const TextStyle(color: Colors.grey, fontWeight: FontWeight.bold, fontSize: 12),
|
||||
),
|
||||
);
|
||||
}
|
||||
@@ -131,25 +104,18 @@ class XPChart extends StatelessWidget {
|
||||
leftTitles: AxisTitles(
|
||||
sideTitles: SideTitles(
|
||||
showTitles: true,
|
||||
interval: maxXP / 4,
|
||||
// interval: maxXP / 4,
|
||||
reservedSize: 50,
|
||||
getTitlesWidget: (value, meta) {
|
||||
return Text(
|
||||
_formatXP(value.toInt()),
|
||||
style: const TextStyle(
|
||||
color: AppTheme.primaryColor,
|
||||
fontWeight: FontWeight.bold,
|
||||
fontSize: 12,
|
||||
),
|
||||
style: const TextStyle(color: AppTheme.primaryColor, fontWeight: FontWeight.bold, fontSize: 12),
|
||||
);
|
||||
},
|
||||
),
|
||||
),
|
||||
),
|
||||
borderData: FlBorderData(
|
||||
show: true,
|
||||
border: Border.all(color: Colors.grey.shade300),
|
||||
),
|
||||
borderData: FlBorderData(show: true, border: Border.all(color: Colors.grey.shade300)),
|
||||
minX: 0,
|
||||
maxX: (history.length - 1).toDouble(),
|
||||
minY: 0,
|
||||
@@ -159,9 +125,7 @@ class XPChart extends StatelessWidget {
|
||||
LineChartBarData(
|
||||
spots: xpSpots,
|
||||
isCurved: true,
|
||||
gradient: const LinearGradient(
|
||||
colors: [AppTheme.primaryColor, AppTheme.accentColor],
|
||||
),
|
||||
gradient: const LinearGradient(colors: [AppTheme.primaryColor, AppTheme.accentColor]),
|
||||
barWidth: 3,
|
||||
isStrokeCapRound: true,
|
||||
dotData: FlDotData(
|
||||
@@ -178,10 +142,7 @@ class XPChart extends StatelessWidget {
|
||||
belowBarData: BarAreaData(
|
||||
show: true,
|
||||
gradient: LinearGradient(
|
||||
colors: [
|
||||
AppTheme.primaryColor.withOpacity(0.3),
|
||||
AppTheme.primaryColor.withOpacity(0.1),
|
||||
],
|
||||
colors: [AppTheme.primaryColor.withOpacity(0.3), AppTheme.primaryColor.withOpacity(0.1)],
|
||||
begin: Alignment.topCenter,
|
||||
end: Alignment.bottomCenter,
|
||||
),
|
||||
@@ -219,24 +180,18 @@ class XPChart extends StatelessWidget {
|
||||
if (index >= 0 && index < history.length) {
|
||||
final historyItem = history[index];
|
||||
final date = DateTime.parse(historyItem.date);
|
||||
|
||||
|
||||
if (barSpot.barIndex == 0) {
|
||||
// XP line
|
||||
return LineTooltipItem(
|
||||
'${date.month}/${date.day}\nXP: ${historyItem.xp}',
|
||||
const TextStyle(
|
||||
color: Colors.white,
|
||||
fontWeight: FontWeight.bold,
|
||||
),
|
||||
const TextStyle(color: Colors.white, fontWeight: FontWeight.bold),
|
||||
);
|
||||
} else {
|
||||
// Level line
|
||||
return LineTooltipItem(
|
||||
'Level: ${historyItem.level}',
|
||||
const TextStyle(
|
||||
color: Colors.white,
|
||||
fontWeight: FontWeight.bold,
|
||||
),
|
||||
const TextStyle(color: Colors.white, fontWeight: FontWeight.bold),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -266,12 +221,7 @@ class XPChart extends StatelessWidget {
|
||||
hasGradient: true,
|
||||
),
|
||||
const SizedBox(width: 24),
|
||||
_buildLegendItem(
|
||||
color: AppTheme.secondaryColor,
|
||||
label: 'Level',
|
||||
isDashed: true,
|
||||
hasGradient: false,
|
||||
),
|
||||
_buildLegendItem(color: AppTheme.secondaryColor, label: 'Level', isDashed: true, hasGradient: false),
|
||||
],
|
||||
),
|
||||
);
|
||||
@@ -290,11 +240,7 @@ class XPChart extends StatelessWidget {
|
||||
width: 24,
|
||||
height: 3,
|
||||
decoration: BoxDecoration(
|
||||
gradient: hasGradient
|
||||
? const LinearGradient(
|
||||
colors: [AppTheme.primaryColor, AppTheme.accentColor],
|
||||
)
|
||||
: null,
|
||||
gradient: hasGradient ? const LinearGradient(colors: [AppTheme.primaryColor, AppTheme.accentColor]) : null,
|
||||
color: hasGradient ? null : color,
|
||||
borderRadius: BorderRadius.circular(2),
|
||||
),
|
||||
@@ -308,11 +254,7 @@ class XPChart extends StatelessWidget {
|
||||
const SizedBox(width: 8),
|
||||
Text(
|
||||
label,
|
||||
style: const TextStyle(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w500,
|
||||
color: Colors.black87,
|
||||
),
|
||||
style: const TextStyle(fontSize: 12, fontWeight: FontWeight.w500, color: Colors.black87),
|
||||
),
|
||||
],
|
||||
);
|
||||
@@ -345,11 +287,7 @@ class DashedLinePainter extends CustomPainter {
|
||||
double startX = 0;
|
||||
|
||||
while (startX < size.width) {
|
||||
canvas.drawLine(
|
||||
Offset(startX, size.height / 2),
|
||||
Offset(startX + dashWidth, size.height / 2),
|
||||
paint,
|
||||
);
|
||||
canvas.drawLine(Offset(startX, size.height / 2), Offset(startX + dashWidth, size.height / 2), paint);
|
||||
startX += dashWidth + dashSpace;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user