From 75984e6579e554fb969b7306f5c82265f2136a54 Mon Sep 17 00:00:00 2001 From: John Ryan Date: Tue, 13 Feb 2024 10:30:43 -0800 Subject: [PATCH] Add url_launcher to gemini sample --- .../lib/src/project_templates.dart | 1 + .../dependencies/pub_dependencies_beta.json | 8 ++ .../dependencies/pub_dependencies_main.json | 8 ++ .../dependencies/pub_dependencies_stable.json | 8 ++ pkgs/samples/lib/gemini.dart | 82 +++++++++++-------- pkgs/samples/pubspec.yaml | 1 + pkgs/sketch_pad/lib/samples.g.dart | 82 +++++++++++-------- 7 files changed, 122 insertions(+), 68 deletions(-) diff --git a/pkgs/dart_services/lib/src/project_templates.dart b/pkgs/dart_services/lib/src/project_templates.dart index 1e94efe63..4897dade4 100644 --- a/pkgs/dart_services/lib/src/project_templates.dart +++ b/pkgs/dart_services/lib/src/project_templates.dart @@ -69,6 +69,7 @@ const Set supportedFlutterPackages = { 'provider', 'riverpod_navigator', 'shared_preferences', + 'url_launcher', 'video_player', }; diff --git a/pkgs/dart_services/tool/dependencies/pub_dependencies_beta.json b/pkgs/dart_services/tool/dependencies/pub_dependencies_beta.json index 32f9419b5..8c9d2326d 100644 --- a/pkgs/dart_services/tool/dependencies/pub_dependencies_beta.json +++ b/pkgs/dart_services/tool/dependencies/pub_dependencies_beta.json @@ -126,6 +126,14 @@ "tuple": "2.0.2", "typed_data": "1.3.2", "unicode": "0.3.1", + "url_launcher": "6.2.4", + "url_launcher_android": "6.2.2", + "url_launcher_ios": "6.2.4", + "url_launcher_linux": "3.1.1", + "url_launcher_macos": "3.1.0", + "url_launcher_platform_interface": "2.3.1", + "url_launcher_web": "2.2.3", + "url_launcher_windows": "3.1.1", "vector_graphics": "1.1.10+1", "vector_graphics_codec": "1.1.10+1", "vector_graphics_compiler": "1.1.10+1", diff --git a/pkgs/dart_services/tool/dependencies/pub_dependencies_main.json b/pkgs/dart_services/tool/dependencies/pub_dependencies_main.json index a45f5ebc6..10cb4f26a 100644 --- a/pkgs/dart_services/tool/dependencies/pub_dependencies_main.json +++ b/pkgs/dart_services/tool/dependencies/pub_dependencies_main.json @@ -126,6 +126,14 @@ "tuple": "2.0.2", "typed_data": "1.3.2", "unicode": "0.3.1", + "url_launcher": "6.2.4", + "url_launcher_android": "6.2.2", + "url_launcher_ios": "6.2.4", + "url_launcher_linux": "3.1.1", + "url_launcher_macos": "3.1.0", + "url_launcher_platform_interface": "2.3.1", + "url_launcher_web": "2.2.3", + "url_launcher_windows": "3.1.1", "vector_graphics": "1.1.10+1", "vector_graphics_codec": "1.1.10+1", "vector_graphics_compiler": "1.1.10+1", diff --git a/pkgs/dart_services/tool/dependencies/pub_dependencies_stable.json b/pkgs/dart_services/tool/dependencies/pub_dependencies_stable.json index 6347cd5a5..300eabb85 100644 --- a/pkgs/dart_services/tool/dependencies/pub_dependencies_stable.json +++ b/pkgs/dart_services/tool/dependencies/pub_dependencies_stable.json @@ -123,6 +123,14 @@ "tuple": "2.0.2", "typed_data": "1.3.2", "unicode": "0.3.1", + "url_launcher": "6.2.4", + "url_launcher_android": "6.2.2", + "url_launcher_ios": "6.2.4", + "url_launcher_linux": "3.1.1", + "url_launcher_macos": "3.1.0", + "url_launcher_platform_interface": "2.3.1", + "url_launcher_web": "2.2.3", + "url_launcher_windows": "3.1.1", "vector_graphics": "1.1.10+1", "vector_graphics_codec": "1.1.10+1", "vector_graphics_compiler": "1.1.10+1", diff --git a/pkgs/samples/lib/gemini.dart b/pkgs/samples/lib/gemini.dart index 767816d7e..00ae5e0e4 100644 --- a/pkgs/samples/lib/gemini.dart +++ b/pkgs/samples/lib/gemini.dart @@ -5,6 +5,7 @@ import 'package:flutter/material.dart'; import 'package:flutter_markdown/flutter_markdown.dart'; import 'package:google_generative_ai/google_generative_ai.dart'; +import 'package:url_launcher/link.dart'; void main() { runApp(const GenerativeAISample()); @@ -48,15 +49,15 @@ class _ChatScreenState extends State { ), body: apiKey == null ? ApiKeyWidget( - onSubmitted: (key) { - setState(() { - apiKey = key; - }); - }, - ) + onSubmitted: (key) { + setState(() { + apiKey = key; + }); + }, + ) : ChatWidget( - apiKey: apiKey!, - ), + apiKey: apiKey!, + ), ); } } @@ -69,31 +70,44 @@ class ApiKeyWidget extends StatelessWidget { @override Widget build(BuildContext context) { return Scaffold( - body: Column( - mainAxisSize: MainAxisSize.min, - children: [ - const Text('Enter your API key'), - Row( - children: [ - Expanded( - child: TextField( - decoration: - textFieldDecoration(context, 'Enter your API key'), - controller: _textController, - onSubmitted: (value) { - onSubmitted(value); + body: Padding( + padding: const EdgeInsets.all(8.0), + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + const Text( + "To use the Gemini API, you'll need an API key. If you don't already have one, create a key in Google AI Studio."), + Link( + uri: Uri.parse('https://makersuite.google.com/app/apikey'), + builder: (context, followLink) { + return TextButton( + onPressed: followLink, + child: const Text('Get an API Key'), + ); + }, + ), + Row( + children: [ + Expanded( + child: TextField( + decoration: + textFieldDecoration(context, 'Enter your API key'), + controller: _textController, + onSubmitted: (value) { + onSubmitted(value); + }, + ), + ), + TextButton( + onPressed: () { + onSubmitted(_textController.value.text); }, + child: const Text('Submit'), ), - ), - TextButton( - onPressed: () { - onSubmitted(_textController.value.text); - }, - child: const Text('Submit'), - ), - ], - ), - ], + ], + ), + ], + ), ), ); } @@ -127,7 +141,7 @@ class _ChatWidgetState extends State { void _scrollDown() { WidgetsBinding.instance.addPostFrameCallback( - (_) => _scrollController.animateTo( + (_) => _scrollController.animateTo( _scrollController.position.maxScrollExtent, duration: const Duration( milliseconds: 750, @@ -174,7 +188,7 @@ class _ChatWidgetState extends State { autofocus: true, focusNode: _textFieldFocus, decoration: - textFieldDecoration(context, 'Enter a prompt...'), + textFieldDecoration(context, 'Enter a prompt...'), controller: _textController, onSubmitted: (String value) { _sendChatMessage(value); @@ -275,7 +289,7 @@ class MessageWidget extends StatelessWidget { Widget build(BuildContext context) { return Row( mainAxisAlignment: - isFromUser ? MainAxisAlignment.end : MainAxisAlignment.start, + isFromUser ? MainAxisAlignment.end : MainAxisAlignment.start, children: [ Flexible( child: Container( diff --git a/pkgs/samples/pubspec.yaml b/pkgs/samples/pubspec.yaml index 43f0ad8e8..7a88567ba 100644 --- a/pkgs/samples/pubspec.yaml +++ b/pkgs/samples/pubspec.yaml @@ -15,6 +15,7 @@ dev_dependencies: path: ^1.8.0 flutter_markdown: any google_generative_ai: any + url_launcher: any flutter: uses-material-design: true diff --git a/pkgs/sketch_pad/lib/samples.g.dart b/pkgs/sketch_pad/lib/samples.g.dart index 7432becc0..79b714c5d 100644 --- a/pkgs/sketch_pad/lib/samples.g.dart +++ b/pkgs/sketch_pad/lib/samples.g.dart @@ -216,6 +216,7 @@ final _gemini = Sample( import 'package:flutter/material.dart'; import 'package:flutter_markdown/flutter_markdown.dart'; import 'package:google_generative_ai/google_generative_ai.dart'; +import 'package:url_launcher/link.dart'; void main() { runApp(const GenerativeAISample()); @@ -259,15 +260,15 @@ class _ChatScreenState extends State { ), body: apiKey == null ? ApiKeyWidget( - onSubmitted: (key) { - setState(() { - apiKey = key; - }); - }, - ) + onSubmitted: (key) { + setState(() { + apiKey = key; + }); + }, + ) : ChatWidget( - apiKey: apiKey!, - ), + apiKey: apiKey!, + ), ); } } @@ -280,31 +281,44 @@ class ApiKeyWidget extends StatelessWidget { @override Widget build(BuildContext context) { return Scaffold( - body: Column( - mainAxisSize: MainAxisSize.min, - children: [ - const Text('Enter your API key'), - Row( - children: [ - Expanded( - child: TextField( - decoration: - textFieldDecoration(context, 'Enter your API key'), - controller: _textController, - onSubmitted: (value) { - onSubmitted(value); + body: Padding( + padding: const EdgeInsets.all(8.0), + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + const Text( + "To use the Gemini API, you'll need an API key. If you don't already have one, create a key in Google AI Studio."), + Link( + uri: Uri.parse('https://makersuite.google.com/app/apikey'), + builder: (context, followLink) { + return TextButton( + onPressed: followLink, + child: const Text('Get an API Key'), + ); + }, + ), + Row( + children: [ + Expanded( + child: TextField( + decoration: + textFieldDecoration(context, 'Enter your API key'), + controller: _textController, + onSubmitted: (value) { + onSubmitted(value); + }, + ), + ), + TextButton( + onPressed: () { + onSubmitted(_textController.value.text); }, + child: const Text('Submit'), ), - ), - TextButton( - onPressed: () { - onSubmitted(_textController.value.text); - }, - child: const Text('Submit'), - ), - ], - ), - ], + ], + ), + ], + ), ), ); } @@ -338,7 +352,7 @@ class _ChatWidgetState extends State { void _scrollDown() { WidgetsBinding.instance.addPostFrameCallback( - (_) => _scrollController.animateTo( + (_) => _scrollController.animateTo( _scrollController.position.maxScrollExtent, duration: const Duration( milliseconds: 750, @@ -385,7 +399,7 @@ class _ChatWidgetState extends State { autofocus: true, focusNode: _textFieldFocus, decoration: - textFieldDecoration(context, 'Enter a prompt...'), + textFieldDecoration(context, 'Enter a prompt...'), controller: _textController, onSubmitted: (String value) { _sendChatMessage(value); @@ -486,7 +500,7 @@ class MessageWidget extends StatelessWidget { Widget build(BuildContext context) { return Row( mainAxisAlignment: - isFromUser ? MainAxisAlignment.end : MainAxisAlignment.start, + isFromUser ? MainAxisAlignment.end : MainAxisAlignment.start, children: [ Flexible( child: Container(