Compare commits
2
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
551ac67daa | ||
|
|
91c86d72ef |
@@ -120,15 +120,76 @@ class _AccountTile extends ConsumerWidget {
|
|||||||
final health = ref.watch(syncHealthProvider(account.id));
|
final health = ref.watch(syncHealthProvider(account.id));
|
||||||
final typeLabel = account.type == AccountType.jmap ? 'JMAP' : 'IMAP';
|
final typeLabel = account.type == AccountType.jmap ? 'JMAP' : 'IMAP';
|
||||||
|
|
||||||
return ListTile(
|
return Column(
|
||||||
leading: const Icon(Icons.account_circle),
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
title: Text(account.displayName),
|
children: [
|
||||||
subtitle: Column(
|
ListTile(
|
||||||
crossAxisAlignment: CrossAxisAlignment.start,
|
leading: const Icon(Icons.account_circle),
|
||||||
children: [
|
title: Text(account.displayName),
|
||||||
Text('${account.email}\n$typeLabel'),
|
subtitle: Text('${account.email}\n$typeLabel'),
|
||||||
const SizedBox(height: 4),
|
isThreeLine: true,
|
||||||
health.when(
|
trailing: Row(
|
||||||
|
mainAxisSize: MainAxisSize.min,
|
||||||
|
children: [
|
||||||
|
status.when(
|
||||||
|
loading: () => const SizedBox(
|
||||||
|
width: 20,
|
||||||
|
height: 20,
|
||||||
|
child: CircularProgressIndicator(strokeWidth: 2),
|
||||||
|
),
|
||||||
|
data: (_) =>
|
||||||
|
const Icon(Icons.check_circle, color: Colors.green),
|
||||||
|
error: (e, _) => Tooltip(
|
||||||
|
message: e.toString(),
|
||||||
|
child: const Icon(Icons.error_outline, color: Colors.red),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
PopupMenuButton<_AccountAction>(
|
||||||
|
onSelected: (action) => _onAction(context, action),
|
||||||
|
itemBuilder: (_) => [
|
||||||
|
const PopupMenuItem(
|
||||||
|
value: _AccountAction.syncLog,
|
||||||
|
child: Text('Sync log'),
|
||||||
|
),
|
||||||
|
const PopupMenuItem(
|
||||||
|
value: _AccountAction.verifySync,
|
||||||
|
child: Text('Verify sync health'),
|
||||||
|
),
|
||||||
|
const PopupMenuItem(
|
||||||
|
value: _AccountAction.forceSync,
|
||||||
|
child: Text('Force full sync'),
|
||||||
|
),
|
||||||
|
const PopupMenuItem(
|
||||||
|
value: _AccountAction.edit,
|
||||||
|
child: Text('Edit'),
|
||||||
|
),
|
||||||
|
if (_sieveSupported(account))
|
||||||
|
const PopupMenuItem(
|
||||||
|
value: _AccountAction.emailFiltersRemote,
|
||||||
|
child: Text('Server email filters'),
|
||||||
|
),
|
||||||
|
const PopupMenuItem(
|
||||||
|
value: _AccountAction.emailFiltersLocal,
|
||||||
|
child: Text('Local email filters'),
|
||||||
|
),
|
||||||
|
const PopupMenuItem(
|
||||||
|
value: _AccountAction.send,
|
||||||
|
child: Text('Send accounts'),
|
||||||
|
),
|
||||||
|
const PopupMenuDivider(),
|
||||||
|
const PopupMenuItem(
|
||||||
|
value: _AccountAction.delete,
|
||||||
|
child: Text('Delete'),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
onTap: () => context.push('/accounts/${account.id}/mailboxes'),
|
||||||
|
),
|
||||||
|
Padding(
|
||||||
|
padding: const EdgeInsets.fromLTRB(72, 0, 16, 8),
|
||||||
|
child: health.when(
|
||||||
data: (h) {
|
data: (h) {
|
||||||
if (h == null) return const Text('Sync health: Not verified yet');
|
if (h == null) return const Text('Sync health: Not verified yet');
|
||||||
final date = h.lastVerifiedAt.toLocal().toString().split('.')[0];
|
final date = h.lastVerifiedAt.toLocal().toString().split('.')[0];
|
||||||
@@ -141,7 +202,7 @@ class _AccountTile extends ConsumerWidget {
|
|||||||
color: h.isHealthy ? Colors.green : Colors.orange,
|
color: h.isHealthy ? Colors.green : Colors.orange,
|
||||||
),
|
),
|
||||||
const SizedBox(width: 4),
|
const SizedBox(width: 4),
|
||||||
Flexible(
|
Expanded(
|
||||||
child: Text(
|
child: Text(
|
||||||
h.isHealthy
|
h.isHealthy
|
||||||
? 'Healthy'
|
? 'Healthy'
|
||||||
@@ -155,66 +216,8 @@ class _AccountTile extends ConsumerWidget {
|
|||||||
loading: () => const Text('Sync health: checking...'),
|
loading: () => const Text('Sync health: checking...'),
|
||||||
error: (e, _) => Text('Sync health error: $e'),
|
error: (e, _) => Text('Sync health error: $e'),
|
||||||
),
|
),
|
||||||
],
|
),
|
||||||
),
|
],
|
||||||
isThreeLine: true,
|
|
||||||
trailing: Row(
|
|
||||||
mainAxisSize: MainAxisSize.min,
|
|
||||||
children: [
|
|
||||||
status.when(
|
|
||||||
loading: () => const SizedBox(
|
|
||||||
width: 20,
|
|
||||||
height: 20,
|
|
||||||
child: CircularProgressIndicator(strokeWidth: 2),
|
|
||||||
),
|
|
||||||
data: (_) => const Icon(Icons.check_circle, color: Colors.green),
|
|
||||||
error: (e, _) => Tooltip(
|
|
||||||
message: e.toString(),
|
|
||||||
child: const Icon(Icons.error_outline, color: Colors.red),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
PopupMenuButton<_AccountAction>(
|
|
||||||
onSelected: (action) => _onAction(context, action),
|
|
||||||
itemBuilder: (_) => [
|
|
||||||
const PopupMenuItem(
|
|
||||||
value: _AccountAction.syncLog,
|
|
||||||
child: Text('Sync log'),
|
|
||||||
),
|
|
||||||
const PopupMenuItem(
|
|
||||||
value: _AccountAction.verifySync,
|
|
||||||
child: Text('Verify sync health'),
|
|
||||||
),
|
|
||||||
const PopupMenuItem(
|
|
||||||
value: _AccountAction.forceSync,
|
|
||||||
child: Text('Force full sync'),
|
|
||||||
),
|
|
||||||
const PopupMenuItem(
|
|
||||||
value: _AccountAction.edit,
|
|
||||||
child: Text('Edit'),
|
|
||||||
),
|
|
||||||
if (_sieveSupported(account))
|
|
||||||
const PopupMenuItem(
|
|
||||||
value: _AccountAction.emailFiltersRemote,
|
|
||||||
child: Text('Server email filters'),
|
|
||||||
),
|
|
||||||
const PopupMenuItem(
|
|
||||||
value: _AccountAction.emailFiltersLocal,
|
|
||||||
child: Text('Local email filters'),
|
|
||||||
),
|
|
||||||
const PopupMenuItem(
|
|
||||||
value: _AccountAction.send,
|
|
||||||
child: Text('Send accounts'),
|
|
||||||
),
|
|
||||||
const PopupMenuDivider(),
|
|
||||||
const PopupMenuItem(
|
|
||||||
value: _AccountAction.delete,
|
|
||||||
child: Text('Delete'),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
onTap: () => context.push('/accounts/${account.id}/mailboxes'),
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -912,9 +912,11 @@ def _run_loop() -> int:
|
|||||||
if not m:
|
if not m:
|
||||||
continue
|
continue
|
||||||
issue_num = int(m.group(1))
|
issue_num = int(m.group(1))
|
||||||
labels = _get_issue_labels(issue_num)
|
try:
|
||||||
if not labels:
|
issue_data = _tea_get(f"/repos/{REPO}/issues/{issue_num}")
|
||||||
# Issue is likely already closed — skip.
|
except RuntimeError:
|
||||||
|
continue
|
||||||
|
if issue_data.get("state") != "open":
|
||||||
continue
|
continue
|
||||||
pr_number = pr["number"]
|
pr_number = pr["number"]
|
||||||
print(f"Catch-up (merged PR): PR #{pr_number} for issue #{issue_num} was merged — closing.")
|
print(f"Catch-up (merged PR): PR #{pr_number} for issue #{issue_num} was merged — closing.")
|
||||||
|
|||||||
@@ -252,5 +252,29 @@ void main() {
|
|||||||
expect(find.textContaining('flag mismatches: 1'), findsOneWidget);
|
expect(find.textContaining('flag mismatches: 1'), findsOneWidget);
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
|
testWidgets(
|
||||||
|
'sync health row is positioned below the account name row',
|
||||||
|
(tester) async {
|
||||||
|
await tester.pumpWidget(
|
||||||
|
buildApp(
|
||||||
|
initialLocation: '/accounts',
|
||||||
|
overrides: baseOverrides(
|
||||||
|
accounts: [kTestAccount],
|
||||||
|
syncHealth: SyncHealthRow(
|
||||||
|
accountId: kTestAccount.id,
|
||||||
|
lastVerifiedAt: DateTime(2024, 6),
|
||||||
|
isHealthy: true,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
await tester.pumpAndSettle();
|
||||||
|
|
||||||
|
final namePos = tester.getTopLeft(find.text('Alice')).dy;
|
||||||
|
final healthPos = tester.getTopLeft(find.textContaining('Healthy')).dy;
|
||||||
|
expect(healthPos, greaterThan(namePos));
|
||||||
|
},
|
||||||
|
);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user