feat: coin log

Signed-off-by: bggRGjQaUbCoE <githubaccount56556@proton.me>
This commit is contained in:
bggRGjQaUbCoE
2025-06-09 19:30:52 +08:00
parent 63a286056c
commit f1e4130201
28 changed files with 323 additions and 117 deletions

View File

@@ -886,4 +886,6 @@ class Api {
static const String spaceSettingMod = '/x/space/privacy/batch/modify'; static const String spaceSettingMod = '/x/space/privacy/batch/modify';
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';
} }

View File

@@ -4,6 +4,7 @@ import 'package:PiliPlus/http/init.dart';
import 'package:PiliPlus/http/loading_state.dart'; import 'package:PiliPlus/http/loading_state.dart';
import 'package:PiliPlus/models/user/info.dart'; import 'package:PiliPlus/models/user/info.dart';
import 'package:PiliPlus/models/user/stat.dart'; import 'package:PiliPlus/models/user/stat.dart';
import 'package:PiliPlus/models_new/coin_log/data.dart';
import 'package:PiliPlus/models_new/history/data.dart'; import 'package:PiliPlus/models_new/history/data.dart';
import 'package:PiliPlus/models_new/later/data.dart'; import 'package:PiliPlus/models_new/later/data.dart';
import 'package:PiliPlus/models_new/media_list/data.dart'; import 'package:PiliPlus/models_new/media_list/data.dart';
@@ -398,4 +399,19 @@ class UserHttp {
return {'status': false, 'msg': res.data['message']}; return {'status': false, 'msg': res.data['message']};
} }
} }
static Future<LoadingState<CoinLogData>> coinLog() async {
final res = await Request().get(
Api.coinLog,
queryParameters: {
'jsonp': 'jsonp',
'web_location': '333.33',
},
);
if (res.data['code'] == 0) {
return Success(CoinLogData.fromJson(res.data['data']));
} else {
return Error(res.data['message']);
}
}
} }

View File

@@ -0,0 +1,15 @@
import 'package:PiliPlus/models_new/coin_log/list.dart';
class CoinLogData {
List<CoinLogItem>? list;
int? count;
CoinLogData({this.list, this.count});
factory CoinLogData.fromJson(Map<String, dynamic> json) => CoinLogData(
list: (json['list'] as List<dynamic>?)
?.map((e) => CoinLogItem.fromJson(e as Map<String, dynamic>))
.toList(),
count: json['count'] as int?,
);
}

View File

@@ -0,0 +1,14 @@
class CoinLogItem {
final String time;
final String delta;
final String reason;
const CoinLogItem(
{required this.time, required this.delta, required this.reason});
factory CoinLogItem.fromJson(Map<String, dynamic> json) => CoinLogItem(
time: json['time'],
delta: (json['delta'] as num).toString(),
reason: json['reason'],
);
}

View File

@@ -69,9 +69,7 @@ class ArticleOpus extends StatelessWidget {
return Text(e.toString()); return Text(e.toString());
} }
}, },
separatorBuilder: (context, index) { separatorBuilder: (context, index) => const SizedBox(height: 10),
return const SizedBox(height: 10);
},
); );
} }
} }

View File

