* Task/Ticket desktop dialogs — widened from 520 → 600dp, and tasks now uses SizedBox(width: 600) instead of ConstrainedBox(maxWidth:) which was the root cause of the "still small" issue (max-only never forced expansion)
* Pass Slip + Leave — both dialogs gained an isSheet flag; callers now branch on AppBreakpoints.tablet: bottom sheet on mobile, dialog on desktop
This commit is contained in:
@@ -261,9 +261,23 @@ class _AnnouncementCard extends ConsumerStatefulWidget {
|
||||
class _AnnouncementCardState extends ConsumerState<_AnnouncementCard> {
|
||||
static const _cooldownSeconds = 60;
|
||||
DateTime? _sentAt;
|
||||
Timer? _cooldownTimer;
|
||||
|
||||
void _startCooldownTimer() {
|
||||
_cooldownTimer?.cancel();
|
||||
_cooldownTimer = Timer.periodic(const Duration(milliseconds: 500), (_) {
|
||||
if (!mounted) {
|
||||
_cooldownTimer?.cancel();
|
||||
return;
|
||||
}
|
||||
setState(() {});
|
||||
if (!_inCooldown) _cooldownTimer?.cancel();
|
||||
});
|
||||
}
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
_cooldownTimer?.cancel();
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
@@ -289,9 +303,15 @@ class _AnnouncementCardState extends ConsumerState<_AnnouncementCard> {
|
||||
await ref
|
||||
.read(announcementsControllerProvider)
|
||||
.resendAnnouncementNotification(widget.announcement);
|
||||
if (mounted) setState(() => _sentAt = DateTime.now());
|
||||
if (mounted) {
|
||||
setState(() => _sentAt = DateTime.now());
|
||||
_startCooldownTimer();
|
||||
}
|
||||
} on AnnouncementNotificationException {
|
||||
if (mounted) setState(() => _sentAt = DateTime.now());
|
||||
if (mounted) {
|
||||
setState(() => _sentAt = DateTime.now());
|
||||
_startCooldownTimer();
|
||||
}
|
||||
} catch (e) {
|
||||
if (mounted) showErrorSnackBar(context, 'Failed to send: $e');
|
||||
}
|
||||
@@ -326,13 +346,6 @@ class _AnnouncementCardState extends ConsumerState<_AnnouncementCard> {
|
||||
final isAnnouncementPending =
|
||||
pendingNew || pendingUpdates.containsKey(widget.announcement.id);
|
||||
|
||||
// Rebuild UI when cooldown is active.
|
||||
if (_inCooldown) {
|
||||
Future.delayed(const Duration(milliseconds: 500), () {
|
||||
if (mounted) setState(() {});
|
||||
});
|
||||
}
|
||||
|
||||
final hasBanner = widget.announcement.bannerEnabled;
|
||||
|
||||
return Padding(
|
||||
@@ -456,7 +469,14 @@ class _AnnouncementCardState extends ConsumerState<_AnnouncementCard> {
|
||||
),
|
||||
Padding(
|
||||
padding: const EdgeInsets.fromLTRB(16, 6, 16, 0),
|
||||
child: Text(widget.announcement.body, style: tt.bodyMedium),
|
||||
child: Text(
|
||||
widget.announcement.body,
|
||||
style: tt.bodyMedium,
|
||||
maxLines: widget.isExpanded ? null : 8,
|
||||
overflow: widget.isExpanded
|
||||
? TextOverflow.clip
|
||||
: TextOverflow.ellipsis,
|
||||
),
|
||||
),
|
||||
// Visible roles chips
|
||||
Padding(
|
||||
|
||||
Reference in New Issue
Block a user