Skip to content
项目
群组
代码片段
帮助
当前项目
正在载入...
登录 / 注册
切换导航面板
F
flutter-chat
Project
Project
详情
活动
周期分析
仓库
仓库
文件
提交
分支
标签
贡献者
Graph
比较
统计图
议题
0
议题
0
列表
看板
标记
Milestones
合并请求
0
合并请求
0
CI / CD
CI / CD
流水线
作业
日程
统计图
Wiki
Wiki
代码片段
代码片段
成员
成员
折叠边栏
关闭边栏
活动
图像
聊天
创建新问题
作业
提交
问题看板
Open sidebar
songchuancai
flutter-chat
Commits
c2c63647
提交
c2c63647
authored
11月 12, 2024
作者:
songchuancai
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
增加会话名称自动生成
上级
0f950dc7
显示空白字符变更
内嵌
并排
正在显示
4 个修改的文件
包含
78 行增加
和
6 行删除
+78
-6
home_page.dart
lib/home_page.dart
+35
-4
chat_page.dart
lib/pages/chat_page.dart
+10
-0
chat_service.dart
lib/services/chat_service.dart
+31
-0
GeneratedPluginRegistrant.swift
macos/Flutter/GeneratedPluginRegistrant.swift
+2
-2
没有找到文件。
lib/home_page.dart
浏览文件 @
c2c63647
...
@@ -39,12 +39,15 @@ class HomePage extends StatefulWidget {
...
@@ -39,12 +39,15 @@ class HomePage extends StatefulWidget {
final
bool
hideNavigation
;
final
bool
hideNavigation
;
final
OpenAIService
?
openAIService
;
const
HomePage
({
const
HomePage
({
super
.
key
,
super
.
key
,
this
.
customTitle
,
this
.
customTitle
,
this
.
customDescription
,
this
.
customDescription
,
this
.
customImageUrl
,
this
.
customImageUrl
,
this
.
hideNavigation
=
false
,
this
.
hideNavigation
=
false
,
this
.
openAIService
,
});
});
@override
@override
...
@@ -58,7 +61,7 @@ class _HomePageState extends State<HomePage> {
...
@@ -58,7 +61,7 @@ class _HomePageState extends State<HomePage> {
String
lastWords
=
''
;
String
lastWords
=
''
;
final
OpenAIService
openAIService
=
OpenAIService
();
late
OpenAIService
openAIService
;
String
?
generatedContent
;
String
?
generatedContent
;
...
@@ -103,6 +106,8 @@ class _HomePageState extends State<HomePage> {
...
@@ -103,6 +106,8 @@ class _HomePageState extends State<HomePage> {
initSpeechToText
();
initSpeechToText
();
_initTts
();
_initTts
();
openAIService
=
widget
.
openAIService
??
OpenAIService
();
}
}
Future
<
void
>
_initializeStorage
()
async
{
Future
<
void
>
_initializeStorage
()
async
{
...
@@ -113,15 +118,23 @@ class _HomePageState extends State<HomePage> {
...
@@ -113,15 +118,23 @@ class _HomePageState extends State<HomePage> {
_conversations
=
await
_storageService
.
getConversations
();
_conversations
=
await
_storageService
.
getConversations
();
// 每次进入应用创建一个新的会话
// 每次进入应用创建一个新的会话
_createNewConversation
();
_createNewConversation
();
// if (_conversations.isEmpty) {
// if (_conversations.isEmpty) {
// _createNewConversation();
// _createNewConversation();
// } else {
// } else {
// _currentConversation = _conversations.first;
// _currentConversation = _conversations.first;
// setState(() {
// setState(() {
// messages = _currentConversation.messages;
// messages = _currentConversation.messages;
// });
// });
// }
// }
}
}
...
@@ -168,27 +181,34 @@ class _HomePageState extends State<HomePage> {
...
@@ -168,27 +181,34 @@ class _HomePageState extends State<HomePage> {
_hasSpeechPermission
=
await
speechToText
.
initialize
(
_hasSpeechPermission
=
await
speechToText
.
initialize
(
onStatus:
(
status
)
{
onStatus:
(
status
)
{
print
(
'语音状态:
$status
'
);
print
(
'语音状态:
$status
'
);
if
(
status
==
'notListening'
)
{
if
(
status
==
'notListening'
)
{
setState
(()
=>
_isListeningPressed
=
false
);
setState
(()
=>
_isListeningPressed
=
false
);
}
}
},
},
onError:
(
error
)
{
onError:
(
error
)
{
print
(
'语音错误:
$error
'
);
print
(
'语音错误:
$error
'
);
setState
(()
=>
_isListeningPressed
=
false
);
setState
(()
=>
_isListeningPressed
=
false
);
_showErrorDialog
(
'语音初始化失败,请检查麦克风权限'
);
_showErrorDialog
(
'语音初始化失败,请检查麦克风权限'
);
},
},
);
);
}
catch
(
e
)
{
}
catch
(
e
)
{
print
(
'语音初始化错误:
$e
'
);
print
(
'语音初始化错误:
$e
'
);
_hasSpeechPermission
=
false
;
_hasSpeechPermission
=
false
;
}
}
setState
(()
{});
setState
(()
{});
}
}
Future
<
void
>
startListening
()
async
{
Future
<
void
>
startListening
()
async
{
if
(!
_hasSpeechPermission
)
{
if
(!
_hasSpeechPermission
)
{
_showErrorDialog
(
'请先授予麦克风权限'
);
_showErrorDialog
(
'请先授予麦克风权限'
);
setState
(()
=>
_isListeningPressed
=
false
);
setState
(()
=>
_isListeningPressed
=
false
);
return
;
return
;
}
}
...
@@ -202,7 +222,9 @@ class _HomePageState extends State<HomePage> {
...
@@ -202,7 +222,9 @@ class _HomePageState extends State<HomePage> {
);
);
}
catch
(
e
)
{
}
catch
(
e
)
{
print
(
'开始录音失败:
$e
'
);
print
(
'开始录音失败:
$e
'
);
setState
(()
=>
_isListeningPressed
=
false
);
setState
(()
=>
_isListeningPressed
=
false
);
_showErrorDialog
(
'启动语音识别失败,请重试'
);
_showErrorDialog
(
'启动语音识别失败,请重试'
);
}
}
}
}
...
@@ -409,27 +431,36 @@ class _HomePageState extends State<HomePage> {
...
@@ -409,27 +431,36 @@ class _HomePageState extends State<HomePage> {
onTap:
()
async
{
onTap:
()
async
{
if
(!
_isListeningPressed
)
{
if
(!
_isListeningPressed
)
{
// 开始录音
// 开始录音
setState
(()
{
setState
(()
{
_isListeningPressed
=
true
;
_isListeningPressed
=
true
;
_currentVoiceText
=
''
;
_currentVoiceText
=
''
;
});
});
await
startListening
();
await
startListening
();
}
else
{
}
else
{
// 停止录音
// 停止录音
setState
(()
=>
_isListeningPressed
=
false
);
setState
(()
=>
_isListeningPressed
=
false
);
await
stopListening
();
await
stopListening
();
// 确保有语音文本才处理
// 确保有语音文本才处理
if
(
_currentVoiceText
.
isNotEmpty
)
{
if
(
_currentVoiceText
.
isNotEmpty
)
{
setState
(()
{
setState
(()
{
messages
.
add
(
ChatMessage
(
messages
.
add
(
ChatMessage
(
text:
_currentVoiceText
,
text:
_currentVoiceText
,
isUserMessage:
true
,
isUserMessage:
true
,
));
));
_isLoading
=
true
;
_isLoading
=
true
;
});
});
await
_processAIResponse
(
_currentVoiceText
);
await
_processAIResponse
(
_currentVoiceText
);
}
}
setState
(()
=>
_currentVoiceText
=
''
);
setState
(()
=>
_currentVoiceText
=
''
);
}
}
},
},
...
@@ -454,7 +485,9 @@ class _HomePageState extends State<HomePage> {
...
@@ -454,7 +485,9 @@ class _HomePageState extends State<HomePage> {
const
SizedBox
(
width:
8
),
const
SizedBox
(
width:
8
),
Text
(
Text
(
_isListeningPressed
_isListeningPressed
?
(
_currentVoiceText
.
isEmpty
?
'点击停止'
:
_currentVoiceText
)
?
(
_currentVoiceText
.
isEmpty
?
'点击停止'
:
_currentVoiceText
)
:
'点击说话'
,
:
'点击说话'
,
textAlign:
TextAlign
.
center
,
textAlign:
TextAlign
.
center
,
style:
TextStyle
(
style:
TextStyle
(
...
@@ -904,4 +937,3 @@ class _HomePageState extends State<HomePage> {
...
@@ -904,4 +937,3 @@ class _HomePageState extends State<HomePage> {
);
);
}
}
}
}
\ No newline at end of file
lib/pages/chat_page.dart
浏览文件 @
c2c63647
...
@@ -6,6 +6,7 @@ import 'package:shared_preferences/shared_preferences.dart';
...
@@ -6,6 +6,7 @@ import 'package:shared_preferences/shared_preferences.dart';
import
'../models/app_item.dart'
;
import
'../models/app_item.dart'
;
import
'../services/chat_service.dart'
;
import
'../services/storage_service.dart'
;
import
'../services/storage_service.dart'
;
import
'../home_page.dart'
;
import
'../home_page.dart'
;
...
@@ -22,6 +23,8 @@ class ChatPage extends ConsumerStatefulWidget {
...
@@ -22,6 +23,8 @@ class ChatPage extends ConsumerStatefulWidget {
}
}
class
_ChatPageState
extends
ConsumerState
<
ChatPage
>
{
class
_ChatPageState
extends
ConsumerState
<
ChatPage
>
{
final
OpenAIService
openAIService
=
OpenAIService
();
@override
@override
void
initState
()
{
void
initState
()
{
super
.
initState
();
super
.
initState
();
...
@@ -46,6 +49,12 @@ class _ChatPageState extends ConsumerState<ChatPage> {
...
@@ -46,6 +49,12 @@ class _ChatPageState extends ConsumerState<ChatPage> {
}
}
@override
@override
void
dispose
()
{
openAIService
.
clearConversation
();
super
.
dispose
();
}
@override
Widget
build
(
BuildContext
context
)
{
Widget
build
(
BuildContext
context
)
{
return
Scaffold
(
return
Scaffold
(
appBar:
AppBar
(
appBar:
AppBar
(
...
@@ -78,6 +87,7 @@ class _ChatPageState extends ConsumerState<ChatPage> {
...
@@ -78,6 +87,7 @@ class _ChatPageState extends ConsumerState<ChatPage> {
customDescription:
widget
.
app
.
description
,
customDescription:
widget
.
app
.
description
,
customImageUrl:
widget
.
app
.
iconUrl
,
customImageUrl:
widget
.
app
.
iconUrl
,
hideNavigation:
true
,
hideNavigation:
true
,
openAIService:
openAIService
,
),
),
);
);
}
}
...
...
lib/services/chat_service.dart
浏览文件 @
c2c63647
...
@@ -8,6 +8,32 @@ class OpenAIService {
...
@@ -8,6 +8,32 @@ class OpenAIService {
// final String apiKey = 'sk-OVjS7VE9mT68Uvg7kSFoMnbU6EU836FO';
// final String apiKey = 'sk-OVjS7VE9mT68Uvg7kSFoMnbU6EU836FO';
// final String appKey = 'app-FRP2s2wSx01rsE67';
// final String appKey = 'app-FRP2s2wSx01rsE67';
String
?
conversationId
;
String
?
conversationId
;
bool
_isFirstMessage
=
true
;
Future
<
void
>
_generateConversationName
()
async
{
if
(
conversationId
==
null
)
return
;
var
prefs
=
await
SharedPreferences
.
getInstance
();
var
storageService
=
StorageService
(
prefs
);
String
appKey
=
storageService
.
getWorkbenchToken
()
??
''
;
try
{
final
response
=
await
http
.
post
(
Uri
.
parse
(
'
$baseUrl
/api/conversations/
$conversationId
/name'
),
headers:
{
'Content-Type'
:
'application/json'
,
'Authorization'
:
'Bearer
$appKey
'
,
},
body:
jsonEncode
({
"auto_generate"
:
true
}),
);
if
(
response
.
statusCode
!=
200
)
{
print
(
'生成会话名称失败:
${response.statusCode}
'
);
}
}
catch
(
e
)
{
print
(
'生成会话名称异常:
$e
'
);
}
}
Stream
<
String
>
chatGPTAPI
(
String
message
)
async
*
{
Stream
<
String
>
chatGPTAPI
(
String
message
)
async
*
{
final
client
=
http
.
Client
();
final
client
=
http
.
Client
();
...
@@ -85,11 +111,16 @@ class OpenAIService {
...
@@ -85,11 +111,16 @@ class OpenAIService {
}
catch
(
e
)
{
}
catch
(
e
)
{
throw
Exception
(
e
.
toString
());
throw
Exception
(
e
.
toString
());
}
finally
{
}
finally
{
if
(
_isFirstMessage
&&
conversationId
!=
null
)
{
await
_generateConversationName
();
_isFirstMessage
=
false
;
}
client
.
close
();
client
.
close
();
}
}
}
}
void
clearConversation
()
{
void
clearConversation
()
{
conversationId
=
null
;
conversationId
=
null
;
_isFirstMessage
=
true
;
}
}
}
}
macos/Flutter/GeneratedPluginRegistrant.swift
浏览文件 @
c2c63647
...
@@ -9,12 +9,12 @@ import audioplayers_darwin
...
@@ -9,12 +9,12 @@ import audioplayers_darwin
import
flutter_tts
import
flutter_tts
import
path_provider_foundation
import
path_provider_foundation
import
shared_preferences_foundation
import
shared_preferences_foundation
import
speech_to_text
_macos
import
speech_to_text
func
RegisterGeneratedPlugins
(
registry
:
FlutterPluginRegistry
)
{
func
RegisterGeneratedPlugins
(
registry
:
FlutterPluginRegistry
)
{
AudioplayersDarwinPlugin
.
register
(
with
:
registry
.
registrar
(
forPlugin
:
"AudioplayersDarwinPlugin"
))
AudioplayersDarwinPlugin
.
register
(
with
:
registry
.
registrar
(
forPlugin
:
"AudioplayersDarwinPlugin"
))
FlutterTtsPlugin
.
register
(
with
:
registry
.
registrar
(
forPlugin
:
"FlutterTtsPlugin"
))
FlutterTtsPlugin
.
register
(
with
:
registry
.
registrar
(
forPlugin
:
"FlutterTtsPlugin"
))
PathProviderPlugin
.
register
(
with
:
registry
.
registrar
(
forPlugin
:
"PathProviderPlugin"
))
PathProviderPlugin
.
register
(
with
:
registry
.
registrar
(
forPlugin
:
"PathProviderPlugin"
))
SharedPreferencesPlugin
.
register
(
with
:
registry
.
registrar
(
forPlugin
:
"SharedPreferencesPlugin"
))
SharedPreferencesPlugin
.
register
(
with
:
registry
.
registrar
(
forPlugin
:
"SharedPreferencesPlugin"
))
SpeechToText
MacosPlugin
.
register
(
with
:
registry
.
registrar
(
forPlugin
:
"SpeechToTextMacos
Plugin"
))
SpeechToText
Plugin
.
register
(
with
:
registry
.
registrar
(
forPlugin
:
"SpeechToText
Plugin"
))
}
}
编写
预览
Markdown
格式
0%
重试
或
添加新文件
添加附件
取消
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论