Line data Source code
1 : import 'dart:io';
2 : import 'dart:math';
3 :
4 : import 'package:cwtch/cwtch_icons_icons.dart';
5 : import 'package:flutter/material.dart';
6 : import 'package:cwtch/themes/opaque.dart';
7 : import 'package:provider/provider.dart';
8 :
9 : import '../settings.dart';
10 :
11 : class ProfileImage extends StatefulWidget {
12 1 : ProfileImage(
13 : {required this.imagePath,
14 : required this.diameter,
15 : required this.border,
16 : this.badgeCount = 0,
17 : required this.badgeColor,
18 : required this.badgeTextColor,
19 : this.maskOut = false,
20 : this.tooltip = "",
21 : this.disabled = false,
22 : this.badgeEdit = false,
23 : this.badgeIcon});
24 : final double diameter;
25 : final String imagePath;
26 : final Color border;
27 : final int badgeCount;
28 : final Color badgeColor;
29 : final Color badgeTextColor;
30 : final bool maskOut;
31 : final bool disabled;
32 : final bool badgeEdit;
33 : final String tooltip;
34 : final Widget? badgeIcon;
35 :
36 1 : @override
37 1 : _ProfileImageState createState() => _ProfileImageState();
38 : }
39 :
40 : class _ProfileImageState extends State<ProfileImage> {
41 1 : @override
42 : Widget build(BuildContext context) {
43 3 : var file = new File(widget.imagePath);
44 1 : var image = Image.file(
45 : file,
46 4 : cacheWidth: (4 * widget.diameter.floor()),
47 : filterQuality: FilterQuality.medium,
48 : fit: BoxFit.cover,
49 : alignment: Alignment.center,
50 : // We need some theme specific blending here...we might want to consider making this a theme level attribute
51 2 : colorBlendMode: !widget.maskOut
52 4 : ? Provider.of<Settings>(context).theme.mode == mode_dark
53 : ? BlendMode.softLight
54 : : BlendMode.darken
55 : : BlendMode.srcOut,
56 3 : color: Provider.of<Settings>(context).theme.portraitBackgroundColor,
57 : isAntiAlias: false,
58 2 : width: widget.diameter,
59 2 : height: widget.diameter,
60 0 : errorBuilder: (context, error, stackTrace) {
61 : // on android the above will fail for asset images, in which case try to load them the original way
62 0 : return Image.asset(widget.imagePath,
63 : filterQuality: FilterQuality.medium,
64 : // We need some theme specific blending here...we might want to consider making this a theme level attribute
65 0 : colorBlendMode: !widget.maskOut
66 0 : ? Provider.of<Settings>(context).theme.mode == mode_dark
67 : ? BlendMode.softLight
68 : : BlendMode.darken
69 : : BlendMode.srcOut,
70 0 : color: Provider.of<Settings>(context).theme.portraitBackgroundColor,
71 : isAntiAlias: true,
72 0 : width: widget.diameter,
73 0 : height: widget.diameter);
74 : },
75 : );
76 :
77 1 : return RepaintBoundary(
78 2 : child: Stack(children: [
79 1 : ClipOval(
80 : clipBehavior: Clip.antiAlias,
81 1 : child: Container(
82 2 : width: widget.diameter,
83 2 : height: widget.diameter,
84 2 : color: widget.border,
85 2 : foregroundDecoration: widget.disabled
86 0 : ? BoxDecoration(
87 0 : color: Provider.of<Settings>(context).theme.portraitBackgroundColor, //Colors.grey,
88 : backgroundBlendMode: BlendMode.color, //saturation,
89 : )
90 : : null,
91 1 : child: Padding(
92 : padding: const EdgeInsets.all(2.0), //border size
93 4 : child: ClipOval(clipBehavior: Clip.antiAlias, child: widget.tooltip == "" ? image : Tooltip(message: widget.tooltip, child: image))))),
94 : // badge
95 1 : Visibility(
96 7 : visible: widget.badgeIcon != null || widget.badgeEdit || widget.badgeCount > 0,
97 1 : child: Positioned(
98 : bottom: 0.0,
99 : right: 0.0,
100 1 : child: CircleAvatar(
101 3 : radius: max(10.0, widget.diameter / 6.0),
102 2 : backgroundColor: widget.badgeColor,
103 2 : child: widget.badgeEdit
104 0 : ? Icon(
105 : Icons.edit,
106 0 : color: widget.badgeTextColor,
107 : )
108 12 : : (widget.badgeIcon != null ? widget.badgeIcon : Text(widget.badgeCount > 99 ? "99+" : widget.badgeCount.toString(), style: TextStyle(color: widget.badgeTextColor, fontSize: 8.0))),
109 : ),
110 : )),
111 : // disabled center icon
112 1 : Visibility(
113 2 : visible: widget.disabled,
114 1 : child: Container(
115 2 : width: widget.diameter,
116 2 : height: widget.diameter,
117 1 : child: Center(
118 1 : child: Icon(
119 : CwtchIcons.negative_heart_24px,
120 3 : size: widget.diameter / 1.5,
121 3 : color: Provider.of<Settings>(context).theme.portraitOfflineBorderColor,
122 : )))),
123 : ]));
124 : }
125 : }
|