import 'package:flutter/material.dart';
import 'package:hmelbakery/core/style/colors.dart';
import 'package:visibility_detector/visibility_detector.dart';
class NotificationChip extends StatefulWidget {
NotificationChip({
required this.index,
required this.visibleIndex,
super.key,
this.title = '',
this.text = '',
this.subtitle = '',
this.status = true,
});
final String title;
final int index;
final ValueChanged<int> visibleIndex;
final String text;
final String subtitle;
final bool status;
@override
State<NotificationChip> createState() => _NotificationChipState();
}
class _NotificationChipState extends State<NotificationChip> {
final UniqueKey key = UniqueKey();
late bool _visible;
@override
void initState() {
_visible = widget.status;
super.initState();
}
@override
Widget build(BuildContext context) {
return VisibilityDetector(
onVisibilityChanged: !_visible
? (visibilityInfo) {
// Здесь определяется на сколько виден объект в процентах
var visiblePercentage = visibilityInfo.visibleFraction * 100;
if (visiblePercentage == 100.0) {
setState(() {
_visible = true;
});
widget.visibleIndex.call(widget.index); // прочитали
}
}
: null,
key: key,
child: Container(
decoration: BoxDecoration(color: AppColors.grey, borderRadius: BorderRadius.circular(16)),
child: Padding(
padding: const EdgeInsets.all(16),
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(
widget.title,
style: Theme.of(context).textTheme.titleLarge,
),
if (!_visible)
Container(
width: 16,
height: 16,
decoration: const BoxDecoration(
color: AppColors.yellow,
shape: BoxShape.circle,
),
),
],
),
const SizedBox(height: 8),
Text(widget.text, style: Theme.of(context).textTheme.bodyMedium),
const SizedBox(height: 16),
Text(
widget.subtitle,
style: Theme.of(context).textTheme.bodyMedium?.copyWith(color: AppColors.black400),
),
],
),
),
),
);
}
}
ListView.builder(
padding: const EdgeInsets.symmetric(horizontal: 16),
itemBuilder: (BuildContext context, int index) {
if (index == state.pageState.data.length - 1 && !state.pageState.loadNewPage) {
context.read<ProfileNotificationsBloc>().add(ProfileNotificationsFetchDataEvent());
}
return Column(
children: [
NotificationChip(
title: state.pageState.data[index].title,
text: state.pageState.data[index].text,
subtitle: DateConverter.formattingDateWTime(state.pageState.data[index].datetime),
status: !(state.pageState.data[index].statusCode == 'unread'),
index: index,
visibleIndex: (int value) {
context
.read<ProfileNotificationsBloc>()
.add(ProfileNotificationsMarkReadEvent(index: value)); // передаем в блок индекс прочитаного
},
),
const SizedBox(height: 8),
if (index == state.pageState.data.length - 1 && state.pageState.loadNewPage) ...[
const Center(child: CircularProgressIndicator(color: AppColors.black)),
const SizedBox(height: 20),
],
],
);
},
itemCount: state.pageState.data.length,
),
markRead(ProfileNotificationsMarkReadEvent event, emit) async {
if (!state.pageState.readIndexes.contains(event.index)) {
emit(ProfileNotificationsUp(state.pageState.copyWith(
readIndexes: [...state.pageState.readIndexes, event.index],
data: state.pageState.data..[event.index] = state.pageState.data[event.index].copyWith(statusCode: 'read'),
)));
}
}
Timer? _timer;
List _tempList = [];
_timerFunc() { // старт функции в блоке
_timer = Timer.periodic(
const Duration(seconds: 1),
(timer) {
if (_tempList.length < state.pageState.readIndexes.length) {
_tempList = state.pageState.readIndexes;
notificationsRepository.markRead(
request: MarkReadNotificationRequest(
notifications: state.pageState.data
.sublist(_tempList.first, _tempList.length > 1 ? _tempList.last : _tempList.first + 1)
.map((e) => e.id)
.toList(),
),
);
}
},
);
}