1+ import 'dart:async' ;
2+
13import 'package:bloc/bloc.dart' ;
24import 'package:core/core.dart' ;
35import 'package:data_repository/data_repository.dart' ;
@@ -15,9 +17,18 @@ class ArchivedHeadlinesBloc
1517 on < LoadArchivedHeadlinesRequested > (_onLoadArchivedHeadlinesRequested);
1618 on < RestoreHeadlineRequested > (_onRestoreHeadlineRequested);
1719 on < DeleteHeadlineForeverRequested > (_onDeleteHeadlineForeverRequested);
20+ on < UndoDeleteHeadlineRequested > (_onUndoDeleteHeadlineRequested);
21+ on < _ConfirmDeleteHeadlineRequested > (_onConfirmDeleteHeadlineRequested);
1822 }
1923
2024 final DataRepository <Headline > _headlinesRepository;
25+ Timer ? _deleteTimer;
26+
27+ @override
28+ Future <void > close () {
29+ _deleteTimer? .cancel ();
30+ return super .close ();
31+ }
2132
2233 Future <void > _onLoadArchivedHeadlinesRequested (
2334 LoadArchivedHeadlinesRequested event,
@@ -96,22 +107,83 @@ class ArchivedHeadlinesBloc
96107 DeleteHeadlineForeverRequested event,
97108 Emitter <ArchivedHeadlinesState > emit,
98109 ) async {
99- final originalHeadlines = List <Headline >.from (state.headlines);
100- final headlineIndex = originalHeadlines.indexWhere ((h) => h.id == event.id);
110+ _deleteTimer? .cancel ();
111+
112+ final headlineIndex = state.headlines.indexWhere ((h) => h.id == event.id);
101113 if (headlineIndex == - 1 ) return ;
102114
103- final updatedHeadlines = originalHeadlines..removeAt (headlineIndex);
104- emit (state.copyWith (headlines: updatedHeadlines));
115+ final headlineToDelete = state.headlines[headlineIndex];
116+ final updatedHeadlines = List <Headline >.from (state.headlines)
117+ ..removeAt (headlineIndex);
118+
119+ emit (
120+ state.copyWith (
121+ headlines: updatedHeadlines,
122+ lastDeletedHeadline: headlineToDelete,
123+ ),
124+ );
125+
126+ _deleteTimer = Timer (
127+ const Duration (seconds: 5 ),
128+ () => add (_ConfirmDeleteHeadlineRequested (event.id)),
129+ );
130+ }
105131
132+ Future <void > _onConfirmDeleteHeadlineRequested (
133+ _ConfirmDeleteHeadlineRequested event,
134+ Emitter <ArchivedHeadlinesState > emit,
135+ ) async {
106136 try {
107137 await _headlinesRepository.delete (id: event.id);
138+ emit (state.copyWith (lastDeletedHeadline: null ));
108139 } on HttpException catch (e) {
109- emit (state.copyWith (headlines: originalHeadlines, exception: e));
140+ // If deletion fails, restore the headline to the list
141+ final originalHeadlines = List <Headline >.from (state.headlines)
142+ ..add (state.lastDeletedHeadline! );
143+ emit (
144+ state.copyWith (
145+ headlines: originalHeadlines,
146+ exception: e,
147+ lastDeletedHeadline: null ,
148+ ),
149+ );
110150 } catch (e) {
151+ final originalHeadlines = List <Headline >.from (state.headlines)
152+ ..add (state.lastDeletedHeadline! );
111153 emit (
112154 state.copyWith (
113155 headlines: originalHeadlines,
114156 exception: UnknownException ('An unexpected error occurred: $e ' ),
157+ lastDeletedHeadline: null ,
158+ ),
159+ );
160+ }
161+ }
162+
163+ void _onUndoDeleteHeadlineRequested (
164+ UndoDeleteHeadlineRequested event,
165+ Emitter <ArchivedHeadlinesState > emit,
166+ ) {
167+ _deleteTimer? .cancel ();
168+ if (state.lastDeletedHeadline != null ) {
169+ final updatedHeadlines = List <Headline >.from (state.headlines)
170+ ..insert (
171+ state.headlines.indexWhere (
172+ (h) =>
173+ h.updatedAt.isBefore (state.lastDeletedHeadline! .updatedAt),
174+ ) !=
175+ - 1
176+ ? state.headlines.indexWhere (
177+ (h) =>
178+ h.updatedAt.isBefore (state.lastDeletedHeadline! .updatedAt),
179+ )
180+ : state.headlines.length,
181+ state.lastDeletedHeadline! ,
182+ );
183+ emit (
184+ state.copyWith (
185+ headlines: updatedHeadlines,
186+ lastDeletedHeadline: null ,
115187 ),
116188 );
117189 }
0 commit comments