对接接口
This commit is contained in:
parent
43b55b378d
commit
c11454b75d
|
|
@ -1,19 +0,0 @@
|
|||
|
||||
import 'package:json_annotation/json_annotation.dart';
|
||||
|
||||
part 'MessageBean.g.dart';
|
||||
|
||||
@JsonSerializable(explicitToJson: true)
|
||||
class MessageBean{
|
||||
|
||||
String? role;
|
||||
String? content;
|
||||
|
||||
|
||||
MessageBean(this.role,this.content,);
|
||||
|
||||
factory MessageBean.fromJson(Map<String, dynamic> json) => _$MessageBeanFromJson(json);
|
||||
|
||||
Map<String, dynamic> toJson() => _$MessageBeanToJson(this);
|
||||
|
||||
}
|
||||
23
lib/beans/category_info_list_bean.dart
Normal file
23
lib/beans/category_info_list_bean.dart
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
import 'package:json_annotation/json_annotation.dart';
|
||||
|
||||
import 'label_bean.dart';
|
||||
|
||||
part 'category_info_list_bean.g.dart';
|
||||
|
||||
///人物信息
|
||||
@JsonSerializable(explicitToJson: true)
|
||||
class CategoryInfoListBean {
|
||||
int? id; //
|
||||
String? name; //
|
||||
String? biography;
|
||||
int? lookCount;
|
||||
String? bgImage;
|
||||
String? iconImage;
|
||||
List<LabelBean>? label;
|
||||
|
||||
CategoryInfoListBean(this.id, this.name, this.biography, this.lookCount, this.bgImage, this.iconImage, this.label);
|
||||
|
||||
factory CategoryInfoListBean.fromJson(Map<String, dynamic> json) => _$CategoryInfoListBeanFromJson(json);
|
||||
|
||||
Map<String, dynamic> toJson() => _$CategoryInfoListBeanToJson(this);
|
||||
}
|
||||
33
lib/beans/category_info_list_bean.g.dart
Normal file
33
lib/beans/category_info_list_bean.g.dart
Normal file
|
|
@ -0,0 +1,33 @@
|
|||
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||
|
||||
part of 'category_info_list_bean.dart';
|
||||
|
||||
// **************************************************************************
|
||||
// JsonSerializableGenerator
|
||||
// **************************************************************************
|
||||
|
||||
CategoryInfoListBean _$CategoryInfoListBeanFromJson(
|
||||
Map<String, dynamic> json) =>
|
||||
CategoryInfoListBean(
|
||||
(json['id'] as num?)?.toInt(),
|
||||
json['name'] as String?,
|
||||
json['biography'] as String?,
|
||||
(json['lookCount'] as num?)?.toInt(),
|
||||
json['bgImage'] as String?,
|
||||
json['iconImage'] as String?,
|
||||
(json['label'] as List<dynamic>?)
|
||||
?.map((e) => LabelBean.fromJson(e as Map<String, dynamic>))
|
||||
.toList(),
|
||||
);
|
||||
|
||||
Map<String, dynamic> _$CategoryInfoListBeanToJson(
|
||||
CategoryInfoListBean instance) =>
|
||||
<String, dynamic>{
|
||||
'id': instance.id,
|
||||
'name': instance.name,
|
||||
'biography': instance.biography,
|
||||
'lookCount': instance.lookCount,
|
||||
'bgImage': instance.bgImage,
|
||||
'iconImage': instance.iconImage,
|
||||
'label': instance.label?.map((e) => e.toJson()).toList(),
|
||||
};
|
||||
|
|
@ -4,7 +4,7 @@ import 'label_bean.dart';
|
|||
|
||||
part 'character_info_bean.g.dart';
|
||||
|
||||
///任务信息
|
||||
///人物信息
|
||||
@JsonSerializable(explicitToJson: true)
|
||||
class CharacterInfoBean {
|
||||
String? icon;
|
||||
|
|
|
|||
21
lib/beans/chat_info_bean.dart
Normal file
21
lib/beans/chat_info_bean.dart
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
import 'package:json_annotation/json_annotation.dart';
|
||||
|
||||
part 'chat_info_bean.g.dart';
|
||||
|
||||
///聊天历史记录
|
||||
@JsonSerializable(explicitToJson: true)
|
||||
class ChatInfoBean {
|
||||
int? id;
|
||||
String? role;
|
||||
String? content;
|
||||
String? timestamp;
|
||||
String? claudeType;
|
||||
int? messageType;
|
||||
String? userIcon;
|
||||
|
||||
ChatInfoBean(this.id, this.role, this.content, this.timestamp, this.claudeType, this.messageType, this.userIcon);
|
||||
|
||||
factory ChatInfoBean.fromJson(Map<String, dynamic> json) => _$ChatInfoBeanFromJson(json);
|
||||
|
||||
Map<String, dynamic> toJson() => _$ChatInfoBeanToJson(this);
|
||||
}
|
||||
28
lib/beans/chat_info_bean.g.dart
Normal file
28
lib/beans/chat_info_bean.g.dart
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||
|
||||
part of 'chat_info_bean.dart';
|
||||
|
||||
// **************************************************************************
|
||||
// JsonSerializableGenerator
|
||||
// **************************************************************************
|
||||
|
||||
ChatInfoBean _$ChatInfoBeanFromJson(Map<String, dynamic> json) => ChatInfoBean(
|
||||
(json['id'] as num?)?.toInt(),
|
||||
json['role'] as String?,
|
||||
json['content'] as String?,
|
||||
json['timestamp'] as String?,
|
||||
json['claudeType'] as String?,
|
||||
(json['messageType'] as num?)?.toInt(),
|
||||
json['userIcon'] as String?,
|
||||
);
|
||||
|
||||
Map<String, dynamic> _$ChatInfoBeanToJson(ChatInfoBean instance) =>
|
||||
<String, dynamic>{
|
||||
'id': instance.id,
|
||||
'role': instance.role,
|
||||
'content': instance.content,
|
||||
'timestamp': instance.timestamp,
|
||||
'claudeType': instance.claudeType,
|
||||
'messageType': instance.messageType,
|
||||
'userIcon': instance.userIcon,
|
||||
};
|
||||
17
lib/beans/find_banner_bean.dart
Normal file
17
lib/beans/find_banner_bean.dart
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
import 'package:json_annotation/json_annotation.dart';
|
||||
|
||||
part 'find_banner_bean.g.dart';
|
||||
|
||||
///标签
|
||||
@JsonSerializable(explicitToJson: true)
|
||||
class FindBannerBean {
|
||||
String? imageUrl;
|
||||
String? actionType;
|
||||
String? actionId;
|
||||
|
||||
FindBannerBean(this.imageUrl, this.actionType, this.actionId);
|
||||
|
||||
factory FindBannerBean.fromJson(Map<String, dynamic> json) => _$FindBannerBeanFromJson(json);
|
||||
|
||||
Map<String, dynamic> toJson() => _$FindBannerBeanToJson(this);
|
||||
}
|
||||
21
lib/beans/find_banner_bean.g.dart
Normal file
21
lib/beans/find_banner_bean.g.dart
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||
|
||||
part of 'find_banner_bean.dart';
|
||||
|
||||
// **************************************************************************
|
||||
// JsonSerializableGenerator
|
||||
// **************************************************************************
|
||||
|
||||
FindBannerBean _$FindBannerBeanFromJson(Map<String, dynamic> json) =>
|
||||
FindBannerBean(
|
||||
json['imageUrl'] as String?,
|
||||
json['actionType'] as String?,
|
||||
json['actionId'] as String?,
|
||||
);
|
||||
|
||||
Map<String, dynamic> _$FindBannerBeanToJson(FindBannerBean instance) =>
|
||||
<String, dynamic>{
|
||||
'imageUrl': instance.imageUrl,
|
||||
'actionType': instance.actionType,
|
||||
'actionId': instance.actionId,
|
||||
};
|
||||
16
lib/beans/find_type_bean.dart
Normal file
16
lib/beans/find_type_bean.dart
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
import 'package:json_annotation/json_annotation.dart';
|
||||
|
||||
part 'find_type_bean.g.dart';
|
||||
|
||||
///标签
|
||||
@JsonSerializable(explicitToJson: true)
|
||||
class FindTypeBean {
|
||||
int? id;
|
||||
String? name;
|
||||
|
||||
FindTypeBean(this.id, this.name);
|
||||
|
||||
factory FindTypeBean.fromJson(Map<String, dynamic> json) => _$FindTypeBeanFromJson(json);
|
||||
|
||||
Map<String, dynamic> toJson() => _$FindTypeBeanToJson(this);
|
||||
}
|
||||
18
lib/beans/find_type_bean.g.dart
Normal file
18
lib/beans/find_type_bean.g.dart
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||
|
||||
part of 'find_type_bean.dart';
|
||||
|
||||
// **************************************************************************
|
||||
// JsonSerializableGenerator
|
||||
// **************************************************************************
|
||||
|
||||
FindTypeBean _$FindTypeBeanFromJson(Map<String, dynamic> json) => FindTypeBean(
|
||||
(json['id'] as num?)?.toInt(),
|
||||
json['name'] as String?,
|
||||
);
|
||||
|
||||
Map<String, dynamic> _$FindTypeBeanToJson(FindTypeBean instance) =>
|
||||
<String, dynamic>{
|
||||
'id': instance.id,
|
||||
'name': instance.name,
|
||||
};
|
||||
19
lib/beans/message_bean.dart
Normal file
19
lib/beans/message_bean.dart
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
import 'package:json_annotation/json_annotation.dart';
|
||||
|
||||
part 'message_bean.g.dart';
|
||||
|
||||
///标签
|
||||
@JsonSerializable(explicitToJson: true)
|
||||
class MessageBean {
|
||||
int? id;
|
||||
String? name;
|
||||
String? biography;
|
||||
String? iconImage;
|
||||
String? lastContactTime;
|
||||
|
||||
MessageBean(this.id, this.name, this.biography, this.iconImage, this.lastContactTime);
|
||||
|
||||
factory MessageBean.fromJson(Map<String, dynamic> json) => _$MessageBeanFromJson(json);
|
||||
|
||||
Map<String, dynamic> toJson() => _$MessageBeanToJson(this);
|
||||
}
|
||||
|
|
@ -1,18 +1,24 @@
|
|||
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||
|
||||
part of 'MessageBean.dart';
|
||||
part of 'message_bean.dart';
|
||||
|
||||
// **************************************************************************
|
||||
// JsonSerializableGenerator
|
||||
// **************************************************************************
|
||||
|
||||
MessageBean _$MessageBeanFromJson(Map<String, dynamic> json) => MessageBean(
|
||||
json['role'] as String?,
|
||||
json['content'] as String?,
|
||||
(json['id'] as num?)?.toInt(),
|
||||
json['name'] as String?,
|
||||
json['biography'] as String?,
|
||||
json['iconImage'] as String?,
|
||||
json['lastContactTime'] as String?,
|
||||
);
|
||||
|
||||
Map<String, dynamic> _$MessageBeanToJson(MessageBean instance) =>
|
||||
<String, dynamic>{
|
||||
'role': instance.role,
|
||||
'content': instance.content,
|
||||
'id': instance.id,
|
||||
'name': instance.name,
|
||||
'biography': instance.biography,
|
||||
'iconImage': instance.iconImage,
|
||||
'lastContactTime': instance.lastContactTime,
|
||||
};
|
||||
25
lib/beans/recommend_bean.dart
Normal file
25
lib/beans/recommend_bean.dart
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
import 'package:json_annotation/json_annotation.dart';
|
||||
|
||||
import 'label_bean.dart';
|
||||
|
||||
part 'recommend_bean.g.dart';
|
||||
|
||||
///标签
|
||||
@JsonSerializable(explicitToJson: true)
|
||||
class RecommendBean {
|
||||
int? id;
|
||||
String? bgImage;
|
||||
String? name;
|
||||
String? biography;
|
||||
int? gender;
|
||||
List<LabelBean>? label;
|
||||
String? imageUrl;
|
||||
String? actionType;
|
||||
String? actionId;
|
||||
|
||||
RecommendBean(this.id, this.bgImage, this.name, this.biography, this.gender, this.label, this.imageUrl, this.actionType, this.actionId);
|
||||
|
||||
factory RecommendBean.fromJson(Map<String, dynamic> json) => _$RecommendBeanFromJson(json);
|
||||
|
||||
Map<String, dynamic> toJson() => _$RecommendBeanToJson(this);
|
||||
}
|
||||
35
lib/beans/recommend_bean.g.dart
Normal file
35
lib/beans/recommend_bean.g.dart
Normal file
|
|
@ -0,0 +1,35 @@
|
|||
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||
|
||||
part of 'recommend_bean.dart';
|
||||
|
||||
// **************************************************************************
|
||||
// JsonSerializableGenerator
|
||||
// **************************************************************************
|
||||
|
||||
RecommendBean _$RecommendBeanFromJson(Map<String, dynamic> json) =>
|
||||
RecommendBean(
|
||||
(json['id'] as num?)?.toInt(),
|
||||
json['bgImage'] as String?,
|
||||
json['name'] as String?,
|
||||
json['biography'] as String?,
|
||||
(json['gender'] as num?)?.toInt(),
|
||||
(json['label'] as List<dynamic>?)
|
||||
?.map((e) => LabelBean.fromJson(e as Map<String, dynamic>))
|
||||
.toList(),
|
||||
json['imageUrl'] as String?,
|
||||
json['actionType'] as String?,
|
||||
json['actionId'] as String?,
|
||||
);
|
||||
|
||||
Map<String, dynamic> _$RecommendBeanToJson(RecommendBean instance) =>
|
||||
<String, dynamic>{
|
||||
'id': instance.id,
|
||||
'bgImage': instance.bgImage,
|
||||
'name': instance.name,
|
||||
'biography': instance.biography,
|
||||
'gender': instance.gender,
|
||||
'label': instance.label?.map((e) => e.toJson()).toList(),
|
||||
'imageUrl': instance.imageUrl,
|
||||
'actionType': instance.actionType,
|
||||
'actionId': instance.actionId,
|
||||
};
|
||||
19
lib/beans/send_message_bean.dart
Normal file
19
lib/beans/send_message_bean.dart
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
import 'package:json_annotation/json_annotation.dart';
|
||||
|
||||
import 'chat_info_bean.dart';
|
||||
|
||||
part 'send_message_bean.g.dart';
|
||||
|
||||
///发送消息对话
|
||||
@JsonSerializable(explicitToJson: true)
|
||||
class SendMessageBean {
|
||||
List<ChatInfoBean>? chatList;
|
||||
int? remainingChatCount;
|
||||
int? lastMessageId;
|
||||
|
||||
SendMessageBean(this.chatList, this.remainingChatCount, this.lastMessageId);
|
||||
|
||||
factory SendMessageBean.fromJson(Map<String, dynamic> json) => _$SendMessageBeanFromJson(json);
|
||||
|
||||
Map<String, dynamic> toJson() => _$SendMessageBeanToJson(this);
|
||||
}
|
||||
23
lib/beans/send_message_bean.g.dart
Normal file
23
lib/beans/send_message_bean.g.dart
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||
|
||||
part of 'send_message_bean.dart';
|
||||
|
||||
// **************************************************************************
|
||||
// JsonSerializableGenerator
|
||||
// **************************************************************************
|
||||
|
||||
SendMessageBean _$SendMessageBeanFromJson(Map<String, dynamic> json) =>
|
||||
SendMessageBean(
|
||||
(json['chatList'] as List<dynamic>?)
|
||||
?.map((e) => ChatInfoBean.fromJson(e as Map<String, dynamic>))
|
||||
.toList(),
|
||||
(json['remainingChatCount'] as num?)?.toInt(),
|
||||
(json['lastMessageId'] as num?)?.toInt(),
|
||||
);
|
||||
|
||||
Map<String, dynamic> _$SendMessageBeanToJson(SendMessageBean instance) =>
|
||||
<String, dynamic>{
|
||||
'chatList': instance.chatList?.map((e) => e.toJson()).toList(),
|
||||
'remainingChatCount': instance.remainingChatCount,
|
||||
'lastMessageId': instance.lastMessageId,
|
||||
};
|
||||
16
lib/custom/easy_load.dart
Normal file
16
lib/custom/easy_load.dart
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_easyloading/flutter_easyloading.dart';
|
||||
import 'package:flutter_spinkit/flutter_spinkit.dart';
|
||||
|
||||
class EasyLoad {
|
||||
// static show() {
|
||||
// EasyLoading.show(
|
||||
// indicator: SpinKitPumpingHeart(
|
||||
// color: Colors.red,
|
||||
// size: 30.0,
|
||||
// ), loadingStyle = EasyLoadingStyle.dark
|
||||
// // text: 'Loading...',
|
||||
// // maskColor: 'transparent',
|
||||
// );
|
||||
// }
|
||||
}
|
||||
|
|
@ -35,6 +35,20 @@ class NetworkConfig {
|
|||
|
||||
static const String getChatInfo = "api/Chat/GetChatInfo"; //获取聊天内容
|
||||
|
||||
static const String sendMessage = "api/Chat/SendMessage"; //发送消息
|
||||
|
||||
static const String delChatByIds = "api/Chat/DelChatByIds"; //删除单条或多条信息
|
||||
|
||||
static const String delChat = "api/Chat/DelChat"; //清空聊天信息(重启聊天)
|
||||
|
||||
static const String getChatHistoryList = "api/Chat/GetChatHistoryList"; //消息列表
|
||||
|
||||
static const String getCategoryList = "api/Category/GetCategoryList"; //发现-获取分类列表
|
||||
|
||||
static const String getCategoryInfoList = "api/Category/GetCategoryInfoList"; //发现-复用页面角色信息
|
||||
|
||||
static const String getCategoryFindList = "api/Category/GetCategoryFindList"; //发现-第一页固定内容
|
||||
|
||||
static const String chat = "/v1/chat/completions"; //聊天
|
||||
|
||||
static const String uploadImg = "/upload/image"; //审核模式上传图片
|
||||
|
|
|
|||
|
|
@ -1,6 +1,5 @@
|
|||
import 'dart:async';
|
||||
import 'dart:convert';
|
||||
import 'dart:typed_data';
|
||||
|
||||
import 'package:crypto/crypto.dart';
|
||||
import 'package:dio/dio.dart';
|
||||
|
|
@ -95,7 +94,12 @@ class RequestCenter {
|
|||
{RequestMethod? method}) async {
|
||||
try {
|
||||
//FormData formData = FormData.fromMap(parmeters);
|
||||
Response response = await _dio!.post(path, data: parmeters);
|
||||
Response response = await _dio!.post(path, data: parmeters,
|
||||
options: Options(
|
||||
headers: {
|
||||
'Authorization': "Bearer ${NetworkConfig.token}"
|
||||
},
|
||||
));
|
||||
BaseEntity entity = BaseEntity.PlayfromJson(response.data);
|
||||
success(entity);
|
||||
return entity;
|
||||
|
|
@ -113,7 +117,12 @@ class RequestCenter {
|
|||
{RequestMethod? method}) async {
|
||||
try {
|
||||
//FormData formData = FormData.fromMap(parmeters);
|
||||
Response response = await _dio!.get(path, queryParameters: parmeters);
|
||||
Response response = await _dio!.get(path, queryParameters: parmeters,
|
||||
options: Options(
|
||||
headers: {
|
||||
'Authorization': "Bearer ${NetworkConfig.token}"
|
||||
},
|
||||
));
|
||||
BaseEntity entity = BaseEntity.PlayfromJson(response.data);
|
||||
success(entity);
|
||||
return entity;
|
||||
|
|
|
|||
|
|
@ -4,7 +4,8 @@ import 'package:talk/network/NetworkConfig.dart';
|
|||
import 'package:talk/network/RequestCenter.dart';
|
||||
|
||||
import '../../beans/character_info_bean.dart';
|
||||
import '../../beans/home_character_bean.dart';
|
||||
import '../../beans/chat_info_bean.dart';
|
||||
import '../../beans/send_message_bean.dart';
|
||||
import '../../network/BaseEntity.dart';
|
||||
|
||||
class ChatModel {
|
||||
|
|
@ -19,7 +20,6 @@ class ChatModel {
|
|||
///获取人物信息
|
||||
Future<void> getCharacterInfo(characterId) async {
|
||||
RequestCenter.instance.requestGet(NetworkConfig.getCharacterInfo, {"characterId": characterId}, (BaseEntity dataEntity) {
|
||||
print("dataEntity==$dataEntity");
|
||||
|
||||
if (dataEntity.code == 0) {
|
||||
CharacterInfoBean characterInfoBean = CharacterInfoBean.fromJson(dataEntity.data);
|
||||
|
|
@ -45,11 +45,84 @@ class ChatModel {
|
|||
print("dataEntity==$dataEntity");
|
||||
|
||||
if (dataEntity.code == 0) {
|
||||
CharacterInfoBean characterInfoBean = CharacterInfoBean.fromJson(dataEntity.data);
|
||||
List<ChatInfoBean> data = (dataEntity.data as List<dynamic>).map((e) => ChatInfoBean.fromJson(e as Map<String, dynamic>)).toList();
|
||||
|
||||
streamController.sink.add({
|
||||
'code': "getChatInfo", //有数据
|
||||
'data': characterInfoBean
|
||||
'data': data
|
||||
});
|
||||
} else {
|
||||
streamController.sink.add({
|
||||
'code': "-1", //有数据
|
||||
'data': dataEntity.message
|
||||
});
|
||||
}
|
||||
}, (ErrorEntity errorEntity) {
|
||||
print("errorEntity==${errorEntity.message}");
|
||||
});
|
||||
}
|
||||
|
||||
///发送消息聊天
|
||||
Future<void> sendMessage(characterId, message) async {
|
||||
RequestCenter.instance.request(NetworkConfig.sendMessage, {
|
||||
"characterId": characterId,
|
||||
"message": message,
|
||||
}, (BaseEntity dataEntity) {
|
||||
print("dataEntity==${dataEntity.data}");
|
||||
|
||||
if (dataEntity.code == 0) {
|
||||
SendMessageBean sendMessageBean = SendMessageBean.fromJson(dataEntity.data);
|
||||
|
||||
streamController.sink.add({
|
||||
'code': "sendMessage", //有数据
|
||||
'data': sendMessageBean
|
||||
});
|
||||
} else {
|
||||
streamController.sink.add({
|
||||
'code': "-1", //有数据
|
||||
'data': dataEntity.message
|
||||
});
|
||||
}
|
||||
}, (ErrorEntity errorEntity) {
|
||||
print("errorEntity==${errorEntity.message}");
|
||||
});
|
||||
}
|
||||
|
||||
///删除单条或多条信息
|
||||
Future<void> delChatByIds(id, characterId) async {
|
||||
RequestCenter.instance.request(NetworkConfig.delChatByIds, {
|
||||
"id": id,
|
||||
"characterId": characterId,
|
||||
}, (BaseEntity dataEntity) {
|
||||
print("dataEntity==$dataEntity");
|
||||
|
||||
if (dataEntity.code == 0) {
|
||||
streamController.sink.add({
|
||||
'code': "delChatByIds", //有数据
|
||||
'data': dataEntity.data
|
||||
});
|
||||
} else {
|
||||
streamController.sink.add({
|
||||
'code': "-1", //有数据
|
||||
'data': dataEntity.message
|
||||
});
|
||||
}
|
||||
}, (ErrorEntity errorEntity) {
|
||||
print("errorEntity==${errorEntity.message}");
|
||||
});
|
||||
}
|
||||
|
||||
///清空聊天信息(重启聊天)
|
||||
Future<void> delChat(characterId) async {
|
||||
RequestCenter.instance.request(NetworkConfig.delChat, {
|
||||
"characterId": characterId,
|
||||
}, (BaseEntity dataEntity) {
|
||||
print("dataEntity==$dataEntity");
|
||||
|
||||
if (dataEntity.code == 0) {
|
||||
streamController.sink.add({
|
||||
'code': "delChat", //有数据
|
||||
'data': dataEntity.data
|
||||
});
|
||||
} else {
|
||||
streamController.sink.add({
|
||||
|
|
|
|||
|
|
@ -1,54 +1,165 @@
|
|||
import 'dart:async';
|
||||
|
||||
import 'package:cached_network_image/cached_network_image.dart';
|
||||
import 'package:expandable_text/expandable_text.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_easyloading/flutter_easyloading.dart';
|
||||
|
||||
import '../../beans/MessageBean.dart';
|
||||
import '../../beans/character_info_bean.dart';
|
||||
import '../../beans/chat_info_bean.dart';
|
||||
import '../../beans/send_message_bean.dart';
|
||||
import 'chat_model.dart';
|
||||
|
||||
class ChatPage extends StatefulWidget {
|
||||
String id;
|
||||
String characterId;
|
||||
|
||||
ChatPage({super.key, required this.id});
|
||||
ChatPage({super.key, required this.characterId});
|
||||
|
||||
@override
|
||||
State<ChatPage> createState() => _ChatPageState();
|
||||
}
|
||||
|
||||
class _ChatPageState extends State<ChatPage> {
|
||||
final TextEditingController _chatController = TextEditingController();
|
||||
final ScrollController _scrollController = ScrollController();
|
||||
List<MessageBean> chatList = [];
|
||||
final TextEditingController _chatController = TextEditingController();
|
||||
|
||||
late StreamSubscription subscription;
|
||||
final ChatModel _viewmodel = ChatModel();
|
||||
|
||||
///人物信息
|
||||
CharacterInfoBean? characterInfoBean;
|
||||
|
||||
///发送消息聊天
|
||||
late SendMessageBean sendMessageBean;
|
||||
|
||||
///聊天列表
|
||||
List<ChatInfoBean> chatList = [];
|
||||
|
||||
///聊天列表是否在底部
|
||||
bool isBottom = true;
|
||||
|
||||
String text = "";
|
||||
bool isHalf = false;
|
||||
bool isMore = false;
|
||||
|
||||
bool isHalf = true;
|
||||
|
||||
///输入框内容
|
||||
String text = "";
|
||||
|
||||
void _textFieldChanged(String str) {
|
||||
text = str;
|
||||
setState(() {});
|
||||
}
|
||||
|
||||
int delIndex = 0;
|
||||
|
||||
void _scrollToBottom() {
|
||||
_scrollController.animateTo(
|
||||
_scrollController.position.maxScrollExtent,
|
||||
curve: Curves.easeOut,
|
||||
duration: const Duration(milliseconds: 300),
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
// TODO: implement initState
|
||||
super.initState();
|
||||
chatList = [MessageBean("user", "你好"), MessageBean("assistant", "你好"), MessageBean("time", "8:00AM"), MessageBean("user", "你好")];
|
||||
|
||||
subscription = _viewmodel.streamController.stream.listen((newData) {
|
||||
String code = newData['code'];
|
||||
if (code.isNotEmpty) {
|
||||
switch (code) {
|
||||
case "getCharacterInfo":
|
||||
characterInfoBean = newData['data'];
|
||||
_viewmodel.getChatInfo(widget.characterId);
|
||||
break;
|
||||
case "getChatInfo":
|
||||
chatList.addAll(newData['data']);
|
||||
EasyLoading.dismiss();
|
||||
setState(() {});
|
||||
Future.delayed(Duration(milliseconds: 100), () {
|
||||
_scrollToBottom();
|
||||
});
|
||||
break;
|
||||
case "sendMessage":
|
||||
sendMessageBean = newData['data'];
|
||||
chatList.addAll(sendMessageBean.chatList!);
|
||||
Future.delayed(Duration(milliseconds: 200), () {
|
||||
_scrollController.jumpTo(_scrollController.position.maxScrollExtent);
|
||||
});
|
||||
EasyLoading.dismiss();
|
||||
break;
|
||||
|
||||
case "delChatByIds":
|
||||
if (newData['data']) {
|
||||
chatList.removeAt(delIndex);
|
||||
setState(() {});
|
||||
}
|
||||
EasyLoading.dismiss();
|
||||
break;
|
||||
|
||||
case "delChat": //重启对话
|
||||
if (newData['data']) {
|
||||
chatList.clear();
|
||||
_viewmodel.getCharacterInfo(widget.characterId);
|
||||
}
|
||||
EasyLoading.dismiss();
|
||||
break;
|
||||
|
||||
default:
|
||||
EasyLoading.dismiss();
|
||||
EasyLoading.showToast(newData['data']);
|
||||
break;
|
||||
}
|
||||
setState(() {});
|
||||
}
|
||||
});
|
||||
|
||||
_scrollController.addListener(() {
|
||||
if (_scrollController.position.pixels >= _scrollController.position.maxScrollExtent) {
|
||||
//滚动到底部
|
||||
isBottom = true;
|
||||
}
|
||||
});
|
||||
|
||||
loadData();
|
||||
}
|
||||
|
||||
loadData() {
|
||||
EasyLoading.show(status: 'loading...');
|
||||
_viewmodel.getCharacterInfo(widget.characterId);
|
||||
}
|
||||
|
||||
///删除消息
|
||||
delChat(int id, index) {
|
||||
EasyLoading.show(status: 'loading...');
|
||||
delIndex = index;
|
||||
List<int> ids = [id];
|
||||
_viewmodel.delChatByIds(ids, widget.characterId);
|
||||
}
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
// TODO: implement dispose
|
||||
_chatController.dispose();
|
||||
_scrollController.dispose();
|
||||
_chatController.dispose();
|
||||
subscription.cancel();
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
backgroundColor: Color(0xFFE8EEFC),
|
||||
backgroundColor: Color(0xFF121213),
|
||||
body: Stack(
|
||||
children: [
|
||||
Image(image: AssetImage('assets/images/bj.png')),
|
||||
characterInfoBean != null && characterInfoBean?.bgUrl != null
|
||||
? CachedNetworkImage(
|
||||
fit: BoxFit.fitHeight,
|
||||
imageUrl: "${characterInfoBean?.bgUrl}",
|
||||
errorWidget: (context, url, error) => const Icon(Icons.error),
|
||||
)
|
||||
: Container(),
|
||||
Positioned(
|
||||
bottom: 0,
|
||||
child: Container(
|
||||
|
|
@ -65,6 +176,7 @@ class _ChatPageState extends State<ChatPage> {
|
|||
Container(
|
||||
child: Column(
|
||||
children: [
|
||||
///返回
|
||||
Container(
|
||||
width: MediaQuery.of(context).size.width,
|
||||
alignment: Alignment.centerLeft,
|
||||
|
|
@ -131,7 +243,7 @@ class _ChatPageState extends State<ChatPage> {
|
|||
SizedBox(
|
||||
width: 35,
|
||||
child: Text(
|
||||
'柳如烟',
|
||||
"${characterInfoBean?.characterName}",
|
||||
overflow: TextOverflow.ellipsis,
|
||||
style: TextStyle(fontSize: 10, color: Colors.white),
|
||||
),
|
||||
|
|
@ -139,7 +251,7 @@ class _ChatPageState extends State<ChatPage> {
|
|||
SizedBox(
|
||||
width: 35,
|
||||
child: Text(
|
||||
'1.2K 聊过',
|
||||
'${characterInfoBean?.lookCount} 聊过',
|
||||
style: TextStyle(fontSize: 7, color: Colors.white),
|
||||
),
|
||||
),
|
||||
|
|
@ -152,13 +264,13 @@ class _ChatPageState extends State<ChatPage> {
|
|||
margin: EdgeInsets.only(left: 6, right: 6),
|
||||
child: GestureDetector(
|
||||
onTap: () {
|
||||
Navigator.push(
|
||||
context,
|
||||
MaterialPageRoute(
|
||||
builder: (context) => ChatPage(
|
||||
id: '123',
|
||||
)),
|
||||
);
|
||||
// Navigator.push(
|
||||
// context,
|
||||
// MaterialPageRoute(
|
||||
// builder: (context) => ChatPage(
|
||||
// id: '123',
|
||||
// )),
|
||||
// );
|
||||
},
|
||||
child: Stack(
|
||||
alignment: Alignment.center,
|
||||
|
|
@ -168,10 +280,12 @@ class _ChatPageState extends State<ChatPage> {
|
|||
height: 21,
|
||||
image: AssetImage('assets/images/ic_beckoning.png'),
|
||||
),
|
||||
Text(
|
||||
'10',
|
||||
style: TextStyle(fontSize: 8, color: Colors.white),
|
||||
)
|
||||
characterInfoBean != null
|
||||
? Text(
|
||||
characterInfoBean!.intimacy.toString(),
|
||||
style: TextStyle(fontSize: 8, color: Colors.white),
|
||||
)
|
||||
: Container(),
|
||||
],
|
||||
),
|
||||
),
|
||||
|
|
@ -264,6 +378,8 @@ class _ChatPageState extends State<ChatPage> {
|
|||
),
|
||||
),
|
||||
),
|
||||
|
||||
///发送
|
||||
Container(
|
||||
margin: const EdgeInsets.only(right: 7),
|
||||
child: text == ""
|
||||
|
|
@ -273,7 +389,9 @@ class _ChatPageState extends State<ChatPage> {
|
|||
)
|
||||
: GestureDetector(
|
||||
onTap: () {
|
||||
chatList.add(MessageBean("user", text));
|
||||
EasyLoading.show(status: 'loading...');
|
||||
chatList.add(ChatInfoBean(0, "user", text, "timestamp", "claudeType", 0, "userIcon"));
|
||||
_viewmodel.sendMessage(widget.characterId, text);
|
||||
_chatController.clear();
|
||||
text = "";
|
||||
Future.delayed(Duration(milliseconds: 200), () {
|
||||
|
|
@ -346,18 +464,24 @@ class _ChatPageState extends State<ChatPage> {
|
|||
),
|
||||
Container(
|
||||
margin: EdgeInsets.only(left: 23),
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
Image(width: 26, image: AssetImage('assets/images/ic_more.png')),
|
||||
Container(
|
||||
margin: EdgeInsets.only(top: 9),
|
||||
child: Text(
|
||||
'重启对话',
|
||||
style: TextStyle(fontSize: 10, color: Color(0xFFA2A2A2)),
|
||||
child: GestureDetector(
|
||||
onTap: () {
|
||||
EasyLoading.show(status: 'loading...');
|
||||
_viewmodel.delChat(widget.characterId);
|
||||
},
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
Image(width: 26, height: 26, image: AssetImage('assets/images/ic_restart.png')),
|
||||
Container(
|
||||
margin: EdgeInsets.only(top: 9),
|
||||
child: Text(
|
||||
'重启对话',
|
||||
style: TextStyle(fontSize: 10, color: Color(0xFFA2A2A2)),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
|
|
@ -384,12 +508,12 @@ class _ChatPageState extends State<ChatPage> {
|
|||
|
||||
///聊天条目
|
||||
_item(index) {
|
||||
if (index == 0) {
|
||||
return Container();
|
||||
}
|
||||
// if (index == 0) {
|
||||
// return Container();
|
||||
// }
|
||||
|
||||
///简介
|
||||
if (chatList[index].role == 'introduce') {
|
||||
if (chatList[index].role == 'profile') {
|
||||
return Center(
|
||||
child: Container(
|
||||
margin: EdgeInsets.only(left: 16, right: 16),
|
||||
|
|
@ -418,6 +542,29 @@ class _ChatPageState extends State<ChatPage> {
|
|||
// );
|
||||
// }
|
||||
|
||||
///提示
|
||||
if (chatList[index].role == 'tips') {
|
||||
return Center(
|
||||
child: Container(
|
||||
padding: const EdgeInsets.only(left: 9, right: 9, top: 6, bottom: 6),
|
||||
decoration: const BoxDecoration(
|
||||
color: Color(0xCC000000),
|
||||
borderRadius: BorderRadius.all(Radius.circular(15)),
|
||||
),
|
||||
child: Row(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
Text(chatList[index].content!, style: TextStyle(color: Color(0xFFB6B6B6), fontSize: 10)),
|
||||
Container(
|
||||
margin: const EdgeInsets.only(left: 10),
|
||||
child: const Text("立即增加", style: TextStyle(color: Color(0xFFFF9000), fontSize: 10)),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
///聊天内容
|
||||
return Padding(
|
||||
padding: const EdgeInsets.symmetric(vertical: 8.0),
|
||||
|
|
@ -435,22 +582,23 @@ class _ChatPageState extends State<ChatPage> {
|
|||
maxWidth: MediaQuery.of(context).size.width - 50, // 确保不超过屏幕宽度
|
||||
),
|
||||
child: Container(
|
||||
margin: const EdgeInsets.symmetric(vertical: 4, horizontal: 16),
|
||||
margin: const EdgeInsets.symmetric(vertical: 4, horizontal: 12),
|
||||
padding: const EdgeInsets.all(11.0),
|
||||
decoration: const BoxDecoration(
|
||||
color: Color(0xFFFF9000),
|
||||
color: Color(0x99FF9000),
|
||||
borderRadius: BorderRadius.only(
|
||||
topRight: Radius.circular(16.0), bottomLeft: Radius.circular(16.0), bottomRight: Radius.circular(16.0)),
|
||||
),
|
||||
child: GestureDetector(
|
||||
onTap: () {
|
||||
EasyLoading.showToast("status");
|
||||
EasyLoading.showToast("status${chatList[index].id}");
|
||||
delChat(chatList[index].id!, index);
|
||||
},
|
||||
child: SelectableText(
|
||||
child: Text(
|
||||
chatList[index].content!,
|
||||
style: const TextStyle(
|
||||
fontSize: 16,
|
||||
color: Colors.black,
|
||||
fontSize: 14,
|
||||
color: Color(0xFFE8E8E8),
|
||||
),
|
||||
),
|
||||
),
|
||||
|
|
@ -498,7 +646,7 @@ class _ChatPageState extends State<ChatPage> {
|
|||
maxWidth: MediaQuery.of(context).size.width - 50, // 确保不超过屏幕宽度
|
||||
),
|
||||
child: Container(
|
||||
margin: const EdgeInsets.symmetric(vertical: 4, horizontal: 16),
|
||||
margin: const EdgeInsets.symmetric(vertical: 4, horizontal: 12),
|
||||
padding: const EdgeInsets.all(11.0),
|
||||
decoration: const BoxDecoration(
|
||||
color: Color(0x99252525),
|
||||
|
|
@ -509,7 +657,7 @@ class _ChatPageState extends State<ChatPage> {
|
|||
chatList[index].content!,
|
||||
style: const TextStyle(
|
||||
fontSize: 16,
|
||||
color: Colors.white,
|
||||
color: Color(0xFFE8E8E8),
|
||||
),
|
||||
),
|
||||
),
|
||||
|
|
|
|||
82
lib/tools/find/find_model.dart
Normal file
82
lib/tools/find/find_model.dart
Normal file
|
|
@ -0,0 +1,82 @@
|
|||
import 'dart:async';
|
||||
|
||||
import 'package:talk/network/NetworkConfig.dart';
|
||||
import 'package:talk/network/RequestCenter.dart';
|
||||
|
||||
import '../../beans/category_info_list_bean.dart';
|
||||
import '../../beans/find_type_bean.dart';
|
||||
import '../../network/BaseEntity.dart';
|
||||
|
||||
class FindModel {
|
||||
StreamController streamController = StreamController.broadcast();
|
||||
|
||||
FindModel() {
|
||||
setUp();
|
||||
}
|
||||
|
||||
void setUp() {}
|
||||
|
||||
///发现-获取分类列表
|
||||
Future<void> getCategoryList() async {
|
||||
RequestCenter.instance.requestGet(NetworkConfig.getCategoryList, {}, (BaseEntity dataEntity) {
|
||||
if (dataEntity.code == 0) {
|
||||
List<FindTypeBean> data = (dataEntity.data as List<dynamic>).map((e) => FindTypeBean.fromJson(e as Map<String, dynamic>)).toList();
|
||||
|
||||
streamController.sink.add({
|
||||
'code': "getChatInfo", //有数据
|
||||
'data': data
|
||||
});
|
||||
} else {
|
||||
streamController.sink.add({
|
||||
'code': "-1", //有数据
|
||||
'data': dataEntity.message
|
||||
});
|
||||
}
|
||||
}, (ErrorEntity errorEntity) {
|
||||
print("errorEntity==${errorEntity.message}");
|
||||
});
|
||||
}
|
||||
|
||||
///发现-复用页面角色信息
|
||||
Future<void> getCategoryInfoList(categoryId) async {
|
||||
RequestCenter.instance.requestGet(NetworkConfig.getCategoryInfoList, {
|
||||
"categoryId": categoryId,
|
||||
}, (BaseEntity dataEntity) {
|
||||
if (dataEntity.code == 0) {
|
||||
List<CategoryInfoListBean> data =
|
||||
(dataEntity.data as List<dynamic>).map((e) => CategoryInfoListBean.fromJson(e as Map<String, dynamic>)).toList();
|
||||
|
||||
streamController.sink.add({
|
||||
'code': "getCategoryInfoList", //有数据
|
||||
'data': data
|
||||
});
|
||||
} else {
|
||||
streamController.sink.add({
|
||||
'code': "-1", //有数据
|
||||
'data': dataEntity.message
|
||||
});
|
||||
}
|
||||
}, (ErrorEntity errorEntity) {
|
||||
print("errorEntity==${errorEntity.message}");
|
||||
});
|
||||
}
|
||||
|
||||
///发现-第一页固定内容
|
||||
Future<void> getCategoryFindList() async {
|
||||
RequestCenter.instance.requestGet(NetworkConfig.getCategoryFindList, {}, (BaseEntity dataEntity) {
|
||||
if (dataEntity.code == 0) {
|
||||
streamController.sink.add({
|
||||
'code': "getCategoryFindList", //有数据
|
||||
'data': dataEntity.data
|
||||
});
|
||||
} else {
|
||||
streamController.sink.add({
|
||||
'code': "-1", //有数据
|
||||
'data': dataEntity.message
|
||||
});
|
||||
}
|
||||
}, (ErrorEntity errorEntity) {
|
||||
print("errorEntity==${errorEntity.message}");
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
@ -1,6 +1,11 @@
|
|||
import 'dart:async';
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_easyloading/flutter_easyloading.dart';
|
||||
import 'package:talk/tools/find/find_model.dart';
|
||||
import 'package:talk/tools/find/recommend_page.dart';
|
||||
|
||||
import '../../beans/find_type_bean.dart';
|
||||
import 'multiplex_page.dart';
|
||||
|
||||
///发现
|
||||
|
|
@ -12,19 +17,45 @@ class FindPage extends StatefulWidget {
|
|||
}
|
||||
|
||||
class _FindPageState extends State<FindPage> {
|
||||
late StreamSubscription subscription;
|
||||
final PageController _pageController = PageController();
|
||||
int currentIndex = 0;
|
||||
|
||||
final FindModel _viewmodel = FindModel();
|
||||
|
||||
List<FindTypeBean> findList = [];
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
// TODO: implement initState
|
||||
super.initState();
|
||||
|
||||
subscription = _viewmodel.streamController.stream.listen((newData) {
|
||||
String code = newData['code'];
|
||||
if (code.isNotEmpty) {
|
||||
switch (code) {
|
||||
case "getChatInfo":
|
||||
findList = newData['data'];
|
||||
break;
|
||||
|
||||
default:
|
||||
EasyLoading.showToast(newData['data']);
|
||||
break;
|
||||
}
|
||||
setState(() {});
|
||||
EasyLoading.dismiss();
|
||||
}
|
||||
});
|
||||
|
||||
EasyLoading.show(status: "'loading...'");
|
||||
_viewmodel.getCategoryList();
|
||||
}
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
// TODO: implement dispose
|
||||
_pageController.dispose();
|
||||
subscription.cancel();
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
|
|
@ -39,11 +70,13 @@ class _FindPageState extends State<FindPage> {
|
|||
itemCount: 10, // 假设有5个页面,其中第一个是固定的
|
||||
itemBuilder: (context, index) {
|
||||
if (index == 0) {
|
||||
// 第一个页面是固定的
|
||||
// 第一个页面固定
|
||||
return RecommendPage();
|
||||
} else {
|
||||
// 其他页面是动态生成的
|
||||
return MultiplexPage();
|
||||
// 其他页面动态生成
|
||||
return MultiplexPage(
|
||||
id: findList[index].id.toString(),
|
||||
);
|
||||
}
|
||||
},
|
||||
physics: NeverScrollableScrollPhysics(),
|
||||
|
|
@ -53,7 +86,7 @@ class _FindPageState extends State<FindPage> {
|
|||
Container(
|
||||
padding: EdgeInsets.only(top: MediaQuery.of(context).padding.top + 9, left: 16, right: 16),
|
||||
// width: MediaQuery.of(context).size.width,
|
||||
color: Color(0xFF18181A),
|
||||
color: Color(0x66121213),
|
||||
child: Row(
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
children: [
|
||||
|
|
@ -66,12 +99,12 @@ class _FindPageState extends State<FindPage> {
|
|||
|
||||
///tab
|
||||
Expanded(
|
||||
child: Container(
|
||||
child: SizedBox(
|
||||
height: 30,
|
||||
child: ListView.builder(
|
||||
itemCount: 10,
|
||||
itemCount: findList.length,
|
||||
itemBuilder: (BuildContext context, int index) {
|
||||
return _item(index);
|
||||
return _item(index, findList[index]);
|
||||
},
|
||||
scrollDirection: Axis.horizontal,
|
||||
),
|
||||
|
|
@ -111,7 +144,7 @@ class _FindPageState extends State<FindPage> {
|
|||
);
|
||||
}
|
||||
|
||||
_item(index) {
|
||||
_item(index, FindTypeBean data) {
|
||||
return Container(
|
||||
margin: EdgeInsets.only(left: 5, right: 12),
|
||||
child: Column(
|
||||
|
|
@ -127,7 +160,7 @@ class _FindPageState extends State<FindPage> {
|
|||
setState(() {});
|
||||
},
|
||||
child: Text(
|
||||
"推荐",
|
||||
"${data.name}",
|
||||
style: TextStyle(color: Color(currentIndex == index ? 0xFFFF9000 : 0xFF8D8D8D)),
|
||||
),
|
||||
),
|
||||
|
|
|
|||
|
|
@ -1,26 +1,69 @@
|
|||
import 'dart:async';
|
||||
|
||||
import 'package:cached_network_image/cached_network_image.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_easyloading/flutter_easyloading.dart';
|
||||
|
||||
import '../../beans/category_info_list_bean.dart';
|
||||
import 'find_model.dart';
|
||||
|
||||
class MultiplexPage extends StatefulWidget {
|
||||
const MultiplexPage({super.key});
|
||||
String id;
|
||||
|
||||
MultiplexPage({super.key, required this.id});
|
||||
|
||||
@override
|
||||
State<MultiplexPage> createState() => _MultiplexPageState();
|
||||
}
|
||||
|
||||
class _MultiplexPageState extends State<MultiplexPage> {
|
||||
late StreamSubscription subscription;
|
||||
|
||||
final FindModel _viewmodel = FindModel();
|
||||
|
||||
List<CategoryInfoListBean> categoryList = [];
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
// TODO: implement initState
|
||||
super.initState();
|
||||
subscription = _viewmodel.streamController.stream.listen((newData) {
|
||||
String code = newData['code'];
|
||||
if (code.isNotEmpty) {
|
||||
switch (code) {
|
||||
case "getCategoryInfoList":
|
||||
categoryList = newData['data'];
|
||||
break;
|
||||
}
|
||||
setState(() {});
|
||||
EasyLoading.dismiss();
|
||||
}
|
||||
});
|
||||
|
||||
EasyLoading.show(status: "'loading...'");
|
||||
_viewmodel.getCategoryInfoList(widget.id);
|
||||
}
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
// TODO: implement dispose
|
||||
subscription.cancel();
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Container(
|
||||
margin: EdgeInsets.only(top: MediaQuery.of(context).padding.top + 25, bottom: 60, left: 16, right: 16),
|
||||
child: ListView.builder(
|
||||
itemCount: 10,
|
||||
itemCount: categoryList.length,
|
||||
itemBuilder: (BuildContext context, int index) {
|
||||
return _item2(index);
|
||||
return _item(index, categoryList[index]);
|
||||
}),
|
||||
);
|
||||
}
|
||||
|
||||
_item2(index) {
|
||||
_item(index, CategoryInfoListBean data) {
|
||||
return Container(
|
||||
height: 130,
|
||||
width: 50,
|
||||
|
|
@ -34,17 +77,19 @@ class _MultiplexPageState extends State<MultiplexPage> {
|
|||
alignment: Alignment.center,
|
||||
children: [
|
||||
Positioned(
|
||||
left: 7,
|
||||
child: Image(
|
||||
width: 83,
|
||||
height: 115,
|
||||
image: AssetImage('assets/images/a3.png'),
|
||||
)),
|
||||
left: 7,
|
||||
child: CachedNetworkImage(
|
||||
width: 83,
|
||||
height: 115,
|
||||
imageUrl: data.iconImage!,
|
||||
errorWidget: (context, url, error) => const Icon(Icons.error),
|
||||
),
|
||||
),
|
||||
Positioned(
|
||||
left: 101,
|
||||
top: 19,
|
||||
child: Text(
|
||||
'重生之千金大小姐倒追我',
|
||||
'${data.name}',
|
||||
style: TextStyle(color: Colors.white, fontSize: 14),
|
||||
)),
|
||||
Positioned(
|
||||
|
|
@ -54,7 +99,7 @@ class _MultiplexPageState extends State<MultiplexPage> {
|
|||
width: 200,
|
||||
height: 16,
|
||||
child: ListView.builder(
|
||||
itemCount: 3,
|
||||
itemCount: data.label?.length,
|
||||
scrollDirection: Axis.horizontal,
|
||||
itemBuilder: (BuildContext context, int index) {
|
||||
return Container(
|
||||
|
|
@ -63,7 +108,7 @@ class _MultiplexPageState extends State<MultiplexPage> {
|
|||
margin: EdgeInsets.only(right: 5),
|
||||
decoration: BoxDecoration(border: Border.all(color: Color(0xFFFF9000)), borderRadius: BorderRadius.all(Radius.circular(7))),
|
||||
child: Text(
|
||||
'123',
|
||||
'${data.label?[index].name}',
|
||||
style: TextStyle(fontSize: 10, color: Color(0xFFFF9000)),
|
||||
),
|
||||
);
|
||||
|
|
@ -76,7 +121,7 @@ class _MultiplexPageState extends State<MultiplexPage> {
|
|||
width: 200,
|
||||
child: Text(
|
||||
maxLines: 3,
|
||||
'这里是属于斗气的世界,没有花俏艳丽的魔法有的,仅仅是,斗王,斗皇,斗宗,斗尊,斗圣,斗帝...',
|
||||
'${data.biography}',
|
||||
overflow: TextOverflow.ellipsis,
|
||||
style: TextStyle(color: Colors.white, fontSize: 10),
|
||||
),
|
||||
|
|
|
|||
|
|
@ -1,7 +1,14 @@
|
|||
import 'dart:async';
|
||||
|
||||
import 'package:cached_network_image/cached_network_image.dart';
|
||||
import 'package:card_swiper/card_swiper.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_easyloading/flutter_easyloading.dart';
|
||||
|
||||
import '../../beans/find_banner_bean.dart';
|
||||
import '../../beans/recommend_bean.dart';
|
||||
import '../../custom/custom_swiper_pagination.dart';
|
||||
import 'find_model.dart';
|
||||
|
||||
///推荐
|
||||
class RecommendPage extends StatefulWidget {
|
||||
|
|
@ -12,6 +19,61 @@ class RecommendPage extends StatefulWidget {
|
|||
}
|
||||
|
||||
class _RecommendPageState extends State<RecommendPage> {
|
||||
late StreamSubscription subscription;
|
||||
|
||||
final FindModel _viewmodel = FindModel();
|
||||
|
||||
List<FindBannerBean> bannerList = [];
|
||||
List<RecommendBean> recommendList = []; //推荐
|
||||
List<RecommendBean> popularList = []; //热门
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
// TODO: implement initState
|
||||
super.initState();
|
||||
|
||||
subscription = _viewmodel.streamController.stream.listen((newData) {
|
||||
String code = newData['code'];
|
||||
if (code.isNotEmpty) {
|
||||
switch (code) {
|
||||
case "getCategoryFindList":
|
||||
List data = newData['data'];
|
||||
for (var value in data) {
|
||||
switch (value['type']) {
|
||||
case "banner": //轮播图
|
||||
bannerList = (value['data'] as List<dynamic>).map((e) => FindBannerBean.fromJson(e as Map<String, dynamic>)).toList();
|
||||
break;
|
||||
case "tuijian": //推荐
|
||||
recommendList = (value['data'] as List<dynamic>).map((e) => RecommendBean.fromJson(e as Map<String, dynamic>)).toList();
|
||||
break;
|
||||
case "xiaoshuo": //推荐
|
||||
popularList = (value['data'] as List<dynamic>).map((e) => RecommendBean.fromJson(e as Map<String, dynamic>)).toList();
|
||||
break;
|
||||
}
|
||||
}
|
||||
setState(() {});
|
||||
break;
|
||||
|
||||
default:
|
||||
EasyLoading.showToast(newData['data']);
|
||||
break;
|
||||
}
|
||||
// setState(() {});
|
||||
EasyLoading.dismiss();
|
||||
}
|
||||
});
|
||||
|
||||
EasyLoading.show(status: "'loading...'");
|
||||
_viewmodel.getCategoryFindList();
|
||||
}
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
// TODO: implement dispose
|
||||
subscription.cancel();
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Stack(
|
||||
|
|
@ -28,14 +90,16 @@ class _RecommendPageState extends State<RecommendPage> {
|
|||
child: Swiper(
|
||||
itemBuilder: (BuildContext context, int index) {
|
||||
return Container(
|
||||
key: ValueKey<int>(index),
|
||||
padding: EdgeInsets.only(bottom: 30),
|
||||
child: Image(
|
||||
image: AssetImage('assets/images/banner1.png'),
|
||||
child: CachedNetworkImage(
|
||||
fit: BoxFit.fill,
|
||||
imageUrl: bannerList[index].imageUrl!,
|
||||
errorWidget: (context, url, error) => const Icon(Icons.error),
|
||||
),
|
||||
);
|
||||
},
|
||||
itemCount: 3,
|
||||
itemCount: bannerList.length,
|
||||
pagination: SwiperPagination(
|
||||
// 此处使用自己编写的样式
|
||||
builder:
|
||||
|
|
@ -55,10 +119,10 @@ class _RecommendPageState extends State<RecommendPage> {
|
|||
margin: EdgeInsets.only(top: 21),
|
||||
height: 360,
|
||||
child: ListView.builder(
|
||||
itemCount: 10,
|
||||
itemCount: recommendList.length,
|
||||
scrollDirection: Axis.horizontal,
|
||||
itemBuilder: (BuildContext context, int index) {
|
||||
return _item(index);
|
||||
return _item(index, recommendList[index]);
|
||||
}),
|
||||
),
|
||||
Container(
|
||||
|
|
@ -70,13 +134,13 @@ class _RecommendPageState extends State<RecommendPage> {
|
|||
),
|
||||
),
|
||||
Container(
|
||||
height: 153 * 10,
|
||||
height: 153.0 * (popularList.length),
|
||||
margin: EdgeInsets.only(left: 16, right: 16, bottom: 60),
|
||||
child: ListView.builder(
|
||||
itemCount: 10,
|
||||
itemCount: popularList.length,
|
||||
physics: NeverScrollableScrollPhysics(),
|
||||
itemBuilder: (BuildContext context, int index) {
|
||||
return _item2(index);
|
||||
return _item2(index, popularList[index]);
|
||||
}),
|
||||
)
|
||||
],
|
||||
|
|
@ -88,19 +152,28 @@ class _RecommendPageState extends State<RecommendPage> {
|
|||
}
|
||||
}
|
||||
|
||||
_item(int index) {
|
||||
_item(int index, RecommendBean data) {
|
||||
return Container(
|
||||
margin: EdgeInsets.only(right: 9, left: index == 0 ? 16 : 0),
|
||||
child: Column(
|
||||
children: [
|
||||
Stack(
|
||||
children: [
|
||||
Image(width: 113, height: 159, image: AssetImage('assets/images/a1.png')),
|
||||
ClipRRect(
|
||||
borderRadius: BorderRadius.all(Radius.circular(15)),
|
||||
child: CachedNetworkImage(
|
||||
width: 113,
|
||||
height: 159,
|
||||
fit: BoxFit.fill,
|
||||
imageUrl: data.imageUrl!,
|
||||
errorWidget: (context, url, error) => const Icon(Icons.error),
|
||||
),
|
||||
),
|
||||
Positioned(
|
||||
left: 7,
|
||||
bottom: 21,
|
||||
child: Text(
|
||||
'细弱',
|
||||
'${data.name}',
|
||||
style: TextStyle(color: Colors.white, fontSize: 12),
|
||||
)),
|
||||
Positioned(
|
||||
|
|
@ -109,7 +182,7 @@ _item(int index) {
|
|||
child: Container(
|
||||
width: 105,
|
||||
child: Text(
|
||||
'这里是属于斗气有圣斗帝...',
|
||||
'${data.biography}',
|
||||
maxLines: 1,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
style: TextStyle(color: Color(0xFFC2C2C2), fontSize: 9),
|
||||
|
|
@ -121,16 +194,21 @@ _item(int index) {
|
|||
margin: EdgeInsets.only(top: 12),
|
||||
child: Stack(
|
||||
children: [
|
||||
Image(
|
||||
width: 113,
|
||||
height: 159,
|
||||
image: AssetImage('assets/images/a2.png'),
|
||||
ClipRRect(
|
||||
borderRadius: BorderRadius.all(Radius.circular(15)),
|
||||
child: CachedNetworkImage(
|
||||
width: 113,
|
||||
height: 159,
|
||||
fit: BoxFit.fill,
|
||||
imageUrl: data.imageUrl!,
|
||||
errorWidget: (context, url, error) => const Icon(Icons.error),
|
||||
),
|
||||
),
|
||||
Positioned(
|
||||
left: 7,
|
||||
bottom: 21,
|
||||
child: Text(
|
||||
'细弱',
|
||||
'${data.name}',
|
||||
style: TextStyle(color: Colors.white, fontSize: 12),
|
||||
)),
|
||||
Positioned(
|
||||
|
|
@ -139,7 +217,7 @@ _item(int index) {
|
|||
child: Container(
|
||||
width: 105,
|
||||
child: Text(
|
||||
'这里是属于斗气有圣斗帝...',
|
||||
'${data.biography}',
|
||||
maxLines: 1,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
style: TextStyle(color: Color(0xFFC2C2C2), fontSize: 9),
|
||||
|
|
@ -153,7 +231,7 @@ _item(int index) {
|
|||
);
|
||||
}
|
||||
|
||||
_item2(index) {
|
||||
_item2(index, RecommendBean data) {
|
||||
return Container(
|
||||
height: 130,
|
||||
width: 50,
|
||||
|
|
@ -167,17 +245,23 @@ _item2(index) {
|
|||
alignment: Alignment.center,
|
||||
children: [
|
||||
Positioned(
|
||||
left: 7,
|
||||
child: Image(
|
||||
left: 7,
|
||||
child: ClipRRect(
|
||||
borderRadius: BorderRadius.all(Radius.circular(15)),
|
||||
child: CachedNetworkImage(
|
||||
width: 83,
|
||||
height: 115,
|
||||
image: AssetImage('assets/images/a3.png'),
|
||||
)),
|
||||
fit: BoxFit.fill,
|
||||
imageUrl: data.imageUrl!,
|
||||
errorWidget: (context, url, error) => const Icon(Icons.error),
|
||||
),
|
||||
),
|
||||
),
|
||||
Positioned(
|
||||
left: 101,
|
||||
top: 19,
|
||||
child: Text(
|
||||
'重生之千金大小姐倒追我',
|
||||
'${data.name}',
|
||||
style: TextStyle(color: Colors.white, fontSize: 14),
|
||||
)),
|
||||
Positioned(
|
||||
|
|
@ -187,7 +271,7 @@ _item2(index) {
|
|||
width: 200,
|
||||
height: 16,
|
||||
child: ListView.builder(
|
||||
itemCount: 3,
|
||||
itemCount: data.label?.length,
|
||||
scrollDirection: Axis.horizontal,
|
||||
itemBuilder: (BuildContext context, int index) {
|
||||
return Container(
|
||||
|
|
@ -196,7 +280,7 @@ _item2(index) {
|
|||
margin: EdgeInsets.only(right: 5),
|
||||
decoration: BoxDecoration(border: Border.all(color: Color(0xFFFF9000)), borderRadius: BorderRadius.all(Radius.circular(7))),
|
||||
child: Text(
|
||||
'123',
|
||||
'${data.label?[index].name}',
|
||||
style: TextStyle(fontSize: 10, color: Color(0xFFFF9000)),
|
||||
),
|
||||
);
|
||||
|
|
@ -209,7 +293,7 @@ _item2(index) {
|
|||
width: 200,
|
||||
child: Text(
|
||||
maxLines: 3,
|
||||
'这里是属于斗气的世界,没有花俏艳丽的魔法有的,仅仅是,斗王,斗皇,斗宗,斗尊,斗圣,斗帝...',
|
||||
'${data.biography}',
|
||||
overflow: TextOverflow.ellipsis,
|
||||
style: TextStyle(color: Colors.white, fontSize: 10),
|
||||
),
|
||||
|
|
|
|||
|
|
@ -5,11 +5,11 @@ import 'package:expandable_text/expandable_text.dart';
|
|||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_easyloading/flutter_easyloading.dart';
|
||||
|
||||
import '../../beans/MessageBean.dart';
|
||||
import '../../beans/character_info_bean.dart';
|
||||
import '../../beans/chat_info_bean.dart';
|
||||
import '../../beans/send_message_bean.dart';
|
||||
import '../chat/chat_info_page.dart';
|
||||
import '../chat/chat_model.dart';
|
||||
import '../chat/chat_page.dart';
|
||||
|
||||
class HomeChatPage extends StatefulWidget {
|
||||
String characterId;
|
||||
|
|
@ -30,8 +30,14 @@ class _HomeChatPageState extends State<HomeChatPage> with AutomaticKeepAliveClie
|
|||
///人物信息
|
||||
late CharacterInfoBean characterInfoBean;
|
||||
|
||||
///发送消息聊天
|
||||
late SendMessageBean sendMessageBean;
|
||||
|
||||
///聊天列表
|
||||
List<MessageBean> chatList = [];
|
||||
List<ChatInfoBean> chatList = [];
|
||||
|
||||
///聊天列表是否在底部
|
||||
bool isBottom = true;
|
||||
|
||||
bool isMore = false;
|
||||
|
||||
|
|
@ -45,6 +51,8 @@ class _HomeChatPageState extends State<HomeChatPage> with AutomaticKeepAliveClie
|
|||
setState(() {});
|
||||
}
|
||||
|
||||
int delIndex = 0;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
// TODO: implement initState
|
||||
|
|
@ -56,20 +64,79 @@ class _HomeChatPageState extends State<HomeChatPage> with AutomaticKeepAliveClie
|
|||
switch (code) {
|
||||
case "getCharacterInfo":
|
||||
characterInfoBean = newData['data'];
|
||||
_viewmodel.getChatInfo(widget.characterId);
|
||||
break;
|
||||
case "getChatInfo":
|
||||
chatList.addAll(newData['data']);
|
||||
setState(() {});
|
||||
Future.delayed(Duration(milliseconds: 100), () {
|
||||
_scrollToBottom();
|
||||
});
|
||||
EasyLoading.dismiss();
|
||||
break;
|
||||
case "sendMessage":
|
||||
sendMessageBean = newData['data'];
|
||||
chatList.addAll(sendMessageBean.chatList!);
|
||||
Future.delayed(Duration(milliseconds: 200), () {
|
||||
_scrollController.jumpTo(_scrollController.position.maxScrollExtent);
|
||||
});
|
||||
EasyLoading.dismiss();
|
||||
break;
|
||||
|
||||
case "delChatByIds":
|
||||
if (newData['data']) {
|
||||
chatList.removeAt(delIndex);
|
||||
setState(() {});
|
||||
}
|
||||
EasyLoading.dismiss();
|
||||
break;
|
||||
|
||||
case "delChat": //重启对话
|
||||
if (newData['data']) {
|
||||
chatList.clear();
|
||||
_viewmodel.getCharacterInfo(widget.characterId);
|
||||
}
|
||||
EasyLoading.dismiss();
|
||||
break;
|
||||
|
||||
default:
|
||||
EasyLoading.dismiss();
|
||||
EasyLoading.showToast(newData['data']);
|
||||
break;
|
||||
}
|
||||
setState(() {});
|
||||
}
|
||||
});
|
||||
|
||||
_viewmodel.getCharacterInfo(widget.characterId);
|
||||
_scrollController.addListener(() {
|
||||
if (_scrollController.position.pixels >= _scrollController.position.maxScrollExtent) {
|
||||
//滚动到底部
|
||||
isBottom = true;
|
||||
}
|
||||
});
|
||||
|
||||
chatList = [
|
||||
MessageBean("user", "你好"),
|
||||
MessageBean("introduce", "王语嫣 年龄22 三围 28 36 48 分别多喜欢打台球旅行,唱歌,当绿茶喜欢打台球旅行,唱歌,当绿茶当绿茶喜欢打台球旅行,唱歌,当绿茶当绿茶喜欢打台球旅行,唱歌,当绿茶"),
|
||||
MessageBean("assistant", "(仔细观察你的样子,露出满意的笑容我想...)"),
|
||||
];
|
||||
loadData();
|
||||
}
|
||||
|
||||
loadData() {
|
||||
EasyLoading.show(status: 'loading...');
|
||||
_viewmodel.getCharacterInfo(widget.characterId);
|
||||
}
|
||||
|
||||
///删除消息
|
||||
delChat(int id, index) {
|
||||
EasyLoading.show(status: 'loading...');
|
||||
delIndex = index;
|
||||
List<int> ids = [id];
|
||||
_viewmodel.delChatByIds(ids, widget.characterId);
|
||||
}
|
||||
|
||||
void _scrollToBottom() {
|
||||
_scrollController.animateTo(
|
||||
_scrollController.position.maxScrollExtent,
|
||||
curve: Curves.easeOut,
|
||||
duration: const Duration(milliseconds: 300),
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
|
|
@ -83,6 +150,7 @@ class _HomeChatPageState extends State<HomeChatPage> with AutomaticKeepAliveClie
|
|||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
super.build(context);
|
||||
return Stack(
|
||||
children: [
|
||||
CachedNetworkImage(
|
||||
|
|
@ -115,6 +183,7 @@ class _HomeChatPageState extends State<HomeChatPage> with AutomaticKeepAliveClie
|
|||
alignment: Alignment.center,
|
||||
children: [
|
||||
Positioned(
|
||||
top: 0,
|
||||
left: 105,
|
||||
child: Text(
|
||||
"+1",
|
||||
|
|
@ -179,13 +248,13 @@ class _HomeChatPageState extends State<HomeChatPage> with AutomaticKeepAliveClie
|
|||
margin: EdgeInsets.only(left: 6, right: 6),
|
||||
child: GestureDetector(
|
||||
onTap: () {
|
||||
Navigator.push(
|
||||
context,
|
||||
MaterialPageRoute(
|
||||
builder: (context) => ChatPage(
|
||||
id: characterInfoBean.characterId.toString(),
|
||||
)),
|
||||
);
|
||||
// Navigator.push(
|
||||
// context,
|
||||
// MaterialPageRoute(
|
||||
// builder: (context) => ChatPage(
|
||||
// characterId: characterInfoBean.characterId.toString(),
|
||||
// )),
|
||||
// );
|
||||
},
|
||||
child: Stack(
|
||||
alignment: Alignment.center,
|
||||
|
|
@ -291,6 +360,8 @@ class _HomeChatPageState extends State<HomeChatPage> with AutomaticKeepAliveClie
|
|||
),
|
||||
),
|
||||
),
|
||||
|
||||
///发送
|
||||
Container(
|
||||
margin: const EdgeInsets.only(right: 7),
|
||||
child: text == ""
|
||||
|
|
@ -300,7 +371,9 @@ class _HomeChatPageState extends State<HomeChatPage> with AutomaticKeepAliveClie
|
|||
)
|
||||
: GestureDetector(
|
||||
onTap: () {
|
||||
chatList.add(MessageBean("user", text));
|
||||
EasyLoading.show(status: 'loading...');
|
||||
chatList.add(ChatInfoBean(0, "user", text, "timestamp", "claudeType", 0, "userIcon"));
|
||||
_viewmodel.sendMessage(widget.characterId, text);
|
||||
_chatController.clear();
|
||||
text = "";
|
||||
Future.delayed(Duration(milliseconds: 200), () {
|
||||
|
|
@ -373,18 +446,24 @@ class _HomeChatPageState extends State<HomeChatPage> with AutomaticKeepAliveClie
|
|||
),
|
||||
Container(
|
||||
margin: EdgeInsets.only(left: 23),
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
Image(width: 26, image: AssetImage('assets/images/ic_more.png')),
|
||||
Container(
|
||||
margin: EdgeInsets.only(top: 9),
|
||||
child: Text(
|
||||
'重启对话',
|
||||
style: TextStyle(fontSize: 10, color: Color(0xFFA2A2A2)),
|
||||
child: GestureDetector(
|
||||
onTap: () {
|
||||
EasyLoading.show(status: 'loading...');
|
||||
_viewmodel.delChat(widget.characterId);
|
||||
},
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
Image(width: 26, height: 26, image: AssetImage('assets/images/ic_restart.png')),
|
||||
Container(
|
||||
margin: EdgeInsets.only(top: 9),
|
||||
child: Text(
|
||||
'重启对话',
|
||||
style: TextStyle(fontSize: 10, color: Color(0xFFA2A2A2)),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
|
|
@ -410,12 +489,12 @@ class _HomeChatPageState extends State<HomeChatPage> with AutomaticKeepAliveClie
|
|||
|
||||
///聊天条目
|
||||
_item(index) {
|
||||
if (index == 0) {
|
||||
return Container();
|
||||
}
|
||||
// if (index == 0) {
|
||||
// return Container();
|
||||
// }
|
||||
|
||||
///简介
|
||||
if (chatList[index].role == 'introduce') {
|
||||
if (chatList[index].role == 'profile') {
|
||||
return Center(
|
||||
child: Container(
|
||||
margin: EdgeInsets.only(left: 16, right: 16),
|
||||
|
|
@ -444,6 +523,29 @@ class _HomeChatPageState extends State<HomeChatPage> with AutomaticKeepAliveClie
|
|||
// );
|
||||
// }
|
||||
|
||||
///提示
|
||||
if (chatList[index].role == 'tips') {
|
||||
return Center(
|
||||
child: Container(
|
||||
padding: const EdgeInsets.only(left: 9, right: 9, top: 6, bottom: 6),
|
||||
decoration: const BoxDecoration(
|
||||
color: Color(0xCC000000),
|
||||
borderRadius: BorderRadius.all(Radius.circular(15)),
|
||||
),
|
||||
child: Row(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
Text(chatList[index].content!, style: TextStyle(color: Color(0xFFB6B6B6), fontSize: 10)),
|
||||
Container(
|
||||
margin: const EdgeInsets.only(left: 10),
|
||||
child: const Text("立即增加", style: TextStyle(color: Color(0xFFFF9000), fontSize: 10)),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
///聊天内容
|
||||
return Padding(
|
||||
padding: const EdgeInsets.symmetric(vertical: 8.0),
|
||||
|
|
@ -464,19 +566,20 @@ class _HomeChatPageState extends State<HomeChatPage> with AutomaticKeepAliveClie
|
|||
margin: const EdgeInsets.symmetric(vertical: 4, horizontal: 12),
|
||||
padding: const EdgeInsets.all(11.0),
|
||||
decoration: const BoxDecoration(
|
||||
color: Color(0xFFFF9000),
|
||||
color: Color(0x99FF9000),
|
||||
borderRadius: BorderRadius.only(
|
||||
topRight: Radius.circular(16.0), bottomLeft: Radius.circular(16.0), bottomRight: Radius.circular(16.0)),
|
||||
),
|
||||
child: GestureDetector(
|
||||
onTap: () {
|
||||
EasyLoading.showToast("status");
|
||||
EasyLoading.showToast("status${chatList[index].id}");
|
||||
delChat(chatList[index].id!, index);
|
||||
},
|
||||
child: SelectableText(
|
||||
child: Text(
|
||||
chatList[index].content!,
|
||||
style: const TextStyle(
|
||||
fontSize: 16,
|
||||
color: Colors.black,
|
||||
fontSize: 14,
|
||||
color: Color(0xFFE8E8E8),
|
||||
),
|
||||
),
|
||||
),
|
||||
|
|
@ -535,7 +638,7 @@ class _HomeChatPageState extends State<HomeChatPage> with AutomaticKeepAliveClie
|
|||
chatList[index].content!,
|
||||
style: const TextStyle(
|
||||
fontSize: 16,
|
||||
color: Colors.white,
|
||||
color: Color(0xFFE8E8E8),
|
||||
),
|
||||
),
|
||||
),
|
||||
|
|
|
|||
|
|
@ -53,6 +53,7 @@ class LoginModel {
|
|||
LoginBean loginBean = LoginBean.fromJson(dataEntity.data);
|
||||
NetworkConfig.userId = loginBean.userId!.toString();
|
||||
NetworkConfig.userName = loginBean.nickName!;
|
||||
NetworkConfig.token = loginBean.token!;
|
||||
|
||||
//
|
||||
final SharedPreferences prefs = await SharedPreferences.getInstance();
|
||||
|
|
|
|||
42
lib/tools/message/message_model.dart
Normal file
42
lib/tools/message/message_model.dart
Normal file
|
|
@ -0,0 +1,42 @@
|
|||
import 'dart:async';
|
||||
|
||||
import 'package:talk/network/NetworkConfig.dart';
|
||||
import 'package:talk/network/RequestCenter.dart';
|
||||
|
||||
import '../../beans/message_bean.dart';
|
||||
import '../../network/BaseEntity.dart';
|
||||
|
||||
class MessageModel {
|
||||
StreamController streamController = StreamController.broadcast();
|
||||
|
||||
MessageModel() {
|
||||
setup();
|
||||
}
|
||||
|
||||
void setup() {
|
||||
//初始化
|
||||
}
|
||||
|
||||
///消息列表
|
||||
Future<void> getChatHistoryList() async {
|
||||
RequestCenter.instance.requestGet(NetworkConfig.getChatHistoryList, {}, (BaseEntity dataEntity) {
|
||||
print("dataEntity==${dataEntity.data}");
|
||||
|
||||
if (dataEntity.code == 0) {
|
||||
List<MessageBean> data = (dataEntity.data as List<dynamic>).map((e) => MessageBean.fromJson(e as Map<String, dynamic>)).toList();
|
||||
|
||||
streamController.sink.add({
|
||||
'code': "getChatHistoryList", //有数据
|
||||
'data': data,
|
||||
});
|
||||
} else {
|
||||
streamController.sink.add({
|
||||
'code': "error", //
|
||||
'data': dataEntity.message,
|
||||
});
|
||||
}
|
||||
}, (ErrorEntity errorEntity) {
|
||||
print("errorEntity==${errorEntity.message}");
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
@ -1,7 +1,15 @@
|
|||
import 'dart:async';
|
||||
|
||||
import 'package:cached_network_image/cached_network_image.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_easyloading/flutter_easyloading.dart';
|
||||
import 'package:flutter_slidable/flutter_slidable.dart';
|
||||
import 'package:talk/beans/message_bean.dart';
|
||||
import 'package:talk/tools/message/message_model.dart';
|
||||
|
||||
import '../chat/chat_page.dart';
|
||||
|
||||
///消息列表
|
||||
class MessagePage extends StatefulWidget {
|
||||
const MessagePage({super.key});
|
||||
|
||||
|
|
@ -10,12 +18,47 @@ class MessagePage extends StatefulWidget {
|
|||
}
|
||||
|
||||
class _MessagePageState extends State<MessagePage> {
|
||||
List messageList = [1, 2, 3, 4, 5, 6];
|
||||
List<MessageBean> messageList = [];
|
||||
|
||||
late StreamSubscription subscription;
|
||||
|
||||
final MessageModel _viewmodel = MessageModel();
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
// TODO: implement initState
|
||||
super.initState();
|
||||
|
||||
subscription = _viewmodel.streamController.stream.listen((newData) {
|
||||
String code = newData['code'];
|
||||
if (code.isNotEmpty) {
|
||||
switch (code) {
|
||||
case "getChatHistoryList":
|
||||
messageList = newData['data'];
|
||||
break;
|
||||
default:
|
||||
EasyLoading.dismiss();
|
||||
EasyLoading.showToast(newData['data']);
|
||||
break;
|
||||
}
|
||||
EasyLoading.dismiss();
|
||||
setState(() {});
|
||||
}
|
||||
});
|
||||
|
||||
loadData();
|
||||
}
|
||||
|
||||
loadData() {
|
||||
EasyLoading.show(status: 'loading...');
|
||||
_viewmodel.getChatHistoryList();
|
||||
}
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
// TODO: implement dispose
|
||||
subscription.cancel();
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
@override
|
||||
|
|
@ -37,11 +80,13 @@ class _MessagePageState extends State<MessagePage> {
|
|||
Expanded(
|
||||
child: Container(
|
||||
padding: EdgeInsets.only(bottom: 60),
|
||||
child: ListView.builder(
|
||||
itemCount: 10,
|
||||
itemBuilder: (BuildContext context, int index) {
|
||||
return _item(index);
|
||||
}),
|
||||
child: SlidableAutoCloseBehavior(
|
||||
child: ListView.builder(
|
||||
itemCount: messageList.length,
|
||||
itemBuilder: (BuildContext context, int index) {
|
||||
return _item(messageList[index], context);
|
||||
}),
|
||||
),
|
||||
))
|
||||
],
|
||||
)
|
||||
|
|
@ -50,7 +95,7 @@ class _MessagePageState extends State<MessagePage> {
|
|||
);
|
||||
}
|
||||
|
||||
_item(index) {
|
||||
_item(MessageBean data, BuildContext context) {
|
||||
return Slidable(
|
||||
//左滑划出的菜单
|
||||
endActionPane: ActionPane(
|
||||
|
|
@ -61,10 +106,11 @@ class _MessagePageState extends State<MessagePage> {
|
|||
// 滑动动效
|
||||
// DrawerMotion() StretchMotion()
|
||||
// motion: ScrollMotion(),
|
||||
// A pane can dismiss the Slidable.
|
||||
motion: BehindMotion(),
|
||||
children: const [
|
||||
children: [
|
||||
SlidableAction(
|
||||
onPressed: doNothing,
|
||||
onPressed: doNothing(context, data.id),
|
||||
backgroundColor: Color(0xFFFF9000),
|
||||
foregroundColor: Colors.black,
|
||||
label: '删除',
|
||||
|
|
@ -72,54 +118,68 @@ class _MessagePageState extends State<MessagePage> {
|
|||
],
|
||||
),
|
||||
|
||||
child: Container(
|
||||
height: 50,
|
||||
margin: EdgeInsets.only(bottom: 10),
|
||||
child: Stack(
|
||||
alignment: Alignment.center,
|
||||
children: [
|
||||
Positioned(
|
||||
child: GestureDetector(
|
||||
behavior: HitTestBehavior.opaque,
|
||||
onTap: () {
|
||||
Navigator.push(
|
||||
context,
|
||||
MaterialPageRoute(
|
||||
builder: (context) => ChatPage(
|
||||
characterId: data.id.toString(),
|
||||
)),
|
||||
);
|
||||
},
|
||||
child: Container(
|
||||
height: 50,
|
||||
margin: EdgeInsets.only(bottom: 10),
|
||||
child: Stack(
|
||||
alignment: Alignment.center,
|
||||
children: [
|
||||
Positioned(
|
||||
left: 16,
|
||||
child: Image(
|
||||
child: CachedNetworkImage(
|
||||
width: 40,
|
||||
height: 40,
|
||||
image: AssetImage('assets/images/img_head2.png'),
|
||||
)),
|
||||
Positioned(
|
||||
left: 68,
|
||||
top: 6,
|
||||
child: Text(
|
||||
'王语嫣',
|
||||
style: TextStyle(fontSize: 13, color: Color(0xFFE1E1E1)),
|
||||
)),
|
||||
Positioned(
|
||||
left: 68,
|
||||
top: 25,
|
||||
child: Container(
|
||||
width: 160,
|
||||
imageUrl: data.iconImage!,
|
||||
errorWidget: (context, url, error) => const Icon(Icons.error),
|
||||
),
|
||||
),
|
||||
Positioned(
|
||||
left: 68,
|
||||
top: 6,
|
||||
child: Text(
|
||||
'你好',
|
||||
maxLines: 1,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
style: TextStyle(fontSize: 12, color: Color(0xFF777777)),
|
||||
),
|
||||
)),
|
||||
Positioned(
|
||||
right: 16,
|
||||
top: 6,
|
||||
child: Container(
|
||||
child: Text(
|
||||
'12:39',
|
||||
style: TextStyle(fontSize: 10, color: Color(0xFF8D8D8D)),
|
||||
),
|
||||
)),
|
||||
],
|
||||
data.name!,
|
||||
style: TextStyle(fontSize: 13, color: Color(0xFFE1E1E1)),
|
||||
)),
|
||||
Positioned(
|
||||
left: 68,
|
||||
top: 25,
|
||||
child: Container(
|
||||
width: 160,
|
||||
child: Text(
|
||||
'你好',
|
||||
maxLines: 1,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
style: TextStyle(fontSize: 12, color: Color(0xFF777777)),
|
||||
),
|
||||
)),
|
||||
Positioned(
|
||||
right: 16,
|
||||
top: 6,
|
||||
child: Container(
|
||||
child: Text(
|
||||
'12:39',
|
||||
style: TextStyle(fontSize: 10, color: Color(0xFF8D8D8D)),
|
||||
),
|
||||
)),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
void doNothing(BuildContext context) {
|
||||
EasyLoading.showToast("删除");
|
||||
doNothing(BuildContext context, id) {
|
||||
// EasyLoading.showToast("删除");
|
||||
}
|
||||
|
|
|
|||
|
|
@ -30,6 +30,7 @@ dependencies:
|
|||
dio: ^5.4.3+1
|
||||
cupertino_icons: ^1.0.6
|
||||
flutter_easyloading: ^3.0.5
|
||||
flutter_spinkit: ^5.2.1
|
||||
crypto: ^3.0.3
|
||||
shared_preferences: ^2.2.3
|
||||
json_annotation: ^4.9.0
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user