feat: 搜索直播间、用户

This commit is contained in:
guozhigq
2023-06-20 22:52:47 +08:00
parent 7e7892aab2
commit c2f8f143f8
15 changed files with 801 additions and 59 deletions

View File

@ -0,0 +1,48 @@
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:pilipala/http/search.dart';
import 'package:pilipala/models/common/search_type.dart';
class SearchPanelController extends GetxController {
SearchPanelController({this.keyword, this.searchType});
ScrollController scrollController = ScrollController();
String? keyword;
SearchType? searchType;
RxInt page = 1.obs;
RxList resultList = [].obs;
@override
void onInit() {
super.onInit();
}
Future onSearch({type = 'init'}) async {
var result = await SearchHttp.searchByType(
searchType: searchType!, keyword: keyword!, page: page.value);
if (result['status']) {
if (type == 'init') {
page.value++;
resultList.addAll(result['data'].list);
} else {
resultList.value = result['data'].list;
}
}
return result;
}
Future onRefresh() async {
page.value = 1;
onSearch(type: 'refresh');
}
// 返回顶部并刷新
void animateToTop() async {
if (scrollController.offset >=
MediaQuery.of(Get.context!).size.height * 5) {
scrollController.jumpTo(0);
} else {
await scrollController.animateTo(0,
duration: const Duration(milliseconds: 500), curve: Curves.easeInOut);
}
}
}

View File

@ -0,0 +1,4 @@
library searchpanel;
export './controller.dart';
export './view.dart';

View File

@ -0,0 +1,94 @@
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:pilipala/common/skeleton/video_card_h.dart';
import 'package:pilipala/common/widgets/http_error.dart';
import 'package:pilipala/common/widgets/live_card.dart';
import 'package:pilipala/common/widgets/video_card_h.dart';
import 'package:pilipala/models/common/search_type.dart';
import 'controller.dart';
import 'widgets/userPanel.dart';
class SearchPanel extends StatefulWidget {
String? keyword;
SearchType? searchType;
SearchPanel({required this.keyword, required this.searchType, Key? key})
: super(key: key);
@override
State<SearchPanel> createState() => _SearchPanelState();
}
class _SearchPanelState extends State<SearchPanel>
with AutomaticKeepAliveClientMixin {
late SearchPanelController? _searchPanelController;
@override
bool get wantKeepAlive => true;
@override
void initState() {
super.initState();
_searchPanelController = Get.put(
SearchPanelController(
keyword: widget.keyword,
searchType: widget.searchType,
),
tag: widget.searchType!.type);
}
@override
Widget build(BuildContext context) {
return RefreshIndicator(
onRefresh: () async {
await _searchPanelController!.onRefresh();
},
child: FutureBuilder(
future: _searchPanelController!.onSearch(),
builder: (context, snapshot) {
if (snapshot.connectionState == ConnectionState.done) {
Map data = snapshot.data;
if (data['status']) {
return Obx(
() => ListView.builder(
controller: _searchPanelController!.scrollController,
addAutomaticKeepAlives: false,
addRepaintBoundaries: false,
itemCount: _searchPanelController!.resultList.length,
itemBuilder: (context, index) {
var i = _searchPanelController!.resultList[index];
switch (widget.searchType) {
case SearchType.video:
return VideoCardH(videoItem: i);
case SearchType.bili_user:
return UserPanel(userItem: i);
case SearchType.live_room:
return LiveCard(liveItem: i);
default:
return const SizedBox();
}
},
),
);
} else {
return HttpError(
errMsg: data['msg'],
fn: () => setState(() {}),
);
}
} else {
// 骨架屏
return ListView.builder(
addAutomaticKeepAlives: false,
addRepaintBoundaries: false,
itemCount: 15,
itemBuilder: (context, index) {
return const VideoCardHSkeleton();
},
);
}
},
),
);
}
}

View File

@ -0,0 +1,63 @@
import 'package:flutter/material.dart';
import 'package:pilipala/common/widgets/network_img_layer.dart';
class UserPanel extends StatelessWidget {
var userItem;
UserPanel({super.key, this.userItem});
@override
Widget build(BuildContext context) {
return InkWell(
onTap: () {},
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 15, vertical: 10),
child: Row(
children: [
NetworkImgLayer(
width: 42,
height: 42,
src: userItem.upic,
type: 'avatar',
),
const SizedBox(width: 10),
Column(
mainAxisSize: MainAxisSize.max,
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.center,
children: [
Row(
children: [
Text(
userItem!.uname,
style: TextStyle(
// color: replyItem!.isUp! ||
// replyItem!.member!.vip!['vipType'] > 0
// ? Theme.of(context).colorScheme.primary
// : Theme.of(context).colorScheme.outline,
fontSize:
Theme.of(context).textTheme.titleMedium!.fontSize,
),
),
const SizedBox(width: 6),
Image.asset(
'assets/images/lv/lv${userItem!.level}.png',
height: 11,
),
],
),
if (userItem.officialVerify['desc'] != '')
Text(
userItem.officialVerify['desc'],
style: TextStyle(
fontSize:
Theme.of(context).textTheme.labelSmall!.fontSize,
color: Theme.of(context).colorScheme.outline),
),
],
)
],
),
),
);
}
}