From 53f9381614b6251f8a59eff37ca28d65a8f69cc4 Mon Sep 17 00:00:00 2001 From: Krushna Kanta Rout <129386740+krushnarout@users.noreply.github.com> Date: Fri, 5 Sep 2025 22:46:47 +0530 Subject: [PATCH 1/2] feat: app version and device info copy button --- app/lib/pages/settings/settings_drawer.dart | 157 +++++++++++++++++--- 1 file changed, 136 insertions(+), 21 deletions(-) diff --git a/app/lib/pages/settings/settings_drawer.dart b/app/lib/pages/settings/settings_drawer.dart index 78ec6bd40fb..8b80a9b93e7 100644 --- a/app/lib/pages/settings/settings_drawer.dart +++ b/app/lib/pages/settings/settings_drawer.dart @@ -1,4 +1,6 @@ +import 'dart:io'; import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; import 'package:font_awesome_flutter/font_awesome_flutter.dart'; import 'package:omi/backend/auth.dart'; import 'package:omi/backend/preferences.dart'; @@ -18,6 +20,7 @@ import 'package:package_info_plus/package_info_plus.dart'; import 'package:provider/provider.dart'; import 'package:url_launcher/url_launcher.dart'; import 'package:share_plus/share_plus.dart'; +import 'package:device_info_plus/device_info_plus.dart'; import 'device_settings.dart'; import '../conversations/sync_page.dart'; @@ -50,15 +53,51 @@ class SettingsDrawer extends StatefulWidget { class _SettingsDrawerState extends State { String? version; String? buildVersion; + String? shortDeviceInfo; @override void initState() { super.initState(); - PackageInfo.fromPlatform().then((PackageInfo packageInfo) { - version = packageInfo.version; - buildVersion = packageInfo.buildNumber.toString(); - setState(() {}); - }); + _loadAppAndDeviceInfo(); + } + + Future _getShortDeviceInfo() async { + try { + final deviceInfoPlugin = DeviceInfoPlugin(); + + if (Platform.isAndroid) { + final androidInfo = await deviceInfoPlugin.androidInfo; + return '${androidInfo.brand} ${androidInfo.model} — Android ${androidInfo.version.release}'; + } else if (Platform.isIOS) { + final iosInfo = await deviceInfoPlugin.iosInfo; + return '${iosInfo.name} — iOS ${iosInfo.systemVersion}'; + } else { + return 'Unknown Device'; + } + } catch (e) { + return 'Unknown Device'; + } + } + + Future _loadAppAndDeviceInfo() async { + try { + final packageInfo = await PackageInfo.fromPlatform(); + final shortDevice = await _getShortDeviceInfo(); + + if (mounted) { + setState(() { + version = packageInfo.version; + buildVersion = packageInfo.buildNumber.toString(); + shortDeviceInfo = shortDevice; + }); + } + } catch (e) { + if (mounted) { + setState(() { + shortDeviceInfo = 'Unknown Device'; + }); + } + } } Widget _buildSettingsItem({ @@ -118,6 +157,96 @@ class _SettingsDrawerState extends State { ); } + Widget _buildVersionInfoSection() { + if (!Platform.isIOS && !Platform.isAndroid) { + return const SizedBox.shrink(); + } + + final displayText = buildVersion != null ? '${version ?? ""} ($buildVersion)' : (version ?? ''); + + return Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Text( + displayText, + style: const TextStyle( + color: Color(0xFF8E8E93), + fontSize: 13, + fontWeight: FontWeight.w400, + ), + ), + const SizedBox(width: 2), + GestureDetector( + onTap: _copyVersionInfo, + child: Container( + padding: const EdgeInsets.all(2), + child: const Icon( + Icons.copy, + size: 12, + color: Color(0xFF8E8E93), + ), + ), + ), + ], + ); + } + + Future _copyVersionInfo() async { + final versionPart = buildVersion != null ? 'Omi AI ${version ?? ""} ($buildVersion)' : 'Omi AI ${version ?? ""}'; + final devicePart = shortDeviceInfo ?? 'Unknown Device'; + final fullVersionInfo = '$versionPart — $devicePart'; + + await Clipboard.setData(ClipboardData(text: fullVersionInfo)); + + if (mounted) { + _showCopyNotification(); + } + } + + void _showCopyNotification() { + final overlay = Overlay.of(context); + late OverlayEntry overlayEntry; + + overlayEntry = OverlayEntry( + builder: (_) => Positioned( + bottom: 20, + left: 0, + right: 0, + child: Center( + child: Material( + color: Colors.transparent, + child: Container( + width: MediaQuery.of(context).size.width * 0.7, + padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 12), + decoration: BoxDecoration( + color: Colors.black87, + borderRadius: BorderRadius.circular(8), + boxShadow: [ + BoxShadow( + color: Colors.black.withOpacity(0.2), + blurRadius: 4, + offset: const Offset(0, 2), + ), + ], + ), + child: const Text( + 'App and device details copied', + textAlign: TextAlign.center, + style: TextStyle(color: Colors.white, fontSize: 14), + ), + ), + ), + ), + ), + ); + + overlay.insert(overlayEntry); + + Future.delayed(const Duration(seconds: 2), () { + overlayEntry.remove(); + }); + } + Widget _buildOmiModeContent(BuildContext context) { return Consumer(builder: (context, usageProvider, child) { final bool showSubscription = usageProvider.subscription?.showSubscriptionUi ?? false; @@ -331,14 +460,7 @@ class _SettingsDrawerState extends State { const SizedBox(height: 32), // Version Info - Text( - '${version ?? ""}${buildVersion != null ? " ($buildVersion)" : ""}', - style: const TextStyle( - color: Color(0xFF8E8E93), - fontSize: 13, - fontWeight: FontWeight.w400, - ), - ), + _buildVersionInfoSection(), const SizedBox(height: 24), ], ); @@ -404,14 +526,7 @@ class _SettingsDrawerState extends State { const SizedBox(height: 32), // Version Info - Text( - '${version ?? ""}${buildVersion != null ? " ($buildVersion)" : ""}', - style: const TextStyle( - color: Color(0xFF8E8E93), - fontSize: 13, - fontWeight: FontWeight.w400, - ), - ), + _buildVersionInfoSection(), const SizedBox(height: 24), ], ); From e1be6da62aa0ec6b6460ee558c8c77c684d9399d Mon Sep 17 00:00:00 2001 From: Krushna Kanta Rout <129386740+krushnarout@users.noreply.github.com> Date: Sat, 6 Sep 2025 12:55:36 +0530 Subject: [PATCH 2/2] fix: add device_info_plus & upgrade json_serializable --- app/pubspec.yaml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/app/pubspec.yaml b/app/pubspec.yaml index 1210a71a2e1..f24b0ea1e6f 100644 --- a/app/pubspec.yaml +++ b/app/pubspec.yaml @@ -83,8 +83,9 @@ dependencies: mcumgr_flutter: ^0.4.2 flutter_archive: ^6.0.3 json_annotation: ^4.9.0 - json_serializable: 6.8.0 + json_serializable: ^6.9.5 package_info_plus: ^8.0.1 + device_info_plus: ^11.5.0 path_provider: 2.1.5 flutter_foreground_task: 9.1.0 upgrader: 11.4.0