mirror of
https://github.com/bggRGjQaUbCoE/PiliPlus.git
synced 2026-07-30 23:40:13 +08:00
feat: dyn topic rcmd
Signed-off-by: bggRGjQaUbCoE <githubaccount56556@proton.me>
This commit is contained in:
@@ -888,4 +888,6 @@ class Api {
|
|||||||
static const String vipExpAdd = '/x/vip/experience/add';
|
static const String vipExpAdd = '/x/vip/experience/add';
|
||||||
|
|
||||||
static const String coinLog = '/x/member/web/coin/log';
|
static const String coinLog = '/x/member/web/coin/log';
|
||||||
|
|
||||||
|
static const String dynTopicRcmd = '/x/topic/web/dynamic/rcmd';
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ import 'package:PiliPlus/models_new/article/article_view/data.dart';
|
|||||||
import 'package:PiliPlus/models_new/dynamic/dyn_reserve/data.dart';
|
import 'package:PiliPlus/models_new/dynamic/dyn_reserve/data.dart';
|
||||||
import 'package:PiliPlus/models_new/dynamic/dyn_topic_feed/topic_card_list.dart';
|
import 'package:PiliPlus/models_new/dynamic/dyn_topic_feed/topic_card_list.dart';
|
||||||
import 'package:PiliPlus/models_new/dynamic/dyn_topic_top/top_details.dart';
|
import 'package:PiliPlus/models_new/dynamic/dyn_topic_top/top_details.dart';
|
||||||
|
import 'package:PiliPlus/models_new/dynamic/dyn_topic_top/topic_item.dart';
|
||||||
import 'package:PiliPlus/utils/accounts/account.dart';
|
import 'package:PiliPlus/utils/accounts/account.dart';
|
||||||
import 'package:PiliPlus/utils/storage.dart';
|
import 'package:PiliPlus/utils/storage.dart';
|
||||||
import 'package:PiliPlus/utils/utils.dart';
|
import 'package:PiliPlus/utils/utils.dart';
|
||||||
@@ -473,4 +474,23 @@ class DynamicsHttp {
|
|||||||
return {'status': false, 'msg': res.data['message']};
|
return {'status': false, 'msg': res.data['message']};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static Future<LoadingState<List<TopicItem>?>> dynTopicRcmd(
|
||||||
|
{int ps = 25}) async {
|
||||||
|
final res = await Request().get(
|
||||||
|
Api.dynTopicRcmd,
|
||||||
|
queryParameters: {
|
||||||
|
'source': 'Web',
|
||||||
|
'page_size': ps,
|
||||||
|
'web_location': 333.1365,
|
||||||
|
},
|
||||||
|
);
|
||||||
|
if (res.data['code'] == 0) {
|
||||||
|
return Success((res.data['data']?['topic_items'] as List?)
|
||||||
|
?.map((e) => TopicItem.fromJson(e))
|
||||||
|
.toList());
|
||||||
|
} else {
|
||||||
|
return Error(res.data['message']);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,11 +1,11 @@
|
|||||||
import 'package:PiliPlus/models_new/dynamic/dyn_topic_pub_search/new_topic.dart';
|
import 'package:PiliPlus/models_new/dynamic/dyn_topic_pub_search/new_topic.dart';
|
||||||
import 'package:PiliPlus/models_new/dynamic/dyn_topic_pub_search/page_info.dart';
|
import 'package:PiliPlus/models_new/dynamic/dyn_topic_pub_search/page_info.dart';
|
||||||
import 'package:PiliPlus/models_new/dynamic/dyn_topic_pub_search/topic_item.dart';
|
import 'package:PiliPlus/models_new/dynamic/dyn_topic_top/topic_item.dart';
|
||||||
|
|
||||||
class TopicPubSearchData {
|
class TopicPubSearchData {
|
||||||
NewTopic? newTopic;
|
NewTopic? newTopic;
|
||||||
bool? hasCreateJurisdiction;
|
bool? hasCreateJurisdiction;
|
||||||
List<TopicPubSearchItem>? topicItems;
|
List<TopicItem>? topicItems;
|
||||||
String? requestId;
|
String? requestId;
|
||||||
PageInfo? pageInfo;
|
PageInfo? pageInfo;
|
||||||
|
|
||||||
@@ -24,7 +24,7 @@ class TopicPubSearchData {
|
|||||||
: NewTopic.fromJson(json['new_topic'] as Map<String, dynamic>),
|
: NewTopic.fromJson(json['new_topic'] as Map<String, dynamic>),
|
||||||
hasCreateJurisdiction: json['has_create_jurisdiction'] as bool?,
|
hasCreateJurisdiction: json['has_create_jurisdiction'] as bool?,
|
||||||
topicItems: (json['topic_items'] as List<dynamic>?)
|
topicItems: (json['topic_items'] as List<dynamic>?)
|
||||||
?.map((e) => TopicPubSearchItem.fromJson(e as Map<String, dynamic>))
|
?.map((e) => TopicItem.fromJson(e as Map<String, dynamic>))
|
||||||
.toList(),
|
.toList(),
|
||||||
requestId: json['request_id'] as String?,
|
requestId: json['request_id'] as String?,
|
||||||
pageInfo: json['page_info'] == null
|
pageInfo: json['page_info'] == null
|
||||||
|
|||||||
@@ -1,30 +0,0 @@
|
|||||||
class TopicPubSearchItem {
|
|
||||||
int? id;
|
|
||||||
String? name;
|
|
||||||
int? view;
|
|
||||||
int? discuss;
|
|
||||||
String? statDesc;
|
|
||||||
String? description;
|
|
||||||
bool? showInteractData;
|
|
||||||
|
|
||||||
TopicPubSearchItem({
|
|
||||||
this.id,
|
|
||||||
this.name,
|
|
||||||
this.view,
|
|
||||||
this.discuss,
|
|
||||||
this.statDesc,
|
|
||||||
this.description,
|
|
||||||
this.showInteractData,
|
|
||||||
});
|
|
||||||
|
|
||||||
factory TopicPubSearchItem.fromJson(Map<String, dynamic> json) =>
|
|
||||||
TopicPubSearchItem(
|
|
||||||
id: json['id'] as int?,
|
|
||||||
name: json['name'] as String?,
|
|
||||||
view: json['view'] as int?,
|
|
||||||
discuss: json['discuss'] as int?,
|
|
||||||
statDesc: json['stat_desc'] as String?,
|
|
||||||
description: json['description'] as String?,
|
|
||||||
showInteractData: json['show_interact_data'] as bool?,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
@@ -1,10 +1,10 @@
|
|||||||
class TopicItem {
|
class TopicItem {
|
||||||
int? id;
|
int id;
|
||||||
String? name;
|
String name;
|
||||||
int? view;
|
int view;
|
||||||
int? discuss;
|
int discuss;
|
||||||
late int fav;
|
int fav;
|
||||||
late int like;
|
int like;
|
||||||
int? dynamics;
|
int? dynamics;
|
||||||
String? jumpUrl;
|
String? jumpUrl;
|
||||||
String? backColor;
|
String? backColor;
|
||||||
@@ -17,10 +17,10 @@ class TopicItem {
|
|||||||
bool? isLike;
|
bool? isLike;
|
||||||
|
|
||||||
TopicItem({
|
TopicItem({
|
||||||
this.id,
|
required this.id,
|
||||||
this.name,
|
required this.name,
|
||||||
this.view,
|
required this.view,
|
||||||
this.discuss,
|
required this.discuss,
|
||||||
required this.fav,
|
required this.fav,
|
||||||
required this.like,
|
required this.like,
|
||||||
this.dynamics,
|
this.dynamics,
|
||||||
@@ -36,12 +36,12 @@ class TopicItem {
|
|||||||
});
|
});
|
||||||
|
|
||||||
factory TopicItem.fromJson(Map<String, dynamic> json) => TopicItem(
|
factory TopicItem.fromJson(Map<String, dynamic> json) => TopicItem(
|
||||||
id: json['id'] as int?,
|
id: json['id'],
|
||||||
name: json['name'] as String?,
|
name: json['name'],
|
||||||
view: json['view'] as int? ?? 0,
|
view: json['view'] ?? 0,
|
||||||
discuss: json['discuss'] as int? ?? 0,
|
discuss: json['discuss'] ?? 0,
|
||||||
fav: json['fav'] as int? ?? 0,
|
fav: json['fav'] ?? 0,
|
||||||
like: json['like'] as int? ?? 0,
|
like: json['like'] ?? 0,
|
||||||
dynamics: json['dynamics'] as int?,
|
dynamics: json['dynamics'] as int?,
|
||||||
jumpUrl: json['jump_url'] as String?,
|
jumpUrl: json['jump_url'] as String?,
|
||||||
backColor: json['back_color'] as String?,
|
backColor: json['back_color'] as String?,
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ import 'package:PiliPlus/common/widgets/pair.dart';
|
|||||||
import 'package:PiliPlus/http/dynamics.dart';
|
import 'package:PiliPlus/http/dynamics.dart';
|
||||||
import 'package:PiliPlus/models/common/publish_panel_type.dart';
|
import 'package:PiliPlus/models/common/publish_panel_type.dart';
|
||||||
import 'package:PiliPlus/models/common/reply/reply_option_type.dart';
|
import 'package:PiliPlus/models/common/reply/reply_option_type.dart';
|
||||||
import 'package:PiliPlus/models_new/dynamic/dyn_topic_pub_search/topic_item.dart';
|
import 'package:PiliPlus/models_new/dynamic/dyn_topic_top/topic_item.dart';
|
||||||
import 'package:PiliPlus/pages/common/common_publish_page.dart';
|
import 'package:PiliPlus/pages/common/common_publish_page.dart';
|
||||||
import 'package:PiliPlus/pages/dynamics_select_topic/controller.dart';
|
import 'package:PiliPlus/pages/dynamics_select_topic/controller.dart';
|
||||||
import 'package:PiliPlus/pages/dynamics_select_topic/view.dart';
|
import 'package:PiliPlus/pages/dynamics_select_topic/view.dart';
|
||||||
@@ -621,7 +621,7 @@ class _CreateDynPanelState extends CommonPublishPageState<CreateDynPanel> {
|
|||||||
|
|
||||||
double _offset = 0;
|
double _offset = 0;
|
||||||
Future<void> _onSelectTopic() async {
|
Future<void> _onSelectTopic() async {
|
||||||
TopicPubSearchItem? res = await showModalBottomSheet(
|
TopicItem? res = await showModalBottomSheet(
|
||||||
context: context,
|
context: context,
|
||||||
useSafeArea: true,
|
useSafeArea: true,
|
||||||
isScrollControlled: true,
|
isScrollControlled: true,
|
||||||
@@ -643,7 +643,7 @@ class _CreateDynPanelState extends CommonPublishPageState<CreateDynPanel> {
|
|||||||
),
|
),
|
||||||
);
|
);
|
||||||
if (res != null) {
|
if (res != null) {
|
||||||
topic.value = Pair(first: res.id!, second: res.name!);
|
topic.value = Pair(first: res.id, second: res.name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,13 +1,13 @@
|
|||||||
import 'package:PiliPlus/http/loading_state.dart';
|
import 'package:PiliPlus/http/loading_state.dart';
|
||||||
import 'package:PiliPlus/http/search.dart';
|
import 'package:PiliPlus/http/search.dart';
|
||||||
import 'package:PiliPlus/models_new/dynamic/dyn_topic_pub_search/data.dart';
|
import 'package:PiliPlus/models_new/dynamic/dyn_topic_pub_search/data.dart';
|
||||||
import 'package:PiliPlus/models_new/dynamic/dyn_topic_pub_search/topic_item.dart';
|
import 'package:PiliPlus/models_new/dynamic/dyn_topic_top/topic_item.dart';
|
||||||
import 'package:PiliPlus/pages/common/common_list_controller.dart';
|
import 'package:PiliPlus/pages/common/common_list_controller.dart';
|
||||||
import 'package:flutter/widgets.dart';
|
import 'package:flutter/widgets.dart';
|
||||||
import 'package:get/get.dart';
|
import 'package:get/get.dart';
|
||||||
|
|
||||||
class SelectTopicController
|
class SelectTopicController
|
||||||
extends CommonListController<TopicPubSearchData, TopicPubSearchItem> {
|
extends CommonListController<TopicPubSearchData, TopicItem> {
|
||||||
final focusNode = FocusNode();
|
final focusNode = FocusNode();
|
||||||
final controller = TextEditingController();
|
final controller = TextEditingController();
|
||||||
|
|
||||||
@@ -20,7 +20,7 @@ class SelectTopicController
|
|||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
List<TopicPubSearchItem>? getDataList(TopicPubSearchData response) {
|
List<TopicItem>? getDataList(TopicPubSearchData response) {
|
||||||
return response.topicItems;
|
return response.topicItems;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,12 +1,11 @@
|
|||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
|
|
||||||
import 'package:PiliPlus/common/widgets/custom_icon.dart';
|
|
||||||
import 'package:PiliPlus/common/widgets/loading_widget/loading_widget.dart';
|
import 'package:PiliPlus/common/widgets/loading_widget/loading_widget.dart';
|
||||||
import 'package:PiliPlus/http/loading_state.dart';
|
import 'package:PiliPlus/http/loading_state.dart';
|
||||||
import 'package:PiliPlus/models_new/dynamic/dyn_topic_pub_search/topic_item.dart';
|
import 'package:PiliPlus/models_new/dynamic/dyn_topic_top/topic_item.dart';
|
||||||
import 'package:PiliPlus/pages/dynamics_select_topic/controller.dart';
|
import 'package:PiliPlus/pages/dynamics_select_topic/controller.dart';
|
||||||
|
import 'package:PiliPlus/pages/dynamics_select_topic/widgets/item.dart';
|
||||||
import 'package:PiliPlus/utils/extension.dart';
|
import 'package:PiliPlus/utils/extension.dart';
|
||||||
import 'package:PiliPlus/utils/utils.dart';
|
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:get/get.dart';
|
import 'package:get/get.dart';
|
||||||
import 'package:stream_transform/stream_transform.dart';
|
import 'package:stream_transform/stream_transform.dart';
|
||||||
@@ -140,70 +139,41 @@ class _SelectTopicPanelState extends State<SelectTopicPanel> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Widget _buildBody(
|
Widget _buildBody(
|
||||||
ThemeData theme, LoadingState<List<TopicPubSearchItem>?> loadingState) {
|
ThemeData theme, LoadingState<List<TopicItem>?> loadingState) {
|
||||||
return switch (loadingState) {
|
return switch (loadingState) {
|
||||||
Loading() => loadingWidget,
|
Loading() => loadingWidget,
|
||||||
Success<List<TopicPubSearchItem>?>(:var response) =>
|
Success<List<TopicItem>?>(:var response) => response?.isNotEmpty == true
|
||||||
response?.isNotEmpty == true
|
? NotificationListener<ScrollNotification>(
|
||||||
? NotificationListener<ScrollNotification>(
|
onNotification: (notification) {
|
||||||
onNotification: (notification) {
|
if (notification is UserScrollNotification) {
|
||||||
if (notification is UserScrollNotification) {
|
if (_controller.focusNode.hasFocus) {
|
||||||
if (_controller.focusNode.hasFocus) {
|
_controller.focusNode.unfocus();
|
||||||
_controller.focusNode.unfocus();
|
|
||||||
}
|
|
||||||
} else if (notification is ScrollEndNotification) {
|
|
||||||
widget.callback?.call(notification.metrics.pixels);
|
|
||||||
}
|
}
|
||||||
return false;
|
} else if (notification is ScrollEndNotification) {
|
||||||
},
|
widget.callback?.call(notification.metrics.pixels);
|
||||||
child: ListView.builder(
|
}
|
||||||
padding: EdgeInsets.only(
|
return false;
|
||||||
bottom: MediaQuery.paddingOf(context).bottom +
|
},
|
||||||
MediaQuery.viewInsetsOf(context).bottom +
|
child: ListView.builder(
|
||||||
80,
|
padding: EdgeInsets.only(
|
||||||
),
|
bottom: MediaQuery.paddingOf(context).bottom +
|
||||||
controller: widget.scrollController,
|
MediaQuery.viewInsetsOf(context).bottom +
|
||||||
itemBuilder: (context, index) {
|
80,
|
||||||
if (index == response.length - 1) {
|
|
||||||
_controller.onLoadMore();
|
|
||||||
}
|
|
||||||
final item = response[index];
|
|
||||||
return ListTile(
|
|
||||||
dense: true,
|
|
||||||
onTap: () => Get.back(result: item),
|
|
||||||
title: Text.rich(
|
|
||||||
TextSpan(
|
|
||||||
children: [
|
|
||||||
const WidgetSpan(
|
|
||||||
alignment: PlaceholderAlignment.middle,
|
|
||||||
child: Padding(
|
|
||||||
padding: EdgeInsets.only(right: 5),
|
|
||||||
child: Icon(
|
|
||||||
CustomIcon.topic_tag,
|
|
||||||
size: 18,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
TextSpan(
|
|
||||||
text: item.name,
|
|
||||||
style: const TextStyle(fontSize: 14),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
|
||||||
subtitle: Padding(
|
|
||||||
padding: const EdgeInsets.only(left: 23),
|
|
||||||
child: Text(
|
|
||||||
'${Utils.numFormat(item.view)}浏览 · ${Utils.numFormat(item.discuss)}讨论',
|
|
||||||
style: TextStyle(color: theme.colorScheme.outline),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
},
|
|
||||||
itemCount: response!.length,
|
|
||||||
),
|
),
|
||||||
)
|
controller: widget.scrollController,
|
||||||
: _errWidget(),
|
itemBuilder: (context, index) {
|
||||||
|
if (index == response.length - 1) {
|
||||||
|
_controller.onLoadMore();
|
||||||
|
}
|
||||||
|
return DynTopicItem(
|
||||||
|
item: response[index],
|
||||||
|
onTap: (item) => Get.back(result: item),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
itemCount: response!.length,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
: _errWidget(),
|
||||||
Error(:var errMsg) => _errWidget(errMsg),
|
Error(:var errMsg) => _errWidget(errMsg),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
50
lib/pages/dynamics_select_topic/widgets/item.dart
Normal file
50
lib/pages/dynamics_select_topic/widgets/item.dart
Normal file
@@ -0,0 +1,50 @@
|
|||||||
|
import 'package:PiliPlus/common/widgets/custom_icon.dart';
|
||||||
|
import 'package:PiliPlus/models_new/dynamic/dyn_topic_top/topic_item.dart';
|
||||||
|
import 'package:PiliPlus/utils/utils.dart';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
|
class DynTopicItem extends StatelessWidget {
|
||||||
|
const DynTopicItem({
|
||||||
|
super.key,
|
||||||
|
required this.item,
|
||||||
|
required this.onTap,
|
||||||
|
});
|
||||||
|
|
||||||
|
final TopicItem item;
|
||||||
|
final ValueChanged<TopicItem> onTap;
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return ListTile(
|
||||||
|
dense: true,
|
||||||
|
onTap: () => onTap(item),
|
||||||
|
title: Text.rich(
|
||||||
|
TextSpan(
|
||||||
|
children: [
|
||||||
|
const WidgetSpan(
|
||||||
|
alignment: PlaceholderAlignment.middle,
|
||||||
|
child: Padding(
|
||||||
|
padding: EdgeInsets.only(right: 5),
|
||||||
|
child: Icon(
|
||||||
|
CustomIcon.topic_tag,
|
||||||
|
size: 18,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
TextSpan(
|
||||||
|
text: item.name,
|
||||||
|
style: const TextStyle(fontSize: 14),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
subtitle: Padding(
|
||||||
|
padding: const EdgeInsets.only(left: 23),
|
||||||
|
child: Text(
|
||||||
|
'${Utils.numFormat(item.view)}浏览 · ${Utils.numFormat(item.discuss)}讨论',
|
||||||
|
style: TextStyle(color: Theme.of(context).colorScheme.outline),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -40,7 +40,7 @@ class DynTopicController
|
|||||||
topState.value = await DynamicsHttp.topicTop(topicId: topicId);
|
topState.value = await DynamicsHttp.topicTop(topicId: topicId);
|
||||||
if (topState.value.isSuccess) {
|
if (topState.value.isSuccess) {
|
||||||
var topicItem = topState.value.data!.topicItem!;
|
var topicItem = topState.value.data!.topicItem!;
|
||||||
topicName = topicItem.name!;
|
topicName = topicItem.name;
|
||||||
isFav.value = topicItem.isFav;
|
isFav.value = topicItem.isFav;
|
||||||
isLike.value = topicItem.isLike;
|
isLike.value = topicItem.isLike;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -153,7 +153,7 @@ class _DynTopicPageState extends State<DynTopicPage> {
|
|||||||
pinned: true,
|
pinned: true,
|
||||||
callback: (value) => _controller.appbarOffset =
|
callback: (value) => _controller.appbarOffset =
|
||||||
value - kToolbarHeight - paddingTop - 7,
|
value - kToolbarHeight - paddingTop - 7,
|
||||||
title: IgnorePointer(child: Text(response!.topicItem!.name!)),
|
title: IgnorePointer(child: Text(response!.topicItem!.name)),
|
||||||
flexibleSpace: Container(
|
flexibleSpace: Container(
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
image: DecorationImage(
|
image: DecorationImage(
|
||||||
@@ -206,7 +206,7 @@ class _DynTopicPageState extends State<DynTopicPage> {
|
|||||||
),
|
),
|
||||||
),
|
),
|
||||||
Text(
|
Text(
|
||||||
response.topicItem!.name!,
|
response.topicItem!.name,
|
||||||
style: const TextStyle(
|
style: const TextStyle(
|
||||||
fontSize: 16,
|
fontSize: 16,
|
||||||
fontWeight: FontWeight.bold,
|
fontWeight: FontWeight.bold,
|
||||||
|
|||||||
17
lib/pages/dynamics_topic_rcmd/controller.dart
Normal file
17
lib/pages/dynamics_topic_rcmd/controller.dart
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
import 'package:PiliPlus/http/dynamics.dart';
|
||||||
|
import 'package:PiliPlus/http/loading_state.dart';
|
||||||
|
import 'package:PiliPlus/models_new/dynamic/dyn_topic_top/topic_item.dart';
|
||||||
|
import 'package:PiliPlus/pages/common/common_list_controller.dart';
|
||||||
|
|
||||||
|
class DynTopicRcmdController
|
||||||
|
extends CommonListController<List<TopicItem>?, TopicItem> {
|
||||||
|
@override
|
||||||
|
void onInit() {
|
||||||
|
super.onInit();
|
||||||
|
queryData();
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future<LoadingState<List<TopicItem>?>> customGetData() =>
|
||||||
|
DynamicsHttp.dynTopicRcmd();
|
||||||
|
}
|
||||||
70
lib/pages/dynamics_topic_rcmd/view.dart
Normal file
70
lib/pages/dynamics_topic_rcmd/view.dart
Normal file
@@ -0,0 +1,70 @@
|
|||||||
|
import 'package:PiliPlus/common/widgets/loading_widget/http_error.dart';
|
||||||
|
import 'package:PiliPlus/common/widgets/refresh_indicator.dart';
|
||||||
|
import 'package:PiliPlus/http/loading_state.dart';
|
||||||
|
import 'package:PiliPlus/models_new/dynamic/dyn_topic_top/topic_item.dart';
|
||||||
|
import 'package:PiliPlus/pages/dynamics_select_topic/widgets/item.dart';
|
||||||
|
import 'package:PiliPlus/pages/dynamics_topic_rcmd/controller.dart';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:get/get.dart';
|
||||||
|
|
||||||
|
class DynTopicRcmdPage extends StatefulWidget {
|
||||||
|
const DynTopicRcmdPage({super.key});
|
||||||
|
|
||||||
|
@override
|
||||||
|
State<DynTopicRcmdPage> createState() => _DynTopicRcmdPageState();
|
||||||
|
}
|
||||||
|
|
||||||
|
class _DynTopicRcmdPageState extends State<DynTopicRcmdPage> {
|
||||||
|
final DynTopicRcmdController _controller = Get.put(DynTopicRcmdController());
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context) {
|
||||||
|
return Scaffold(
|
||||||
|
appBar: AppBar(title: const Text('话题')),
|
||||||
|
body: SafeArea(
|
||||||
|
top: false,
|
||||||
|
bottom: false,
|
||||||
|
child: refreshIndicator(
|
||||||
|
onRefresh: _controller.onRefresh,
|
||||||
|
child: CustomScrollView(
|
||||||
|
slivers: [
|
||||||
|
SliverPadding(
|
||||||
|
padding: EdgeInsets.only(
|
||||||
|
bottom: MediaQuery.paddingOf(context).bottom + 80,
|
||||||
|
),
|
||||||
|
sliver: Obx(() => _buildBody(_controller.loadingState.value)),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Widget _buildBody(LoadingState<List<TopicItem>?> loadingState) {
|
||||||
|
return switch (loadingState) {
|
||||||
|
Loading() => const SliverToBoxAdapter(child: LinearProgressIndicator()),
|
||||||
|
Success(:var response) => response?.isNotEmpty == true
|
||||||
|
? SliverList.builder(
|
||||||
|
itemCount: response!.length,
|
||||||
|
itemBuilder: (context, index) {
|
||||||
|
return DynTopicItem(
|
||||||
|
item: response[index],
|
||||||
|
onTap: (item) => Get.toNamed(
|
||||||
|
'/dynTopic',
|
||||||
|
parameters: {
|
||||||
|
'id': item.id.toString(),
|
||||||
|
'name': item.name,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
)
|
||||||
|
: HttpError(onReload: _controller.onReload),
|
||||||
|
Error(:var errMsg) => HttpError(
|
||||||
|
errMsg: errMsg,
|
||||||
|
onReload: _controller.onReload,
|
||||||
|
),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -174,31 +174,48 @@ class _SearchPageState extends State<SearchPage> {
|
|||||||
mainAxisSize: MainAxisSize.min,
|
mainAxisSize: MainAxisSize.min,
|
||||||
children: [
|
children: [
|
||||||
text,
|
text,
|
||||||
Padding(
|
const SizedBox(width: 14),
|
||||||
padding: const EdgeInsets.only(left: 14),
|
SizedBox(
|
||||||
child: SizedBox(
|
height: 34,
|
||||||
height: 34,
|
child: TextButton.icon(
|
||||||
child: TextButton.icon(
|
onPressed: () => Get.toNamed(
|
||||||
onPressed: () => Get.toNamed(
|
'/searchTrending',
|
||||||
'/searchTrending',
|
parameters: {'tag': _tag},
|
||||||
parameters: {'tag': _tag},
|
),
|
||||||
),
|
label: Text(
|
||||||
label: Text(
|
'完整榜单',
|
||||||
'完整榜单',
|
style: TextStyle(
|
||||||
style: TextStyle(
|
fontSize: 13,
|
||||||
fontSize: 13,
|
|
||||||
color: theme.colorScheme.outline,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
icon: Icon(
|
|
||||||
size: 16,
|
|
||||||
Icons.keyboard_arrow_right,
|
|
||||||
color: theme.colorScheme.outline,
|
color: theme.colorScheme.outline,
|
||||||
),
|
),
|
||||||
iconAlignment: IconAlignment.end,
|
|
||||||
),
|
),
|
||||||
|
icon: Icon(
|
||||||
|
size: 16,
|
||||||
|
Icons.keyboard_arrow_right,
|
||||||
|
color: theme.colorScheme.outline,
|
||||||
|
),
|
||||||
|
iconAlignment: IconAlignment.end,
|
||||||
),
|
),
|
||||||
)
|
),
|
||||||
|
SizedBox(
|
||||||
|
height: 34,
|
||||||
|
child: TextButton.icon(
|
||||||
|
onPressed: () => Get.toNamed('/dynTopicRcmd'),
|
||||||
|
label: Text(
|
||||||
|
'话题',
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 13,
|
||||||
|
color: theme.colorScheme.outline,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
icon: Icon(
|
||||||
|
size: 16,
|
||||||
|
Icons.keyboard_arrow_right,
|
||||||
|
color: theme.colorScheme.outline,
|
||||||
|
),
|
||||||
|
iconAlignment: IconAlignment.end,
|
||||||
|
),
|
||||||
|
),
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
: text,
|
: text,
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ import 'package:PiliPlus/pages/danmaku_block/view.dart';
|
|||||||
import 'package:PiliPlus/pages/dynamics/view.dart';
|
import 'package:PiliPlus/pages/dynamics/view.dart';
|
||||||
import 'package:PiliPlus/pages/dynamics_detail/view.dart';
|
import 'package:PiliPlus/pages/dynamics_detail/view.dart';
|
||||||
import 'package:PiliPlus/pages/dynamics_topic/view.dart';
|
import 'package:PiliPlus/pages/dynamics_topic/view.dart';
|
||||||
|
import 'package:PiliPlus/pages/dynamics_topic_rcmd/view.dart';
|
||||||
import 'package:PiliPlus/pages/fan/view.dart';
|
import 'package:PiliPlus/pages/fan/view.dart';
|
||||||
import 'package:PiliPlus/pages/fav/view.dart';
|
import 'package:PiliPlus/pages/fav/view.dart';
|
||||||
import 'package:PiliPlus/pages/fav_create/view.dart';
|
import 'package:PiliPlus/pages/fav_create/view.dart';
|
||||||
@@ -177,6 +178,7 @@ class Routes {
|
|||||||
CustomGetPage(name: '/barSetting', page: () => const BarSetPage()),
|
CustomGetPage(name: '/barSetting', page: () => const BarSetPage()),
|
||||||
CustomGetPage(name: '/upowerRank', page: () => const UpowerRankPage()),
|
CustomGetPage(name: '/upowerRank', page: () => const UpowerRankPage()),
|
||||||
CustomGetPage(name: '/spaceSetting', page: () => const SpaceSettingPage()),
|
CustomGetPage(name: '/spaceSetting', page: () => const SpaceSettingPage()),
|
||||||
|
CustomGetPage(name: '/dynTopicRcmd', page: () => const DynTopicRcmdPage()),
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user