✨ 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/app_scaffold.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:material_symbols_icons/symbols.dart';
|
||||
import 'package:styled_widget/styled_widget.dart';
|
||||
@@ -98,6 +99,10 @@ class AccountScreen extends HookConsumerWidget {
|
||||
child: ProfilePictureWidget(
|
||||
file: user.value?.profile.picture,
|
||||
radius: 32,
|
||||
decoration: ProfileDecoration(
|
||||
text: '#OpenToWork',
|
||||
color: Colors.green,
|
||||
),
|
||||
),
|
||||
onTap: () {
|
||||
context.pushNamed(
|
||||
@@ -331,23 +336,21 @@ class AccountScreen extends HookConsumerWidget {
|
||||
if (availableWidth > totalMin) {
|
||||
return Row(
|
||||
spacing: 8,
|
||||
children:
|
||||
children
|
||||
.map((child) => Expanded(child: child))
|
||||
.toList(),
|
||||
children: children
|
||||
.map((child) => Expanded(child: child))
|
||||
.toList(),
|
||||
).padding(horizontal: 12).height(48);
|
||||
} else {
|
||||
return SingleChildScrollView(
|
||||
scrollDirection: Axis.horizontal,
|
||||
child: Row(
|
||||
spacing: 8,
|
||||
children:
|
||||
children
|
||||
.map(
|
||||
(child) =>
|
||||
SizedBox(width: minWidth, child: child),
|
||||
)
|
||||
.toList(),
|
||||
children: children
|
||||
.map(
|
||||
(child) =>
|
||||
SizedBox(width: minWidth, child: child),
|
||||
)
|
||||
.toList(),
|
||||
).padding(horizontal: 12),
|
||||
).height(48);
|
||||
}
|
||||
@@ -495,97 +498,96 @@ class _UnauthorizedAccountScreen extends StatelessWidget {
|
||||
Widget build(BuildContext context) {
|
||||
return AppScaffold(
|
||||
appBar: AppBar(title: const Text('account').tr()),
|
||||
body:
|
||||
ConstrainedBox(
|
||||
constraints: const BoxConstraints(maxWidth: 360),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.stretch,
|
||||
body: ConstrainedBox(
|
||||
constraints: const BoxConstraints(maxWidth: 360),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.stretch,
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: <Widget>[
|
||||
Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 24),
|
||||
child: Card(
|
||||
child: InkWell(
|
||||
borderRadius: const BorderRadius.all(Radius.circular(8)),
|
||||
onTap: () {
|
||||
context.pushNamed('createAccount');
|
||||
},
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(16),
|
||||
child: Column(
|
||||
children: [
|
||||
Icon(Symbols.person_add, size: 48),
|
||||
const SizedBox(height: 8),
|
||||
Text('createAccount').tr().bold(),
|
||||
Text('createAccountDescription').tr(),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
const Gap(8),
|
||||
Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 24),
|
||||
child: Card(
|
||||
child: InkWell(
|
||||
borderRadius: const BorderRadius.all(Radius.circular(8)),
|
||||
onTap: () {
|
||||
context.pushNamed('login');
|
||||
},
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(16),
|
||||
child: Column(
|
||||
children: [
|
||||
Icon(Symbols.login, size: 48),
|
||||
const SizedBox(height: 8),
|
||||
Text('login').tr().bold(),
|
||||
Text('loginDescription').tr(),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
const Gap(8),
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: <Widget>[
|
||||
Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 24),
|
||||
child: Card(
|
||||
child: InkWell(
|
||||
borderRadius: const BorderRadius.all(Radius.circular(8)),
|
||||
onTap: () {
|
||||
context.pushNamed('createAccount');
|
||||
},
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(16),
|
||||
child: Column(
|
||||
children: [
|
||||
Icon(Symbols.person_add, size: 48),
|
||||
const SizedBox(height: 8),
|
||||
Text('createAccount').tr().bold(),
|
||||
Text('createAccountDescription').tr(),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
children: [
|
||||
IconButton(
|
||||
onPressed: () {
|
||||
context.pushNamed('about');
|
||||
},
|
||||
iconSize: 18,
|
||||
color: Theme.of(context).colorScheme.secondary,
|
||||
icon: const Icon(Icons.info, fill: 1),
|
||||
tooltip: 'about'.tr(),
|
||||
),
|
||||
const Gap(8),
|
||||
Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 24),
|
||||
child: Card(
|
||||
child: InkWell(
|
||||
borderRadius: const BorderRadius.all(Radius.circular(8)),
|
||||
onTap: () {
|
||||
context.pushNamed('login');
|
||||
},
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(16),
|
||||
child: Column(
|
||||
children: [
|
||||
Icon(Symbols.login, size: 48),
|
||||
const SizedBox(height: 8),
|
||||
Text('login').tr().bold(),
|
||||
Text('loginDescription').tr(),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
IconButton(
|
||||
icon: const Icon(Icons.bug_report, fill: 1),
|
||||
onPressed: () {
|
||||
showModalBottomSheet(
|
||||
context: context,
|
||||
builder: (context) => DebugSheet(),
|
||||
);
|
||||
},
|
||||
iconSize: 18,
|
||||
color: Theme.of(context).colorScheme.secondary,
|
||||
tooltip: 'debugOptions'.tr(),
|
||||
),
|
||||
const Gap(8),
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
IconButton(
|
||||
onPressed: () {
|
||||
context.pushNamed('about');
|
||||
},
|
||||
iconSize: 18,
|
||||
color: Theme.of(context).colorScheme.secondary,
|
||||
icon: const Icon(Icons.info, fill: 1),
|
||||
tooltip: 'about'.tr(),
|
||||
),
|
||||
IconButton(
|
||||
icon: const Icon(Icons.bug_report, fill: 1),
|
||||
onPressed: () {
|
||||
showModalBottomSheet(
|
||||
context: context,
|
||||
builder: (context) => DebugSheet(),
|
||||
);
|
||||
},
|
||||
iconSize: 18,
|
||||
color: Theme.of(context).colorScheme.secondary,
|
||||
tooltip: 'debugOptions'.tr(),
|
||||
),
|
||||
IconButton(
|
||||
onPressed: () {
|
||||
context.pushNamed('settings');
|
||||
},
|
||||
icon: const Icon(Icons.settings, fill: 1),
|
||||
iconSize: 18,
|
||||
color: Theme.of(context).colorScheme.secondary,
|
||||
tooltip: 'appSettings'.tr(),
|
||||
),
|
||||
],
|
||||
IconButton(
|
||||
onPressed: () {
|
||||
context.pushNamed('settings');
|
||||
},
|
||||
icon: const Icon(Icons.settings, fill: 1),
|
||||
iconSize: 18,
|
||||
color: Theme.of(context).colorScheme.secondary,
|
||||
tooltip: 'appSettings'.tr(),
|
||||
),
|
||||
],
|
||||
),
|
||||
).center(),
|
||||
],
|
||||
),
|
||||
).center(),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,8 +9,11 @@ import 'package:island/models/file.dart';
|
||||
import 'package:island/pods/config.dart';
|
||||
import 'package:island/services/time.dart';
|
||||
import 'package:island/utils/format.dart';
|
||||
import 'package:island/widgets/content/profile_decoration.dart';
|
||||
import 'package:material_symbols_icons/symbols.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 'file_viewer_contents.dart';
|
||||
@@ -258,17 +261,15 @@ class CloudFileWidget extends HookConsumerWidget {
|
||||
var content = switch (item.mimeType?.split('/').firstOrNull) {
|
||||
'image' => AspectRatio(
|
||||
aspectRatio: ratio,
|
||||
child:
|
||||
(useInternalGate && dataSaving && !unlocked.value)
|
||||
? dataPlaceHolder(Symbols.image)
|
||||
: cloudImage(),
|
||||
child: (useInternalGate && dataSaving && !unlocked.value)
|
||||
? dataPlaceHolder(Symbols.image)
|
||||
: cloudImage(),
|
||||
),
|
||||
'video' => AspectRatio(
|
||||
aspectRatio: ratio,
|
||||
child:
|
||||
(useInternalGate && dataSaving && !unlocked.value)
|
||||
? dataPlaceHolder(Symbols.play_arrow)
|
||||
: cloudVideo(),
|
||||
child: (useInternalGate && dataSaving && !unlocked.value)
|
||||
? dataPlaceHolder(Symbols.play_arrow)
|
||||
: cloudVideo(),
|
||||
),
|
||||
'audio' => AudioFileContent(item: item, uri: uri),
|
||||
_ => Builder(
|
||||
@@ -383,10 +384,9 @@ class CloudVideoWidget extends HookConsumerWidget {
|
||||
final serverUrl = ref.watch(serverUrlProvider);
|
||||
final uri = '$serverUrl/drive/files/${item.id}';
|
||||
|
||||
var ratio =
|
||||
item.fileMeta?['ratio'] is num
|
||||
? item.fileMeta!['ratio'].toDouble()
|
||||
: 1.0;
|
||||
var ratio = item.fileMeta?['ratio'] is num
|
||||
? item.fileMeta!['ratio'].toDouble()
|
||||
: 1.0;
|
||||
if (ratio == 0) ratio = 1.0;
|
||||
|
||||
if (open.value) {
|
||||
@@ -533,10 +533,9 @@ class CloudImageWidget extends ConsumerWidget {
|
||||
|
||||
return AspectRatio(
|
||||
aspectRatio: aspectRatio,
|
||||
child:
|
||||
file != null
|
||||
? CloudFileWidget(item: file!, fit: fit)
|
||||
: UniversalImage(uri: uri, blurHash: blurHash, fit: fit),
|
||||
child: file != null
|
||||
? CloudFileWidget(item: file!, fit: fit)
|
||||
: UniversalImage(uri: uri, blurHash: blurHash, fit: fit),
|
||||
);
|
||||
}
|
||||
|
||||
@@ -545,10 +544,9 @@ class CloudImageWidget extends ConsumerWidget {
|
||||
required String serverUrl,
|
||||
bool original = false,
|
||||
}) {
|
||||
final uri =
|
||||
original
|
||||
? '$serverUrl/drive/files/$fileId?original=true'
|
||||
: '$serverUrl/drive/files/$fileId';
|
||||
final uri = original
|
||||
? '$serverUrl/drive/files/$fileId?original=true'
|
||||
: '$serverUrl/drive/files/$fileId';
|
||||
return CachedNetworkImageProvider(uri);
|
||||
}
|
||||
}
|
||||
@@ -560,6 +558,7 @@ class ProfilePictureWidget extends ConsumerWidget {
|
||||
final double? borderRadius;
|
||||
final IconData? fallbackIcon;
|
||||
final Color? fallbackColor;
|
||||
final ProfileDecoration? decoration;
|
||||
const ProfilePictureWidget({
|
||||
super.key,
|
||||
this.fileId,
|
||||
@@ -568,6 +567,7 @@ class ProfilePictureWidget extends ConsumerWidget {
|
||||
this.borderRadius,
|
||||
this.fallbackIcon,
|
||||
this.fallbackColor,
|
||||
this.decoration,
|
||||
});
|
||||
|
||||
@override
|
||||
@@ -575,36 +575,49 @@ class ProfilePictureWidget extends ConsumerWidget {
|
||||
final serverUrl = ref.watch(serverUrlProvider);
|
||||
final String? id = file?.id ?? fileId;
|
||||
|
||||
final fallback =
|
||||
Icon(
|
||||
fallbackIcon ?? Symbols.account_circle,
|
||||
size: radius,
|
||||
color:
|
||||
fallbackColor ?? Theme.of(context).colorScheme.onPrimaryContainer,
|
||||
).center();
|
||||
final fallback = Icon(
|
||||
fallbackIcon ?? Symbols.account_circle,
|
||||
size: radius,
|
||||
color: fallbackColor ?? Theme.of(context).colorScheme.onPrimaryContainer,
|
||||
).center();
|
||||
|
||||
final image = id == null
|
||||
? fallback
|
||||
: DataSavingGate(
|
||||
bypass: true,
|
||||
placeholder: fallback,
|
||||
content: () => UniversalImage(
|
||||
uri: '$serverUrl/drive/files/$id',
|
||||
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: Container(
|
||||
width: radius * 2,
|
||||
height: radius * 2,
|
||||
color: Theme.of(context).colorScheme.primaryContainer,
|
||||
child:
|
||||
id == null
|
||||
? fallback
|
||||
: DataSavingGate(
|
||||
bypass: true,
|
||||
placeholder: fallback,
|
||||
content:
|
||||
() => UniversalImage(
|
||||
uri: '$serverUrl/drive/files/$id',
|
||||
fit: BoxFit.cover,
|
||||
),
|
||||
),
|
||||
),
|
||||
borderRadius: borderRadius == null
|
||||
? BorderRadius.all(Radius.circular(radius))
|
||||
: BorderRadius.all(Radius.circular(borderRadius!)),
|
||||
child: content,
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -716,32 +729,29 @@ class SplitAvatarWidget extends ConsumerWidget {
|
||||
),
|
||||
),
|
||||
Expanded(
|
||||
child:
|
||||
filesId.length > 4
|
||||
? Container(
|
||||
color:
|
||||
Theme.of(
|
||||
child: filesId.length > 4
|
||||
? Container(
|
||||
color: Theme.of(
|
||||
context,
|
||||
).colorScheme.primaryContainer,
|
||||
child: Center(
|
||||
child: Text(
|
||||
'+${filesId.length - 3}',
|
||||
style: TextStyle(
|
||||
fontSize: radius * 0.4,
|
||||
color: Theme.of(
|
||||
context,
|
||||
).colorScheme.primaryContainer,
|
||||
child: Center(
|
||||
child: Text(
|
||||
'+${filesId.length - 3}',
|
||||
style: TextStyle(
|
||||
fontSize: radius * 0.4,
|
||||
color:
|
||||
Theme.of(
|
||||
context,
|
||||
).colorScheme.onPrimaryContainer,
|
||||
),
|
||||
).colorScheme.onPrimaryContainer,
|
||||
),
|
||||
),
|
||||
)
|
||||
: _buildQuadrant(
|
||||
context,
|
||||
filesId[3],
|
||||
ref,
|
||||
radius,
|
||||
),
|
||||
)
|
||||
: _buildQuadrant(
|
||||
context,
|
||||
filesId[3],
|
||||
ref,
|
||||
radius,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
@@ -765,14 +775,12 @@ class SplitAvatarWidget extends ConsumerWidget {
|
||||
width: radius,
|
||||
height: radius,
|
||||
color: Theme.of(context).colorScheme.primaryContainer,
|
||||
child:
|
||||
Icon(
|
||||
fallbackIcon,
|
||||
size: radius * 0.6,
|
||||
color:
|
||||
fallbackColor ??
|
||||
Theme.of(context).colorScheme.onPrimaryContainer,
|
||||
).center(),
|
||||
child: Icon(
|
||||
fallbackIcon,
|
||||
size: radius * 0.6,
|
||||
color:
|
||||
fallbackColor ?? Theme.of(context).colorScheme.onPrimaryContainer,
|
||||
).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