Add an animated AI icon for Scribe in desktop web
I moved the previous static icon in its own component and created a component that manage the loading of the appropriate icon: static or dynamic.
This commit is contained in:
File diff suppressed because one or more lines are too long
@@ -247,6 +247,7 @@ class ImagePaths {
|
|||||||
String get icFileDownload => _getImagePath('ic_file_download.svg');
|
String get icFileDownload => _getImagePath('ic_file_download.svg');
|
||||||
String get icTwakeWorkplace => _getIconPath('icon_twp.png');
|
String get icTwakeWorkplace => _getIconPath('icon_twp.png');
|
||||||
String get animLottieTmail => _getAnimationPath('lottie-tmail.json');
|
String get animLottieTmail => _getAnimationPath('lottie-tmail.json');
|
||||||
|
String get animLottieScribe => _getAnimationPath('lottie-scribe.json');
|
||||||
String get icExpandArrows => _getImagePath('ic_expand_arrows.svg');
|
String get icExpandArrows => _getImagePath('ic_expand_arrows.svg');
|
||||||
String get icPremium => _getImagePath('ic_premium.svg');
|
String get icPremium => _getImagePath('ic_premium.svg');
|
||||||
String get icCloud => _getImagePath('ic_cloud.svg');
|
String get icCloud => _getImagePath('ic_cloud.svg');
|
||||||
|
|||||||
@@ -0,0 +1,70 @@
|
|||||||
|
import 'package:core/presentation/resources/image_paths.dart';
|
||||||
|
import 'package:core/presentation/views/container/tmail_container_widget.dart';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:lottie/lottie.dart';
|
||||||
|
import 'package:scribe/scribe.dart';
|
||||||
|
|
||||||
|
class AiAssistantAnimatedButton extends StatefulWidget {
|
||||||
|
final ImagePaths imagePaths;
|
||||||
|
final void Function() onTapActionCallback;
|
||||||
|
final EdgeInsetsGeometry? margin;
|
||||||
|
|
||||||
|
const AiAssistantAnimatedButton({
|
||||||
|
super.key,
|
||||||
|
required this.imagePaths,
|
||||||
|
required this.onTapActionCallback,
|
||||||
|
this.margin,
|
||||||
|
});
|
||||||
|
|
||||||
|
@override
|
||||||
|
State<AiAssistantAnimatedButton> createState() =>
|
||||||
|
_AiAssistantAnimatedButtonState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _AiAssistantAnimatedButtonState extends State<AiAssistantAnimatedButton>
|
||||||
|
with TickerProviderStateMixin {
|
||||||
|
late AnimationController _animationController;
|
||||||
|
|
||||||
|
@override
|
||||||
|
void initState() {
|
||||||
|
super.initState();
|
||||||
|
_animationController = AnimationController(vsync: this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void dispose() {
|
||||||
|
_animationController.dispose();
|
||||||
|
super.dispose();
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return TMailContainerWidget(
|
||||||
|
margin: widget.margin,
|
||||||
|
padding: AIScribeSizes.aiAssistantIconPadding,
|
||||||
|
backgroundColor: Colors.transparent,
|
||||||
|
borderRadius: AIScribeSizes.aiAssistantIconRadius,
|
||||||
|
tooltipMessage: ScribeLocalizations.of(context).aiAssistant,
|
||||||
|
onTapActionCallback: widget.onTapActionCallback,
|
||||||
|
child: MouseRegion(
|
||||||
|
cursor: SystemMouseCursors.click,
|
||||||
|
onEnter: (event) {
|
||||||
|
_animationController.forward();
|
||||||
|
},
|
||||||
|
onExit: (event) {
|
||||||
|
_animationController.reset();
|
||||||
|
},
|
||||||
|
child: Lottie.asset(
|
||||||
|
widget.imagePaths.animLottieScribe,
|
||||||
|
width: AIScribeSizes.aiAssistantIcon,
|
||||||
|
height: AIScribeSizes.aiAssistantIcon,
|
||||||
|
fit: BoxFit.fill,
|
||||||
|
controller: _animationController,
|
||||||
|
onLoaded: (composition) {
|
||||||
|
_animationController.duration = composition.duration;
|
||||||
|
},
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,7 +1,8 @@
|
|||||||
import 'package:core/presentation/resources/image_paths.dart';
|
import 'package:core/presentation/resources/image_paths.dart';
|
||||||
import 'package:core/presentation/views/button/tmail_button_widget.dart';
|
import 'package:core/utils/platform_info.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:scribe/scribe.dart';
|
import 'ai_assistant_animated_button.dart';
|
||||||
|
import 'ai_assistant_static_button.dart';
|
||||||
|
|
||||||
typedef OnOpenAiAssistantModal = void Function(
|
typedef OnOpenAiAssistantModal = void Function(
|
||||||
Offset? position,
|
Offset? position,
|
||||||
@@ -24,17 +25,20 @@ class AiAssistantButton extends StatelessWidget {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return TMailButtonWidget.fromIcon(
|
if (PlatformInfo.isWebDesktop) {
|
||||||
icon: imagePaths.icGradientSparkle,
|
return AiAssistantAnimatedButton(
|
||||||
padding: AIScribeSizes.aiAssistantIconPadding,
|
imagePaths: imagePaths,
|
||||||
backgroundColor: Colors.transparent,
|
onTapActionCallback: () => _onTapActionCallback(context),
|
||||||
iconSize: AIScribeSizes.aiAssistantIcon,
|
margin: margin,
|
||||||
iconColor: iconColor,
|
);
|
||||||
margin: margin,
|
} else {
|
||||||
borderRadius: AIScribeSizes.aiAssistantIconRadius,
|
return AiAssistantStaticButton(
|
||||||
tooltipMessage: ScribeLocalizations.of(context).aiAssistant,
|
imagePaths: imagePaths,
|
||||||
onTapActionCallback: () => _onTapActionCallback(context),
|
onTapActionCallback: () => _onTapActionCallback(context),
|
||||||
);
|
iconColor: iconColor,
|
||||||
|
margin: margin,
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void _onTapActionCallback(BuildContext context) {
|
void _onTapActionCallback(BuildContext context) {
|
||||||
|
|||||||
@@ -0,0 +1,34 @@
|
|||||||
|
import 'package:core/presentation/resources/image_paths.dart';
|
||||||
|
import 'package:core/presentation/views/button/tmail_button_widget.dart';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:scribe/scribe.dart';
|
||||||
|
|
||||||
|
class AiAssistantStaticButton extends StatelessWidget {
|
||||||
|
final ImagePaths imagePaths;
|
||||||
|
final void Function() onTapActionCallback;
|
||||||
|
final Color? iconColor;
|
||||||
|
final EdgeInsetsGeometry? margin;
|
||||||
|
|
||||||
|
const AiAssistantStaticButton({
|
||||||
|
super.key,
|
||||||
|
required this.imagePaths,
|
||||||
|
required this.onTapActionCallback,
|
||||||
|
this.iconColor,
|
||||||
|
this.margin,
|
||||||
|
});
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return TMailButtonWidget.fromIcon(
|
||||||
|
icon: imagePaths.icGradientSparkle,
|
||||||
|
padding: AIScribeSizes.aiAssistantIconPadding,
|
||||||
|
backgroundColor: Colors.transparent,
|
||||||
|
iconSize: AIScribeSizes.aiAssistantIcon,
|
||||||
|
iconColor: iconColor,
|
||||||
|
margin: margin,
|
||||||
|
borderRadius: AIScribeSizes.aiAssistantIconRadius,
|
||||||
|
tooltipMessage: ScribeLocalizations.of(context).aiAssistant,
|
||||||
|
onTapActionCallback: onTapActionCallback,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user