mirror of
https://github.com/GopeedLab/gopeed.git
synced 2026-11-13 11:53:41 +00:00
perf(extensions): load store summaries and check updates asynchronously (#1583)
This commit is contained in:
41 files changed
+1567
-257
No files matched your search
@@ -0,0 +1,217 @@
|
||||
import 'package:flutter/widgets.dart';
|
||||
|
||||
import '../theme/app_palette.dart';
|
||||
|
||||
enum AppEmptyIllustrationType { inbox, puzzle, search, connectionError, documentError }
|
||||
|
||||
/// Context-specific drawings share the same muted colors and rounded strokes.
|
||||
class AppEmptyIllustration extends StatelessWidget {
|
||||
const AppEmptyIllustration({super.key, required this.type});
|
||||
|
||||
final AppEmptyIllustrationType type;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final palette = AppPalette.of(context);
|
||||
return CustomPaint(
|
||||
size: const Size(148, 108),
|
||||
painter: type == AppEmptyIllustrationType.inbox
|
||||
? _InboxIllustrationPainter(palette: palette)
|
||||
: _ContextIllustrationPainter(palette: palette, type: type),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class _ContextIllustrationPainter extends CustomPainter {
|
||||
const _ContextIllustrationPainter({required this.palette, required this.type});
|
||||
|
||||
final AppPalette palette;
|
||||
final AppEmptyIllustrationType type;
|
||||
|
||||
Paint get _outline => Paint()
|
||||
..color = palette.textSecondary.withValues(alpha: 0.72)
|
||||
..style = PaintingStyle.stroke
|
||||
..strokeWidth = 1.8
|
||||
..strokeCap = StrokeCap.round
|
||||
..strokeJoin = StrokeJoin.round;
|
||||
|
||||
Paint get _detail => Paint()
|
||||
..color = palette.textMuted.withValues(alpha: 0.34)
|
||||
..style = PaintingStyle.stroke
|
||||
..strokeWidth = 2
|
||||
..strokeCap = StrokeCap.round;
|
||||
|
||||
Paint get _fill => Paint()..color = palette.surfaceSoft;
|
||||
|
||||
@override
|
||||
void paint(Canvas canvas, Size size) {
|
||||
canvas.save();
|
||||
canvas.scale(size.width / 148, size.height / 108);
|
||||
switch (type) {
|
||||
case AppEmptyIllustrationType.puzzle:
|
||||
_paintPuzzle(canvas);
|
||||
case AppEmptyIllustrationType.search:
|
||||
_paintSearch(canvas);
|
||||
case AppEmptyIllustrationType.connectionError:
|
||||
_paintConnectionError(canvas);
|
||||
case AppEmptyIllustrationType.documentError:
|
||||
_paintDocumentError(canvas);
|
||||
case AppEmptyIllustrationType.inbox:
|
||||
break;
|
||||
}
|
||||
canvas.restore();
|
||||
}
|
||||
|
||||
void _paintPuzzle(Canvas canvas) {
|
||||
canvas.translate(9, 0);
|
||||
final piece = Path()
|
||||
..moveTo(42, 29)
|
||||
..lineTo(62, 29)
|
||||
..cubicTo(55, 10, 86, 10, 79, 29)
|
||||
..lineTo(98, 29)
|
||||
..quadraticBezierTo(104, 29, 104, 35)
|
||||
..lineTo(104, 49)
|
||||
..cubicTo(84, 42, 84, 73, 104, 66)
|
||||
..lineTo(104, 86)
|
||||
..quadraticBezierTo(104, 92, 98, 92)
|
||||
..lineTo(79, 92)
|
||||
..cubicTo(86, 73, 55, 73, 62, 92)
|
||||
..lineTo(42, 92)
|
||||
..quadraticBezierTo(36, 92, 36, 86)
|
||||
..lineTo(36, 66)
|
||||
..cubicTo(17, 73, 17, 42, 36, 49)
|
||||
..lineTo(36, 35)
|
||||
..quadraticBezierTo(36, 29, 42, 29)
|
||||
..close();
|
||||
canvas.drawPath(piece, _fill);
|
||||
canvas.drawPath(piece, _outline);
|
||||
}
|
||||
|
||||
void _paintSearch(Canvas canvas) {
|
||||
final lens = const Offset(64, 45);
|
||||
canvas.drawCircle(lens, 29, _fill);
|
||||
canvas.drawCircle(lens, 29, _outline);
|
||||
canvas.drawLine(const Offset(85, 67), const Offset(115, 96), _outline..strokeWidth = 4);
|
||||
canvas.drawLine(const Offset(53, 45), const Offset(75, 45), _detail);
|
||||
canvas.drawLine(const Offset(27, 85), const Offset(41, 85), _detail);
|
||||
canvas.drawCircle(const Offset(112, 23), 3, Paint()..color = palette.border);
|
||||
}
|
||||
|
||||
void _paintConnectionError(Canvas canvas) {
|
||||
final cloud = Path()
|
||||
..moveTo(40, 70)
|
||||
..cubicTo(21, 70, 19, 43, 39, 41)
|
||||
..cubicTo(40, 14, 77, 8, 91, 32)
|
||||
..cubicTo(111, 23, 129, 40, 121, 56)
|
||||
..cubicTo(133, 66, 119, 79, 108, 74)
|
||||
..lineTo(40, 74)
|
||||
..close();
|
||||
canvas.drawPath(cloud, _fill);
|
||||
canvas.drawPath(cloud, _outline);
|
||||
canvas.drawLine(const Offset(74, 74), const Offset(74, 82), _detail);
|
||||
canvas.drawLine(const Offset(48, 96), const Offset(63, 96), _outline);
|
||||
canvas.drawLine(const Offset(86, 96), const Offset(101, 96), _outline);
|
||||
canvas.drawLine(const Offset(71, 91), const Offset(77, 101), _detail);
|
||||
canvas.drawCircle(const Offset(45, 96), 2, _fill);
|
||||
canvas.drawCircle(const Offset(104, 96), 2, _fill);
|
||||
}
|
||||
|
||||
void _paintDocumentError(Canvas canvas) {
|
||||
final document = Path()
|
||||
..moveTo(47, 12)
|
||||
..lineTo(89, 12)
|
||||
..lineTo(107, 30)
|
||||
..lineTo(107, 89)
|
||||
..quadraticBezierTo(107, 96, 100, 96)
|
||||
..lineTo(47, 96)
|
||||
..quadraticBezierTo(40, 96, 40, 89)
|
||||
..lineTo(40, 19)
|
||||
..quadraticBezierTo(40, 12, 47, 12)
|
||||
..close();
|
||||
canvas.drawPath(document, _fill);
|
||||
canvas.drawPath(document, _outline);
|
||||
canvas.drawPath(
|
||||
Path()
|
||||
..moveTo(89, 12)
|
||||
..lineTo(89, 30)
|
||||
..lineTo(107, 30),
|
||||
_detail,
|
||||
);
|
||||
for (final y in [43.0, 56.0, 69.0]) {
|
||||
canvas.drawLine(Offset(53, y), Offset(y == 69 ? 74 : 91, y), _detail);
|
||||
}
|
||||
canvas.drawCircle(const Offset(107, 85), 16, Paint()..color = palette.cardBg);
|
||||
canvas.drawCircle(const Offset(107, 85), 16, _outline);
|
||||
canvas.drawLine(const Offset(107, 77), const Offset(107, 86), _outline);
|
||||
canvas.drawCircle(const Offset(107, 92), 1.2, Paint()..color = palette.textSecondary.withValues(alpha: 0.72));
|
||||
}
|
||||
|
||||
@override
|
||||
bool shouldRepaint(_ContextIllustrationPainter oldDelegate) =>
|
||||
oldDelegate.palette != palette || oldDelegate.type != type;
|
||||
}
|
||||
|
||||
class _InboxIllustrationPainter extends CustomPainter {
|
||||
const _InboxIllustrationPainter({required this.palette});
|
||||
|
||||
final AppPalette palette;
|
||||
|
||||
@override
|
||||
void paint(Canvas canvas, Size size) {
|
||||
final borderPaint = Paint()
|
||||
..color = palette.border
|
||||
..style = PaintingStyle.stroke
|
||||
..strokeWidth = 1.4;
|
||||
final sheetRect = RRect.fromRectAndRadius(Rect.fromLTWH(size.width / 2 - 34, 6, 68, 72), const Radius.circular(7));
|
||||
|
||||
canvas.drawRRect(sheetRect.shift(const Offset(0, 3)), Paint()..color = palette.textMuted.withValues(alpha: 0.06));
|
||||
canvas.drawRRect(sheetRect, Paint()..color = palette.cardBg);
|
||||
canvas.drawRRect(sheetRect, borderPaint);
|
||||
|
||||
final rowPaint = Paint()
|
||||
..color = palette.textMuted.withValues(alpha: 0.34)
|
||||
..strokeWidth = 2
|
||||
..strokeCap = StrokeCap.round;
|
||||
final centerX = size.width / 2;
|
||||
for (var row = 0; row < 2; row++) {
|
||||
final y = 20.0 + row * 14;
|
||||
canvas.drawCircle(Offset(centerX - 22, y), 2.5, Paint()..color = palette.surfaceSoft);
|
||||
canvas.drawLine(Offset(centerX - 14, y), Offset(centerX + 21, y), rowPaint);
|
||||
}
|
||||
|
||||
final emptyBadgePaint = Paint()
|
||||
..color = palette.surfaceSoft
|
||||
..style = PaintingStyle.fill;
|
||||
canvas.drawCircle(Offset(centerX, 56), 11, emptyBadgePaint);
|
||||
canvas.drawCircle(Offset(centerX, 56), 11, borderPaint);
|
||||
canvas.drawLine(Offset(centerX - 4, 56), Offset(centerX + 4, 56), rowPaint);
|
||||
|
||||
final trayPath = Path()
|
||||
..moveTo(26, 63)
|
||||
..lineTo(49, 63)
|
||||
..lineTo(57, 75)
|
||||
..quadraticBezierTo(59, 78, 63, 78)
|
||||
..lineTo(85, 78)
|
||||
..quadraticBezierTo(89, 78, 91, 75)
|
||||
..lineTo(99, 63)
|
||||
..lineTo(122, 63)
|
||||
..lineTo(115, 96)
|
||||
..quadraticBezierTo(114, 101, 108, 101)
|
||||
..lineTo(40, 101)
|
||||
..quadraticBezierTo(34, 101, 33, 96)
|
||||
..close();
|
||||
canvas.drawPath(trayPath, Paint()..color = palette.surfaceSoft);
|
||||
final trayPaint = Paint()
|
||||
..color = palette.textSecondary.withValues(alpha: 0.72)
|
||||
..style = PaintingStyle.stroke
|
||||
..strokeWidth = 1.8
|
||||
..strokeCap = StrokeCap.round
|
||||
..strokeJoin = StrokeJoin.round;
|
||||
canvas.drawPath(trayPath, trayPaint);
|
||||
}
|
||||
|
||||
@override
|
||||
bool shouldRepaint(_InboxIllustrationPainter oldDelegate) {
|
||||
return oldDelegate.palette != palette;
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user