M3 Overhaul

This commit is contained in:
2026-03-06 20:03:32 +08:00
parent 82fe619f22
commit 73dc735cce
32 changed files with 1940 additions and 682 deletions
+10 -8
View File
@@ -1,5 +1,6 @@
// ignore_for_file: use_build_context_synchronously
import 'package:flutter/material.dart';
import '../../theme/m3_motion.dart';
import 'package:flutter/services.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
@@ -1919,7 +1920,7 @@ class _TaskDetailScreenState extends ConsumerState<TaskDetailScreen>
onPressed: () async {
final urlCtrl =
TextEditingController();
final res = await showDialog<String?>(
final res = await m3ShowDialog<String?>(
context:
context,
builder: (ctx) => AlertDialog(
@@ -2234,7 +2235,7 @@ class _TaskDetailScreenState extends ConsumerState<TaskDetailScreen>
onPressed: () async {
final urlCtrl =
TextEditingController();
final res = await showDialog<String?>(
final res = await m3ShowDialog<String?>(
context:
context,
builder: (ctx) => AlertDialog(
@@ -2848,7 +2849,8 @@ class _TaskDetailScreenState extends ConsumerState<TaskDetailScreen>
child: SizedBox(
width: 280,
child: Card(
elevation: 4,
elevation: 0,
shadowColor: Colors.transparent,
child: Padding(
padding: const EdgeInsets.all(12.0),
child: Row(
@@ -3779,7 +3781,7 @@ class _TaskDetailScreenState extends ConsumerState<TaskDetailScreen>
Timer? titleTypingTimer;
try {
await showDialog<void>(
await m3ShowDialog<void>(
context: context,
builder: (dialogContext) {
var saving = false;
@@ -3999,7 +4001,7 @@ class _TaskDetailScreenState extends ConsumerState<TaskDetailScreen>
: () => Navigator.of(dialogContext).pop(),
child: const Text('Cancel'),
),
ElevatedButton(
FilledButton(
onPressed: saving
? null
: () async {
@@ -4174,7 +4176,7 @@ class _TaskDetailScreenState extends ConsumerState<TaskDetailScreen>
// If cancelling, require a reason — show dialog with spinner.
if (value == 'cancelled') {
final reasonCtrl = TextEditingController();
await showDialog<void>(
await m3ShowDialog<void>(
context: context,
builder: (dialogContext) {
var isSaving = false;
@@ -4399,7 +4401,7 @@ class _TaskDetailScreenState extends ConsumerState<TaskDetailScreen>
if (!mounted) return;
// Show loading dialog
showDialog(
m3ShowDialog(
context: context,
barrierDismissible: false,
builder: (BuildContext dialogContext) {
@@ -4543,7 +4545,7 @@ class _TaskDetailScreenState extends ConsumerState<TaskDetailScreen>
Future<void> _deleteTaskAttachment(String taskId, String fileName) async {
try {
final confirmed = await showDialog<bool>(
final confirmed = await m3ShowDialog<bool>(
context: context,
builder: (ctx) => AlertDialog(
title: const Text('Delete Attachment?'),
+2 -1
View File
@@ -2,6 +2,7 @@ import 'dart:convert';
import 'dart:typed_data';
import 'package:flutter/material.dart';
import '../../theme/m3_motion.dart';
import 'package:flutter/services.dart' show rootBundle;
import 'package:flutter_quill/flutter_quill.dart' as quill;
import 'package:pdf/widgets.dart' as pw;
@@ -495,7 +496,7 @@ Future<void> showTaskPdfPreview(
List<TaskAssignment> assignments,
List<Profile> profiles,
) async {
await showDialog<void>(
await m3ShowDialog<void>(
context: context,
builder: (ctx) => TaskPdfDialog(
task: task,
+6 -2
View File
@@ -1,6 +1,7 @@
import 'dart:async';
import 'package:flutter/material.dart';
import '../../theme/m3_motion.dart';
import 'package:flutter/services.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:flutter_typeahead/flutter_typeahead.dart';
@@ -554,7 +555,7 @@ class _TasksListScreenState extends ConsumerState<TasksListScreen>
right: 16,
bottom: 16,
child: SafeArea(
child: FloatingActionButton.extended(
child: M3ExpandedFab(
onPressed: () => _showCreateTaskDialog(context, ref),
icon: const Icon(Icons.add),
label: const Text('New Task'),
@@ -588,7 +589,7 @@ class _TasksListScreenState extends ConsumerState<TasksListScreen>
var showTitleGemini = false;
Timer? titleTypingTimer;
await showDialog<void>(
await m3ShowDialog<void>(
context: context,
builder: (dialogContext) {
bool saving = false;
@@ -1099,8 +1100,11 @@ class _StatusSummaryCard extends StatelessWidget {
_ => scheme.onSurfaceVariant,
};
// M3 Expressive: filled card with semantic tonal color, no shadow.
return Card(
color: background,
elevation: 0,
shadowColor: Colors.transparent,
// summary cards are compact — use compact token for consistent density
shape: AppSurfaces.of(context).compactShape,
child: Padding(