diff --git a/android/app/src/main/AndroidManifest.xml b/android/app/src/main/AndroidManifest.xml
index a102c69..aa71ce3 100644
--- a/android/app/src/main/AndroidManifest.xml
+++ b/android/app/src/main/AndroidManifest.xml
@@ -30,4 +30,21 @@
android:name="flutterEmbedding"
android:value="2" />
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/ios/Runner.xcodeproj/project.pbxproj b/ios/Runner.xcodeproj/project.pbxproj
index c2f47d2..1342eed 100644
--- a/ios/Runner.xcodeproj/project.pbxproj
+++ b/ios/Runner.xcodeproj/project.pbxproj
@@ -445,6 +445,7 @@
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
+ ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES;
CLANG_ANALYZER_NONNULL = YES;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
CLANG_CXX_LIBRARY = "libc++";
@@ -464,6 +465,7 @@
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
+ CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
CLANG_WARN_STRICT_PROTOTYPES = YES;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
@@ -474,6 +476,7 @@
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
ENABLE_NS_ASSERTIONS = NO;
ENABLE_STRICT_OBJC_MSGSEND = YES;
+ ENABLE_USER_SCRIPT_SANDBOXING = NO;
GCC_C_LANGUAGE_STANDARD = gnu99;
GCC_NO_COMMON_BLOCKS = YES;
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
@@ -502,10 +505,13 @@
DEVELOPMENT_TEAM = W7HPZ53V6B;
ENABLE_BITCODE = NO;
INFOPLIST_FILE = Runner/Info.plist;
+ INFOPLIST_KEY_CFBundleDisplayName = GoatAgent;
+ INFOPLIST_KEY_LSApplicationCategoryType = "public.app-category.utilities";
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
);
+ MARKETING_VERSION = 1.0.0;
PRODUCT_BUNDLE_IDENTIFIER = studio.smartsheep.goatagent;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
@@ -568,6 +574,7 @@
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
+ ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES;
CLANG_ANALYZER_NONNULL = YES;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
CLANG_CXX_LIBRARY = "libc++";
@@ -587,6 +594,7 @@
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
+ CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
CLANG_WARN_STRICT_PROTOTYPES = YES;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
@@ -597,6 +605,7 @@
DEBUG_INFORMATION_FORMAT = dwarf;
ENABLE_STRICT_OBJC_MSGSEND = YES;
ENABLE_TESTABILITY = YES;
+ ENABLE_USER_SCRIPT_SANDBOXING = NO;
GCC_C_LANGUAGE_STANDARD = gnu99;
GCC_DYNAMIC_NO_PIC = NO;
GCC_NO_COMMON_BLOCKS = YES;
@@ -623,6 +632,7 @@
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
+ ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES;
CLANG_ANALYZER_NONNULL = YES;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
CLANG_CXX_LIBRARY = "libc++";
@@ -642,6 +652,7 @@
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
+ CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
CLANG_WARN_STRICT_PROTOTYPES = YES;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
@@ -652,6 +663,7 @@
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
ENABLE_NS_ASSERTIONS = NO;
ENABLE_STRICT_OBJC_MSGSEND = YES;
+ ENABLE_USER_SCRIPT_SANDBOXING = NO;
GCC_C_LANGUAGE_STANDARD = gnu99;
GCC_NO_COMMON_BLOCKS = YES;
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
@@ -682,10 +694,13 @@
DEVELOPMENT_TEAM = W7HPZ53V6B;
ENABLE_BITCODE = NO;
INFOPLIST_FILE = Runner/Info.plist;
+ INFOPLIST_KEY_CFBundleDisplayName = GoatAgent;
+ INFOPLIST_KEY_LSApplicationCategoryType = "public.app-category.utilities";
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
);
+ MARKETING_VERSION = 1.0.0;
PRODUCT_BUNDLE_IDENTIFIER = studio.smartsheep.goatagent;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
@@ -706,10 +721,13 @@
DEVELOPMENT_TEAM = W7HPZ53V6B;
ENABLE_BITCODE = NO;
INFOPLIST_FILE = Runner/Info.plist;
+ INFOPLIST_KEY_CFBundleDisplayName = GoatAgent;
+ INFOPLIST_KEY_LSApplicationCategoryType = "public.app-category.utilities";
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
);
+ MARKETING_VERSION = 1.0.0;
PRODUCT_BUNDLE_IDENTIFIER = studio.smartsheep.goatagent;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
diff --git a/ios/Runner/Info.plist b/ios/Runner/Info.plist
index 2b9c475..606c466 100644
--- a/ios/Runner/Info.plist
+++ b/ios/Runner/Info.plist
@@ -7,7 +7,7 @@
CFBundleDevelopmentRegion
$(DEVELOPMENT_LANGUAGE)
CFBundleDisplayName
- Goatagent
+ GoatAgent
CFBundleExecutable
$(EXECUTABLE_NAME)
CFBundleIdentifier
@@ -28,6 +28,11 @@
UIApplicationSupportsIndirectInputEvents
+ LSApplicationQueriesSchemes
+
+ sms
+ tel
+
UIBackgroundModes
fetch
diff --git a/ios/Runner/Runner.entitlements b/ios/Runner/Runner.entitlements
index 903def2..0c67376 100644
--- a/ios/Runner/Runner.entitlements
+++ b/ios/Runner/Runner.entitlements
@@ -1,8 +1,5 @@
-
- aps-environment
- development
-
+
diff --git a/lib/main.dart b/lib/main.dart
index 2eb5e95..265dc14 100644
--- a/lib/main.dart
+++ b/lib/main.dart
@@ -2,6 +2,7 @@ import 'package:flutter/material.dart';
import 'package:go_router/go_router.dart';
import 'package:goatagent/auth.dart';
import 'package:goatagent/firebase.dart';
+import 'package:goatagent/screens/about.dart';
import 'package:goatagent/screens/account.dart';
import 'package:goatagent/screens/dashboard.dart';
import 'package:goatagent/screens/notifications.dart';
@@ -11,7 +12,13 @@ import 'layouts/navigation.dart';
void main() async {
WidgetsFlutterBinding.ensureInitialized();
- AuthGuard().pickClient();
+ try {
+ await initializeFirebase();
+ } catch (e) {
+ print(e);
+ }
+
+ await AuthGuard().pickClient();
runApp(GoatAgent());
}
@@ -32,6 +39,10 @@ class GoatAgent extends StatelessWidget {
path: '/account',
builder: (context, state) => const AccountScreen(),
),
+ GoRoute(
+ path: '/about',
+ builder: (context, state) => const AboutScreen(),
+ ),
],
);
@@ -39,34 +50,23 @@ class GoatAgent extends StatelessWidget {
@override
Widget build(BuildContext context) {
- return FutureBuilder(
- future: initializeFirebase(),
- builder: (context, snapshot) {
- if (!snapshot.hasData) {
- return const Center(
- child: CircularProgressIndicator(),
- );
- }
-
- return MaterialApp.router(
- routerConfig: _router,
- title: 'GoatAgent',
- theme: ThemeData(
- colorScheme: ColorScheme.fromSeed(seedColor: Colors.indigo),
- useMaterial3: true,
- ),
- builder: (BuildContext context, Widget? child) {
- return Overlay(initialEntries: [
- OverlayEntry(
- builder: (context) => Scaffold(
- body: child,
- // bottomNavigationBar: const AgentBottomNavigation()
- bottomNavigationBar: AgentNavigation(router: _router),
- ),
- )
- ]);
- },
- );
+ return MaterialApp.router(
+ routerConfig: _router,
+ title: 'GoatAgent',
+ theme: ThemeData(
+ colorScheme: ColorScheme.fromSeed(seedColor: Colors.indigo),
+ useMaterial3: true,
+ ),
+ builder: (BuildContext context, Widget? child) {
+ return Overlay(initialEntries: [
+ OverlayEntry(
+ builder: (context) => Scaffold(
+ body: child,
+ // bottomNavigationBar: const AgentBottomNavigation()
+ bottomNavigationBar: AgentNavigation(router: _router),
+ ),
+ )
+ ]);
},
);
}
diff --git a/lib/screens/about.dart b/lib/screens/about.dart
new file mode 100644
index 0000000..3669f22
--- /dev/null
+++ b/lib/screens/about.dart
@@ -0,0 +1,49 @@
+import 'package:flutter/material.dart';
+import 'package:package_info_plus/package_info_plus.dart';
+import 'package:url_launcher/url_launcher.dart';
+
+class AboutScreen extends StatelessWidget {
+ const AboutScreen({super.key});
+
+ @override
+ Widget build(BuildContext context) {
+ return Scaffold(
+ appBar: AppBar(
+ title: const Text('About'),
+ ),
+ body: Center(
+ child: Column(
+ mainAxisAlignment: MainAxisAlignment.center,
+ crossAxisAlignment: CrossAxisAlignment.center,
+ children: [
+ Text('GoatAgent',
+ style: Theme.of(context).textTheme.headlineMedium),
+ Text('Goatworks Official Mobile Helper',
+ style: Theme.of(context).textTheme.bodyLarge),
+ const SizedBox(height: 20),
+ FutureBuilder(
+ future: PackageInfo.fromPlatform(),
+ builder: (context, snapshot) {
+ if (snapshot.hasData) {
+ var version = snapshot.data!.version;
+ return Text('v$version',
+ style: Theme.of(context).textTheme.bodyLarge);
+ } else {
+ return Container();
+ }
+ },
+ ),
+ Text('Open sourced under GOLv1', style: Theme.of(context).textTheme.bodyMedium),
+ const SizedBox(height: 10),
+ MaterialButton(
+ onPressed: () async {
+ await launchUrl(Uri.parse('https://smartsheep.studio'));
+ },
+ child: const Text('Official Website'),
+ ),
+ ],
+ ),
+ ),
+ );
+ }
+}
diff --git a/lib/screens/account.dart b/lib/screens/account.dart
index 079b701..9e46be9 100644
--- a/lib/screens/account.dart
+++ b/lib/screens/account.dart
@@ -1,4 +1,5 @@
import 'package:flutter/material.dart';
+import 'package:go_router/go_router.dart';
import 'package:goatagent/auth.dart';
import 'package:goatagent/widgets/name_card.dart';
@@ -28,57 +29,67 @@ class _AccountScreenState extends State {
body: SafeArea(
child: Padding(
padding: const EdgeInsets.symmetric(vertical: 5, horizontal: 20),
- child: Column(
- children: [
- Padding(
- padding: const EdgeInsets.only(top: 20),
- child: NameCard(
- onLogin: () async {
- await AuthGuard().login(context);
- var authorized = await AuthGuard().isAuthorized();
- setState(() {
- isAuthorized = authorized;
- });
- },
- ),
- ),
- FutureBuilder(
- future: AuthGuard().isAuthorized(),
- builder: (BuildContext context, AsyncSnapshot snapshot) {
- if (snapshot.hasData && snapshot.data == true) {
- return Padding(
- padding: const EdgeInsets.only(top: 5),
- child: Wrap(
- spacing: 5,
- children: [
- Card(
- elevation: 0,
- child: InkWell(
- splashColor: Colors.indigo.withAlpha(30),
- onTap: () async {
- AuthGuard().logout();
- var authorized =
- await AuthGuard().isAuthorized();
- setState(() {
- isAuthorized = authorized;
- });
- },
- child: const ListTile(
- leading: Icon(Icons.logout),
- title: Text('Logout'),
- ),
- ),
- ),
- ],
- ),
- );
- } else {
- return const Padding(padding: EdgeInsets.only(top: 5));
- }
+ child: Column(children: [
+ Padding(
+ padding: const EdgeInsets.only(top: 20),
+ child: NameCard(
+ onLogin: () async {
+ await AuthGuard().login(context);
+ var authorized = await AuthGuard().isAuthorized();
+ setState(() {
+ isAuthorized = authorized;
+ });
},
),
- ],
- ),
+ ),
+ Padding(
+ padding: const EdgeInsets.only(top: 5),
+ child: Wrap(
+ spacing: 5,
+ children: [
+ FutureBuilder(
+ future: AuthGuard().isAuthorized(),
+ builder: (BuildContext context, AsyncSnapshot snapshot) {
+ if (snapshot.hasData && snapshot.data == true) {
+ return Card(
+ elevation: 0,
+ child: InkWell(
+ splashColor: Colors.indigo.withAlpha(30),
+ onTap: () async {
+ AuthGuard().logout();
+ var authorized = await AuthGuard().isAuthorized();
+ setState(() {
+ isAuthorized = authorized;
+ });
+ },
+ child: const ListTile(
+ leading: Icon(Icons.logout),
+ title: Text('Logout'),
+ ),
+ ),
+ );
+ } else {
+ return Container();
+ }
+ },
+ ),
+ Card(
+ elevation: 0,
+ child: InkWell(
+ splashColor: Colors.indigo.withAlpha(30),
+ onTap: () {
+ GoRouter.of(context).push("/about");
+ },
+ child: const ListTile(
+ leading: Icon(Icons.info_outline),
+ title: Text('About'),
+ ),
+ ),
+ ),
+ ],
+ ),
+ ),
+ ]),
),
),
);
diff --git a/linux/flutter/generated_plugin_registrant.cc b/linux/flutter/generated_plugin_registrant.cc
index d0e7f79..38dd0bc 100644
--- a/linux/flutter/generated_plugin_registrant.cc
+++ b/linux/flutter/generated_plugin_registrant.cc
@@ -7,9 +7,13 @@
#include "generated_plugin_registrant.h"
#include
+#include
void fl_register_plugins(FlPluginRegistry* registry) {
g_autoptr(FlPluginRegistrar) flutter_secure_storage_linux_registrar =
fl_plugin_registry_get_registrar_for_plugin(registry, "FlutterSecureStorageLinuxPlugin");
flutter_secure_storage_linux_plugin_register_with_registrar(flutter_secure_storage_linux_registrar);
+ g_autoptr(FlPluginRegistrar) url_launcher_linux_registrar =
+ fl_plugin_registry_get_registrar_for_plugin(registry, "UrlLauncherPlugin");
+ url_launcher_plugin_register_with_registrar(url_launcher_linux_registrar);
}
diff --git a/linux/flutter/generated_plugins.cmake b/linux/flutter/generated_plugins.cmake
index b29e9ba..65240e9 100644
--- a/linux/flutter/generated_plugins.cmake
+++ b/linux/flutter/generated_plugins.cmake
@@ -4,6 +4,7 @@
list(APPEND FLUTTER_PLUGIN_LIST
flutter_secure_storage_linux
+ url_launcher_linux
)
list(APPEND FLUTTER_FFI_PLUGIN_LIST
diff --git a/macos/Flutter/GeneratedPluginRegistrant.swift b/macos/Flutter/GeneratedPluginRegistrant.swift
index 64fad2b..2bb1105 100644
--- a/macos/Flutter/GeneratedPluginRegistrant.swift
+++ b/macos/Flutter/GeneratedPluginRegistrant.swift
@@ -10,7 +10,9 @@ import firebase_crashlytics
import firebase_messaging
import flutter_appauth
import flutter_secure_storage_macos
+import package_info_plus
import path_provider_foundation
+import url_launcher_macos
func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) {
FLTFirebaseCorePlugin.register(with: registry.registrar(forPlugin: "FLTFirebaseCorePlugin"))
@@ -18,5 +20,7 @@ func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) {
FLTFirebaseMessagingPlugin.register(with: registry.registrar(forPlugin: "FLTFirebaseMessagingPlugin"))
FlutterAppauthPlugin.register(with: registry.registrar(forPlugin: "FlutterAppauthPlugin"))
FlutterSecureStoragePlugin.register(with: registry.registrar(forPlugin: "FlutterSecureStoragePlugin"))
+ FPPPackageInfoPlusPlugin.register(with: registry.registrar(forPlugin: "FPPPackageInfoPlusPlugin"))
PathProviderPlugin.register(with: registry.registrar(forPlugin: "PathProviderPlugin"))
+ UrlLauncherPlugin.register(with: registry.registrar(forPlugin: "UrlLauncherPlugin"))
}
diff --git a/pubspec.lock b/pubspec.lock
index dd0cebe..fc3d90c 100644
--- a/pubspec.lock
+++ b/pubspec.lock
@@ -376,6 +376,22 @@ packages:
url: "https://pub.dev"
source: hosted
version: "2.0.2"
+ package_info_plus:
+ dependency: "direct main"
+ description:
+ name: package_info_plus
+ sha256: "88bc797f44a94814f2213db1c9bd5badebafdfb8290ca9f78d4b9ee2a3db4d79"
+ url: "https://pub.dev"
+ source: hosted
+ version: "5.0.1"
+ package_info_plus_platform_interface:
+ dependency: transitive
+ description:
+ name: package_info_plus_platform_interface
+ sha256: "9bc8ba46813a4cc42c66ab781470711781940780fd8beddd0c3da62506d3a6c6"
+ url: "https://pub.dev"
+ source: hosted
+ version: "2.0.1"
path:
dependency: transitive
description:
@@ -525,6 +541,70 @@ packages:
url: "https://pub.dev"
source: hosted
version: "1.3.2"
+ url_launcher:
+ dependency: "direct main"
+ description:
+ name: url_launcher
+ sha256: c512655380d241a337521703af62d2c122bf7b77a46ff7dd750092aa9433499c
+ url: "https://pub.dev"
+ source: hosted
+ version: "6.2.4"
+ url_launcher_android:
+ dependency: transitive
+ description:
+ name: url_launcher_android
+ sha256: "507dc655b1d9cb5ebc756032eb785f114e415f91557b73bf60b7e201dfedeb2f"
+ url: "https://pub.dev"
+ source: hosted
+ version: "6.2.2"
+ url_launcher_ios:
+ dependency: transitive
+ description:
+ name: url_launcher_ios
+ sha256: "75bb6fe3f60070407704282a2d295630cab232991eb52542b18347a8a941df03"
+ url: "https://pub.dev"
+ source: hosted
+ version: "6.2.4"
+ url_launcher_linux:
+ dependency: transitive
+ description:
+ name: url_launcher_linux
+ sha256: ab360eb661f8879369acac07b6bb3ff09d9471155357da8443fd5d3cf7363811
+ url: "https://pub.dev"
+ source: hosted
+ version: "3.1.1"
+ url_launcher_macos:
+ dependency: transitive
+ description:
+ name: url_launcher_macos
+ sha256: b7244901ea3cf489c5335bdacda07264a6e960b1c1b1a9f91e4bc371d9e68234
+ url: "https://pub.dev"
+ source: hosted
+ version: "3.1.0"
+ url_launcher_platform_interface:
+ dependency: transitive
+ description:
+ name: url_launcher_platform_interface
+ sha256: a932c3a8082e118f80a475ce692fde89dc20fddb24c57360b96bc56f7035de1f
+ url: "https://pub.dev"
+ source: hosted
+ version: "2.3.1"
+ url_launcher_web:
+ dependency: transitive
+ description:
+ name: url_launcher_web
+ sha256: fff0932192afeedf63cdd50ecbb1bc825d31aed259f02bb8dba0f3b729a5e88b
+ url: "https://pub.dev"
+ source: hosted
+ version: "2.2.3"
+ url_launcher_windows:
+ dependency: transitive
+ description:
+ name: url_launcher_windows
+ sha256: ecf9725510600aa2bb6d7ddabe16357691b6d2805f66216a97d1b881e21beff7
+ url: "https://pub.dev"
+ source: hosted
+ version: "3.1.1"
vector_math:
dependency: transitive
description:
diff --git a/pubspec.yaml b/pubspec.yaml
index 531b8bd..4b01f77 100644
--- a/pubspec.yaml
+++ b/pubspec.yaml
@@ -44,6 +44,8 @@ dependencies:
http: ^1.2.0
webview_flutter: ^4.5.0
go_router: ^13.1.0
+ package_info_plus: ^5.0.1
+ url_launcher: ^6.2.4
dev_dependencies:
flutter_test:
diff --git a/windows/flutter/generated_plugin_registrant.cc b/windows/flutter/generated_plugin_registrant.cc
index 39cedd3..0e0afee 100644
--- a/windows/flutter/generated_plugin_registrant.cc
+++ b/windows/flutter/generated_plugin_registrant.cc
@@ -8,10 +8,13 @@
#include
#include
+#include
void RegisterPlugins(flutter::PluginRegistry* registry) {
FirebaseCorePluginCApiRegisterWithRegistrar(
registry->GetRegistrarForPlugin("FirebaseCorePluginCApi"));
FlutterSecureStorageWindowsPluginRegisterWithRegistrar(
registry->GetRegistrarForPlugin("FlutterSecureStorageWindowsPlugin"));
+ UrlLauncherWindowsRegisterWithRegistrar(
+ registry->GetRegistrarForPlugin("UrlLauncherWindows"));
}
diff --git a/windows/flutter/generated_plugins.cmake b/windows/flutter/generated_plugins.cmake
index 1f5d05f..9efea82 100644
--- a/windows/flutter/generated_plugins.cmake
+++ b/windows/flutter/generated_plugins.cmake
@@ -5,6 +5,7 @@
list(APPEND FLUTTER_PLUGIN_LIST
firebase_core
flutter_secure_storage_windows
+ url_launcher_windows
)
list(APPEND FLUTTER_FFI_PLUGIN_LIST