Add back button on ticket and task detail screens

This commit is contained in:
Marc Rejohn Castillano 2026-03-03 18:15:18 +08:00
parent d9270b3edf
commit 1e678ea2e5
2 changed files with 101 additions and 77 deletions

View File

@ -2400,7 +2400,21 @@ class _TaskDetailScreenState extends ConsumerState<TaskDetailScreen>
final detailsCard = Card( final detailsCard = Card(
child: Padding( child: Padding(
padding: const EdgeInsets.all(20), padding: const EdgeInsets.all(20),
child: SingleChildScrollView(child: detailsContent), child: SingleChildScrollView(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Align(
alignment: Alignment.topLeft,
child: IconButton(
icon: const Icon(Icons.arrow_back),
onPressed: () => Navigator.of(context).pop(),
),
),
detailsContent,
],
),
),
), ),
); );
@ -2605,67 +2619,67 @@ class _TaskDetailScreenState extends ConsumerState<TaskDetailScreen>
), ),
); );
if (isWide) { final mainContent = isWide
return Row( ? Row(
children: [ children: [
Expanded(flex: 2, child: detailsCard), Expanded(flex: 2, child: detailsCard),
const SizedBox(width: 16), const SizedBox(width: 16),
Expanded(flex: 3, child: tabbedCard), Expanded(flex: 3, child: tabbedCard),
], ],
); )
} : Stack(
children: [
// Mobile/tablet: allow vertical scrolling of detail card while CustomScrollView(
// keeping the chat/activity panel filling the remaining viewport slivers: [
// (and scrolling internally). Use a CustomScrollView to provide a SliverToBoxAdapter(child: detailsCard),
// bounded height for the tabbed card via SliverFillRemaining. const SliverToBoxAdapter(child: SizedBox(height: 12)),
return Stack( SliverFillRemaining(
children: [ hasScrollBody: true,
CustomScrollView( child: tabbedCard,
slivers: [ ),
SliverToBoxAdapter(child: detailsCard), ],
const SliverToBoxAdapter(child: SizedBox(height: 12)), ),
SliverFillRemaining(hasScrollBody: true, child: tabbedCard), if (isRetrieving)
], Positioned.fill(
), child: AbsorbPointer(
if (isRetrieving) absorbing: true,
Positioned.fill( child: Container(
child: AbsorbPointer( color: Theme.of(context).colorScheme.surface
absorbing: true, .withAlpha((0.35 * 255).round()),
child: Container( alignment: Alignment.topCenter,
color: Theme.of( padding: const EdgeInsets.only(top: 36),
context, child: SizedBox(
).colorScheme.surface.withAlpha((0.35 * 255).round()), width: 280,
alignment: Alignment.topCenter, child: Card(
padding: const EdgeInsets.only(top: 36), elevation: 4,
child: SizedBox( child: Padding(
width: 280, padding: const EdgeInsets.all(12.0),
child: Card( child: Row(
elevation: 4, mainAxisSize: MainAxisSize.min,
child: Padding( children: const [
padding: const EdgeInsets.all(12.0), SizedBox(
child: Row( width: 20,
mainAxisSize: MainAxisSize.min, height: 20,
children: const [ child: CircularProgressIndicator(
SizedBox( strokeWidth: 2,
width: 20, ),
height: 20, ),
child: CircularProgressIndicator( SizedBox(width: 12),
strokeWidth: 2, Expanded(
child: Text('Retrieving updates…'),
),
],
), ),
), ),
SizedBox(width: 12), ),
Expanded(child: Text('Retrieving updates…')),
],
), ),
), ),
), ),
), ),
), ],
), );
),
], return mainContent;
);
}, },
), ),
), ),

View File

@ -199,7 +199,21 @@ class _TicketDetailScreenState extends ConsumerState<TicketDetailScreen> {
final detailsCard = Card( final detailsCard = Card(
child: Padding( child: Padding(
padding: const EdgeInsets.all(20), padding: const EdgeInsets.all(20),
child: SingleChildScrollView(child: detailsContent), child: SingleChildScrollView(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Align(
alignment: Alignment.topLeft,
child: IconButton(
icon: const Icon(Icons.arrow_back),
onPressed: () => Navigator.of(context).pop(),
),
),
detailsContent,
],
),
),
), ),
); );
@ -437,27 +451,23 @@ class _TicketDetailScreenState extends ConsumerState<TicketDetailScreen> {
), ),
); );
if (isWide) { final mainContent = isWide
return Row( ? Row(
children: [ children: [
Expanded(flex: 2, child: detailsCard), Expanded(flex: 2, child: detailsCard),
const SizedBox(width: 16), const SizedBox(width: 16),
Expanded(flex: 3, child: messagesCard), Expanded(flex: 3, child: messagesCard),
], ],
); )
} : Column(
children: [
detailsCard,
const SizedBox(height: 12),
Expanded(child: messagesCard),
],
);
// Mobile: avoid nesting scrollables. detailsCard itself is return mainContent;
// scrollable if it grows tall, and the messages area takes the
// remaining space so the chat list can always receive touch
// gestures and never end up offscreen.
return Column(
children: [
detailsCard,
const SizedBox(height: 12),
Expanded(child: messagesCard),
],
);
}, },
), ),
); );