Worklog, anti geo spoofing and UI Polish
This commit is contained in:
@@ -254,11 +254,18 @@ class _StatusChip extends StatelessWidget {
|
||||
}
|
||||
}
|
||||
|
||||
class _CacheGrid extends StatelessWidget {
|
||||
class _CacheGrid extends StatefulWidget {
|
||||
final Map<String, int> counts;
|
||||
|
||||
const _CacheGrid({required this.counts});
|
||||
|
||||
@override
|
||||
State<_CacheGrid> createState() => _CacheGridState();
|
||||
}
|
||||
|
||||
class _CacheGridState extends State<_CacheGrid> with SingleTickerProviderStateMixin {
|
||||
late final AnimationController _controller;
|
||||
|
||||
static const _groups = [
|
||||
('Tasks', 'tasks', Icons.task_alt_rounded),
|
||||
('Tickets', 'tickets', Icons.confirmation_number_rounded),
|
||||
@@ -274,6 +281,21 @@ class _CacheGrid extends StatelessWidget {
|
||||
('Offices', 'offices', Icons.business_rounded),
|
||||
];
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
_controller = AnimationController(
|
||||
duration: const Duration(milliseconds: 800),
|
||||
vsync: this,
|
||||
)..forward();
|
||||
}
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
_controller.dispose();
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final scheme = Theme.of(context).colorScheme;
|
||||
@@ -284,22 +306,41 @@ class _CacheGrid extends StatelessWidget {
|
||||
crossAxisCount: 3,
|
||||
mainAxisSpacing: 8,
|
||||
crossAxisSpacing: 8,
|
||||
childAspectRatio: 1.1,
|
||||
childAspectRatio: 0.9,
|
||||
),
|
||||
itemCount: _groups.length,
|
||||
itemBuilder: (context, i) {
|
||||
final (label, key, icon) = _groups[i];
|
||||
final count = counts[key] ?? -1;
|
||||
final count = widget.counts[key] ?? -1;
|
||||
final cached = count >= 0;
|
||||
return AnimatedSwitcher(
|
||||
duration: const Duration(milliseconds: 400),
|
||||
child: _CacheTile(
|
||||
key: ValueKey('$key-$count'),
|
||||
label: label,
|
||||
icon: icon,
|
||||
count: count,
|
||||
cached: cached,
|
||||
scheme: scheme,
|
||||
|
||||
final start = i * 0.055;
|
||||
final end = (start + 0.45).clamp(0.0, 1.0);
|
||||
final curve = CurvedAnimation(
|
||||
parent: _controller,
|
||||
curve: Interval(start, end, curve: Curves.easeOutCubic),
|
||||
);
|
||||
final fadeAnim = Tween<double>(begin: 0.0, end: 1.0).animate(curve);
|
||||
final slideAnim = Tween<Offset>(
|
||||
begin: const Offset(0, 0.25),
|
||||
end: Offset.zero,
|
||||
).animate(curve);
|
||||
|
||||
return FadeTransition(
|
||||
opacity: fadeAnim,
|
||||
child: SlideTransition(
|
||||
position: slideAnim,
|
||||
child: AnimatedSwitcher(
|
||||
duration: const Duration(milliseconds: 400),
|
||||
child: _CacheTile(
|
||||
key: ValueKey('$key-$count'),
|
||||
label: label,
|
||||
icon: icon,
|
||||
count: count,
|
||||
cached: cached,
|
||||
scheme: scheme,
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
},
|
||||
@@ -328,24 +369,25 @@ class _CacheTile extends StatelessWidget {
|
||||
final bg = cached ? scheme.primaryContainer.withValues(alpha: 0.5) : scheme.surfaceContainerHighest;
|
||||
final fg = cached ? scheme.onPrimaryContainer : scheme.onSurfaceVariant;
|
||||
return Container(
|
||||
decoration: BoxDecoration(color: bg, borderRadius: BorderRadius.circular(12)),
|
||||
padding: const EdgeInsets.all(10),
|
||||
decoration: BoxDecoration(color: bg, borderRadius: BorderRadius.circular(14)),
|
||||
padding: const EdgeInsets.all(12),
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
Icon(icon, color: fg, size: 22),
|
||||
const SizedBox(height: 4),
|
||||
Icon(icon, color: fg, size: 24),
|
||||
const SizedBox(height: 6),
|
||||
Text(
|
||||
label,
|
||||
style: TextStyle(color: fg, fontSize: 10, fontWeight: FontWeight.w500),
|
||||
style: TextStyle(color: fg, fontSize: 11, fontWeight: FontWeight.w500),
|
||||
textAlign: TextAlign.center,
|
||||
maxLines: 1,
|
||||
maxLines: 2,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
),
|
||||
const SizedBox(height: 2),
|
||||
Text(
|
||||
cached ? '$count items' : 'Not cached',
|
||||
style: TextStyle(color: fg.withValues(alpha: 0.7), fontSize: 9),
|
||||
style: TextStyle(color: fg.withValues(alpha: 0.7), fontSize: 10),
|
||||
textAlign: TextAlign.center,
|
||||
),
|
||||
],
|
||||
),
|
||||
|
||||
Reference in New Issue
Block a user