mirror of
https://github.com/bggRGjQaUbCoE/PiliPlus.git
synced 2026-06-11 13:21:36 +08:00
@@ -1,15 +1,12 @@
|
||||
import 'dart:async';
|
||||
|
||||
import 'package:PiliPlus/http/dynamics.dart';
|
||||
import 'package:PiliPlus/http/follow.dart';
|
||||
import 'package:PiliPlus/http/loading_state.dart';
|
||||
import 'package:PiliPlus/models/common/dynamic/dynamics_type.dart';
|
||||
import 'package:PiliPlus/models/dynamics/up.dart';
|
||||
import 'package:PiliPlus/models_new/follow/data.dart';
|
||||
import 'package:PiliPlus/pages/common/common_controller.dart';
|
||||
import 'package:PiliPlus/pages/dynamics_tab/controller.dart';
|
||||
import 'package:PiliPlus/services/account_service.dart';
|
||||
import 'package:PiliPlus/utils/accounts.dart';
|
||||
import 'package:PiliPlus/utils/extension/scroll_controller_ext.dart';
|
||||
import 'package:PiliPlus/utils/extension/string_ext.dart';
|
||||
import 'package:PiliPlus/utils/storage_pref.dart';
|
||||
@@ -29,11 +26,8 @@ class DynamicsController extends GetxController
|
||||
|
||||
final Rx<LoadingState<FollowUpModel>> upState =
|
||||
LoadingState<FollowUpModel>.loading().obs;
|
||||
late int _upPage = 1;
|
||||
late bool _upEnd = false;
|
||||
Set<UpItem>? _cacheUpList;
|
||||
late final _showAllUp = Pref.dynamicsShowAllFollowedUp;
|
||||
late bool showLiveUp = Pref.expandDynLivePanel;
|
||||
late bool showLiveUp = false;
|
||||
|
||||
final upPanelPosition = Pref.upPanelPosition;
|
||||
|
||||
@@ -56,17 +50,12 @@ class DynamicsController extends GetxController
|
||||
tabController = TabController(
|
||||
length: DynamicsTabType.values.length,
|
||||
vsync: this,
|
||||
initialIndex: Pref.defaultDynamicTypeIndex,
|
||||
);
|
||||
queryFollowUp();
|
||||
}
|
||||
|
||||
void onLoadMoreUp() {
|
||||
if (_showAllUp) {
|
||||
queryAllUp();
|
||||
} else {
|
||||
queryUpList();
|
||||
}
|
||||
queryUpList();
|
||||
}
|
||||
|
||||
Future<void> queryUpList() async {
|
||||
@@ -92,33 +81,6 @@ class DynamicsController extends GetxController
|
||||
isQuerying = false;
|
||||
}
|
||||
|
||||
Future<void> queryAllUp() async {
|
||||
if (isQuerying || _upEnd) return;
|
||||
isQuerying = true;
|
||||
|
||||
final res = await FollowHttp.followings(
|
||||
vmid: Accounts.main.mid,
|
||||
pn: _upPage,
|
||||
orderType: 'attention',
|
||||
ps: 50,
|
||||
);
|
||||
|
||||
if (res case Success(:final response)) {
|
||||
_upPage++;
|
||||
final list = response.list;
|
||||
if (list.isEmpty) {
|
||||
_upEnd = true;
|
||||
}
|
||||
upState
|
||||
..value.data.upList.addAll(
|
||||
list..removeWhere((e) => _cacheUpList?.contains(e) == true),
|
||||
)
|
||||
..refresh();
|
||||
}
|
||||
|
||||
isQuerying = false;
|
||||
}
|
||||
|
||||
late bool isQuerying = false;
|
||||
Future<void> queryFollowUp() async {
|
||||
if (isQuerying) return;
|
||||
@@ -132,39 +94,13 @@ class DynamicsController extends GetxController
|
||||
|
||||
// reset
|
||||
_upEnd = false;
|
||||
if (_showAllUp) _upPage = 1;
|
||||
|
||||
final res = await Future.wait([
|
||||
DynamicsHttp.followUp(),
|
||||
if (_showAllUp)
|
||||
FollowHttp.followings(
|
||||
vmid: Accounts.main.mid,
|
||||
pn: _upPage,
|
||||
orderType: 'attention',
|
||||
ps: 50,
|
||||
),
|
||||
]);
|
||||
final res = await DynamicsHttp.followUp();
|
||||
|
||||
final first = res.first;
|
||||
if (first case final Success<FollowUpModel> i) {
|
||||
if (res case final Success<FollowUpModel> i) {
|
||||
final data = i.response;
|
||||
final second = res.elementAtOrNull(1);
|
||||
if (second case final Success<FollowData> j) {
|
||||
final data1 = j.response;
|
||||
final list1 = data1.list;
|
||||
|
||||
_upPage++;
|
||||
if (list1.isEmpty || list1.length >= (data1.total ?? 0)) {
|
||||
_upEnd = true;
|
||||
}
|
||||
|
||||
final list = data.upList;
|
||||
list.addAll(list1..removeWhere((_cacheUpList = list.toSet()).contains));
|
||||
}
|
||||
if (!_showAllUp) {
|
||||
if (data.hasMore == false || data.offset.isNullOrEmpty) {
|
||||
_upEnd = true;
|
||||
}
|
||||
if (data.hasMore == false || data.offset.isNullOrEmpty) {
|
||||
_upEnd = true;
|
||||
}
|
||||
upState.value = Success(data);
|
||||
} else {
|
||||
@@ -195,10 +131,6 @@ class DynamicsController extends GetxController
|
||||
}
|
||||
|
||||
void _refreshFollowUp() {
|
||||
if (_showAllUp) {
|
||||
_upPage = 1;
|
||||
_cacheUpList = null;
|
||||
}
|
||||
queryFollowUp();
|
||||
}
|
||||
|
||||
|
||||
@@ -3,12 +3,10 @@ import 'package:PiliPlus/http/loading_state.dart';
|
||||
import 'package:PiliPlus/models/common/dynamic/dynamics_type.dart';
|
||||
import 'package:PiliPlus/models/common/dynamic/up_panel_position.dart';
|
||||
import 'package:PiliPlus/models/dynamics/up.dart';
|
||||
import 'package:PiliPlus/pages/common/common_page.dart';
|
||||
import 'package:PiliPlus/pages/dynamics/controller.dart';
|
||||
import 'package:PiliPlus/pages/dynamics/widgets/up_panel.dart';
|
||||
import 'package:PiliPlus/pages/dynamics_create/view.dart';
|
||||
import 'package:PiliPlus/pages/dynamics_tab/view.dart';
|
||||
import 'package:PiliPlus/pages/main/controller.dart';
|
||||
import 'package:PiliPlus/utils/extension/get_ext.dart';
|
||||
import 'package:flutter/material.dart' hide DraggableScrollableSheet;
|
||||
import 'package:get/get.dart';
|
||||
@@ -20,11 +18,10 @@ class DynamicsPage extends StatefulWidget {
|
||||
State<DynamicsPage> createState() => _DynamicsPageState();
|
||||
}
|
||||
|
||||
class _DynamicsPageState extends CommonPageState<DynamicsPage>
|
||||
class _DynamicsPageState extends State<DynamicsPage>
|
||||
with AutomaticKeepAliveClientMixin {
|
||||
final _dynamicsController = Get.putOrFind(DynamicsController.new);
|
||||
UpPanelPosition get upPanelPosition => _dynamicsController.upPanelPosition;
|
||||
late final MainController _mainController = Get.find<MainController>();
|
||||
|
||||
@override
|
||||
bool get wantKeepAlive => true;
|
||||
@@ -52,8 +49,7 @@ class _DynamicsPageState extends CommonPageState<DynamicsPage>
|
||||
),
|
||||
);
|
||||
|
||||
Widget upPanelPart(ThemeData theme) {
|
||||
final isTop = upPanelPosition == .top;
|
||||
Widget upPanelPart(ThemeData theme, {bool isTop = false}) {
|
||||
final needBg = upPanelPosition.index > 2;
|
||||
return Material(
|
||||
type: needBg ? .canvas : .transparency,
|
||||
@@ -92,34 +88,11 @@ class _DynamicsPageState extends CommonPageState<DynamicsPage>
|
||||
};
|
||||
}
|
||||
|
||||
bool get checkPage =>
|
||||
_mainController.navigationBars[0] != .dynamics &&
|
||||
_mainController.selectedIndex.value == 0;
|
||||
|
||||
@override
|
||||
bool onNotificationType1(UserScrollNotification notification) {
|
||||
if (checkPage) {
|
||||
return false;
|
||||
}
|
||||
return super.onNotificationType1(notification);
|
||||
}
|
||||
|
||||
@override
|
||||
bool onNotificationType2(ScrollNotification notification) {
|
||||
if (checkPage) {
|
||||
return false;
|
||||
}
|
||||
return super.onNotificationType2(notification);
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
super.build(context);
|
||||
final theme = Theme.of(context);
|
||||
|
||||
Widget? drawer;
|
||||
Widget? endDrawer;
|
||||
|
||||
Widget? leading;
|
||||
List<Widget>? actions;
|
||||
|
||||
@@ -134,7 +107,7 @@ class _DynamicsPageState extends CommonPageState<DynamicsPage>
|
||||
case UpPanelPosition.top:
|
||||
child = Column(
|
||||
children: [
|
||||
upPanelPart(theme),
|
||||
upPanelPart(theme, isTop: true),
|
||||
Expanded(child: child),
|
||||
],
|
||||
);
|
||||
@@ -155,52 +128,44 @@ class _DynamicsPageState extends CommonPageState<DynamicsPage>
|
||||
],
|
||||
);
|
||||
actions = [_createDynamicBtn(theme)];
|
||||
case UpPanelPosition.leftDrawer:
|
||||
drawer = upPanelPart(theme);
|
||||
actions = [_createDynamicBtn(theme)];
|
||||
case UpPanelPosition.rightDrawer:
|
||||
endDrawer = upPanelPart(theme);
|
||||
leading = _createDynamicBtn(theme, isRight: false);
|
||||
}
|
||||
|
||||
return Scaffold(
|
||||
resizeToAvoidBottomInset: false,
|
||||
backgroundColor: Colors.transparent,
|
||||
appBar: AppBar(
|
||||
primary: false,
|
||||
leading: leading,
|
||||
leadingWidth: 50,
|
||||
toolbarHeight: 50,
|
||||
backgroundColor: Colors.transparent,
|
||||
title: SizedBox(
|
||||
height: 50,
|
||||
child: TabBar(
|
||||
dividerHeight: 0,
|
||||
isScrollable: true,
|
||||
tabAlignment: .center,
|
||||
dividerColor: Colors.transparent,
|
||||
labelColor: theme.colorScheme.primary,
|
||||
indicatorColor: theme.colorScheme.primary,
|
||||
controller: _dynamicsController.tabController,
|
||||
unselectedLabelColor: theme.colorScheme.onSurface,
|
||||
labelStyle:
|
||||
TabBarTheme.of(context).labelStyle?.copyWith(fontSize: 13) ??
|
||||
const TextStyle(fontSize: 13),
|
||||
tabs: DynamicsTabType.values
|
||||
.map((e) => Tab(text: e.label))
|
||||
.toList(),
|
||||
onTap: (index) {
|
||||
if (!_dynamicsController.tabController.indexIsChanging) {
|
||||
_dynamicsController.animateToTop();
|
||||
}
|
||||
},
|
||||
return Column(
|
||||
children: [
|
||||
AppBar(
|
||||
primary: false,
|
||||
leading: leading,
|
||||
leadingWidth: 50,
|
||||
toolbarHeight: 50,
|
||||
backgroundColor: Colors.transparent,
|
||||
title: SizedBox(
|
||||
height: 50,
|
||||
child: TabBar(
|
||||
dividerHeight: 0,
|
||||
isScrollable: true,
|
||||
tabAlignment: .center,
|
||||
dividerColor: Colors.transparent,
|
||||
labelColor: theme.colorScheme.primary,
|
||||
indicatorColor: theme.colorScheme.primary,
|
||||
controller: _dynamicsController.tabController,
|
||||
unselectedLabelColor: theme.colorScheme.onSurface,
|
||||
labelStyle:
|
||||
TabBarTheme.of(context).labelStyle?.copyWith(fontSize: 13) ??
|
||||
const TextStyle(fontSize: 13),
|
||||
tabs: DynamicsTabType.values
|
||||
.map((e) => Tab(text: e.label))
|
||||
.toList(),
|
||||
onTap: (index) {
|
||||
if (!_dynamicsController.tabController.indexIsChanging) {
|
||||
_dynamicsController.animateToTop();
|
||||
}
|
||||
},
|
||||
),
|
||||
),
|
||||
actions: actions,
|
||||
),
|
||||
actions: actions,
|
||||
),
|
||||
drawer: drawer,
|
||||
endDrawer: endDrawer,
|
||||
body: onBuild(child),
|
||||
Expanded(child: child),
|
||||
],
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,10 +5,10 @@ import 'package:PiliPlus/http/dynamics.dart';
|
||||
import 'package:PiliPlus/http/loading_state.dart';
|
||||
import 'package:PiliPlus/models/dynamics/result.dart';
|
||||
import 'package:PiliPlus/pages/dynamics/widgets/vote.dart';
|
||||
import 'package:PiliPlus/pages/webview/view.dart';
|
||||
import 'package:PiliPlus/utils/app_scheme.dart';
|
||||
import 'package:PiliPlus/utils/num_utils.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:get/get.dart';
|
||||
|
||||
Widget? addWidget(
|
||||
BuildContext context, {
|
||||
@@ -124,14 +124,9 @@ Widget? addWidget(
|
||||
recognizer: reserve.desc3!.jumpUrl == null
|
||||
? null
|
||||
: (NoDeadlineTapGestureRecognizer()
|
||||
..onTap = () {
|
||||
Get.toNamed(
|
||||
'/webview',
|
||||
parameters: {
|
||||
'url': reserve.desc3!.jumpUrl!,
|
||||
},
|
||||
);
|
||||
}),
|
||||
..onTap = () => WebViewPage.toWebView(
|
||||
reserve.desc3!.jumpUrl!,
|
||||
)),
|
||||
),
|
||||
],
|
||||
],
|
||||
@@ -261,14 +256,9 @@ Widget? addWidget(
|
||||
recognizer: content.desc!.jumpUrl == null
|
||||
? null
|
||||
: (NoDeadlineTapGestureRecognizer()
|
||||
..onTap = () {
|
||||
Get.toNamed(
|
||||
'/webview',
|
||||
parameters: {
|
||||
'url': content.desc!.jumpUrl!,
|
||||
},
|
||||
);
|
||||
}),
|
||||
..onTap = () => WebViewPage.toWebView(
|
||||
content.desc!.jumpUrl!,
|
||||
)),
|
||||
),
|
||||
],
|
||||
),
|
||||
|
||||
@@ -6,7 +6,6 @@ import 'package:PiliPlus/pages/dynamics/widgets/action_panel.dart';
|
||||
import 'package:PiliPlus/pages/dynamics/widgets/author_panel.dart';
|
||||
import 'package:PiliPlus/pages/dynamics/widgets/dyn_content.dart';
|
||||
import 'package:PiliPlus/pages/dynamics/widgets/interaction.dart';
|
||||
import 'package:PiliPlus/utils/extension/theme_ext.dart';
|
||||
import 'package:PiliPlus/utils/page_utils.dart';
|
||||
import 'package:PiliPlus/utils/platform_utils.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
@@ -87,8 +86,6 @@ class DynamicPanel extends StatelessWidget {
|
||||
padding: const EdgeInsets.fromLTRB(12, 12, 12, 6),
|
||||
child: authorWidget,
|
||||
),
|
||||
if (item.modules.moduleDispute case final moduleDispute?)
|
||||
_buildDispute(theme, moduleDispute),
|
||||
...dynContent(
|
||||
context,
|
||||
theme: theme,
|
||||
@@ -252,53 +249,4 @@ class DynamicPanel extends StatelessWidget {
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget _buildDispute(ThemeData theme, ModuleDispute moduleDispute) {
|
||||
final child = Container(
|
||||
width: .infinity,
|
||||
margin: const .fromLTRB(12, 2, 12, 6),
|
||||
padding: const .symmetric(horizontal: 8, vertical: 6),
|
||||
decoration: BoxDecoration(
|
||||
color: theme.colorScheme.secondaryContainer.withValues(
|
||||
alpha: theme.isLight ? 0.5 : 0.7,
|
||||
),
|
||||
borderRadius: const BorderRadius.all(Radius.circular(6)),
|
||||
),
|
||||
child: Text.rich(
|
||||
style: TextStyle(
|
||||
height: 1,
|
||||
fontSize: 13,
|
||||
color: theme.colorScheme.onSecondaryContainer,
|
||||
),
|
||||
strutStyle: const StrutStyle(
|
||||
leading: 0,
|
||||
height: 1,
|
||||
fontSize: 13,
|
||||
),
|
||||
TextSpan(
|
||||
children: [
|
||||
WidgetSpan(
|
||||
alignment: .middle,
|
||||
child: Padding(
|
||||
padding: const .only(right: 4),
|
||||
child: Icon(
|
||||
size: 15,
|
||||
Icons.warning_rounded,
|
||||
color: theme.colorScheme.onSecondaryContainer,
|
||||
),
|
||||
),
|
||||
),
|
||||
TextSpan(text: moduleDispute.title),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
if (moduleDispute.jumpUrl?.isNotEmpty == true) {
|
||||
return GestureDetector(
|
||||
onTap: () => PageUtils.handleWebview(moduleDispute.jumpUrl!),
|
||||
child: child,
|
||||
);
|
||||
}
|
||||
return child;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,6 +10,7 @@ import 'package:PiliPlus/pages/dynamics/widgets/live_panel.dart';
|
||||
import 'package:PiliPlus/pages/dynamics/widgets/live_panel_sub.dart';
|
||||
import 'package:PiliPlus/pages/dynamics/widgets/live_rcmd_panel.dart';
|
||||
import 'package:PiliPlus/pages/dynamics/widgets/video_panel.dart';
|
||||
import 'package:PiliPlus/utils/app_scheme.dart';
|
||||
import 'package:PiliPlus/utils/extension/num_ext.dart';
|
||||
import 'package:PiliPlus/utils/image_utils.dart';
|
||||
import 'package:PiliPlus/utils/page_utils.dart';
|
||||
@@ -124,7 +125,7 @@ Widget module(
|
||||
PageUtils.viewPgcFromUri(url)) {
|
||||
return;
|
||||
}
|
||||
PageUtils.handleWebview(url, inApp: true);
|
||||
PiliScheme.routePushFromUrl(url);
|
||||
} catch (_) {}
|
||||
},
|
||||
child: Padding(
|
||||
|
||||
@@ -11,6 +11,7 @@ import 'package:PiliPlus/models/common/image_preview_type.dart'
|
||||
import 'package:PiliPlus/models/common/image_type.dart';
|
||||
import 'package:PiliPlus/models/dynamics/result.dart';
|
||||
import 'package:PiliPlus/pages/dynamics/widgets/vote.dart';
|
||||
import 'package:PiliPlus/utils/app_scheme.dart';
|
||||
import 'package:PiliPlus/utils/page_utils.dart';
|
||||
import 'package:flutter/foundation.dart' show kDebugMode;
|
||||
import 'package:flutter/material.dart';
|
||||
@@ -128,7 +129,8 @@ TextSpan? richNode(
|
||||
style: style,
|
||||
recognizer: hasLink
|
||||
? (NoDeadlineTapGestureRecognizer()
|
||||
..onTap = () => PageUtils.handleWebview(i.jumpUrl!))
|
||||
..onTap = () =>
|
||||
PiliScheme.routePushFromUrl(i.jumpUrl!))
|
||||
: null,
|
||||
),
|
||||
);
|
||||
@@ -193,12 +195,8 @@ TextSpan? richNode(
|
||||
text: '${i.origText} ',
|
||||
style: style,
|
||||
recognizer: NoDeadlineTapGestureRecognizer()
|
||||
..onTap = () => Get.toNamed(
|
||||
'/webview',
|
||||
parameters: {
|
||||
'url':
|
||||
'https://www.bilibili.com/h5/lottery/result?business_id=${item.idStr}',
|
||||
},
|
||||
..onTap = () => PiliScheme.routePushFromUrl(
|
||||
'https://www.bilibili.com/h5/lottery/result?business_id=${item.idStr}',
|
||||
),
|
||||
),
|
||||
);
|
||||
@@ -223,7 +221,8 @@ TextSpan? richNode(
|
||||
recognizer: i.jumpUrl == null
|
||||
? null
|
||||
: (NoDeadlineTapGestureRecognizer()
|
||||
..onTap = () => PageUtils.handleWebview(i.jumpUrl!)),
|
||||
..onTap = () =>
|
||||
PiliScheme.routePushFromUrl(i.jumpUrl!)),
|
||||
),
|
||||
);
|
||||
break;
|
||||
@@ -347,7 +346,8 @@ TextSpan? richNode(
|
||||
recognizer: i.jumpUrl == null
|
||||
? null
|
||||
: (NoDeadlineTapGestureRecognizer()
|
||||
..onTap = () => PageUtils.handleWebview(i.jumpUrl!)),
|
||||
..onTap = () =>
|
||||
PiliScheme.routePushFromUrl(i.jumpUrl!)),
|
||||
),
|
||||
);
|
||||
break;
|
||||
@@ -359,7 +359,8 @@ TextSpan? richNode(
|
||||
recognizer: i.jumpUrl == null
|
||||
? null
|
||||
: (NoDeadlineTapGestureRecognizer()
|
||||
..onTap = () => PageUtils.handleWebview(i.jumpUrl!)),
|
||||
..onTap = () =>
|
||||
PiliScheme.routePushFromUrl(i.jumpUrl!)),
|
||||
),
|
||||
);
|
||||
break;
|
||||
|
||||
Reference in New Issue
Block a user