@@ -6,6 +6,7 @@ import 'package:PiliPlus/http/loading_state.dart';
import 'package:PiliPlus/models_new/space/space/data.dart'; import 'package:PiliPlus/models_new/space/space/data.dart';
import 'package:PiliPlus/pages/member/controller.dart'; import 'package:PiliPlus/pages/member/controller.dart';
import 'package:PiliPlus/pages/member/widget/user_info_card.dart'; import 'package:PiliPlus/pages/member/widget/user_info_card.dart';
import 'package:PiliPlus/pages/member_coin_log/view.dart';
import 'package:PiliPlus/pages/member_contribute/view.dart'; import 'package:PiliPlus/pages/member_contribute/view.dart';
import 'package:PiliPlus/pages/member_dynamics/view.dart'; import 'package:PiliPlus/pages/member_dynamics/view.dart';
import 'package:PiliPlus/pages/member_favorite/view.dart'; import 'package:PiliPlus/pages/member_favorite/view.dart';
@@ -14,6 +15,7 @@ import 'package:PiliPlus/pages/member_pgc/view.dart';
import 'package:PiliPlus/utils/utils.dart'; import 'package:PiliPlus/utils/utils.dart';
import 'package:extended_nested_scroll_view/extended_nested_scroll_view.dart'; import 'package:extended_nested_scroll_view/extended_nested_scroll_view.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
import 'package:get/get.dart'; import 'package:get/get.dart';
class MemberPage extends StatefulWidget { class MemberPage extends StatefulWidget {
@@ -152,6 +154,17 @@ class _MemberPageState extends State<MemberPage> {
], ],
), ),
), ),
PopupMenuItem(
onTap: () => Get.to(const MemberCoinLogPage()),
child: const Row(
mainAxisSize: MainAxisSize.min,
children: [
Icon(FontAwesomeIcons.b, size: 18),
SizedBox(width: 10),
Text('硬币记录'),
],
),
),
PopupMenuItem( PopupMenuItem(
onTap: () => Get.toNamed('/spaceSetting'), onTap: () => Get.toNamed('/spaceSetting'),
child: const Row( child: const Row(

View File

@@ -4,10 +4,10 @@ import 'package:PiliPlus/models_new/member/coin_like_arc/data.dart';
import 'package:PiliPlus/models_new/member/coin_like_arc/item.dart'; import 'package:PiliPlus/models_new/member/coin_like_arc/item.dart';
import 'package:PiliPlus/pages/common/common_list_controller.dart'; import 'package:PiliPlus/pages/common/common_list_controller.dart';
class MemberCoinController class MemberCoinArcController
extends CommonListController<CoinLikeArcData, CoinLikeArcItem> { extends CommonListController<CoinLikeArcData, CoinLikeArcItem> {
final dynamic mid; final dynamic mid;
MemberCoinController({this.mid}); MemberCoinArcController({this.mid});
@override @override
void onInit() { void onInit() {

View File

@@ -3,16 +3,16 @@ import 'package:PiliPlus/common/skeleton/video_card_v.dart';
import 'package:PiliPlus/common/widgets/loading_widget/http_error.dart'; import 'package:PiliPlus/common/widgets/loading_widget/http_error.dart';
import 'package:PiliPlus/http/loading_state.dart'; import 'package:PiliPlus/http/loading_state.dart';
import 'package:PiliPlus/models_new/member/coin_like_arc/item.dart'; import 'package:PiliPlus/models_new/member/coin_like_arc/item.dart';
import 'package:PiliPlus/pages/member_coin/controller.dart'; import 'package:PiliPlus/pages/member_coin_arc/controller.dart';
import 'package:PiliPlus/pages/member_coin/widgets/item.dart'; import 'package:PiliPlus/pages/member_coin_arc/widgets/item.dart';
import 'package:PiliPlus/utils/grid.dart'; import 'package:PiliPlus/utils/grid.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';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:get/get.dart'; import 'package:get/get.dart';
class MemberCoinPage extends StatefulWidget { class MemberCoinArcPage extends StatefulWidget {
const MemberCoinPage({ const MemberCoinArcPage({
super.key, super.key,
required this.mid, required this.mid,
this.name, this.name,
@@ -22,14 +22,14 @@ class MemberCoinPage extends StatefulWidget {
final String? name; final String? name;
@override @override
State<MemberCoinPage> createState() => _MemberCoinPageState(); State<MemberCoinArcPage> createState() => _MemberCoinArcPageState();
} }
class _MemberCoinPageState extends State<MemberCoinPage> { class _MemberCoinArcPageState extends State<MemberCoinArcPage> {
late final _ownerMid = Accounts.main.mid; late final _ownerMid = Accounts.main.mid;
late final _ctr = Get.put( late final _ctr = Get.put(
MemberCoinController(mid: widget.mid), MemberCoinArcController(mid: widget.mid),
tag: Utils.makeHeroTag(widget.mid), tag: Utils.makeHeroTag(widget.mid),
); );

View File

@@ -0,0 +1,22 @@
import 'package:PiliPlus/http/loading_state.dart';
import 'package:PiliPlus/http/user.dart';
import 'package:PiliPlus/models_new/coin_log/data.dart';
import 'package:PiliPlus/models_new/coin_log/list.dart';
import 'package:PiliPlus/pages/common/common_list_controller.dart';
class MemberCoinLogController
extends CommonListController<CoinLogData, CoinLogItem> {
@override
void onInit() {
super.onInit();
queryData();
}
@override
List<CoinLogItem>? getDataList(CoinLogData response) {
return response.list;
}
@override
Future<LoadingState<CoinLogData>> customGetData() => UserHttp.coinLog();
}

View File

@@ -0,0 +1,136 @@
import 'package:PiliPlus/common/widgets/loading_widget/http_error.dart';
import 'package:PiliPlus/http/loading_state.dart';
import 'package:PiliPlus/models_new/coin_log/list.dart';
import 'package:PiliPlus/pages/member_coin_log/controller.dart';
import 'package:flutter/material.dart';
import 'package:get/get.dart';
class MemberCoinLogPage extends StatefulWidget {
const MemberCoinLogPage({super.key});
@override
State<MemberCoinLogPage> createState() => _MemberCoinLogPageState();
}
class _MemberCoinLogPageState extends State<MemberCoinLogPage> {
late final _controller = Get.put(MemberCoinLogController());
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text('硬币记录')),
body: SafeArea(
top: false,
bottom: false,
child: Center(
child: ConstrainedBox(
constraints: const BoxConstraints(maxWidth: 680),
child: CustomScrollView(
slivers: [
SliverPadding(
padding: EdgeInsets.only(
left: 10,
right: 10,
bottom: MediaQuery.paddingOf(context).bottom + 80,
),
sliver: Obx(() => _buildBody(_controller.loadingState.value)),
),
],
),
),
),
),
);
}
Widget _buildBody(LoadingState<List<CoinLogItem>?> loadingState) {
return switch (loadingState) {
Loading() => const SliverToBoxAdapter(child: LinearProgressIndicator()),
Success(:var response) => response?.isNotEmpty == true
? Builder(
builder: (context) {
final them = Theme.of(context);
final outline = them.colorScheme.outline.withValues(alpha: 0.1);
final divider = Divider(
height: 1,
color: outline,
);
final sliverDivider = SliverToBoxAdapter(
child: divider,
);
final dividerV = VerticalDivider(
width: 1,
color: outline,
);
return SliverMainAxisGroup(
slivers: [
sliverDivider,
SliverToBoxAdapter(
child: ColoredBox(
color: them.colorScheme.onInverseSurface,
child: _item(
const CoinLogItem(
time: '时间',
delta: '变化',
reason: '原因',
),
dividerV,
isHeader: true,
),
),
),
sliverDivider,
SliverList.separated(
itemCount: response!.length,
itemBuilder: (context, index) {
return _item(response[index], dividerV);
},
separatorBuilder: (context, index) => divider,
),
sliverDivider,
],
);
},
)
: HttpError(onReload: _controller.onReload),
Error(:var errMsg) => HttpError(
errMsg: errMsg,
onReload: _controller.onReload,
),
};
}
Widget _item(CoinLogItem item, Widget divider, {bool isHeader = false}) {
Widget text(int flex, String text) => Expanded(
flex: flex,
child: Padding(
padding: isHeader
? const EdgeInsets.symmetric(vertical: 6)
: const EdgeInsets.symmetric(vertical: 8),
child: Center(
child: Text(
text,
textAlign: TextAlign.center,
style: isHeader
? const TextStyle(fontSize: 13, fontWeight: FontWeight.bold)
: const TextStyle(fontSize: 13),
),
),
),
);
Widget content = Row(
children: [
divider,
text(3, item.time),
divider,
text(1, item.delta),
divider,
text(4, item.reason),
divider,
],
);
return IntrinsicHeight(
child: isHeader ? content : SelectionArea(child: content),
);
}
}

View File

@@ -7,11 +7,11 @@ import 'package:PiliPlus/models_new/space/space/data.dart';
import 'package:PiliPlus/models_new/space/space/tab2.dart'; import 'package:PiliPlus/models_new/space/space/tab2.dart';
import 'package:PiliPlus/pages/member/controller.dart'; import 'package:PiliPlus/pages/member/controller.dart';
import 'package:PiliPlus/pages/member_article/widget/item.dart'; import 'package:PiliPlus/pages/member_article/widget/item.dart';
import 'package:PiliPlus/pages/member_coin/view.dart'; import 'package:PiliPlus/pages/member_coin_arc/view.dart';
import 'package:PiliPlus/pages/member_contribute/controller.dart'; import 'package:PiliPlus/pages/member_contribute/controller.dart';
import 'package:PiliPlus/pages/member_home/widgets/fav_item.dart'; import 'package:PiliPlus/pages/member_home/widgets/fav_item.dart';
import 'package:PiliPlus/pages/member_home/widgets/video_card_v_member_home.dart'; import 'package:PiliPlus/pages/member_home/widgets/video_card_v_member_home.dart';
import 'package:PiliPlus/pages/member_like/view.dart'; import 'package:PiliPlus/pages/member_like_arc/view.dart';
import 'package:PiliPlus/pages/member_pgc/widgets/pgc_card_v_member_pgc.dart'; import 'package:PiliPlus/pages/member_pgc/widgets/pgc_card_v_member_pgc.dart';
import 'package:PiliPlus/utils/grid.dart'; import 'package:PiliPlus/utils/grid.dart';
import 'package:flutter/foundation.dart' show kDebugMode; import 'package:flutter/foundation.dart' show kDebugMode;
@@ -281,7 +281,7 @@ class _MemberHomeState extends State<MemberHome>
_ctr.tabController?.animateTo(index); _ctr.tabController?.animateTo(index);
} else { } else {
if (param == 'coinArchive') { if (param == 'coinArchive') {
Get.to(MemberCoinPage( Get.to(MemberCoinArcPage(
mid: _ctr.mid, mid: _ctr.mid,
name: _ctr.username, name: _ctr.username,
)); ));
@@ -289,7 +289,7 @@ class _MemberHomeState extends State<MemberHome>
} }
if (param == 'likeArchive') { if (param == 'likeArchive') {
Get.to(MemberLikePage( Get.to(MemberLikeArcPage(
mid: _ctr.mid, mid: _ctr.mid,
name: _ctr.username, name: _ctr.username,
)); ));

View File

@@ -4,10 +4,10 @@ import 'package:PiliPlus/models_new/member/coin_like_arc/data.dart';
import 'package:PiliPlus/models_new/member/coin_like_arc/item.dart'; import 'package:PiliPlus/models_new/member/coin_like_arc/item.dart';
import 'package:PiliPlus/pages/common/common_list_controller.dart'; import 'package:PiliPlus/pages/common/common_list_controller.dart';
class MemberLikeController class MemberLikeArcController
extends CommonListController<CoinLikeArcData, CoinLikeArcItem> { extends CommonListController<CoinLikeArcData, CoinLikeArcItem> {
final dynamic mid; final dynamic mid;
MemberLikeController({this.mid}); MemberLikeArcController({this.mid});
@override @override
void onInit() { void onInit() {

View File

@@ -3,16 +3,16 @@ import 'package:PiliPlus/common/skeleton/video_card_v.dart';
import 'package:PiliPlus/common/widgets/loading_widget/http_error.dart'; import 'package:PiliPlus/common/widgets/loading_widget/http_error.dart';
import 'package:PiliPlus/http/loading_state.dart'; import 'package:PiliPlus/http/loading_state.dart';
import 'package:PiliPlus/models_new/member/coin_like_arc/item.dart'; import 'package:PiliPlus/models_new/member/coin_like_arc/item.dart';
import 'package:PiliPlus/pages/member_coin/widgets/item.dart'; import 'package:PiliPlus/pages/member_coin_arc/widgets/item.dart';
import 'package:PiliPlus/pages/member_like/controller.dart'; import 'package:PiliPlus/pages/member_like_arc/controller.dart';
import 'package:PiliPlus/utils/grid.dart'; import 'package:PiliPlus/utils/grid.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';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:get/get.dart'; import 'package:get/get.dart';
class MemberLikePage extends StatefulWidget { class MemberLikeArcPage extends StatefulWidget {
const MemberLikePage({ const MemberLikeArcPage({
super.key, super.key,
required this.mid, required this.mid,
this.name, this.name,
@@ -22,14 +22,14 @@ class MemberLikePage extends StatefulWidget {
final String? name; final String? name;
@override @override
State<MemberLikePage> createState() => _MemberLikePageState(); State<MemberLikeArcPage> createState() => _MemberLikeArcPageState();
} }
class _MemberLikePageState extends State<MemberLikePage> { class _MemberLikeArcPageState extends State<MemberLikeArcPage> {
late final _ownerMid = Accounts.main.mid; late final _ownerMid = Accounts.main.mid;
late final _ctr = Get.put( late final _ctr = Get.put(
MemberLikeController(mid: widget.mid), MemberLikeArcController(mid: widget.mid),
tag: Utils.makeHeroTag(widget.mid), tag: Utils.makeHeroTag(widget.mid),
); );

View File

@@ -103,6 +103,7 @@ class _MinePageState extends State<MinePage> {
color: theme.colorScheme.primary, color: theme.colorScheme.primary,
fontWeight: FontWeight.bold, fontWeight: FontWeight.bold,
); );
final isVip = userInfo.vipStatus != null && userInfo.vipStatus! > 0;
return Column( return Column(
mainAxisSize: MainAxisSize.min, mainAxisSize: MainAxisSize.min,
children: [ children: [
@@ -125,8 +126,7 @@ class _MinePageState extends State<MinePage> {
width: 55, width: 55,
height: 55, height: 55,
), ),
if (userInfo.vipStatus != null && if (isVip)
userInfo.vipStatus! > 0)
Positioned( Positioned(
right: -1, right: -1,
bottom: -2, bottom: -2,
@@ -161,9 +161,7 @@ class _MinePageState extends State<MinePage> {
userInfo.uname ?? '点击头像登录', userInfo.uname ?? '点击头像登录',
style: theme.textTheme.titleMedium!.copyWith( style: theme.textTheme.titleMedium!.copyWith(
height: 1, height: 1,
color: userInfo.vipStatus != null && color: isVip && userInfo.vipType == 2
userInfo.vipStatus! > 0 &&
userInfo.vipType == 2
? context.vipColor ? context.vipColor
: null, : null,
), ),

View File

@@ -65,6 +65,12 @@ class _AtMePageState extends State<AtMePage> {
Widget _buildBody( Widget _buildBody(
ThemeData theme, LoadingState<List<MsgAtItem>?> loadingState) { ThemeData theme, LoadingState<List<MsgAtItem>?> loadingState) {
late final divider = Divider(
indent: 72,
endIndent: 20,
height: 6,
color: Colors.grey.withValues(alpha: 0.1),
);
return switch (loadingState) { return switch (loadingState) {
Loading() => SliverList.builder( Loading() => SliverList.builder(
itemCount: 12, itemCount: 12,
@@ -152,14 +158,7 @@ class _AtMePageState extends State<AtMePage> {
: null, : null,
); );
}, },
separatorBuilder: (BuildContext context, int index) { separatorBuilder: (context, index) => divider,
return Divider(
indent: 72,
endIndent: 20,
height: 6,
color: Colors.grey.withValues(alpha: 0.1),
);
},
) )
: HttpError(onReload: _atMeController.onReload), : HttpError(onReload: _atMeController.onReload),
Error(:var errMsg) => HttpError( Error(:var errMsg) => HttpError(

View File

@@ -65,6 +65,12 @@ class _LikeMePageState extends State<LikeMePage> {
} }
Widget _buildBody(ThemeData theme, LoadingState loadingState) { Widget _buildBody(ThemeData theme, LoadingState loadingState) {
late final divider = Divider(
indent: 72,
endIndent: 20,
height: 6,
color: Colors.grey.withValues(alpha: 0.1),
);
return switch (loadingState) { return switch (loadingState) {
Loading() => SliverList.builder( Loading() => SliverList.builder(
itemCount: 12, itemCount: 12,
@@ -99,14 +105,7 @@ class _LikeMePageState extends State<LikeMePage> {
); );
}, },
itemCount: latest.length, itemCount: latest.length,
separatorBuilder: (BuildContext context, int index) { separatorBuilder: (context, index) => divider,
return Divider(
indent: 72,
endIndent: 20,
height: 6,
color: Colors.grey.withValues(alpha: 0.1),
);
},
), ),
], ],
if (total.isNotEmpty) ...[ if (total.isNotEmpty) ...[
@@ -129,14 +128,7 @@ class _LikeMePageState extends State<LikeMePage> {
); );
}, },
itemCount: total.length, itemCount: total.length,
separatorBuilder: (BuildContext context, int index) { separatorBuilder: (context, index) => divider,
return Divider(
indent: 72,
endIndent: 20,
height: 6,
color: Colors.grey.withValues(alpha: 0.1),
);
},
), ),
], ],
], ],

View File

@@ -65,6 +65,12 @@ class _ReplyMePageState extends State<ReplyMePage> {
Widget _buildBody( Widget _buildBody(
ThemeData theme, LoadingState<List<MsgReplyItem>?> loadingState) { ThemeData theme, LoadingState<List<MsgReplyItem>?> loadingState) {
late final divider = Divider(
indent: 72,
endIndent: 20,
height: 6,
color: Colors.grey.withValues(alpha: 0.1),
);
return switch (loadingState) { return switch (loadingState) {
Loading() => SliverList.builder( Loading() => SliverList.builder(
itemCount: 12, itemCount: 12,
@@ -166,14 +172,7 @@ class _ReplyMePageState extends State<ReplyMePage> {
), ),
); );
}, },
separatorBuilder: (BuildContext context, int index) { separatorBuilder: (context, index) => divider,
return Divider(
indent: 72,
endIndent: 20,
height: 6,
color: Colors.grey.withValues(alpha: 0.1),
);
},
) )
: HttpError(onReload: _replyMeController.onReload), : HttpError(onReload: _replyMeController.onReload),
Error(:var errMsg) => HttpError( Error(:var errMsg) => HttpError(

View File

@@ -50,6 +50,12 @@ class _SysMsgPageState extends State<SysMsgPage> {
Widget _buildBody( Widget _buildBody(
ThemeData theme, LoadingState<List<MsgSysItem>?> loadingState) { ThemeData theme, LoadingState<List<MsgSysItem>?> loadingState) {
late final divider = Divider(
indent: 72,
endIndent: 20,
height: 6,
color: Colors.grey.withValues(alpha: 0.1),
);
return switch (loadingState) { return switch (loadingState) {
Loading() => SliverSafeArea( Loading() => SliverSafeArea(
sliver: SliverList.builder( sliver: SliverList.builder(
@@ -107,14 +113,7 @@ class _SysMsgPageState extends State<SysMsgPage> {
), ),
); );
}, },
separatorBuilder: (BuildContext context, int index) { separatorBuilder: (context, index) => divider,
return Divider(
indent: 72,
endIndent: 20,
height: 6,
color: Colors.grey.withValues(alpha: 0.1),
);
},
) )
: HttpError(onReload: _sysMsgController.onReload), : HttpError(onReload: _sysMsgController.onReload),
Error(:var errMsg) => HttpError( Error(:var errMsg) => HttpError(

View File

@@ -73,6 +73,10 @@ class _PgcReviewChildPageState extends State<PgcReviewChildPage>
Widget _buildBody( Widget _buildBody(
ThemeData theme, LoadingState<List<PgcReviewItemModel>?> loadingState) { ThemeData theme, LoadingState<List<PgcReviewItemModel>?> loadingState) {
late final divider = Divider(
height: 1,
color: theme.colorScheme.outline.withValues(alpha: 0.1),
);
return switch (loadingState) { return switch (loadingState) {
Loading() => SliverToBoxAdapter( Loading() => SliverToBoxAdapter(
child: ListView.builder( child: ListView.builder(
@@ -93,10 +97,7 @@ class _PgcReviewChildPageState extends State<PgcReviewChildPage>
return _itemWidget(theme, index, response[index]); return _itemWidget(theme, index, response[index]);
}, },
itemCount: response!.length, itemCount: response!.length,
separatorBuilder: (context, index) => Divider( separatorBuilder: (context, index) => divider,
height: 1,
color: theme.colorScheme.outline.withValues(alpha: 0.1),
),
) )
: HttpError(onReload: _controller.onReload), : HttpError(onReload: _controller.onReload),
Error(:var errMsg) => HttpError( Error(:var errMsg) => HttpError(

View File

@@ -142,6 +142,11 @@ class _SearchTrendingPageState extends State<SearchTrendingPage> {
Widget _buildBody(ThemeData theme, Widget _buildBody(ThemeData theme,
LoadingState<List<SearchTrendingItemModel>?> loadingState) { LoadingState<List<SearchTrendingItemModel>?> loadingState) {
late final divider = Divider(
height: 1,
indent: 48,
color: theme.colorScheme.outline.withValues(alpha: 0.1),
);
return switch (loadingState) { return switch (loadingState) {
Loading() => const SliverToBoxAdapter(child: LinearProgressIndicator()), Loading() => const SliverToBoxAdapter(child: LinearProgressIndicator()),
Success(:var response) => response?.isNotEmpty == true Success(:var response) => response?.isNotEmpty == true
@@ -206,11 +211,7 @@ class _SearchTrendingPageState extends State<SearchTrendingPage> {
), ),
); );
}, },
separatorBuilder: (context, index) => Divider( separatorBuilder: (context, index) => divider,
height: 1,
indent: 48,
color: theme.colorScheme.outline.withValues(alpha: 0.1),
),
) )
: HttpError( : HttpError(
onReload: _controller.onReload, onReload: _controller.onReload,

View File

@@ -417,13 +417,13 @@ class _SponsorBlockPageState extends State<SponsorBlockPage> {
color: theme.colorScheme.outline, color: theme.colorScheme.outline,
); );
final divider = SliverToBoxAdapter( final divider = Divider(
child: Divider( height: 1,
height: 1, color: theme.colorScheme.outline.withValues(alpha: 0.1),
color: theme.colorScheme.outline.withValues(alpha: 0.1),
),
); );
final sliverDivider = SliverToBoxAdapter(child: divider);
final dividerL = SliverToBoxAdapter( final dividerL = SliverToBoxAdapter(
child: Divider( child: Divider(
thickness: 16, thickness: 16,
@@ -440,9 +440,9 @@ class _SponsorBlockPageState extends State<SponsorBlockPage> {
dividerL, dividerL,
SliverToBoxAdapter( SliverToBoxAdapter(
child: _blockLimitItem(theme, titleStyle, subTitleStyle)), child: _blockLimitItem(theme, titleStyle, subTitleStyle)),
divider, sliverDivider,
SliverToBoxAdapter(child: _blockToastItem(titleStyle)), SliverToBoxAdapter(child: _blockToastItem(titleStyle)),
divider, sliverDivider,
SliverToBoxAdapter(child: _blockTrackItem(titleStyle, subTitleStyle)), SliverToBoxAdapter(child: _blockTrackItem(titleStyle, subTitleStyle)),
dividerL, dividerL,
SliverList.separated( SliverList.separated(
@@ -536,15 +536,12 @@ class _SponsorBlockPageState extends State<SponsorBlockPage> {
), ),
), ),
), ),
separatorBuilder: (context, index) => Divider( separatorBuilder: (context, index) => divider,
height: 1,
color: theme.colorScheme.outline.withValues(alpha: 0.1),
),
), ),
dividerL, dividerL,
SliverToBoxAdapter( SliverToBoxAdapter(
child: _userIdItem(theme, titleStyle, subTitleStyle)), child: _userIdItem(theme, titleStyle, subTitleStyle)),
divider, sliverDivider,
SliverToBoxAdapter( SliverToBoxAdapter(
child: _blockServerItem(theme, titleStyle, subTitleStyle)), child: _blockServerItem(theme, titleStyle, subTitleStyle)),
dividerL, dividerL,

View File

@@ -160,6 +160,10 @@ class _NoteListPageState extends CommonSlidePageState<NoteListPage> {
Widget _buildBody( Widget _buildBody(
ThemeData theme, LoadingState<List<VideoNoteItemModel>?> loadingState) { ThemeData theme, LoadingState<List<VideoNoteItemModel>?> loadingState) {
late final divider = Divider(
height: 1,
color: theme.colorScheme.outline.withValues(alpha: 0.1),
);
return switch (loadingState) { return switch (loadingState) {
Loading() => SliverToBoxAdapter( Loading() => SliverToBoxAdapter(
child: ListView.builder( child: ListView.builder(
@@ -180,10 +184,7 @@ class _NoteListPageState extends CommonSlidePageState<NoteListPage> {
return _itemWidget(theme, response[index]); return _itemWidget(theme, response[index]);
}, },
itemCount: response!.length, itemCount: response!.length,
separatorBuilder: (context, index) => Divider( separatorBuilder: (context, index) => divider,
height: 1,
color: theme.colorScheme.outline.withValues(alpha: 0.1),
),
) )
: HttpError(onReload: _controller.onReload), : HttpError(onReload: _controller.onReload),
Error(:var errMsg) => HttpError( Error(:var errMsg) => HttpError(

View File

@@ -87,6 +87,10 @@ class _ViewPointsPageState
@override @override
Widget buildList(ThemeData theme) { Widget buildList(ThemeData theme) {
final divider = Divider(
height: 1,
color: theme.dividerColor.withValues(alpha: 0.1),
);
return ListView.separated( return ListView.separated(
controller: ScrollController(), controller: ScrollController(),
physics: const AlwaysScrollableScrollPhysics(), physics: const AlwaysScrollableScrollPhysics(),
@@ -157,10 +161,7 @@ class _ViewPointsPageState
), ),
); );
}, },
separatorBuilder: (context, index) => Divider( separatorBuilder: (context, index) => divider,
height: 1,
color: theme.dividerColor.withValues(alpha: 0.1),
),
); );
} }
} }

View File

@@ -86,6 +86,12 @@ class _WhisperPageState extends State<WhisperPage> {
} }
Widget _buildBody(LoadingState<List<Session>?> loadingState) { Widget _buildBody(LoadingState<List<Session>?> loadingState) {
late final divider = Divider(
indent: 72,
endIndent: 20,
height: 1,
color: Colors.grey.withValues(alpha: 0.1),
);
return switch (loadingState) { return switch (loadingState) {
Loading() => SliverList.builder( Loading() => SliverList.builder(
itemCount: 12, itemCount: 12,
@@ -109,12 +115,7 @@ class _WhisperPageState extends State<WhisperPage> {
onRemove: (talkerId) => _controller.onRemove(index, talkerId), onRemove: (talkerId) => _controller.onRemove(index, talkerId),
); );
}, },
separatorBuilder: (context, index) => Divider( separatorBuilder: (context, index) => divider,
indent: 72,
endIndent: 20,
height: 1,
color: Colors.grey.withValues(alpha: 0.1),
),
) )
: HttpError( : HttpError(
onReload: _controller.onReload, onReload: _controller.onReload,

View File

@@ -168,8 +168,7 @@ class _WhisperDetailPageState
: null, : null,
); );
}, },
separatorBuilder: (BuildContext context, int index) => separatorBuilder: (context, index) => const SizedBox(height: 12),
const SizedBox(height: 12),
) )
: scrollErrorWidget( : scrollErrorWidget(
onReload: _whisperDetailController.onReload, onReload: _whisperDetailController.onReload,

View File

@@ -77,6 +77,12 @@ class _WhisperSecPageState extends State<WhisperSecPage> {
} }
Widget _buildBody(LoadingState<List<Session>?> loadingState) { Widget _buildBody(LoadingState<List<Session>?> loadingState) {
late final divider = Divider(
indent: 72,
endIndent: 20,
height: 1,
color: Colors.grey.withValues(alpha: 0.1),
);
return switch (loadingState) { return switch (loadingState) {
Loading() => SliverList.builder( Loading() => SliverList.builder(
itemCount: 12, itemCount: 12,
@@ -100,12 +106,7 @@ class _WhisperSecPageState extends State<WhisperSecPage> {
onRemove: (talkerId) => _controller.onRemove(index, talkerId), onRemove: (talkerId) => _controller.onRemove(index, talkerId),
); );
}, },
separatorBuilder: (context, index) => Divider( separatorBuilder: (context, index) => divider,
indent: 72,
endIndent: 20,
height: 1,
color: Colors.grey.withValues(alpha: 0.1),
),
) )
: HttpError( : HttpError(
onReload: _controller.onReload, onReload: _controller.onReload,

View File

@@ -145,6 +145,10 @@ class _WhisperSettingsPageState extends State<WhisperSettingsPage> {
Widget _buildBody( Widget _buildBody(
ThemeData theme, LoadingState<PbMap<int, Setting>> loadingState) { ThemeData theme, LoadingState<PbMap<int, Setting>> loadingState) {
late final divider = Divider(
height: 1,
color: theme.colorScheme.outline.withValues(alpha: 0.1),
);
return switch (loadingState) { return switch (loadingState) {
Loading() => const SizedBox.shrink(), Loading() => const SizedBox.shrink(),
Success<PbMap<int, Setting>>(:var response) => Success<PbMap<int, Setting>>(:var response) =>
@@ -163,10 +167,7 @@ class _WhisperSettingsPageState extends State<WhisperSettingsPage> {
onRedirect: () => onRedirect(theme, key, response, item), onRedirect: () => onRedirect(theme, key, response, item),
); );
}, },
separatorBuilder: (context, index) => Divider( separatorBuilder: (context, index) => divider,
height: 1,
color: theme.colorScheme.outline.withValues(alpha: 0.1),
),
); );
}), }),
Error(:var errMsg) => scrollErrorWidget( Error(:var errMsg) => scrollErrorWidget(