✨ Profile decoration
This commit is contained in:
@@ -16,6 +16,7 @@ import 'package:island/widgets/account/leveling_progress.dart';
|
|||||||
import 'package:island/widgets/alert.dart';
|
import 'package:island/widgets/alert.dart';
|
||||||
import 'package:island/widgets/app_scaffold.dart';
|
import 'package:island/widgets/app_scaffold.dart';
|
||||||
import 'package:island/widgets/content/cloud_files.dart';
|
import 'package:island/widgets/content/cloud_files.dart';
|
||||||
|
import 'package:island/widgets/content/profile_decoration.dart';
|
||||||
import 'package:island/widgets/debug_sheet.dart';
|
import 'package:island/widgets/debug_sheet.dart';
|
||||||
import 'package:material_symbols_icons/symbols.dart';
|
import 'package:material_symbols_icons/symbols.dart';
|
||||||
import 'package:styled_widget/styled_widget.dart';
|
import 'package:styled_widget/styled_widget.dart';
|
||||||
@@ -98,6 +99,10 @@ class AccountScreen extends HookConsumerWidget {
|
|||||||
child: ProfilePictureWidget(
|
child: ProfilePictureWidget(
|
||||||
file: user.value?.profile.picture,
|
file: user.value?.profile.picture,
|
||||||
radius: 32,
|
radius: 32,
|
||||||
|
decoration: ProfileDecoration(
|
||||||
|
text: '#OpenToWork',
|
||||||
|
color: Colors.green,
|
||||||
|
),
|
||||||
),
|
),
|
||||||
onTap: () {
|
onTap: () {
|
||||||
context.pushNamed(
|
context.pushNamed(
|
||||||
@@ -331,8 +336,7 @@ class AccountScreen extends HookConsumerWidget {
|
|||||||
if (availableWidth > totalMin) {
|
if (availableWidth > totalMin) {
|
||||||
return Row(
|
return Row(
|
||||||
spacing: 8,
|
spacing: 8,
|
||||||
children:
|
children: children
|
||||||
children
|
|
||||||
.map((child) => Expanded(child: child))
|
.map((child) => Expanded(child: child))
|
||||||
.toList(),
|
.toList(),
|
||||||
).padding(horizontal: 12).height(48);
|
).padding(horizontal: 12).height(48);
|
||||||
@@ -341,8 +345,7 @@ class AccountScreen extends HookConsumerWidget {
|
|||||||
scrollDirection: Axis.horizontal,
|
scrollDirection: Axis.horizontal,
|
||||||
child: Row(
|
child: Row(
|
||||||
spacing: 8,
|
spacing: 8,
|
||||||
children:
|
children: children
|
||||||
children
|
|
||||||
.map(
|
.map(
|
||||||
(child) =>
|
(child) =>
|
||||||
SizedBox(width: minWidth, child: child),
|
SizedBox(width: minWidth, child: child),
|
||||||
@@ -495,8 +498,7 @@ class _UnauthorizedAccountScreen extends StatelessWidget {
|
|||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return AppScaffold(
|
return AppScaffold(
|
||||||
appBar: AppBar(title: const Text('account').tr()),
|
appBar: AppBar(title: const Text('account').tr()),
|
||||||
body:
|
body: ConstrainedBox(
|
||||||
ConstrainedBox(
|
|
||||||
constraints: const BoxConstraints(maxWidth: 360),
|
constraints: const BoxConstraints(maxWidth: 360),
|
||||||
child: Column(
|
child: Column(
|
||||||
crossAxisAlignment: CrossAxisAlignment.stretch,
|
crossAxisAlignment: CrossAxisAlignment.stretch,
|
||||||
|
|||||||
@@ -9,8 +9,11 @@ import 'package:island/models/file.dart';
|
|||||||
import 'package:island/pods/config.dart';
|
import 'package:island/pods/config.dart';
|
||||||
import 'package:island/services/time.dart';
|
import 'package:island/services/time.dart';
|
||||||
import 'package:island/utils/format.dart';
|
import 'package:island/utils/format.dart';
|
||||||
|
import 'package:island/widgets/content/profile_decoration.dart';
|
||||||
import 'package:material_symbols_icons/symbols.dart';
|
import 'package:material_symbols_icons/symbols.dart';
|
||||||
import 'package:styled_widget/styled_widget.dart';
|
import 'package:styled_widget/styled_widget.dart';
|
||||||
|
import 'dart:math' as math;
|
||||||
|
import 'dart:ui' as ui;
|
||||||
import 'package:island/widgets/data_saving_gate.dart';
|
import 'package:island/widgets/data_saving_gate.dart';
|
||||||
|
|
||||||
import 'file_viewer_contents.dart';
|
import 'file_viewer_contents.dart';
|
||||||
@@ -258,15 +261,13 @@ class CloudFileWidget extends HookConsumerWidget {
|
|||||||
var content = switch (item.mimeType?.split('/').firstOrNull) {
|
var content = switch (item.mimeType?.split('/').firstOrNull) {
|
||||||
'image' => AspectRatio(
|
'image' => AspectRatio(
|
||||||
aspectRatio: ratio,
|
aspectRatio: ratio,
|
||||||
child:
|
child: (useInternalGate && dataSaving && !unlocked.value)
|
||||||
(useInternalGate && dataSaving && !unlocked.value)
|
|
||||||
? dataPlaceHolder(Symbols.image)
|
? dataPlaceHolder(Symbols.image)
|
||||||
: cloudImage(),
|
: cloudImage(),
|
||||||
),
|
),
|
||||||
'video' => AspectRatio(
|
'video' => AspectRatio(
|
||||||
aspectRatio: ratio,
|
aspectRatio: ratio,
|
||||||
child:
|
child: (useInternalGate && dataSaving && !unlocked.value)
|
||||||
(useInternalGate && dataSaving && !unlocked.value)
|
|
||||||
? dataPlaceHolder(Symbols.play_arrow)
|
? dataPlaceHolder(Symbols.play_arrow)
|
||||||
: cloudVideo(),
|
: cloudVideo(),
|
||||||
),
|
),
|
||||||
@@ -383,8 +384,7 @@ class CloudVideoWidget extends HookConsumerWidget {
|
|||||||
final serverUrl = ref.watch(serverUrlProvider);
|
final serverUrl = ref.watch(serverUrlProvider);
|
||||||
final uri = '$serverUrl/drive/files/${item.id}';
|
final uri = '$serverUrl/drive/files/${item.id}';
|
||||||
|
|
||||||
var ratio =
|
var ratio = item.fileMeta?['ratio'] is num
|
||||||
item.fileMeta?['ratio'] is num
|
|
||||||
? item.fileMeta!['ratio'].toDouble()
|
? item.fileMeta!['ratio'].toDouble()
|
||||||
: 1.0;
|
: 1.0;
|
||||||
if (ratio == 0) ratio = 1.0;
|
if (ratio == 0) ratio = 1.0;
|
||||||
@@ -533,8 +533,7 @@ class CloudImageWidget extends ConsumerWidget {
|
|||||||
|
|
||||||
return AspectRatio(
|
return AspectRatio(
|
||||||
aspectRatio: aspectRatio,
|
aspectRatio: aspectRatio,
|
||||||
child:
|
child: file != null
|
||||||
file != null
|
|
||||||
? CloudFileWidget(item: file!, fit: fit)
|
? CloudFileWidget(item: file!, fit: fit)
|
||||||
: UniversalImage(uri: uri, blurHash: blurHash, fit: fit),
|
: UniversalImage(uri: uri, blurHash: blurHash, fit: fit),
|
||||||
);
|
);
|
||||||
@@ -545,8 +544,7 @@ class CloudImageWidget extends ConsumerWidget {
|
|||||||
required String serverUrl,
|
required String serverUrl,
|
||||||
bool original = false,
|
bool original = false,
|
||||||
}) {
|
}) {
|
||||||
final uri =
|
final uri = original
|
||||||
original
|
|
||||||
? '$serverUrl/drive/files/$fileId?original=true'
|
? '$serverUrl/drive/files/$fileId?original=true'
|
||||||
: '$serverUrl/drive/files/$fileId';
|
: '$serverUrl/drive/files/$fileId';
|
||||||
return CachedNetworkImageProvider(uri);
|
return CachedNetworkImageProvider(uri);
|
||||||
@@ -560,6 +558,7 @@ class ProfilePictureWidget extends ConsumerWidget {
|
|||||||
final double? borderRadius;
|
final double? borderRadius;
|
||||||
final IconData? fallbackIcon;
|
final IconData? fallbackIcon;
|
||||||
final Color? fallbackColor;
|
final Color? fallbackColor;
|
||||||
|
final ProfileDecoration? decoration;
|
||||||
const ProfilePictureWidget({
|
const ProfilePictureWidget({
|
||||||
super.key,
|
super.key,
|
||||||
this.fileId,
|
this.fileId,
|
||||||
@@ -568,6 +567,7 @@ class ProfilePictureWidget extends ConsumerWidget {
|
|||||||
this.borderRadius,
|
this.borderRadius,
|
||||||
this.fallbackIcon,
|
this.fallbackIcon,
|
||||||
this.fallbackColor,
|
this.fallbackColor,
|
||||||
|
this.decoration,
|
||||||
});
|
});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
@@ -575,36 +575,49 @@ class ProfilePictureWidget extends ConsumerWidget {
|
|||||||
final serverUrl = ref.watch(serverUrlProvider);
|
final serverUrl = ref.watch(serverUrlProvider);
|
||||||
final String? id = file?.id ?? fileId;
|
final String? id = file?.id ?? fileId;
|
||||||
|
|
||||||
final fallback =
|
final fallback = Icon(
|
||||||
Icon(
|
|
||||||
fallbackIcon ?? Symbols.account_circle,
|
fallbackIcon ?? Symbols.account_circle,
|
||||||
size: radius,
|
size: radius,
|
||||||
color:
|
color: fallbackColor ?? Theme.of(context).colorScheme.onPrimaryContainer,
|
||||||
fallbackColor ?? Theme.of(context).colorScheme.onPrimaryContainer,
|
|
||||||
).center();
|
).center();
|
||||||
|
|
||||||
return ClipRRect(
|
final image = id == null
|
||||||
borderRadius:
|
|
||||||
borderRadius == null
|
|
||||||
? BorderRadius.all(Radius.circular(radius))
|
|
||||||
: BorderRadius.all(Radius.circular(borderRadius!)),
|
|
||||||
child: Container(
|
|
||||||
width: radius * 2,
|
|
||||||
height: radius * 2,
|
|
||||||
color: Theme.of(context).colorScheme.primaryContainer,
|
|
||||||
child:
|
|
||||||
id == null
|
|
||||||
? fallback
|
? fallback
|
||||||
: DataSavingGate(
|
: DataSavingGate(
|
||||||
bypass: true,
|
bypass: true,
|
||||||
placeholder: fallback,
|
placeholder: fallback,
|
||||||
content:
|
content: () => UniversalImage(
|
||||||
() => UniversalImage(
|
|
||||||
uri: '$serverUrl/drive/files/$id',
|
uri: '$serverUrl/drive/files/$id',
|
||||||
fit: BoxFit.cover,
|
fit: BoxFit.cover,
|
||||||
),
|
),
|
||||||
|
);
|
||||||
|
|
||||||
|
Widget content = Container(
|
||||||
|
width: radius * 2,
|
||||||
|
height: radius * 2,
|
||||||
|
color: Theme.of(context).colorScheme.primaryContainer,
|
||||||
|
child: decoration != null
|
||||||
|
? Stack(
|
||||||
|
fit: StackFit.expand,
|
||||||
|
children: [
|
||||||
|
image,
|
||||||
|
CustomPaint(
|
||||||
|
painter: _ProfileDecorationPainter(
|
||||||
|
text: decoration!.text,
|
||||||
|
color: decoration!.color,
|
||||||
|
textColor: decoration!.textColor ?? Colors.white,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
],
|
||||||
|
)
|
||||||
|
: image,
|
||||||
|
);
|
||||||
|
|
||||||
|
return ClipRRect(
|
||||||
|
borderRadius: borderRadius == null
|
||||||
|
? BorderRadius.all(Radius.circular(radius))
|
||||||
|
: BorderRadius.all(Radius.circular(borderRadius!)),
|
||||||
|
child: content,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -716,11 +729,9 @@ class SplitAvatarWidget extends ConsumerWidget {
|
|||||||
),
|
),
|
||||||
),
|
),
|
||||||
Expanded(
|
Expanded(
|
||||||
child:
|
child: filesId.length > 4
|
||||||
filesId.length > 4
|
|
||||||
? Container(
|
? Container(
|
||||||
color:
|
color: Theme.of(
|
||||||
Theme.of(
|
|
||||||
context,
|
context,
|
||||||
).colorScheme.primaryContainer,
|
).colorScheme.primaryContainer,
|
||||||
child: Center(
|
child: Center(
|
||||||
@@ -728,8 +739,7 @@ class SplitAvatarWidget extends ConsumerWidget {
|
|||||||
'+${filesId.length - 3}',
|
'+${filesId.length - 3}',
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
fontSize: radius * 0.4,
|
fontSize: radius * 0.4,
|
||||||
color:
|
color: Theme.of(
|
||||||
Theme.of(
|
|
||||||
context,
|
context,
|
||||||
).colorScheme.onPrimaryContainer,
|
).colorScheme.onPrimaryContainer,
|
||||||
),
|
),
|
||||||
@@ -765,13 +775,11 @@ class SplitAvatarWidget extends ConsumerWidget {
|
|||||||
width: radius,
|
width: radius,
|
||||||
height: radius,
|
height: radius,
|
||||||
color: Theme.of(context).colorScheme.primaryContainer,
|
color: Theme.of(context).colorScheme.primaryContainer,
|
||||||
child:
|
child: Icon(
|
||||||
Icon(
|
|
||||||
fallbackIcon,
|
fallbackIcon,
|
||||||
size: radius * 0.6,
|
size: radius * 0.6,
|
||||||
color:
|
color:
|
||||||
fallbackColor ??
|
fallbackColor ?? Theme.of(context).colorScheme.onPrimaryContainer,
|
||||||
Theme.of(context).colorScheme.onPrimaryContainer,
|
|
||||||
).center(),
|
).center(),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -786,3 +794,106 @@ class SplitAvatarWidget extends ConsumerWidget {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class _ProfileDecorationPainter extends CustomPainter {
|
||||||
|
final String text;
|
||||||
|
final Color color;
|
||||||
|
final Color textColor;
|
||||||
|
|
||||||
|
_ProfileDecorationPainter({
|
||||||
|
required this.text,
|
||||||
|
required this.color,
|
||||||
|
required this.textColor,
|
||||||
|
});
|
||||||
|
|
||||||
|
@override
|
||||||
|
void paint(Canvas canvas, Size size) {
|
||||||
|
if (text.isEmpty) return;
|
||||||
|
|
||||||
|
final radius = size.width / 2;
|
||||||
|
final center = Offset(size.width / 2, size.height / 2);
|
||||||
|
|
||||||
|
final strokeWidth = radius * 0.4; // Increased thickness
|
||||||
|
final centerAngle = 3 * math.pi / 4;
|
||||||
|
final sweepAngle = math.pi / 1;
|
||||||
|
final startAngle = centerAngle - (sweepAngle / 2);
|
||||||
|
|
||||||
|
final arcRadius = radius - (strokeWidth / 2);
|
||||||
|
final rect = Rect.fromCircle(center: center, radius: arcRadius);
|
||||||
|
|
||||||
|
final paint = Paint()
|
||||||
|
..style = PaintingStyle.stroke
|
||||||
|
..strokeWidth = strokeWidth
|
||||||
|
..shader = SweepGradient(
|
||||||
|
startAngle: startAngle,
|
||||||
|
endAngle: startAngle + sweepAngle,
|
||||||
|
colors: [color.withOpacity(0), color, color, color.withOpacity(0)],
|
||||||
|
stops: const [0.0, 0.25, 0.75, 1.0],
|
||||||
|
).createShader(rect);
|
||||||
|
|
||||||
|
canvas.drawArc(rect, startAngle, sweepAngle, false, paint);
|
||||||
|
|
||||||
|
_drawTextOnArc(canvas, center, arcRadius, text, centerAngle);
|
||||||
|
}
|
||||||
|
|
||||||
|
void _drawTextOnArc(
|
||||||
|
Canvas canvas,
|
||||||
|
Offset center,
|
||||||
|
double radius,
|
||||||
|
String text,
|
||||||
|
double centerAngle,
|
||||||
|
) {
|
||||||
|
final textStyle = TextStyle(
|
||||||
|
color: textColor,
|
||||||
|
fontSize: radius * 0.28,
|
||||||
|
fontWeight: FontWeight.bold,
|
||||||
|
);
|
||||||
|
|
||||||
|
double totalAngle = 0;
|
||||||
|
List<double> charAngles = [];
|
||||||
|
|
||||||
|
// Calculate total angle occupied by text
|
||||||
|
for (int i = 0; i < text.length; i++) {
|
||||||
|
final char = text[i];
|
||||||
|
final span = TextSpan(text: char, style: textStyle);
|
||||||
|
final tp = TextPainter(text: span, textDirection: ui.TextDirection.ltr);
|
||||||
|
tp.layout();
|
||||||
|
final charWidth = tp.width;
|
||||||
|
final angle = charWidth / radius;
|
||||||
|
charAngles.add(angle);
|
||||||
|
totalAngle += angle;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Start from "Left" of the center (High angle)
|
||||||
|
// We want to traverse from centerAngle + total/2 to centerAngle - total/2
|
||||||
|
double currentAngle = centerAngle + (totalAngle / 2);
|
||||||
|
|
||||||
|
for (int i = 0; i < text.length; i++) {
|
||||||
|
final char = text[i];
|
||||||
|
final span = TextSpan(text: char, style: textStyle);
|
||||||
|
final tp = TextPainter(text: span, textDirection: ui.TextDirection.ltr);
|
||||||
|
tp.layout();
|
||||||
|
|
||||||
|
final charAngle = charAngles[i];
|
||||||
|
final midCharAngle = currentAngle - charAngle / 2;
|
||||||
|
|
||||||
|
final x = center.dx + radius * math.cos(midCharAngle);
|
||||||
|
final y = center.dy + radius * math.sin(midCharAngle);
|
||||||
|
|
||||||
|
canvas.save();
|
||||||
|
canvas.translate(x, y);
|
||||||
|
canvas.rotate(midCharAngle - math.pi / 2);
|
||||||
|
|
||||||
|
tp.paint(canvas, Offset(-tp.width / 2, -tp.height / 2));
|
||||||
|
|
||||||
|
canvas.restore();
|
||||||
|
|
||||||
|
currentAngle -= charAngle;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
bool shouldRepaint(covariant CustomPainter oldDelegate) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
13
lib/widgets/content/profile_decoration.dart
Normal file
13
lib/widgets/content/profile_decoration.dart
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:freezed_annotation/freezed_annotation.dart';
|
||||||
|
|
||||||
|
part 'profile_decoration.freezed.dart';
|
||||||
|
|
||||||
|
@freezed
|
||||||
|
sealed class ProfileDecoration with _$ProfileDecoration {
|
||||||
|
const factory ProfileDecoration({
|
||||||
|
required String text,
|
||||||
|
required Color color,
|
||||||
|
Color? textColor,
|
||||||
|
}) = _ProfileDecoration;
|
||||||
|
}
|
||||||
277
lib/widgets/content/profile_decoration.freezed.dart
Normal file
277
lib/widgets/content/profile_decoration.freezed.dart
Normal file
@@ -0,0 +1,277 @@
|
|||||||
|
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||||
|
// coverage:ignore-file
|
||||||
|
// ignore_for_file: type=lint
|
||||||
|
// ignore_for_file: unused_element, deprecated_member_use, deprecated_member_use_from_same_package, use_function_type_syntax_for_parameters, unnecessary_const, avoid_init_to_null, invalid_override_different_default_values_named, prefer_expression_function_bodies, annotate_overrides, invalid_annotation_target, unnecessary_question_mark
|
||||||
|
|
||||||
|
part of 'profile_decoration.dart';
|
||||||
|
|
||||||
|
// **************************************************************************
|
||||||
|
// FreezedGenerator
|
||||||
|
// **************************************************************************
|
||||||
|
|
||||||
|
// dart format off
|
||||||
|
T _$identity<T>(T value) => value;
|
||||||
|
/// @nodoc
|
||||||
|
mixin _$ProfileDecoration {
|
||||||
|
|
||||||
|
String get text; Color get color; Color? get textColor;
|
||||||
|
/// Create a copy of ProfileDecoration
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
|
@JsonKey(includeFromJson: false, includeToJson: false)
|
||||||
|
@pragma('vm:prefer-inline')
|
||||||
|
$ProfileDecorationCopyWith<ProfileDecoration> get copyWith => _$ProfileDecorationCopyWithImpl<ProfileDecoration>(this as ProfileDecoration, _$identity);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@override
|
||||||
|
bool operator ==(Object other) {
|
||||||
|
return identical(this, other) || (other.runtimeType == runtimeType&&other is ProfileDecoration&&(identical(other.text, text) || other.text == text)&&(identical(other.color, color) || other.color == color)&&(identical(other.textColor, textColor) || other.textColor == textColor));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@override
|
||||||
|
int get hashCode => Object.hash(runtimeType,text,color,textColor);
|
||||||
|
|
||||||
|
@override
|
||||||
|
String toString() {
|
||||||
|
return 'ProfileDecoration(text: $text, color: $color, textColor: $textColor)';
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @nodoc
|
||||||
|
abstract mixin class $ProfileDecorationCopyWith<$Res> {
|
||||||
|
factory $ProfileDecorationCopyWith(ProfileDecoration value, $Res Function(ProfileDecoration) _then) = _$ProfileDecorationCopyWithImpl;
|
||||||
|
@useResult
|
||||||
|
$Res call({
|
||||||
|
String text, Color color, Color? textColor
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
/// @nodoc
|
||||||
|
class _$ProfileDecorationCopyWithImpl<$Res>
|
||||||
|
implements $ProfileDecorationCopyWith<$Res> {
|
||||||
|
_$ProfileDecorationCopyWithImpl(this._self, this._then);
|
||||||
|
|
||||||
|
final ProfileDecoration _self;
|
||||||
|
final $Res Function(ProfileDecoration) _then;
|
||||||
|
|
||||||
|
/// Create a copy of ProfileDecoration
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
|
@pragma('vm:prefer-inline') @override $Res call({Object? text = null,Object? color = null,Object? textColor = freezed,}) {
|
||||||
|
return _then(_self.copyWith(
|
||||||
|
text: null == text ? _self.text : text // ignore: cast_nullable_to_non_nullable
|
||||||
|
as String,color: null == color ? _self.color : color // ignore: cast_nullable_to_non_nullable
|
||||||
|
as Color,textColor: freezed == textColor ? _self.textColor : textColor // ignore: cast_nullable_to_non_nullable
|
||||||
|
as Color?,
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/// Adds pattern-matching-related methods to [ProfileDecoration].
|
||||||
|
extension ProfileDecorationPatterns on ProfileDecoration {
|
||||||
|
/// A variant of `map` that fallback to returning `orElse`.
|
||||||
|
///
|
||||||
|
/// It is equivalent to doing:
|
||||||
|
/// ```dart
|
||||||
|
/// switch (sealedClass) {
|
||||||
|
/// case final Subclass value:
|
||||||
|
/// return ...;
|
||||||
|
/// case _:
|
||||||
|
/// return orElse();
|
||||||
|
/// }
|
||||||
|
/// ```
|
||||||
|
|
||||||
|
@optionalTypeArgs TResult maybeMap<TResult extends Object?>(TResult Function( _ProfileDecoration value)? $default,{required TResult orElse(),}){
|
||||||
|
final _that = this;
|
||||||
|
switch (_that) {
|
||||||
|
case _ProfileDecoration() when $default != null:
|
||||||
|
return $default(_that);case _:
|
||||||
|
return orElse();
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/// A `switch`-like method, using callbacks.
|
||||||
|
///
|
||||||
|
/// Callbacks receives the raw object, upcasted.
|
||||||
|
/// It is equivalent to doing:
|
||||||
|
/// ```dart
|
||||||
|
/// switch (sealedClass) {
|
||||||
|
/// case final Subclass value:
|
||||||
|
/// return ...;
|
||||||
|
/// case final Subclass2 value:
|
||||||
|
/// return ...;
|
||||||
|
/// }
|
||||||
|
/// ```
|
||||||
|
|
||||||
|
@optionalTypeArgs TResult map<TResult extends Object?>(TResult Function( _ProfileDecoration value) $default,){
|
||||||
|
final _that = this;
|
||||||
|
switch (_that) {
|
||||||
|
case _ProfileDecoration():
|
||||||
|
return $default(_that);case _:
|
||||||
|
throw StateError('Unexpected subclass');
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/// A variant of `map` that fallback to returning `null`.
|
||||||
|
///
|
||||||
|
/// It is equivalent to doing:
|
||||||
|
/// ```dart
|
||||||
|
/// switch (sealedClass) {
|
||||||
|
/// case final Subclass value:
|
||||||
|
/// return ...;
|
||||||
|
/// case _:
|
||||||
|
/// return null;
|
||||||
|
/// }
|
||||||
|
/// ```
|
||||||
|
|
||||||
|
@optionalTypeArgs TResult? mapOrNull<TResult extends Object?>(TResult? Function( _ProfileDecoration value)? $default,){
|
||||||
|
final _that = this;
|
||||||
|
switch (_that) {
|
||||||
|
case _ProfileDecoration() when $default != null:
|
||||||
|
return $default(_that);case _:
|
||||||
|
return null;
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/// A variant of `when` that fallback to an `orElse` callback.
|
||||||
|
///
|
||||||
|
/// It is equivalent to doing:
|
||||||
|
/// ```dart
|
||||||
|
/// switch (sealedClass) {
|
||||||
|
/// case Subclass(:final field):
|
||||||
|
/// return ...;
|
||||||
|
/// case _:
|
||||||
|
/// return orElse();
|
||||||
|
/// }
|
||||||
|
/// ```
|
||||||
|
|
||||||
|
@optionalTypeArgs TResult maybeWhen<TResult extends Object?>(TResult Function( String text, Color color, Color? textColor)? $default,{required TResult orElse(),}) {final _that = this;
|
||||||
|
switch (_that) {
|
||||||
|
case _ProfileDecoration() when $default != null:
|
||||||
|
return $default(_that.text,_that.color,_that.textColor);case _:
|
||||||
|
return orElse();
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/// A `switch`-like method, using callbacks.
|
||||||
|
///
|
||||||
|
/// As opposed to `map`, this offers destructuring.
|
||||||
|
/// It is equivalent to doing:
|
||||||
|
/// ```dart
|
||||||
|
/// switch (sealedClass) {
|
||||||
|
/// case Subclass(:final field):
|
||||||
|
/// return ...;
|
||||||
|
/// case Subclass2(:final field2):
|
||||||
|
/// return ...;
|
||||||
|
/// }
|
||||||
|
/// ```
|
||||||
|
|
||||||
|
@optionalTypeArgs TResult when<TResult extends Object?>(TResult Function( String text, Color color, Color? textColor) $default,) {final _that = this;
|
||||||
|
switch (_that) {
|
||||||
|
case _ProfileDecoration():
|
||||||
|
return $default(_that.text,_that.color,_that.textColor);case _:
|
||||||
|
throw StateError('Unexpected subclass');
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/// A variant of `when` that fallback to returning `null`
|
||||||
|
///
|
||||||
|
/// It is equivalent to doing:
|
||||||
|
/// ```dart
|
||||||
|
/// switch (sealedClass) {
|
||||||
|
/// case Subclass(:final field):
|
||||||
|
/// return ...;
|
||||||
|
/// case _:
|
||||||
|
/// return null;
|
||||||
|
/// }
|
||||||
|
/// ```
|
||||||
|
|
||||||
|
@optionalTypeArgs TResult? whenOrNull<TResult extends Object?>(TResult? Function( String text, Color color, Color? textColor)? $default,) {final _that = this;
|
||||||
|
switch (_that) {
|
||||||
|
case _ProfileDecoration() when $default != null:
|
||||||
|
return $default(_that.text,_that.color,_that.textColor);case _:
|
||||||
|
return null;
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @nodoc
|
||||||
|
|
||||||
|
|
||||||
|
class _ProfileDecoration implements ProfileDecoration {
|
||||||
|
const _ProfileDecoration({required this.text, required this.color, this.textColor});
|
||||||
|
|
||||||
|
|
||||||
|
@override final String text;
|
||||||
|
@override final Color color;
|
||||||
|
@override final Color? textColor;
|
||||||
|
|
||||||
|
/// Create a copy of ProfileDecoration
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
|
@override @JsonKey(includeFromJson: false, includeToJson: false)
|
||||||
|
@pragma('vm:prefer-inline')
|
||||||
|
_$ProfileDecorationCopyWith<_ProfileDecoration> get copyWith => __$ProfileDecorationCopyWithImpl<_ProfileDecoration>(this, _$identity);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@override
|
||||||
|
bool operator ==(Object other) {
|
||||||
|
return identical(this, other) || (other.runtimeType == runtimeType&&other is _ProfileDecoration&&(identical(other.text, text) || other.text == text)&&(identical(other.color, color) || other.color == color)&&(identical(other.textColor, textColor) || other.textColor == textColor));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@override
|
||||||
|
int get hashCode => Object.hash(runtimeType,text,color,textColor);
|
||||||
|
|
||||||
|
@override
|
||||||
|
String toString() {
|
||||||
|
return 'ProfileDecoration(text: $text, color: $color, textColor: $textColor)';
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @nodoc
|
||||||
|
abstract mixin class _$ProfileDecorationCopyWith<$Res> implements $ProfileDecorationCopyWith<$Res> {
|
||||||
|
factory _$ProfileDecorationCopyWith(_ProfileDecoration value, $Res Function(_ProfileDecoration) _then) = __$ProfileDecorationCopyWithImpl;
|
||||||
|
@override @useResult
|
||||||
|
$Res call({
|
||||||
|
String text, Color color, Color? textColor
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
/// @nodoc
|
||||||
|
class __$ProfileDecorationCopyWithImpl<$Res>
|
||||||
|
implements _$ProfileDecorationCopyWith<$Res> {
|
||||||
|
__$ProfileDecorationCopyWithImpl(this._self, this._then);
|
||||||
|
|
||||||
|
final _ProfileDecoration _self;
|
||||||
|
final $Res Function(_ProfileDecoration) _then;
|
||||||
|
|
||||||
|
/// Create a copy of ProfileDecoration
|
||||||
|
/// with the given fields replaced by the non-null parameter values.
|
||||||
|
@override @pragma('vm:prefer-inline') $Res call({Object? text = null,Object? color = null,Object? textColor = freezed,}) {
|
||||||
|
return _then(_ProfileDecoration(
|
||||||
|
text: null == text ? _self.text : text // ignore: cast_nullable_to_non_nullable
|
||||||
|
as String,color: null == color ? _self.color : color // ignore: cast_nullable_to_non_nullable
|
||||||
|
as Color,textColor: freezed == textColor ? _self.textColor : textColor // ignore: cast_nullable_to_non_nullable
|
||||||
|
as Color?,
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// dart format on
|
||||||
Reference in New Issue
Block a user