524 lines
16 KiB
Dart
524 lines
16 KiB
Dart
import 'package:custom_pop_up_menu/custom_pop_up_menu.dart';
|
|
import 'package:flutter/material.dart';
|
|
import 'package:flutter_screenutil/flutter_screenutil.dart';
|
|
import 'package:flutter_translate/common/components/common_language_selector_bar.dart';
|
|
import 'package:flutter_translate/common/utils/object_utils.dart';
|
|
import 'package:flutter_translate/global/app_config.dart';
|
|
import 'package:flutter_translate/generated/assets.dart';
|
|
import 'package:flutter_translate/model/history_model.dart';
|
|
import 'package:flutter_translate/pages/home/components/setting_drawer.dart';
|
|
import 'package:flutter_translate/pages/home/home_controller.dart';
|
|
import 'package:get/get.dart';
|
|
import 'package:pie_menu/pie_menu.dart';
|
|
import 'package:quds_ui_kit/animations/quds_animated_icon.dart';
|
|
|
|
class HomeView extends GetView<HomeController> {
|
|
const HomeView({super.key});
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
return PieCanvas(
|
|
theme: PieTheme(
|
|
delayDuration: Duration.zero,
|
|
tooltipTextStyle: TextStyle(
|
|
fontSize: 44.sp,
|
|
fontWeight: FontWeight.w600,
|
|
),
|
|
),
|
|
child: Builder(
|
|
builder: (context) => Scaffold(
|
|
resizeToAvoidBottomInset: false,
|
|
key: controller.scaffoldKey,
|
|
drawer: const SettingDrawer(),
|
|
body: GetBuilder<HomeController>(
|
|
id: "home_view",
|
|
builder: (_) => Container(
|
|
padding: const EdgeInsets.symmetric(horizontal: 12).w,
|
|
decoration: BoxDecoration(
|
|
gradient: LinearGradient(
|
|
colors: [
|
|
Color(controller.appColor.value).withOpacity(0.2),
|
|
Colors.white,
|
|
],
|
|
begin: const FractionalOffset(0, -2),
|
|
end: const FractionalOffset(0, 1),
|
|
),
|
|
),
|
|
child: SafeArea(
|
|
child: Column(
|
|
children: [
|
|
15.verticalSpace,
|
|
const CommonLanguageSelectorBar(),
|
|
30.verticalSpace,
|
|
_dailyQuote(),
|
|
20.verticalSpace,
|
|
_buildTranslate(),
|
|
20.verticalSpace,
|
|
_historyList(),
|
|
_bottomBar(context),
|
|
],
|
|
),
|
|
),
|
|
),
|
|
),
|
|
),
|
|
),
|
|
);
|
|
}
|
|
|
|
Widget _title() {
|
|
return Row(
|
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
|
children: [
|
|
GestureDetector(
|
|
onTap: controller.openHomeDrawer,
|
|
child: Container(
|
|
width: 32.w,
|
|
height: 32.w,
|
|
padding: const EdgeInsets.all(3).w,
|
|
decoration: BoxDecoration(
|
|
color: Color(controller.appColor.value),
|
|
borderRadius: BorderRadius.circular(8.r),
|
|
),
|
|
child: Image.asset(Assets.iconHomeTitleMore),
|
|
),
|
|
),
|
|
Text(
|
|
appName,
|
|
style: TextStyle(
|
|
color: const Color(0xff1E1E1E),
|
|
fontSize: 24.sp,
|
|
fontWeight: FontWeight.w600,
|
|
),
|
|
),
|
|
32.horizontalSpace,
|
|
],
|
|
);
|
|
}
|
|
|
|
Widget _dailyQuote() {
|
|
return GestureDetector(
|
|
onTap: controller.sceneCategory,
|
|
child: Column(
|
|
children: [
|
|
Container(
|
|
padding: const EdgeInsets.only(top: 28, left: 22, bottom: 31).w,
|
|
decoration: BoxDecoration(
|
|
color: const Color(0xffBFE9D4),
|
|
borderRadius: BorderRadius.only(
|
|
topLeft: Radius.circular(16.r),
|
|
topRight: Radius.circular(16.r),
|
|
),
|
|
),
|
|
child: Stack(
|
|
clipBehavior: Clip.none,
|
|
alignment: AlignmentDirectional.bottomStart,
|
|
children: [
|
|
Positioned(
|
|
bottom: 2.8.w,
|
|
child: Container(
|
|
width: 73.w,
|
|
height: 7.w,
|
|
decoration: BoxDecoration(
|
|
color: const Color(0xff5CC2AD),
|
|
borderRadius: BorderRadius.circular(16),
|
|
),
|
|
),
|
|
),
|
|
Row(
|
|
children: [
|
|
Text(
|
|
"Daily Quote",
|
|
style: TextStyle(
|
|
fontSize: 20.sp,
|
|
fontWeight: FontWeight.w800,
|
|
fontStyle: FontStyle.italic,
|
|
color: const Color(0xff240F69),
|
|
),
|
|
),
|
|
Container(
|
|
margin: const EdgeInsets.only(left: 5).w,
|
|
child: Image.asset(
|
|
Assets.iconArrowRight,
|
|
color: const Color(0xff240F69),
|
|
width: 14.w,
|
|
height: 14.w,
|
|
),
|
|
),
|
|
],
|
|
),
|
|
Positioned(
|
|
right: -20.w,
|
|
bottom: -31.w,
|
|
child: Image.asset(
|
|
Assets.imagesSuspendedDecoration,
|
|
width: 211.41.w,
|
|
height: 99.14.w,
|
|
),
|
|
),
|
|
],
|
|
),
|
|
),
|
|
Container(
|
|
width: double.infinity,
|
|
height: 168.w,
|
|
padding: const EdgeInsets.symmetric(horizontal: 20).w,
|
|
alignment: Alignment.center,
|
|
decoration: BoxDecoration(
|
|
color: Colors.white,
|
|
borderRadius: BorderRadius.only(
|
|
bottomLeft: Radius.circular(16.r),
|
|
bottomRight: Radius.circular(16.r),
|
|
),
|
|
),
|
|
child: Column(
|
|
children: [
|
|
_sceneWidget(true),
|
|
const Divider(height: 1, thickness: 1),
|
|
_sceneWidget(false),
|
|
],
|
|
),
|
|
),
|
|
],
|
|
),
|
|
);
|
|
}
|
|
|
|
Widget _sceneWidget(bool isFrom) {
|
|
return SizedBox(
|
|
height: 83.5.w,
|
|
child: Column(
|
|
mainAxisAlignment: MainAxisAlignment.center,
|
|
crossAxisAlignment: CrossAxisAlignment.start,
|
|
children: [
|
|
Obx(() {
|
|
return Text(
|
|
isFrom
|
|
? controller.fromLanguage.value.name
|
|
: controller.toLanguage.value.name,
|
|
style: TextStyle(
|
|
fontSize: 12.sp,
|
|
color: const Color(0xffC2C3C5),
|
|
),
|
|
);
|
|
}),
|
|
9.verticalSpace,
|
|
Row(
|
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
|
children: [
|
|
Obx(
|
|
() => Text(
|
|
isFrom
|
|
? controller.fromScene.value
|
|
: controller.toScene.value,
|
|
overflow: TextOverflow.ellipsis,
|
|
style: TextStyle(
|
|
fontSize: 14.sp,
|
|
color: const Color(0xff152A3D),
|
|
fontWeight: FontWeight.w500,
|
|
),
|
|
),
|
|
),
|
|
Obx(
|
|
() => GestureDetector(
|
|
onTap: () => controller.textConvertVoice(isFrom),
|
|
child: ClipOval(
|
|
child: Container(
|
|
width: 24.w,
|
|
height: 24.w,
|
|
color: Color(controller.appColor.value),
|
|
child: QudsAnimatedIcon(
|
|
color: Colors.white,
|
|
iconData: AnimatedIcons.pause_play,
|
|
showStartIcon: isFrom
|
|
? controller.isPlayingFrom.value
|
|
: controller.isPlayingTo.value,
|
|
),
|
|
),
|
|
),
|
|
),
|
|
),
|
|
],
|
|
),
|
|
],
|
|
),
|
|
);
|
|
}
|
|
|
|
Widget _buildTranslate() {
|
|
return Column(
|
|
children: [
|
|
GestureDetector(
|
|
onTap: controller.translator,
|
|
child: Container(
|
|
height: 91.w,
|
|
alignment: Alignment.center,
|
|
decoration: BoxDecoration(
|
|
color: Color(controller.appColor.value),
|
|
borderRadius: BorderRadius.circular(22.r),
|
|
),
|
|
padding: const EdgeInsets.symmetric(horizontal: 20).w,
|
|
child: Row(
|
|
children: [
|
|
Expanded(
|
|
child: Text(
|
|
"Type to Translate",
|
|
style: TextStyle(
|
|
fontSize: 20.sp,
|
|
fontWeight: FontWeight.w600,
|
|
color: Colors.white,
|
|
),
|
|
),
|
|
),
|
|
],
|
|
),
|
|
),
|
|
),
|
|
],
|
|
);
|
|
}
|
|
|
|
Widget _historyList() {
|
|
return Obx(
|
|
() => controller.historyList.isNotEmpty
|
|
? Expanded(
|
|
child: Container(
|
|
padding: const EdgeInsets.symmetric(horizontal: 15).w,
|
|
child: Column(
|
|
children: [
|
|
Row(
|
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
|
children: [
|
|
Text(
|
|
"History",
|
|
style: TextStyle(
|
|
fontSize: 16.sp,
|
|
color: const Color(0xff979797),
|
|
fontWeight: FontWeight.w500,
|
|
),
|
|
),
|
|
],
|
|
),
|
|
Expanded(
|
|
child: ListView.builder(
|
|
itemCount: controller.historyList.length,
|
|
itemBuilder: (context, index) {
|
|
HistoryModel historyModel =
|
|
controller.historyList[index];
|
|
return _historyItem(historyModel, index);
|
|
},
|
|
),
|
|
),
|
|
],
|
|
),
|
|
),
|
|
)
|
|
: Expanded(child: Container()),
|
|
);
|
|
}
|
|
|
|
Widget _historyItem(HistoryModel historyModel, int index) {
|
|
return CustomPopupMenu(
|
|
arrowColor: Colors.black,
|
|
barrierColor: Colors.transparent,
|
|
position: PreferredPosition.top,
|
|
verticalMargin: 0,
|
|
pressType: PressType.longPress,
|
|
menuBuilder: () {
|
|
return GestureDetector(
|
|
onTap: () => controller.removeHistoryByIndex(index),
|
|
child: Container(
|
|
padding: const EdgeInsets.all(10).w,
|
|
decoration: BoxDecoration(
|
|
color: Colors.black,
|
|
borderRadius: BorderRadius.circular(8.r),
|
|
),
|
|
child: Image.asset(Assets.iconDelete, width: 24.w),
|
|
),
|
|
);
|
|
},
|
|
child: InkWell(
|
|
onTap: () => controller.historyTranslate(historyModel),
|
|
child: Column(
|
|
crossAxisAlignment: CrossAxisAlignment.start,
|
|
children: [
|
|
Padding(
|
|
padding: const EdgeInsets.symmetric(vertical: 10).w,
|
|
child: RichText(
|
|
maxLines: 1,
|
|
overflow: TextOverflow.ellipsis,
|
|
text: TextSpan(
|
|
children: [
|
|
TextSpan(
|
|
text: ObjectUtils.getStr(historyModel.sourceText),
|
|
style: TextStyle(
|
|
fontWeight: FontWeight.w500,
|
|
fontSize: 16.sp,
|
|
color: const Color(0xff212121),
|
|
),
|
|
),
|
|
WidgetSpan(child: 6.horizontalSpace),
|
|
TextSpan(
|
|
text: ObjectUtils.getStr(historyModel.targetText),
|
|
style: TextStyle(
|
|
color: const Color(0xff979797),
|
|
fontSize: 13.sp,
|
|
fontWeight: FontWeight.w400,
|
|
),
|
|
),
|
|
],
|
|
),
|
|
),
|
|
),
|
|
],
|
|
),
|
|
),
|
|
);
|
|
}
|
|
|
|
// Widget _tools() {
|
|
// return Padding(
|
|
// padding: const EdgeInsets.symmetric(horizontal: 12).w,
|
|
// child: Row(
|
|
// mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
|
// children: [
|
|
// _toolItemWidget(
|
|
// controller.photos,
|
|
// Assets.iconToolsPhoto,
|
|
// "Photo",
|
|
// ),
|
|
// _toolItemWidget(
|
|
// controller.face2face,
|
|
// Assets.iconToolsDialog,
|
|
// "Face2face",
|
|
// ),
|
|
// _toolItemWidget(
|
|
// controller.history,
|
|
// Assets.iconToolsHistory,
|
|
// "History",
|
|
// ),
|
|
// ],
|
|
// ),
|
|
// );
|
|
// }
|
|
|
|
// Widget _toolItemWidget(
|
|
// GestureTapCallback? onTap,
|
|
// String icon,
|
|
// String title,
|
|
// ) {
|
|
// return Column(
|
|
// children: [
|
|
// GestureDetector(
|
|
// onTap: onTap,
|
|
// child: Container(
|
|
// width: 32.w,
|
|
// height: 32.w,
|
|
// padding: const EdgeInsets.all(8).w,
|
|
// decoration: BoxDecoration(
|
|
// color: Colors.white,
|
|
// borderRadius: BorderRadius.circular(24.r),
|
|
// ),
|
|
// child: Image.asset(icon),
|
|
// ),
|
|
// ),
|
|
// 10.verticalSpace,
|
|
// Text(
|
|
// title,
|
|
// style: TextStyle(
|
|
// fontSize: 14.sp,
|
|
// color: Colors.black,
|
|
// fontWeight: FontWeight.w500,
|
|
// ),
|
|
// ),
|
|
// ],
|
|
// );
|
|
// }
|
|
|
|
Widget _bottomBar(context) {
|
|
return Padding(
|
|
padding: const EdgeInsets.symmetric(horizontal: 40).w,
|
|
child: Row(
|
|
children: [
|
|
GestureDetector(
|
|
onTap: controller.openHomeDrawer,
|
|
child: Icon(
|
|
Icons.menu,
|
|
size: 30.w,
|
|
color: Colors.grey,
|
|
),
|
|
),
|
|
const Spacer(),
|
|
Flexible(
|
|
child: GestureDetector(
|
|
onTap: controller.speak,
|
|
child: Container(
|
|
height: 65.w,
|
|
width: 65.w,
|
|
padding: const EdgeInsets.all(15).w,
|
|
decoration: BoxDecoration(
|
|
color: Color(controller.appColor.value).withOpacity(.7),
|
|
borderRadius: BorderRadius.circular(65.r),
|
|
),
|
|
child: Image.asset(
|
|
Assets.iconHomeMicrophone,
|
|
color: Colors.white,
|
|
),
|
|
),
|
|
),
|
|
),
|
|
const Spacer(),
|
|
SizedBox(
|
|
width: 30.w,
|
|
height: 30.w,
|
|
child: PieMenu(
|
|
theme: PieTheme.of(context).copyWith(
|
|
buttonTheme: const PieButtonTheme(
|
|
backgroundColor: Colors.white,
|
|
iconColor: Colors.white,
|
|
),
|
|
buttonThemeHovered: const PieButtonTheme(
|
|
backgroundColor: Colors.white,
|
|
iconColor: Colors.black,
|
|
),
|
|
brightness: Brightness.dark,
|
|
),
|
|
actions: [
|
|
PieAction(
|
|
tooltip: const Text(''),
|
|
onSelect: controller.photos,
|
|
child: Container(
|
|
padding: const EdgeInsets.all(5).w,
|
|
child: Image.asset(Assets.iconToolsPhoto),
|
|
),
|
|
),
|
|
PieAction(
|
|
tooltip: const Text(''),
|
|
onSelect: controller.face2face,
|
|
child: Container(
|
|
padding: const EdgeInsets.all(5).w,
|
|
child: Image.asset(Assets.iconToolsDialog),
|
|
),
|
|
),
|
|
PieAction(
|
|
tooltip: const Text(''),
|
|
onSelect: controller.history,
|
|
child: Container(
|
|
padding: const EdgeInsets.all(5).w,
|
|
child: Image.asset(Assets.iconToolsHistory),
|
|
),
|
|
),
|
|
],
|
|
child: Icon(
|
|
Icons.more_outlined,
|
|
size: 30.w,
|
|
color: Colors.grey,
|
|
),
|
|
),
|
|
),
|
|
],
|
|
),
|
|
);
|
|
}
|
|
}
|