Your avatar is your photo, picked from the device by tapping it on Home or from a new Profile photo row in Settings, shrunk to 256 px and kept on the phone (there is no upload endpoint yet). Group members show the photo the server sends in a new `photo` field, everywhere avatars appear. Without a photo, an initial on a neutral disc. Mock mode bundles free Unsplash portraits for the sample people. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01KhQh614DMeYoQEH9SoMRUw
40 lines
1.0 KiB
Dart
40 lines
1.0 KiB
Dart
import 'package:flutter/material.dart';
|
|
|
|
/// A dashed rounded-rectangle outline: the target a bar is measured against.
|
|
class DashedOutline extends CustomPainter {
|
|
final Color color;
|
|
|
|
final double radius;
|
|
|
|
const DashedOutline({required this.color, this.radius = 10});
|
|
|
|
@override
|
|
void paint(Canvas canvas, Size size) {
|
|
if (size.height <= 0) {
|
|
return;
|
|
}
|
|
final Paint paint = Paint()
|
|
..color = color
|
|
..style = PaintingStyle.stroke
|
|
..strokeWidth = 1.2;
|
|
|
|
final Path outline = Path()
|
|
..addRRect(
|
|
RRect.fromRectAndRadius(Offset.zero & size, Radius.circular(radius)));
|
|
|
|
const double dash = 4;
|
|
const double gap = 3;
|
|
for (final metric in outline.computeMetrics()) {
|
|
double distance = 0;
|
|
while (distance < metric.length) {
|
|
canvas.drawPath(metric.extractPath(distance, distance + dash), paint);
|
|
distance = distance + dash + gap;
|
|
}
|
|
}
|
|
}
|
|
|
|
@override
|
|
bool shouldRepaint(DashedOutline oldDelegate) =>
|
|
oldDelegate.color != color || oldDelegate.radius != radius;
|
|
}
|