Files
voidea/flutter/lib/widgets/notification_bell.dart

107 lines
3.3 KiB
Dart

import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:go_router/go_router.dart';
import '../providers/notification_provider.dart';
import '../models/collaboration.dart';
import '../core/theme/app_theme.dart';
class NotificationBell extends ConsumerWidget {
const NotificationBell({super.key});
@override
Widget build(BuildContext context, WidgetRef ref) {
final unreadCount = ref.watch(unreadCountProvider);
return Stack(
children: [
IconButton(
icon: const Icon(Icons.notifications_outlined),
onPressed: () => context.push('/notifications'),
),
if (unreadCount > 0)
Positioned(
right: 6,
top: 6,
child: Container(
padding: const EdgeInsets.all(4),
decoration: const BoxDecoration(
color: VoIdeaColors.error,
shape: BoxShape.circle,
),
constraints: const BoxConstraints(minWidth: 18, minHeight: 18),
child: Text(
unreadCount > 99 ? '99+' : unreadCount.toString(),
style: const TextStyle(
color: Colors.white,
fontSize: 10,
fontWeight: FontWeight.bold,
),
textAlign: TextAlign.center,
),
),
),
],
);
}
}
class NotificationDropdown extends ConsumerStatefulWidget {
const NotificationDropdown({super.key});
@override
ConsumerState<NotificationDropdown> createState() =>
_NotificationDropdownState();
}
class _NotificationDropdownState
extends ConsumerState<NotificationDropdown> {
@override
Widget build(BuildContext context) {
final state = ref.watch(notificationProvider);
final notifier = ref.read(notificationProvider.notifier);
return PopupMenuButton(
icon: const NotificationBell(),
onOpened: () => notifier.loadNotifications(),
itemBuilder: (context) {
final items = state.notifications.take(5).toList();
if (items.isEmpty) {
return [
const PopupMenuItem(
enabled: false,
child: Text('Нет уведомлений'),
),
];
}
return [
...items.map((n) => PopupMenuItem(
child: ListTile(
title: Text(
n.title,
style: TextStyle(
fontWeight: n.isRead ? FontWeight.normal : FontWeight.w600,
fontSize: 13,
),
),
subtitle: Text(n.body, maxLines: 1, overflow: TextOverflow.ellipsis),
dense: true,
onTap: () {
notifier.markAsRead(n.id);
if (n.ideaId != null) {
context.push('/ideas/${n.ideaId}');
}
},
),
)),
const PopupMenuDivider(),
PopupMenuItem(
child: TextButton(
onPressed: () => context.push('/notifications'),
child: const Text('Все уведомления'),
),
),
];
},
);
}
}