Signed-off-by: dom <githubaccount56556@proton.me>
This commit is contained in:
dom
2026-05-06 14:14:19 +08:00
parent 1a8c348af1
commit 07843a5e77
239 changed files with 3175 additions and 13237 deletions

View File

@@ -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();
}

View File

@@ -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),
],
);
}
}

View File

@@ -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!,
)),
),
],
),

View File

@@ -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;
}
}

View File

@@ -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(

View File

@@ -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;