@@ -27,6 +27,8 @@ class _PrivateCloudSyncPageState extends State<PrivateCloudSyncPage> {
2727 bool _isDeleting = false ;
2828 bool _isAudioLoading = false ;
2929 List <CloudAudioConversation > _conversations = [];
30+ bool ? _lastPrivateCloudSyncEnabled;
31+ int _playbackGeneration = 0 ;
3032
3133 final AudioPlayer _audioPlayer = AudioPlayer ();
3234 StreamSubscription <PlayerState >? _playerStateSubscription;
@@ -50,9 +52,40 @@ class _PrivateCloudSyncPageState extends State<PrivateCloudSyncPage> {
5052 setState (() {});
5153 }
5254 });
53- if (context.read <UserProvider >().privateCloudSyncEnabled) {
54- _loadCloudAudioConversations ();
55+ }
56+
57+ @override
58+ void didChangeDependencies () {
59+ super .didChangeDependencies ();
60+
61+ final isEnabled = context.watch <UserProvider >().privateCloudSyncEnabled;
62+ if (_lastPrivateCloudSyncEnabled == isEnabled) return ;
63+ _lastPrivateCloudSyncEnabled = isEnabled;
64+
65+ if (isEnabled) {
66+ unawaited (_loadCloudAudioConversations ());
67+ return ;
5568 }
69+
70+ _cancelPendingPlayback (clearConversations: true );
71+ }
72+
73+ void _cancelPendingPlayback ({bool clearConversations = false }) {
74+ _playbackGeneration++ ;
75+ unawaited (_audioPlayer.stop ());
76+ _currentPlayingConversationId = null ;
77+ _isAudioLoading = false ;
78+ if (clearConversations) {
79+ _conversations = [];
80+ }
81+ }
82+
83+ bool _shouldAbortPlaybackStart (String conversationId, int playbackGeneration) {
84+ return ! mounted ||
85+ _isDeleting ||
86+ ! context.read <UserProvider >().privateCloudSyncEnabled ||
87+ _currentPlayingConversationId != conversationId ||
88+ _playbackGeneration != playbackGeneration;
5689 }
5790
5891 @override
@@ -98,9 +131,6 @@ class _PrivateCloudSyncPageState extends State<PrivateCloudSyncPage> {
98131 backgroundColor: Colors .green,
99132 ),
100133 );
101- if (value) {
102- await _loadCloudAudioConversations ();
103- }
104134 } catch (e) {
105135 Logger .debug ('Error toggling cloud storage: $e ' );
106136 if (! mounted) return ;
@@ -127,6 +157,7 @@ class _PrivateCloudSyncPageState extends State<PrivateCloudSyncPage> {
127157 }
128158
129159 await _audioPlayer.stop ();
160+ final playbackGeneration = ++ _playbackGeneration;
130161 if (! mounted) return ;
131162 setState (() {
132163 _currentPlayingConversationId = conversation.id;
@@ -135,17 +166,19 @@ class _PrivateCloudSyncPageState extends State<PrivateCloudSyncPage> {
135166
136167 try {
137168 final audioFileInfos = await getConversationAudioSignedUrls (conversation.id);
169+ if (_shouldAbortPlaybackStart (conversation.id, playbackGeneration)) return ;
138170 if (audioFileInfos.isEmpty) {
139171 throw Exception ('No audio files available to play' );
140172 }
141173
142174 if (audioFileInfos.any ((af) => ! af.isCached)) {
143175 await precacheConversationAudio (conversation.id);
144- if (! mounted ) return ;
176+ if (_shouldAbortPlaybackStart (conversation.id, playbackGeneration) ) return ;
145177 setState (() {
146178 _currentPlayingConversationId = null ;
147179 _isAudioLoading = false ;
148180 });
181+ if (! mounted) return ;
149182 ScaffoldMessenger .of (context).showSnackBar (
150183 SnackBar (content: Text (context.l10n.preparingCloudAudioTryAgain), backgroundColor: Colors .orange),
151184 );
@@ -165,9 +198,15 @@ class _PrivateCloudSyncPageState extends State<PrivateCloudSyncPage> {
165198 );
166199
167200 await _audioPlayer.setAudioSource (playlist, preload: true );
168- if (! mounted) return ;
201+ if (_shouldAbortPlaybackStart (conversation.id, playbackGeneration)) {
202+ await _audioPlayer.stop ();
203+ return ;
204+ }
169205 setState (() => _isAudioLoading = false );
170206 await _audioPlayer.play ();
207+ if (_shouldAbortPlaybackStart (conversation.id, playbackGeneration)) {
208+ await _audioPlayer.stop ();
209+ }
171210 } catch (e) {
172211 Logger .debug ('Error playing conversation audio: $e ' );
173212 if (! mounted) return ;
@@ -227,12 +266,7 @@ class _PrivateCloudSyncPageState extends State<PrivateCloudSyncPage> {
227266 if (confirmed != true ) return ;
228267
229268 setState (() => _isDeleting = true );
230- await _audioPlayer.stop ();
231- if (mounted) {
232- setState (() {
233- _currentPlayingConversationId = null ;
234- });
235- }
269+ _cancelPendingPlayback ();
236270
237271 try {
238272 final success = await deleteAllCloudAudio ();
0 commit comments