From 07ecf3e7bc15e7ecbceb83b953a9709e3b1fb0f7 Mon Sep 17 00:00:00 2001 From: Sikander Saleem Date: Thu, 15 Oct 2026 12:48:52 +0300 Subject: [PATCH] improvements --- lib/controllers/api_routes/urls.dart | 10 +- lib/extensions/string_extensions.dart | 9 ++ .../widgets/copilot_message_bubble.dart | 150 +++++++++++------- .../land_page/contact_us_bottom_sheet.dart | 8 +- .../widgets/item_views/info_text_widget.dart | 8 +- 5 files changed, 106 insertions(+), 79 deletions(-) diff --git a/lib/controllers/api_routes/urls.dart b/lib/controllers/api_routes/urls.dart index 01c9ae7a..b6fb9c72 100644 --- a/lib/controllers/api_routes/urls.dart +++ b/lib/controllers/api_routes/urls.dart @@ -1,14 +1,14 @@ class URLs { URLs._(); - static const String appReleaseBuildNumber = "53"; + static const String appReleaseBuildNumber = "55"; - // static const host1 = "https://atomsm.hmg.com"; // production url + static const host1 = "https://atomsm.hmg.com"; // production url // static const host1 = "https://atomsmdev.hmg.com"; // local DEV url - static const host1 = "https://atomsmuat.hmg.com"; // local UAT url + // static const host1 = "https://atomsmuat.hmg.com"; // local UAT url - // static final String _baseUrl = "$_host/mobile"; // host local UAT - static final String _baseUrl = "$_host/v2/mobile"; // new V2 apis + static final String _baseUrl = "$_host/mobile"; // host local UAT + // static final String _baseUrl = "$_host/v2/mobile"; // new V2 apis // static final String _baseUrl = "$_host/v3/mobile"; // v3 for production CM,PM,TM // static final String _baseUrl = "$_host/v4/mobile"; // v4 for Demo module // static final String _baseUrl = "$_host/v5/mobile"; // v5 for data segregation diff --git a/lib/extensions/string_extensions.dart b/lib/extensions/string_extensions.dart index eb143e4b..88c0f6a5 100644 --- a/lib/extensions/string_extensions.dart +++ b/lib/extensions/string_extensions.dart @@ -1,3 +1,6 @@ +import 'dart:io'; + +import 'package:flutter/services.dart'; import 'package:fluttertoast/fluttertoast.dart'; import 'package:intl/intl.dart'; @@ -6,6 +9,12 @@ extension StringExtensions on String { void get showToast => Fluttertoast.showToast(msg: this); + Future get copyToClipboard => Clipboard.setData(ClipboardData(text: this)).then((value) { + if (Platform.isIOS) { + "Copied.".addTranslation.showToast; + } + }); + String get toTime { DateTime dateTime = DateFormat("HH:mm:ss").parse(this); return DateFormat('hh:mm a').format(dateTime); diff --git a/lib/modules/copilot/widgets/copilot_message_bubble.dart b/lib/modules/copilot/widgets/copilot_message_bubble.dart index 10f6927d..5657c89b 100644 --- a/lib/modules/copilot/widgets/copilot_message_bubble.dart +++ b/lib/modules/copilot/widgets/copilot_message_bubble.dart @@ -1,5 +1,7 @@ import 'dart:convert'; +import 'dart:io'; import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; import 'package:flutter_markdown_plus/flutter_markdown_plus.dart'; import 'package:test_sa/extensions/context_extension.dart'; import 'package:test_sa/extensions/int_extensions.dart'; @@ -89,7 +91,16 @@ class CopilotMessageBubble extends StatelessWidget { ), ), ), - (26 + 8).width, + SizedBox.square( + dimension: (26 + 8).toScreenWidth, + child: IconButton( + onPressed: () => message.content.copyToClipboard, + style: const ButtonStyle(tapTargetSize: MaterialTapTargetSize.shrinkWrap), + icon: Icon(Icons.copy_rounded, size: 18, color: AppColor.icon2Color(context)), + constraints: const BoxConstraints(), + tooltip: "Copy", + ), + ), ], ), ], @@ -125,68 +136,87 @@ class CopilotMessageBubble extends StatelessWidget { crossAxisAlignment: CrossAxisAlignment.start, children: [ if (showHeader) ...[recipientHeader, 4.height] else 8.height, - Container( - padding: const EdgeInsets.all(8), - margin: const EdgeInsets.only(left: 26 + 8, right: 26 + 8), - constraints: BoxConstraints(maxWidth: MediaQuery.of(context).size.width * 0.75), - decoration: BoxDecoration( - color: AppColor.background(context), - border: Border.all(color: AppColor.borderColor(context)), - borderRadius: BorderRadius.circular(12), - ), - child: Column( - mainAxisSize: MainAxisSize.min, - crossAxisAlignment: CrossAxisAlignment.end, - children: [ - if (showLoadingDots) - Align( - alignment: Alignment.centerLeft, - child: ThinkingOrb( - size: 48, - state: ThinkingOrbState.searching, - theme: context.isDark ? ThinkingOrbTheme.dark : ThinkingOrbTheme.light, - )) - else - _buildMessageContent(context), - // if (message.content.isNotEmpty && message.images.isNotEmpty) 8.height, - // if (message.content.isNotEmpty) - // Text( - // message.content, - // style: AppTextStyles.bodyText2.copyWith( - // color: message.isError ? Colors.red : AppColor.white10, - // ), - // ), - if (message.images.isNotEmpty) ...[ - 8.height, - SizedBox( - height: 90, - width: double.infinity, - child: ListView.separated( - scrollDirection: Axis.horizontal, - itemCount: message.images.length, - separatorBuilder: (_, __) => 8.width, - itemBuilder: (context, index) { - final img = message.images[index]; - return Image.memory( - base64Decode(img.base64), - width: 100, - height: 100, - fit: BoxFit.contain, - ); - }, - ), + Row( + mainAxisSize: MainAxisSize.min, + crossAxisAlignment: CrossAxisAlignment.end, + children: [ + SizedBox.square( + dimension: (26 + 8).toScreenWidth, + child: IconButton( + onPressed: () => message.content.copyToClipboard, + style: const ButtonStyle(tapTargetSize: MaterialTapTargetSize.shrinkWrap), + icon: Icon(Icons.copy_rounded, size: 18, color: AppColor.icon2Color(context)), + constraints: const BoxConstraints(), + tooltip: "Copy", + ), + ), + Flexible( + fit: FlexFit.loose, + child: Container( + padding: const EdgeInsets.all(8), + margin: const EdgeInsets.only(left: 0, right: 26 + 8), + constraints: BoxConstraints(maxWidth: MediaQuery.of(context).size.width * 0.75), + decoration: BoxDecoration( + color: AppColor.background(context), + border: Border.all(color: AppColor.borderColor(context)), + borderRadius: BorderRadius.circular(12), ), - ], - Align( - alignment: Alignment.centerRight, - widthFactor: 1, - child: Text( - _timeText, - style: AppTextStyles.textFieldLabelStyle.copyWith(color: AppColor.textColor(context)), + child: Column( + mainAxisSize: MainAxisSize.min, + crossAxisAlignment: CrossAxisAlignment.end, + children: [ + if (showLoadingDots) + Align( + alignment: Alignment.centerLeft, + child: ThinkingOrb( + size: 48, + state: ThinkingOrbState.searching, + theme: context.isDark ? ThinkingOrbTheme.dark : ThinkingOrbTheme.light, + )) + else + _buildMessageContent(context), + // if (message.content.isNotEmpty && message.images.isNotEmpty) 8.height, + // if (message.content.isNotEmpty) + // Text( + // message.content, + // style: AppTextStyles.bodyText2.copyWith( + // color: message.isError ? Colors.red : AppColor.white10, + // ), + // ), + if (message.images.isNotEmpty) ...[ + 8.height, + SizedBox( + height: 90, + width: double.infinity, + child: ListView.separated( + scrollDirection: Axis.horizontal, + itemCount: message.images.length, + separatorBuilder: (_, __) => 8.width, + itemBuilder: (context, index) { + final img = message.images[index]; + return Image.memory( + base64Decode(img.base64), + width: 100, + height: 100, + fit: BoxFit.contain, + ); + }, + ), + ), + ], + Align( + alignment: Alignment.centerRight, + widthFactor: 1, + child: Text( + _timeText, + style: AppTextStyles.textFieldLabelStyle.copyWith(color: AppColor.textColor(context)), + ), + ), + ], ), ), - ], - ), + ), + ], ), ], ), diff --git a/lib/new_views/pages/land_page/contact_us_bottom_sheet.dart b/lib/new_views/pages/land_page/contact_us_bottom_sheet.dart index 4574b7ac..6a82d6a4 100644 --- a/lib/new_views/pages/land_page/contact_us_bottom_sheet.dart +++ b/lib/new_views/pages/land_page/contact_us_bottom_sheet.dart @@ -78,13 +78,7 @@ class ContactUsBottomSheet extends StatelessWidget { color: AppColor.icon2Color(context), iconSize: 20, tooltip: "Copy", - onPressed: () { - Clipboard.setData(ClipboardData(text: sites[index].phoneNumber!)).then((value) { - if (Platform.isIOS) { - "Copied.".addTranslation.showToast; - } - }); - }, + onPressed: () => sites[index].phoneNumber!.copyToClipboard, ), IconButton( icon: const Icon(Icons.call), diff --git a/lib/views/widgets/item_views/info_text_widget.dart b/lib/views/widgets/item_views/info_text_widget.dart index 29f3fba0..6bb9b310 100644 --- a/lib/views/widgets/item_views/info_text_widget.dart +++ b/lib/views/widgets/item_views/info_text_widget.dart @@ -46,13 +46,7 @@ class InfoTextWidget extends StatelessWidget { children: [ Flexible(child: text), 8.width, - const Icon(Icons.copy_rounded, color: AppColor.primary10, size: 14).onPress(() { - Clipboard.setData(ClipboardData(text: value!)).then((value) { - if (Platform.isIOS) { - "Copied.".addTranslation.showToast; - } - }); - }), + const Icon(Icons.copy_rounded, color: AppColor.primary10, size: 14).onPress(() => value!.copyToClipboard), ], ); }