Commit 992c2f82 authored by 关振斌's avatar 关振斌

update

parent 5fcf9f32
// import 'dart:ffi';
import 'package:chart/pages/frame/notfound/index.dart';
import 'package:chart/pages/frame/product/index.dart';
import 'package:flutter/material.dart';
import 'package:flutter_client_sse/flutter_client_sse.dart';
import 'package:get/get.dart';
import 'routes.dart';
......@@ -22,6 +24,17 @@ class RouteObservers<R extends Route<dynamic>> extends RouteObserver<R> {
String? name = route.settings.name;
if (ChatNewController.to.state.isLoading) {
ChatNewController.to.sse?.cancel();
ChatNewController.to.state.isLoading = false;
SSEClient.unsubscribeFromSSE();
}
if (ProductController.to.state.isLoading) {
ProductController.to.sse?.cancel();
ProductController.to.state.isLoading = false;
SSEClient.unsubscribeFromSSE();
}
if (name != null) {
bool isProduct = name.contains('product?title');
......
// baidu yapi
// const SERVER_API_URL = 'https://yapi.baidu.com/mock/41008';
// const SERVER_API_URL = 'http://192.168.110.127:8083/api';
const SERVER_API_URL = 'http://101.34.153.228:8083/api';//线上
// const SERVER_API_URL = 'http://101.34.153.228:8083/api';//线上
const SERVER_API_URL = "http://192.168.120.108:8083/api";
// http://192.168.110.127:8083/api/doc.html
// http://192.168.110.66:8083/api/doc.html
// const SERVER_API_URL = 'http://192.168.110.66:8083/api';
......
......@@ -2,16 +2,21 @@ library dash_chat_2;
import 'dart:math';
import 'package:highlight/highlight.dart' show highlight, Node;
import 'package:animated_text_kit/animated_text_kit.dart';
import 'package:chart/package/markdown/flutter_markdown.dart';
import 'package:flutter/gestures.dart';
import 'package:flutter/material.dart';
import 'package:flutter_markdown/flutter_markdown.dart';
import 'package:flutter_parsed_text/flutter_parsed_text.dart';
import 'package:get/get_connect/http/src/utils/utils.dart';
import 'package:gradient_borders/input_borders/gradient_outline_input_border.dart';
import 'package:highlight/highlight.dart';
import 'package:intl/intl.dart' as intl;
import 'package:url_launcher/url_launcher.dart';
import 'package:video_player/video_player.dart' as vp;
import '../markdown/src/style_sheet.dart';
import 'src/widgets/image_provider/image_provider.dart';
export 'package:flutter_parsed_text/flutter_parsed_text.dart';
......
......@@ -42,9 +42,7 @@ class DefaultAvatar extends StatelessWidget {
onLongPress:
onLongPressAvatar != null ? () => onLongPressAvatar!(user) : null,
child: Padding(
padding: const EdgeInsets.symmetric(
horizontal: 10,
),
padding: const EdgeInsets.symmetric(horizontal: 10),
child: SizedBox(
height: size,
width: size,
......
part of dash_chat_2;
// ignore: non_constant_identifier_names
// part of animated_text_kit;
/// {@category Default widgets}
......@@ -113,11 +114,27 @@ class DefaultMessageText extends StatelessWidget {
// child: Markdown(data: text, selectable: true),
// );
return RichText(
text: TextSpan(text: text, style: TextStyle(color: Colors.black)),
// selectionRegistrar: SelectionContainer.maybeOf(context),
selectionColor: const Color(0xAF6694e8),
return MyMarkdown(
// syntaxHighlighter: SyntaxHighlighter(),
// styleConfig: StyleConfig(),
data: text,
// styleSheet: MarkdownStyleSheet(
// // code: TextStyle(color: Colors.red),
// ),
);
// Column(
// children: [
// Expanded(
// child: Markdown(data: text),
// )
// ],
// );
// RichText(
// text: TextSpan(text: text, style: TextStyle(color: Colors.black)),
// // selectionRegistrar: SelectionContainer.maybeOf(context),
// selectionColor: const Color(0xAF6694e8),
// );
// Markdown(data: text, selectable: true);
}
......@@ -162,3 +179,50 @@ class DefaultMessageText extends StatelessWidget {
);
}
}
class MyStyleSheet extends MarkdownStyleSheet {
@override
// TextStyle codeblockStyle = TextStyle(fontFamily: 'monospace', fontSize: 12.0);
//
@override
// BoxDecoration codeblockDecoration = BoxDecoration(color: Colors.red);
@override
TextStyle codeStyle = TextStyle(fontFamily: 'monospace', color: Colors.red);
@override
Widget codeBlock({
required String code,
required String language,
// required SyntaxHighlighterStyle syntaxHighlighterStyle
}) {
final nodes = highlight.parse(code, language: language);
return Container(
padding: EdgeInsets.all(16.0),
decoration: codeblockDecoration,
child: SingleChildScrollView(
scrollDirection: Axis.horizontal,
child: RichText(
text: TextSpan(
style: codeStyle,
children: _toTextSpan(nodes.nodes!),
),
)));
}
List<TextSpan> _toTextSpan(List<Node> nodes) {
final result = <TextSpan>[];
for (final node in nodes) {
if (node.value != null) {
result.add(TextSpan(text: node.value!, style: TextStyle()));
} else if (node.children != null) {
result.add(TextSpan(
children: _toTextSpan(node.children!),
style: TextStyle(color: node.className == null ? null : Colors.blue),
));
}
}
return result;
}
}
......@@ -71,7 +71,7 @@ class MessageRow extends StatelessWidget {
return Padding(
padding: EdgeInsets.only(top: isPreviousSameAuthor ? 2 : 15),
child: Row(
crossAxisAlignment: CrossAxisAlignment.end,
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment:
isOwnMessage ? MainAxisAlignment.end : MainAxisAlignment.start,
children: <Widget>[
......
......@@ -83,9 +83,7 @@ class TextContainer extends StatelessWidget {
: 18.0,
),
padding: messageOptions.messagePadding ?? const EdgeInsets.all(11),
child: messageTextBuilder != null
? messageTextBuilder!(message, previousMessage, nextMessage)
: DefaultMessageText(
child: DefaultMessageText(
index: index,
messageLength: messageLength,
message: message,
......@@ -95,3 +93,6 @@ class TextContainer extends StatelessWidget {
);
}
}
// messageTextBuilder != null
// ? messageTextBuilder!(message, previousMessage, nextMessage)
// :
\ No newline at end of file
// Copyright 2013 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
/// A library to render markdown formatted text.
library flutter_markdown;
export 'src/builder.dart';
export 'src/style_sheet.dart';
export 'src/widget.dart';
// Copyright 2013 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import 'dart:io';
import 'package:flutter/cupertino.dart' show CupertinoTheme;
import 'package:flutter/material.dart' show Theme;
import 'package:flutter/widgets.dart';
import 'style_sheet.dart';
import 'widget.dart';
/// Type for a function that creates image widgets.
typedef ImageBuilder = Widget Function(
Uri uri, String? imageDirectory, double? width, double? height);
/// A default image builder handling http/https, resource, and file URLs.
// ignore: prefer_function_declarations_over_variables
final ImageBuilder kDefaultImageBuilder = (
Uri uri,
String? imageDirectory,
double? width,
double? height,
) {
if (uri.scheme == 'http' || uri.scheme == 'https') {
return Image.network(uri.toString(), width: width, height: height);
} else if (uri.scheme == 'data') {
return _handleDataSchemeUri(uri, width, height);
} else if (uri.scheme == 'resource') {
return Image.asset(uri.path, width: width, height: height);
} else {
final Uri fileUri = imageDirectory != null
? Uri.parse(imageDirectory + uri.toString())
: uri;
if (fileUri.scheme == 'http' || fileUri.scheme == 'https') {
return Image.network(fileUri.toString(), width: width, height: height);
} else {
return Image.file(File.fromUri(fileUri), width: width, height: height);
}
}
};
/// A default style sheet generator.
final MarkdownStyleSheet Function(BuildContext, MarkdownStyleSheetBaseTheme?)
// ignore: prefer_function_declarations_over_variables
kFallbackStyle = (
BuildContext context,
MarkdownStyleSheetBaseTheme? baseTheme,
) {
MarkdownStyleSheet result;
switch (baseTheme) {
case MarkdownStyleSheetBaseTheme.platform:
result = (Platform.isIOS || Platform.isMacOS)
? MarkdownStyleSheet.fromCupertinoTheme(CupertinoTheme.of(context))
: MarkdownStyleSheet.fromTheme(Theme.of(context));
break;
case MarkdownStyleSheetBaseTheme.cupertino:
result =
MarkdownStyleSheet.fromCupertinoTheme(CupertinoTheme.of(context));
break;
case MarkdownStyleSheetBaseTheme.material:
// ignore: no_default_cases
default:
result = MarkdownStyleSheet.fromTheme(Theme.of(context));
}
return result.copyWith(
textScaleFactor: MediaQuery.textScaleFactorOf(context),
);
};
Widget _handleDataSchemeUri(
Uri uri, final double? width, final double? height) {
final String mimeType = uri.data!.mimeType;
if (mimeType.startsWith('image/')) {
return Image.memory(
uri.data!.contentAsBytes(),
width: width,
height: height,
);
} else if (mimeType.startsWith('text/')) {
return Text(uri.data!.contentAsString());
}
return const SizedBox();
}
// Copyright 2013 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import 'dart:html'; // ignore: avoid_web_libraries_in_flutter
import 'package:flutter/cupertino.dart' show CupertinoTheme;
import 'package:flutter/material.dart' show Theme;
import 'package:flutter/widgets.dart';
import 'package:path/path.dart' as p;
import 'style_sheet.dart';
import 'widget.dart';
/// Type for a function that creates image widgets.
typedef ImageBuilder = Widget Function(
Uri uri, String? imageDirectory, double? width, double? height);
/// A default image builder handling http/https, resource, data, and file URLs.
// ignore: prefer_function_declarations_over_variables
final ImageBuilder kDefaultImageBuilder = (
Uri uri,
String? imageDirectory,
double? width,
double? height,
) {
if (uri.scheme == 'http' || uri.scheme == 'https') {
return Image.network(uri.toString(), width: width, height: height);
} else if (uri.scheme == 'data') {
return _handleDataSchemeUri(uri, width, height);
} else if (uri.scheme == 'resource') {
return Image.asset(uri.path, width: width, height: height);
} else {
final Uri fileUri = imageDirectory != null
? Uri.parse(p.join(imageDirectory, uri.toString()))
: uri;
if (fileUri.scheme == 'http' || fileUri.scheme == 'https') {
return Image.network(fileUri.toString(), width: width, height: height);
} else {
final String src = p.join(p.current, fileUri.toString());
return Image.network(src, width: width, height: height);
}
}
};
/// A default style sheet generator.
final MarkdownStyleSheet Function(BuildContext, MarkdownStyleSheetBaseTheme?)
// ignore: prefer_function_declarations_over_variables
kFallbackStyle = (
BuildContext context,
MarkdownStyleSheetBaseTheme? baseTheme,
) {
MarkdownStyleSheet result;
switch (baseTheme) {
case MarkdownStyleSheetBaseTheme.platform:
final String userAgent = window.navigator.userAgent;
result = userAgent.contains('Mac OS X')
? MarkdownStyleSheet.fromCupertinoTheme(CupertinoTheme.of(context))
: MarkdownStyleSheet.fromTheme(Theme.of(context));
break;
case MarkdownStyleSheetBaseTheme.cupertino:
result =
MarkdownStyleSheet.fromCupertinoTheme(CupertinoTheme.of(context));
break;
case MarkdownStyleSheetBaseTheme.material:
default: // ignore: no_default_cases
result = MarkdownStyleSheet.fromTheme(Theme.of(context));
}
return result.copyWith(
textScaleFactor: MediaQuery.textScaleFactorOf(context),
);
};
Widget _handleDataSchemeUri(
Uri uri, final double? width, final double? height) {
final String mimeType = uri.data!.mimeType;
if (mimeType.startsWith('image/')) {
return Image.memory(
uri.data!.contentAsBytes(),
width: width,
height: height,
);
} else if (mimeType.startsWith('text/')) {
return Text(uri.data!.contentAsString());
}
return const SizedBox();
}
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
......@@ -20,11 +20,13 @@ import 'index.dart';
import 'package:eventsource/eventsource.dart';
import 'dart:convert';
import 'package:flutter/services.dart';
import 'package:flutter_client_sse/flutter_client_sse.dart';
// EventSource eventSource = EventSource(Uri.parse('http://example.com/events'));
//
class ChatNewController extends GetxController {
ChatNewController();
static ChatNewController get to => Get.put(ChatNewController());
/// 响应式成员变量
......@@ -32,6 +34,9 @@ class ChatNewController extends GetxController {
late StreamSubscription<Event> eventSource;
// ignore: prefer_typing_uninitialized_variables
late var sse;
/// 成员变量
/// 事件
......@@ -93,6 +98,7 @@ class ChatNewController extends GetxController {
// );
_addMessage(textMessage);
// _addMessage(loadingMessage);
// ("正在思考中...");
......@@ -100,10 +106,13 @@ class ChatNewController extends GetxController {
try {
// print("1321312321${UserStore.to.profile.id}");
if (UserStore.to.profile.id != '') {
await initEventSource();
state.isLoading = true;
int? result =
await NewsAPI.aiAnswerWithStream({"question": message.text});
// _cancelLoading();
// print(
// "eventSource.isPausedeventSource.isPausedeventSource.isPaused---------------${eventSource.isPaused}");
if (result == 200) {
EasyLoading.dismiss();
......@@ -143,7 +152,7 @@ class ChatNewController extends GetxController {
Vibrate.feedback(FeedbackType.error);
}
} catch (e) {
// print("eeeeeeee$e");
print("eeeeeeee$e");
state.isLoading = false;
// _cancelLoading();
final receiveErrorMessage = Chat.ChatMessage(
......@@ -200,24 +209,20 @@ class ChatNewController extends GetxController {
}
initEventSource() async {
final eventSourceUrl = await EventSource.connect(
"$SERVER_API_URL/openAi/connect/${UserStore.to.profile.id}")
as EventSource;
eventSource = eventSourceUrl.listen(
(Event event) {
// print("New event:");
// print(" event: ${event.event}");
// print(" data: ${event.data}");
// final a = json['event.data'];
if (event.data == "[DONE]") {
// if (UserStore.to.isLogin) {
sse = SSEClient.subscribeToSSE(
url: "$SERVER_API_URL/openAi/connect/${UserStore.to.profile.id}",
header: {}).listen((event) {
if (event.id == "[DONE]") {
state.isLoading = false;
// SSEClient.unsubscribeFromSSE();
// eventSource.cancel();
return;
}
print('Id: ' + event.id!);
print('Event: ' + event.event!);
print('Data: ' + event.data!);
Map<String, dynamic> jsonMap = jsonDecode("${event.data}");
// if()
if (jsonMap['askType'] == 1) {
_updateMessage("${jsonMap['content']}" as String);
} else {
......@@ -227,20 +232,7 @@ class ChatNewController extends GetxController {
ProductController.to.state.inderText + jsonMap['content'];
// state.genText
}
// list.setRange(1, 4, [9, 9, 9]);
// final receiveMessage = Chat.ChatMessage(
// user: receiveUser,
// createdAt: DateTime.now(),
// // id: const Uuid().v4(),
// text: "${event.data}",
// );
// _addMessage(receiveMessage);
},
);
// eventSource.onOpen.listen();
// eventSource
});
}
_updateMessage(String text) {
......@@ -286,12 +278,25 @@ class ChatNewController extends GetxController {
Get.snackbar("复制成功", "", colorText: Colors.white);
}
@override
void onReady() async {
print("1____________________onReadyonReadyonReadyonReadyonReady");
super.onReady();
}
@override
void onClose() {
print("222____________________onCloseonCloseonCloseonCloseonCloseonClose");
super.onClose();
}
/// 生命周期
@override
void onInit() async {
// await initEventSource();
// connect("http://example.org/events");
// http://192.168.110.127:8083/api/openAi/connect
await initEventSource();
// await initEventSource();
super.onInit();
// ever(Get.parameters['question'].obs, (value) {
......@@ -302,6 +307,7 @@ class ChatNewController extends GetxController {
///dispose 释放内存
@override
void dispose() {
print("disposedisposedisposedisposedispose");
super.dispose();
// dispose 释放对象
// refreshController.dispose();
......
......@@ -31,7 +31,17 @@ class ChatNewPage extends GetView<ChatNewController> {
// ),
// )
// final c = Get.put(ChatNewController());
return Obx(() => Scaffold(
// return WillPopScope(
// onWillPop: () async {
// 禁止返回
// return false;
// },
return WillPopScope(
onWillPop: () async {
return false;
},
child: Obx(() => Scaffold(
appBar: transparentAppBar(
actions: [
IconButton(
......@@ -208,7 +218,7 @@ class ChatNewPage extends GetView<ChatNewController> {
)
// Obx(() => )),
));
)));
}
}
......
......@@ -8,6 +8,7 @@ import 'package:eventsource/eventsource.dart';
// import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_client_sse/flutter_client_sse.dart';
import 'package:flutter_easyloading/flutter_easyloading.dart';
import 'package:get/get_connect/http/src/utils/utils.dart';
import 'package:share_plus/share_plus.dart';
......@@ -18,12 +19,13 @@ import 'index.dart';
class ProductController extends GetxController {
static ProductController get to => Get.put(ProductController());
// ProductController();
// late var sse;
/// 响应式成员变量
final state = ProductState();
late EventSource eventSourceConnect;
late final List<String> initDataList;
late var sse;
TextEditingController controller1 = TextEditingController();
TextEditingController controller2 = TextEditingController();
......@@ -63,6 +65,25 @@ class ProductController extends GetxController {
// 初始静态数据
}
initEventSource() async {
// if (UserStore.to.isLogin) {
sse = SSEClient.subscribeToSSE(
url: "$SERVER_API_URL/openAi/connect/${UserStore.to.profile.id}",
header: {}).listen((event) {
if (event.id == "[DONE]") {
state.isLoading = false;
return;
}
Map<String, dynamic> jsonMap = jsonDecode("${event.data}");
if (jsonMap['askType'] == 1) {
// _updateMessage("${jsonMap['content']}" as String);
} else {
state.inderText = state.inderText + jsonMap['content'];
// state.genText
}
});
}
share() async {
if (state.inderText?.isNotEmpty) {
await Share.share(
......@@ -119,6 +140,8 @@ class ProductController extends GetxController {
// json.encode(map);
if (UserStore.to.isLogin) {
state.isLoading = true;
await initEventSource();
int result = await NewsAPI.sendMessageByDetailId([
{
"label": params['firstLabel'],
......@@ -146,6 +169,7 @@ class ProductController extends GetxController {
});
} else {
EasyLoading.dismiss();
state.isLoading = false;
}
// state.genText = result;
......
......@@ -28,6 +28,10 @@ class ProductState {
set inderText(value) => _inderText.value = value;
get inderText => _inderText.value;
final _isLoading = false.obs;
set isLoading(value) => _isLoading.value = value;
get isLoading => _isLoading.value;
RxList<MessageQueenItem> messageQueenItemQueen = <MessageQueenItem>[].obs;
}
......
......@@ -95,7 +95,8 @@ class NewsCategoriesWidget extends GetView<MainController> {
if (GetPlatform.isAndroid) {
Get.toNamed(AppRoutes.AN_PAY_LIST);
} else {
Get.toNamed(AppRoutes.PAY_LIST);
Get.toNamed(AppRoutes.AN_PAY_LIST);
// Get.toNamed(AppRoutes.PAY_LIST);
}
// AN_PAY_LIST
......
......@@ -386,7 +386,8 @@ class UserDetailPage extends GetView<UserDetailController> {
if (GetPlatform.isAndroid) {
Get.toNamed(AppRoutes.AN_PAY_LIST);
} else {
Get.toNamed(AppRoutes.PAY_LIST);
Get.toNamed(AppRoutes.AN_PAY_LIST);
// Get.toNamed(AppRoutes.PAY_LIST);
}
} else {
Get.toNamed(AppRoutes.SIGN_IN);
......
......@@ -398,6 +398,13 @@ packages:
url: "https://pub.dartlang.org"
source: hosted
version: "1.6.6"
flutter_client_sse:
dependency: "direct main"
description:
name: flutter_client_sse
url: "https://pub.dartlang.org"
source: hosted
version: "1.0.0"
flutter_easyloading:
dependency: "direct main"
description:
......@@ -623,6 +630,13 @@ packages:
url: "https://pub.dartlang.org"
source: hosted
version: "0.6.0"
highlight:
dependency: "direct main"
description:
name: highlight
url: "https://pub.dartlang.org"
source: hosted
version: "0.7.0"
html:
dependency: transitive
description:
......
......@@ -115,6 +115,8 @@ dependencies:
alipay_kit_ios: 5.0.0
pointycastle: ^3.1.1
eventsource: ^0.4.0
flutter_client_sse: ^1.0.0
highlight: ^0.7.0
# package:bubble/bubble.dart
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment