Update Scribe mobile custom prompt bar UI
This commit is contained in:
@@ -16,6 +16,18 @@ abstract final class AIScribeColors {
|
|||||||
|
|
||||||
// Overlays
|
// Overlays
|
||||||
static final Color dialogBarrier = Colors.black.withValues(alpha: 0.12);
|
static final Color dialogBarrier = Colors.black.withValues(alpha: 0.12);
|
||||||
|
|
||||||
|
// Gradients
|
||||||
|
static const LinearGradient barGradient = LinearGradient(
|
||||||
|
begin: Alignment.centerLeft,
|
||||||
|
end: Alignment.centerRight,
|
||||||
|
colors: [
|
||||||
|
Color.fromRGBO(0, 183, 255, 0.90),
|
||||||
|
Color.fromRGBO(224, 109, 209, 0.90),
|
||||||
|
Color.fromRGBO(232, 167, 138, 0.90),
|
||||||
|
],
|
||||||
|
stops: [0.0, 0.75, 1.0],
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
abstract final class AIScribeShadows {
|
abstract final class AIScribeShadows {
|
||||||
@@ -131,6 +143,7 @@ abstract final class AIScribeSizes {
|
|||||||
static const double aiAssistantIconRadius = 8;
|
static const double aiAssistantIconRadius = 8;
|
||||||
static const double contentCardRadius = 16;
|
static const double contentCardRadius = 16;
|
||||||
static const double improveButtonBorderRadius = 4;
|
static const double improveButtonBorderRadius = 4;
|
||||||
|
static const double bottomBarRadius = 28;
|
||||||
|
|
||||||
// Width / height
|
// Width / height
|
||||||
static const double menuItemHeight = 40;
|
static const double menuItemHeight = 40;
|
||||||
|
|||||||
+20
-23
@@ -1,4 +1,3 @@
|
|||||||
import 'package:core/presentation/extensions/color_extension.dart';
|
|
||||||
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/presentation/views/button/tmail_button_widget.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
@@ -154,33 +153,16 @@ class _AiScribeMobileActionsBottomSheetState
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
Widget _buildBottomBar(BuildContext context) {
|
Widget _buildBottomBarContent(BuildContext context) {
|
||||||
if (!widget.showCustomPromptBar) {
|
if (!widget.showCustomPromptBar) {
|
||||||
return const SizedBox.shrink();
|
return const SizedBox.shrink();
|
||||||
}
|
}
|
||||||
|
|
||||||
return Column(
|
return AIScribeBar(
|
||||||
mainAxisSize: MainAxisSize.min,
|
|
||||||
children: [
|
|
||||||
const Divider(
|
|
||||||
height: 1,
|
|
||||||
thickness: 1,
|
|
||||||
color: AppColor.colorDividerComposer,
|
|
||||||
),
|
|
||||||
Padding(
|
|
||||||
padding: EdgeInsets.only(
|
|
||||||
bottom: MediaQuery.of(context).viewInsets.bottom + 8.0,
|
|
||||||
left: 16.0,
|
|
||||||
right: 16.0,
|
|
||||||
top: 8.0,
|
|
||||||
),
|
|
||||||
child: AIScribeBar(
|
|
||||||
onCustomPrompt: _onCustomPromptSubmit,
|
onCustomPrompt: _onCustomPromptSubmit,
|
||||||
imagePaths: widget.imagePaths,
|
imagePaths: widget.imagePaths,
|
||||||
boxShadow: const [],
|
borderRadius: AIScribeSizes.bottomBarRadius,
|
||||||
),
|
hintStyle: AIScribeTextStyles.searchBar,
|
||||||
),
|
|
||||||
],
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -203,6 +185,9 @@ class _AiScribeMobileActionsBottomSheetState
|
|||||||
|
|
||||||
final hasContent = widget.content?.isNotEmpty ?? false;
|
final hasContent = widget.content?.isNotEmpty ?? false;
|
||||||
|
|
||||||
|
final bottomBarPadding = MediaQuery.of(context).viewInsets.bottom + 16.0;
|
||||||
|
final bottomBarInset = bottomBarPadding + (widget.showCustomPromptBar ? AIScribeSizes.searchBarMaxHeight : 0.0);
|
||||||
|
|
||||||
return PointerInterceptor(
|
return PointerInterceptor(
|
||||||
child: Container(
|
child: Container(
|
||||||
height: double.infinity,
|
height: double.infinity,
|
||||||
@@ -210,6 +195,10 @@ class _AiScribeMobileActionsBottomSheetState
|
|||||||
color: AIScribeColors.background,
|
color: AIScribeColors.background,
|
||||||
),
|
),
|
||||||
child: SafeArea(
|
child: SafeArea(
|
||||||
|
child: Stack(
|
||||||
|
children: [
|
||||||
|
Padding(
|
||||||
|
padding: EdgeInsets.only(bottom: bottomBarInset),
|
||||||
child: Column(
|
child: Column(
|
||||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||||
crossAxisAlignment: CrossAxisAlignment.stretch,
|
crossAxisAlignment: CrossAxisAlignment.stretch,
|
||||||
@@ -235,7 +224,15 @@ class _AiScribeMobileActionsBottomSheetState
|
|||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
_buildBottomBar(context),
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Positioned(
|
||||||
|
bottom: bottomBarPadding,
|
||||||
|
left: 16.0,
|
||||||
|
right: 16.0,
|
||||||
|
child: _buildBottomBarContent(context),
|
||||||
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|||||||
@@ -9,13 +9,15 @@ typedef OnCustomPromptCallback = void Function(String customPrompt);
|
|||||||
class AIScribeBar extends StatefulWidget {
|
class AIScribeBar extends StatefulWidget {
|
||||||
final OnCustomPromptCallback onCustomPrompt;
|
final OnCustomPromptCallback onCustomPrompt;
|
||||||
final ImagePaths imagePaths;
|
final ImagePaths imagePaths;
|
||||||
final List<BoxShadow>? boxShadow;
|
final double? borderRadius;
|
||||||
|
final TextStyle? hintStyle;
|
||||||
|
|
||||||
const AIScribeBar({
|
const AIScribeBar({
|
||||||
super.key,
|
super.key,
|
||||||
required this.onCustomPrompt,
|
required this.onCustomPrompt,
|
||||||
required this.imagePaths,
|
required this.imagePaths,
|
||||||
this.boxShadow,
|
this.borderRadius,
|
||||||
|
this.hintStyle,
|
||||||
});
|
});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
@@ -65,15 +67,21 @@ class _AIScribeBarState extends State<AIScribeBar> {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
|
final borderRadius = BorderRadius.circular(widget.borderRadius ?? AIScribeSizes.searchBarRadius);
|
||||||
|
|
||||||
return Container(
|
return Container(
|
||||||
|
padding: const EdgeInsets.all(2),
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
borderRadius: borderRadius,
|
||||||
|
gradient: AIScribeColors.barGradient,
|
||||||
|
),
|
||||||
|
child: ClipRRect(
|
||||||
|
borderRadius: borderRadius,
|
||||||
|
child: Container(
|
||||||
width: AIScribeSizes.searchBarWidth,
|
width: AIScribeSizes.searchBarWidth,
|
||||||
padding: AIScribeSizes.searchBarPadding,
|
padding: AIScribeSizes.searchBarPadding,
|
||||||
decoration: BoxDecoration(
|
decoration: const BoxDecoration(
|
||||||
borderRadius: const BorderRadius.all(
|
|
||||||
Radius.circular(AIScribeSizes.searchBarRadius),
|
|
||||||
),
|
|
||||||
color: AIScribeColors.background,
|
color: AIScribeColors.background,
|
||||||
boxShadow: widget.boxShadow ?? AIScribeShadows.modal,
|
|
||||||
),
|
),
|
||||||
constraints: const BoxConstraints(
|
constraints: const BoxConstraints(
|
||||||
maxHeight: AIScribeSizes.searchBarMaxHeight,
|
maxHeight: AIScribeSizes.searchBarMaxHeight,
|
||||||
@@ -90,7 +98,7 @@ class _AIScribeBarState extends State<AIScribeBar> {
|
|||||||
focusNode: _textFieldFocusNode,
|
focusNode: _textFieldFocusNode,
|
||||||
decoration: InputDecoration(
|
decoration: InputDecoration(
|
||||||
hintText: ScribeLocalizations.of(context).customPromptAction,
|
hintText: ScribeLocalizations.of(context).customPromptAction,
|
||||||
hintStyle: AIScribeTextStyles.searchBarHint,
|
hintStyle: widget.hintStyle ?? AIScribeTextStyles.searchBarHint,
|
||||||
border: InputBorder.none,
|
border: InputBorder.none,
|
||||||
contentPadding: const EdgeInsets.symmetric(vertical: 8),
|
contentPadding: const EdgeInsets.symmetric(vertical: 8),
|
||||||
isDense: true,
|
isDense: true,
|
||||||
@@ -120,6 +128,8 @@ class _AIScribeBarState extends State<AIScribeBar> {
|
|||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user