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