feat: 动态样式切换

This commit is contained in:
guozhigq
2024-10-20 00:29:31 +08:00
parent 83c9ce55c8
commit 8292f0e15a
5 changed files with 144 additions and 105 deletions

View File

@ -11,6 +11,7 @@ import 'package:pilipala/common/widgets/no_data.dart';
import 'package:pilipala/models/dynamics/result.dart'; import 'package:pilipala/models/dynamics/result.dart';
import 'package:pilipala/plugin/pl_popup/index.dart'; import 'package:pilipala/plugin/pl_popup/index.dart';
import 'package:pilipala/utils/feed_back.dart'; import 'package:pilipala/utils/feed_back.dart';
import 'package:pilipala/utils/global_data_cache.dart';
import 'package:pilipala/utils/main_stream.dart'; import 'package:pilipala/utils/main_stream.dart';
import 'package:pilipala/utils/route_push.dart'; import 'package:pilipala/utils/route_push.dart';
import 'package:pilipala/utils/storage.dart'; import 'package:pilipala/utils/storage.dart';
@ -90,32 +91,34 @@ class _DynamicsPageState extends State<DynamicsPage>
mainAxisAlignment: MainAxisAlignment.center, mainAxisAlignment: MainAxisAlignment.center,
children: [ children: [
Obx(() { Obx(() {
if (_dynamicsController.mid.value != -1 && final mid = _dynamicsController.mid.value;
_dynamicsController.upInfo.value.uname != null) { final uname = _dynamicsController.upInfo.value.uname;
return SizedBox(
height: 36, if (mid == -1 || uname == null) {
child: AnimatedSwitcher(
duration: const Duration(milliseconds: 300),
transitionBuilder:
(Widget child, Animation<double> animation) {
return ScaleTransition(
scale: animation, child: child);
},
child: Text(
'${_dynamicsController.upInfo.value.uname!}的动态',
key: ValueKey<String>(
_dynamicsController.upInfo.value.uname!),
style: TextStyle(
fontSize: Theme.of(context)
.textTheme
.labelLarge!
.fontSize,
)),
),
);
} else {
return const SizedBox(); return const SizedBox();
} }
return SizedBox(
height: 36,
child: AnimatedSwitcher(
duration: const Duration(milliseconds: 300),
transitionBuilder:
(Widget child, Animation<double> animation) {
return ScaleTransition(
scale: animation, child: child);
},
child: Text(
'$uname的动态',
key: ValueKey<String>(uname),
style: TextStyle(
fontSize: Theme.of(context)
.textTheme
.labelLarge!
.fontSize,
),
),
),
);
}), }),
Obx( Obx(
() => _dynamicsController.userLogin.value () => _dynamicsController.userLogin.value
@ -207,14 +210,19 @@ class _DynamicsPageState extends State<DynamicsPage>
() => UpPanel( () => UpPanel(
upData: _dynamicsController.upData.value, upData: _dynamicsController.upData.value,
onClickUpCb: (data) { onClickUpCb: (data) {
// _dynamicsController.onTapUp(data); if (GlobalDataCache().enableDynamicSwitch) {
Navigator.push( Navigator.push(
context, context,
PlPopupRoute( PlPopupRoute(
child: OverlayPanel( child: OverlayPanel(
ctr: _dynamicsController, upInfo: data), ctr: _dynamicsController,
), upInfo: data,
); ),
),
);
} else {
_dynamicsController.onTapUp(data);
}
}, },
), ),
); );

View File

@ -5,6 +5,7 @@ import 'package:pilipala/common/widgets/network_img_layer.dart';
import 'package:pilipala/models/dynamics/up.dart'; import 'package:pilipala/models/dynamics/up.dart';
import 'package:pilipala/models/live/item.dart'; import 'package:pilipala/models/live/item.dart';
import 'package:pilipala/utils/feed_back.dart'; import 'package:pilipala/utils/feed_back.dart';
import 'package:pilipala/utils/global_data_cache.dart';
import 'package:pilipala/utils/utils.dart'; import 'package:pilipala/utils/utils.dart';
class UpPanel extends StatefulWidget { class UpPanel extends StatefulWidget {
@ -23,7 +24,7 @@ class UpPanel extends StatefulWidget {
class _UpPanelState extends State<UpPanel> { class _UpPanelState extends State<UpPanel> {
final ScrollController scrollController = ScrollController(); final ScrollController scrollController = ScrollController();
int currentMid = -1; RxInt currentMid = (-1).obs;
late double contentWidth = 56; late double contentWidth = 56;
List<UpItem> upList = []; List<UpItem> upList = [];
List<LiveUserItem> liveList = []; List<LiveUserItem> liveList = [];
@ -37,26 +38,36 @@ class _UpPanelState extends State<UpPanel> {
} }
void onClickUp(data, i) { void onClickUp(data, i) {
currentMid = data.mid; currentMid.value = data.mid;
widget.onClickUpCb?.call(data); widget.onClickUpCb?.call(data);
// int liveLen = liveList.length; }
// int upLen = upList.length;
// double itemWidth = contentWidth + itemPadding.horizontal; void onClickUpAni(data, i) {
// double screenWidth = MediaQuery.sizeOf(context).width; final screenWidth = MediaQuery.sizeOf(context).width;
// double moveDistance = 0.0; final itemWidth = contentWidth + itemPadding.horizontal;
// if (itemWidth * (upList.length + liveList.length) <= screenWidth) { final liveLen = liveList.length;
// } else if ((upLen - i - 0.5) * itemWidth > screenWidth / 2) { final upLen = upList.length;
// moveDistance = (i + liveLen + 0.5) * itemWidth + 46 - screenWidth / 2;
// } else { currentMid.value = data.mid;
// moveDistance = (upLen + liveLen) * itemWidth + 46 - screenWidth; widget.onClickUpCb?.call(data);
// }
// data.hasUpdate = false; double moveDistance = 0.0;
// scrollController.animateTo( final totalItemsWidth = itemWidth * (upLen + liveLen);
// moveDistance,
// duration: const Duration(milliseconds: 200), if (totalItemsWidth > screenWidth) {
// curve: Curves.linear, if ((upLen - i - 0.5) * itemWidth > screenWidth / 2) {
// ); moveDistance = (i + liveLen + 0.5) * itemWidth + 46 - screenWidth / 2;
// setState(() {}); } else {
moveDistance = totalItemsWidth + 46 - screenWidth;
}
}
data.hasUpdate = false;
scrollController.animateTo(
moveDistance,
duration: const Duration(milliseconds: 500),
curve: Curves.easeInOut,
);
} }
@override @override
@ -144,14 +155,17 @@ class _UpPanelState extends State<UpPanel> {
} }
Widget upItemBuild(data, i) { Widget upItemBuild(data, i) {
bool isCurrent = currentMid == data.mid || currentMid == -1;
return InkWell( return InkWell(
onTap: () { onTap: () {
feedBack(); feedBack();
if (data.type == 'up') { if (data.type == 'up') {
EasyThrottle.throttle('follow', const Duration(milliseconds: 300), EasyThrottle.throttle('follow', const Duration(milliseconds: 300),
() { () {
onClickUp(data, i); if (GlobalDataCache().enableDynamicSwitch) {
onClickUp(data, i);
} else {
onClickUpAni(data, i);
}
}); });
} else if (data.type == 'live') { } else if (data.type == 'live') {
LiveItemModel liveItem = LiveItemModel.fromJson({ LiveItemModel liveItem = LiveItemModel.fromJson({
@ -177,60 +191,66 @@ class _UpPanelState extends State<UpPanel> {
}, },
child: Padding( child: Padding(
padding: itemPadding, padding: itemPadding,
child: AnimatedOpacity( child: Obx(
opacity: isCurrent ? 1 : 0.3, () => AnimatedOpacity(
duration: const Duration(milliseconds: 200), opacity: currentMid.value == data.mid || currentMid.value == -1
curve: Curves.easeInOut, ? 1
child: Column( : 0.3,
mainAxisSize: MainAxisSize.min, duration: const Duration(milliseconds: 200),
mainAxisAlignment: MainAxisAlignment.center, curve: Curves.easeInOut,
children: [ child: Column(
Badge( mainAxisSize: MainAxisSize.min,
smallSize: 8, mainAxisAlignment: MainAxisAlignment.center,
label: data.type == 'live' ? const Text('Live') : null, children: [
textColor: Theme.of(context).colorScheme.onSecondaryContainer, Badge(
alignment: data.type == 'live' smallSize: 8,
? AlignmentDirectional.topCenter label: data.type == 'live' ? const Text('Live') : null,
: AlignmentDirectional.topEnd, textColor: Theme.of(context).colorScheme.onSecondaryContainer,
padding: const EdgeInsets.only(left: 6, right: 6), alignment: data.type == 'live'
isLabelVisible: data.type == 'live' || ? AlignmentDirectional.topCenter
(data.type == 'up' && (data.hasUpdate ?? false)), : AlignmentDirectional.topEnd,
backgroundColor: data.type == 'live' padding: const EdgeInsets.only(left: 6, right: 6),
? Theme.of(context).colorScheme.secondaryContainer isLabelVisible: data.type == 'live' ||
: Theme.of(context).colorScheme.primary, (data.type == 'up' && (data.hasUpdate ?? false)),
child: data.face != '' backgroundColor: data.type == 'live'
? NetworkImgLayer( ? Theme.of(context).colorScheme.secondaryContainer
width: 50, : Theme.of(context).colorScheme.primary,
height: 50, child: data.face != ''
src: data.face, ? NetworkImgLayer(
type: 'avatar', width: 50,
) height: 50,
: const CircleAvatar( src: data.face,
radius: 25, type: 'avatar',
backgroundImage: AssetImage( )
'assets/images/noface.jpeg', : const CircleAvatar(
radius: 25,
backgroundImage: AssetImage(
'assets/images/noface.jpeg',
),
), ),
), ),
), Padding(
Padding( padding: const EdgeInsets.only(top: 4),
padding: const EdgeInsets.only(top: 4), child: SizedBox(
child: SizedBox( width: contentWidth,
width: contentWidth, child: Text(
child: Text( data.uname,
data.uname, overflow: TextOverflow.ellipsis,
overflow: TextOverflow.ellipsis, softWrap: false,
softWrap: false, textAlign: TextAlign.center,
textAlign: TextAlign.center, style: TextStyle(
style: TextStyle( color: currentMid.value == data.mid
color: currentMid == data.mid ? Theme.of(context).colorScheme.primary
? Theme.of(context).colorScheme.primary : Theme.of(context).colorScheme.outline,
: Theme.of(context).colorScheme.outline, fontSize: Theme.of(context)
fontSize: .textTheme
Theme.of(context).textTheme.labelMedium!.fontSize), .labelMedium!
.fontSize),
),
), ),
), ),
), ],
], ),
), ),
), ),
), ),

View File

@ -108,6 +108,12 @@ class _StyleSettingState extends State<StyleSetting> {
defaultVal: true, defaultVal: true,
needReboot: true, needReboot: true,
), ),
const SetSwitchItem(
title: '动态页滑动切换up',
setKey: SettingBoxKey.enableDynamicSwitch,
defaultVal: true,
needReboot: true,
),
ListTile( ListTile(
onTap: () async { onTap: () async {
int? result = await showDialog( int? result = await showDialog(

View File

@ -51,6 +51,8 @@ class GlobalDataCache {
late bool enableSearchSuggest = true; late bool enableSearchSuggest = true;
// 简介默认展开 // 简介默认展开
late bool enableAutoExpand = false; late bool enableAutoExpand = false;
//
late bool enableDynamicSwitch = true;
// 私有构造函数 // 私有构造函数
GlobalDataCache._(); GlobalDataCache._();
@ -116,5 +118,7 @@ class GlobalDataCache {
setting.get(SettingBoxKey.enableSearchSuggest, defaultValue: true); setting.get(SettingBoxKey.enableSearchSuggest, defaultValue: true);
enableAutoExpand = enableAutoExpand =
setting.get(SettingBoxKey.enableAutoExpand, defaultValue: false); setting.get(SettingBoxKey.enableAutoExpand, defaultValue: false);
enableDynamicSwitch =
setting.get(SettingBoxKey.enableDynamicSwitch, defaultValue: true);
} }
} }

View File

@ -131,6 +131,7 @@ class SettingBoxKey {
tabbarSort = 'tabbarSort', // 首页tabbar tabbarSort = 'tabbarSort', // 首页tabbar
dynamicBadgeMode = 'dynamicBadgeMode', dynamicBadgeMode = 'dynamicBadgeMode',
enableGradientBg = 'enableGradientBg', enableGradientBg = 'enableGradientBg',
enableDynamicSwitch = 'enableDynamicSwitch',
navBarSort = 'navBarSort', navBarSort = 'navBarSort',
actionTypeSort = 'actionTypeSort'; actionTypeSort = 'actionTypeSort';
} }