247 lines
6.8 KiB
Dart
247 lines
6.8 KiB
Dart
import 'package:flutter/material.dart';
|
|
import 'package:yumi/ui_kit/widgets/svga/sc_svga_asset_widget.dart';
|
|
|
|
class SCSpecialIdAssets {
|
|
static const String roomId = 'sc_images/general/room_id.svga';
|
|
static const String roomOwnerId = 'sc_images/general/room_id_custom.svga';
|
|
static const String userId = 'sc_images/general/user_id.svga';
|
|
static const String userIdLarge = 'sc_images/general/user_id_4.svga';
|
|
}
|
|
|
|
const LinearGradient _scSpecialIdVipTextGradient = LinearGradient(
|
|
begin: Alignment.centerLeft,
|
|
end: Alignment.centerRight,
|
|
colors: [
|
|
Color(0xFFFFD24D),
|
|
Color(0xFFFF7A4D),
|
|
Color(0xFFFF4FB3),
|
|
Color(0xFF8E63FF),
|
|
Color(0xFF38D6FF),
|
|
],
|
|
);
|
|
|
|
class SCSpecialIdBadge extends StatelessWidget {
|
|
const SCSpecialIdBadge({
|
|
super.key,
|
|
required this.idText,
|
|
this.showAnimated = false,
|
|
this.assetPath,
|
|
this.animationWidth = 120,
|
|
this.animationHeight = 28,
|
|
this.textPadding = EdgeInsets.zero,
|
|
this.showTextWhenAnimated = false,
|
|
this.showTextBesideAnimated = false,
|
|
this.animatedTextSpacing = 0,
|
|
this.animatedTextPrefix = '',
|
|
this.animationTextStyle,
|
|
this.normalTextStyle,
|
|
this.normalPrefix = 'ID:',
|
|
this.showCopyIcon = false,
|
|
this.showCopyIconWhenAnimated = false,
|
|
this.copyIconAssetPath = 'sc_images/room/sc_icon_user_card_copy_id.png',
|
|
this.copyIconSize = 12,
|
|
this.copyIconSpacing = 5,
|
|
this.copyIconColor,
|
|
this.loop = true,
|
|
this.active = true,
|
|
this.animationFit = BoxFit.fill,
|
|
this.inlineAnimationWidth,
|
|
this.showAnimatedGradientText = false,
|
|
this.animatedTextGradient,
|
|
});
|
|
|
|
final String idText;
|
|
final bool showAnimated;
|
|
final String? assetPath;
|
|
final double animationWidth;
|
|
final double animationHeight;
|
|
final EdgeInsetsGeometry textPadding;
|
|
final bool showTextWhenAnimated;
|
|
final bool showTextBesideAnimated;
|
|
final double animatedTextSpacing;
|
|
final String animatedTextPrefix;
|
|
final TextStyle? animationTextStyle;
|
|
final TextStyle? normalTextStyle;
|
|
final String normalPrefix;
|
|
final bool showCopyIcon;
|
|
final bool showCopyIconWhenAnimated;
|
|
final String copyIconAssetPath;
|
|
final double copyIconSize;
|
|
final double copyIconSpacing;
|
|
final Color? copyIconColor;
|
|
final bool loop;
|
|
final bool active;
|
|
final BoxFit animationFit;
|
|
final double? inlineAnimationWidth;
|
|
final bool showAnimatedGradientText;
|
|
final Gradient? animatedTextGradient;
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
final normalizedId = idText.trim();
|
|
final shouldAnimate =
|
|
showAnimated &&
|
|
(assetPath?.isNotEmpty ?? false) &&
|
|
normalizedId.isNotEmpty;
|
|
|
|
final children = <Widget>[
|
|
shouldAnimate
|
|
? (showTextWhenAnimated
|
|
? _buildAnimatedBadge(normalizedId)
|
|
: (showTextBesideAnimated
|
|
? _buildAnimatedInlineBadge(normalizedId)
|
|
: _buildAnimatedAsset()))
|
|
: _buildPlainBadge(normalizedId),
|
|
];
|
|
|
|
if (showCopyIcon && (!shouldAnimate || showCopyIconWhenAnimated)) {
|
|
children.add(SizedBox(width: copyIconSpacing));
|
|
children.add(
|
|
Image.asset(
|
|
copyIconAssetPath,
|
|
width: copyIconSize,
|
|
height: copyIconSize,
|
|
color: copyIconColor,
|
|
),
|
|
);
|
|
}
|
|
|
|
return Row(
|
|
mainAxisSize: MainAxisSize.min,
|
|
textDirection: TextDirection.ltr,
|
|
children: children,
|
|
);
|
|
}
|
|
|
|
Widget _buildAnimatedAsset() {
|
|
return SizedBox(
|
|
width: animationWidth,
|
|
height: animationHeight,
|
|
child: SCSvgaAssetWidget(
|
|
assetPath: assetPath!,
|
|
width: animationWidth,
|
|
height: animationHeight,
|
|
active: active,
|
|
loop: loop,
|
|
fit: animationFit,
|
|
fallback: const SizedBox.shrink(),
|
|
),
|
|
);
|
|
}
|
|
|
|
Widget _buildAnimatedInlineBadge(String normalizedId) {
|
|
final compactAnimationWidth = inlineAnimationWidth ?? animationHeight;
|
|
return Row(
|
|
mainAxisSize: MainAxisSize.min,
|
|
children: [
|
|
SizedBox(
|
|
width: compactAnimationWidth,
|
|
height: animationHeight,
|
|
child: SCSvgaAssetWidget(
|
|
assetPath: assetPath!,
|
|
width: compactAnimationWidth,
|
|
height: animationHeight,
|
|
active: active,
|
|
loop: loop,
|
|
fit: animationFit,
|
|
fallback: const SizedBox.shrink(),
|
|
),
|
|
),
|
|
SizedBox(width: animatedTextSpacing),
|
|
_buildGradientAwareText('$animatedTextPrefix$normalizedId'),
|
|
],
|
|
);
|
|
}
|
|
|
|
Widget _buildGradientAwareText(
|
|
String text, {
|
|
TextStyle? styleOverride,
|
|
TextOverflow overflow = TextOverflow.ellipsis,
|
|
}) {
|
|
final style =
|
|
styleOverride ??
|
|
animationTextStyle ??
|
|
const TextStyle(
|
|
color: Colors.white,
|
|
fontSize: 12,
|
|
fontWeight: FontWeight.w700,
|
|
);
|
|
|
|
if (!showAnimatedGradientText) {
|
|
return Text(text, maxLines: 1, overflow: overflow, style: style);
|
|
}
|
|
|
|
return ShaderMask(
|
|
blendMode: BlendMode.srcIn,
|
|
shaderCallback: (bounds) {
|
|
final shaderBounds = Rect.fromLTWH(
|
|
0,
|
|
0,
|
|
bounds.width <= 0 ? 1 : bounds.width,
|
|
bounds.height <= 0 ? 1 : bounds.height,
|
|
);
|
|
return (animatedTextGradient ?? _scSpecialIdVipTextGradient)
|
|
.createShader(shaderBounds);
|
|
},
|
|
child: Text(
|
|
text,
|
|
maxLines: 1,
|
|
overflow: overflow,
|
|
style: style.copyWith(color: Colors.white),
|
|
),
|
|
);
|
|
}
|
|
|
|
Widget _buildAnimatedBadge(String normalizedId) {
|
|
return SizedBox(
|
|
width: animationWidth,
|
|
height: animationHeight,
|
|
child: Stack(
|
|
clipBehavior: Clip.none,
|
|
children: [
|
|
Positioned.fill(
|
|
child: SCSvgaAssetWidget(
|
|
assetPath: assetPath!,
|
|
width: animationWidth,
|
|
height: animationHeight,
|
|
active: active,
|
|
loop: loop,
|
|
fit: animationFit,
|
|
fallback: const SizedBox.shrink(),
|
|
),
|
|
),
|
|
Positioned.fill(
|
|
child: Padding(
|
|
padding: textPadding,
|
|
child: Align(
|
|
alignment: Alignment.centerLeft,
|
|
child: FittedBox(
|
|
fit: BoxFit.scaleDown,
|
|
alignment: Alignment.centerLeft,
|
|
child: _buildGradientAwareText(
|
|
normalizedId,
|
|
overflow: TextOverflow.visible,
|
|
),
|
|
),
|
|
),
|
|
),
|
|
),
|
|
],
|
|
),
|
|
);
|
|
}
|
|
|
|
Widget _buildPlainBadge(String normalizedId) {
|
|
return _buildGradientAwareText(
|
|
'$normalPrefix$normalizedId',
|
|
styleOverride:
|
|
normalTextStyle ??
|
|
const TextStyle(
|
|
color: Colors.white,
|
|
fontSize: 12,
|
|
fontWeight: FontWeight.w600,
|
|
),
|
|
);
|
|
}
|
|
}
|