mirror of
https://github.com/HChaZZY/PiliPlus.git
synced 2025-12-06 09:13:48 +08:00
@@ -2,47 +2,64 @@ import 'package:flutter/material.dart';
|
|||||||
import 'package:flutter_svg/flutter_svg.dart';
|
import 'package:flutter_svg/flutter_svg.dart';
|
||||||
|
|
||||||
class HttpError extends StatelessWidget {
|
class HttpError extends StatelessWidget {
|
||||||
const HttpError(
|
const HttpError({
|
||||||
{required this.errMsg, required this.fn, this.btnText, super.key});
|
this.isSliver = true,
|
||||||
|
this.errMsg,
|
||||||
|
this.callback,
|
||||||
|
this.btnText,
|
||||||
|
super.key,
|
||||||
|
});
|
||||||
|
|
||||||
|
final bool isSliver;
|
||||||
final String? errMsg;
|
final String? errMsg;
|
||||||
final Function()? fn;
|
final Function()? callback;
|
||||||
final String? btnText;
|
final String? btnText;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return SliverToBoxAdapter(
|
return isSliver
|
||||||
child: Column(
|
? SliverToBoxAdapter(child: content(context))
|
||||||
|
: SizedBox(
|
||||||
|
width: double.infinity,
|
||||||
|
child: content(context),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Widget content(BuildContext context) => Column(
|
||||||
|
mainAxisSize: MainAxisSize.min,
|
||||||
crossAxisAlignment: CrossAxisAlignment.center,
|
crossAxisAlignment: CrossAxisAlignment.center,
|
||||||
mainAxisAlignment: MainAxisAlignment.center,
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
children: [
|
children: [
|
||||||
|
const SizedBox(height: 40),
|
||||||
SvgPicture.asset(
|
SvgPicture.asset(
|
||||||
"assets/images/error.svg",
|
"assets/images/error.svg",
|
||||||
height: 200,
|
height: 200,
|
||||||
),
|
),
|
||||||
const SizedBox(height: 30),
|
const SizedBox(height: 30),
|
||||||
Text(
|
Padding(
|
||||||
errMsg ?? '请求异常',
|
padding: const EdgeInsets.symmetric(horizontal: 16),
|
||||||
textAlign: TextAlign.center,
|
child: SelectableText(
|
||||||
style: Theme.of(context).textTheme.titleSmall,
|
errMsg ?? '没有数据',
|
||||||
),
|
textAlign: TextAlign.center,
|
||||||
const SizedBox(height: 20),
|
style: Theme.of(context).textTheme.titleSmall,
|
||||||
FilledButton.tonal(
|
|
||||||
onPressed: () {
|
|
||||||
fn!();
|
|
||||||
},
|
|
||||||
style: ButtonStyle(
|
|
||||||
backgroundColor: WidgetStateProperty.resolveWith((states) {
|
|
||||||
return Theme.of(context).colorScheme.primary.withAlpha(20);
|
|
||||||
}),
|
|
||||||
),
|
|
||||||
child: Text(
|
|
||||||
btnText ?? '点击重试',
|
|
||||||
style: TextStyle(color: Theme.of(context).colorScheme.primary),
|
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
if (callback != null) ...[
|
||||||
|
const SizedBox(height: 20),
|
||||||
|
FilledButton.tonal(
|
||||||
|
onPressed: callback,
|
||||||
|
style: ButtonStyle(
|
||||||
|
backgroundColor: WidgetStateProperty.resolveWith((states) {
|
||||||
|
return Theme.of(context).colorScheme.primary.withAlpha(20);
|
||||||
|
}),
|
||||||
|
),
|
||||||
|
child: Text(
|
||||||
|
btnText ?? '点击重试',
|
||||||
|
style: TextStyle(color: Theme.of(context).colorScheme.primary),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
SizedBox(height: 40 + MediaQuery.paddingOf(context).bottom),
|
||||||
],
|
],
|
||||||
),
|
);
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
10
lib/common/widgets/loading_widget.dart
Normal file
10
lib/common/widgets/loading_widget.dart
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
import 'package:PiliPalaX/common/widgets/http_error.dart';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
|
Widget get loadingWidget => Center(child: CircularProgressIndicator());
|
||||||
|
|
||||||
|
Widget errorWidget({errMsg, callback}) => HttpError(
|
||||||
|
isSliver: false,
|
||||||
|
errMsg: errMsg,
|
||||||
|
callback: callback,
|
||||||
|
);
|
||||||
@@ -1,31 +0,0 @@
|
|||||||
import 'package:flutter/material.dart';
|
|
||||||
import 'package:flutter_svg/flutter_svg.dart';
|
|
||||||
|
|
||||||
class NoData extends StatelessWidget {
|
|
||||||
const NoData({super.key});
|
|
||||||
|
|
||||||
@override
|
|
||||||
Widget build(BuildContext context) {
|
|
||||||
return SliverToBoxAdapter(
|
|
||||||
child: SizedBox(
|
|
||||||
height: 400,
|
|
||||||
child: Column(
|
|
||||||
crossAxisAlignment: CrossAxisAlignment.center,
|
|
||||||
mainAxisAlignment: MainAxisAlignment.center,
|
|
||||||
children: [
|
|
||||||
SvgPicture.asset(
|
|
||||||
"assets/images/error.svg",
|
|
||||||
height: 200,
|
|
||||||
),
|
|
||||||
const SizedBox(height: 20),
|
|
||||||
Text(
|
|
||||||
'没有数据',
|
|
||||||
textAlign: TextAlign.center,
|
|
||||||
style: Theme.of(context).textTheme.titleSmall,
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,5 +1,4 @@
|
|||||||
import 'package:PiliPalaX/http/loading_state.dart';
|
import 'package:PiliPalaX/http/loading_state.dart';
|
||||||
import 'package:PiliPalaX/utils/extension.dart';
|
|
||||||
|
|
||||||
import '../models/bangumi/list.dart';
|
import '../models/bangumi/list.dart';
|
||||||
import 'index.dart';
|
import 'index.dart';
|
||||||
@@ -10,11 +9,7 @@ class BangumiHttp {
|
|||||||
if (res.data['code'] == 0) {
|
if (res.data['code'] == 0) {
|
||||||
BangumiListDataModel data =
|
BangumiListDataModel data =
|
||||||
BangumiListDataModel.fromJson(res.data['data']);
|
BangumiListDataModel.fromJson(res.data['data']);
|
||||||
if (!data.list.isNullOrEmpty) {
|
return LoadingState.success(data.list);
|
||||||
return LoadingState.success(data.list);
|
|
||||||
} else {
|
|
||||||
return LoadingState.empty();
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
return LoadingState.error(res.data['message']);
|
return LoadingState.error(res.data['message']);
|
||||||
}
|
}
|
||||||
@@ -25,11 +20,7 @@ class BangumiHttp {
|
|||||||
if (res.data['code'] == 0) {
|
if (res.data['code'] == 0) {
|
||||||
BangumiListDataModel data =
|
BangumiListDataModel data =
|
||||||
BangumiListDataModel.fromJson(res.data['data']);
|
BangumiListDataModel.fromJson(res.data['data']);
|
||||||
if (!data.list.isNullOrEmpty) {
|
return LoadingState.success(data.list);
|
||||||
return LoadingState.success(data.list);
|
|
||||||
} else {
|
|
||||||
return LoadingState.empty();
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
return LoadingState.error(res.data['message']);
|
return LoadingState.error(res.data['message']);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
import 'package:PiliPalaX/http/loading_state.dart';
|
import 'package:PiliPalaX/http/loading_state.dart';
|
||||||
import 'package:PiliPalaX/utils/extension.dart';
|
|
||||||
|
|
||||||
import '../models/user/black.dart';
|
import '../models/user/black.dart';
|
||||||
import 'index.dart';
|
import 'index.dart';
|
||||||
@@ -15,11 +14,7 @@ class BlackHttp {
|
|||||||
});
|
});
|
||||||
if (res.data['code'] == 0) {
|
if (res.data['code'] == 0) {
|
||||||
BlackListDataModel data = BlackListDataModel.fromJson(res.data['data']);
|
BlackListDataModel data = BlackListDataModel.fromJson(res.data['data']);
|
||||||
if (!data.list.isNullOrEmpty) {
|
return LoadingState.success(data);
|
||||||
return LoadingState.success(data);
|
|
||||||
} else {
|
|
||||||
return LoadingState.empty();
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
return LoadingState.error(res.data['message']);
|
return LoadingState.error(res.data['message']);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
import 'package:PiliPalaX/http/loading_state.dart';
|
import 'package:PiliPalaX/http/loading_state.dart';
|
||||||
import 'package:PiliPalaX/utils/extension.dart';
|
|
||||||
|
|
||||||
import '../models/dynamics/result.dart';
|
import '../models/dynamics/result.dart';
|
||||||
import '../models/dynamics/up.dart';
|
import '../models/dynamics/up.dart';
|
||||||
@@ -25,11 +24,7 @@ class DynamicsHttp {
|
|||||||
if (res.data['code'] == 0) {
|
if (res.data['code'] == 0) {
|
||||||
try {
|
try {
|
||||||
DynamicsDataModel data = DynamicsDataModel.fromJson(res.data['data']);
|
DynamicsDataModel data = DynamicsDataModel.fromJson(res.data['data']);
|
||||||
if (!data.items.isNullOrEmpty) {
|
return LoadingState.success(data);
|
||||||
return LoadingState.success(data);
|
|
||||||
} else {
|
|
||||||
return LoadingState.empty();
|
|
||||||
}
|
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
return LoadingState.error(err.toString());
|
return LoadingState.error(err.toString());
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,11 +17,7 @@ class LiveHttp {
|
|||||||
List<LiveItemModel> list = res.data['data']['list']
|
List<LiveItemModel> list = res.data['data']['list']
|
||||||
.map<LiveItemModel>((e) => LiveItemModel.fromJson(e))
|
.map<LiveItemModel>((e) => LiveItemModel.fromJson(e))
|
||||||
.toList();
|
.toList();
|
||||||
if (list.isNotEmpty) {
|
return LoadingState.success(list);
|
||||||
return LoadingState.success(list);
|
|
||||||
} else {
|
|
||||||
return LoadingState.empty();
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
return LoadingState.error(res.data['message']);
|
return LoadingState.error(res.data['message']);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ abstract class LoadingState<T> {
|
|||||||
const LoadingState();
|
const LoadingState();
|
||||||
|
|
||||||
factory LoadingState.loading() = Loading;
|
factory LoadingState.loading() = Loading;
|
||||||
factory LoadingState.empty() = Empty;
|
// factory LoadingState.empty() = Empty;
|
||||||
factory LoadingState.success(T response) = Success<T>;
|
factory LoadingState.success(T response) = Success<T>;
|
||||||
factory LoadingState.error(String errMsg) = Error;
|
factory LoadingState.error(String errMsg) = Error;
|
||||||
}
|
}
|
||||||
@@ -11,9 +11,9 @@ class Loading extends LoadingState<Never> {
|
|||||||
const Loading();
|
const Loading();
|
||||||
}
|
}
|
||||||
|
|
||||||
class Empty extends LoadingState<Never> {
|
// class Empty extends LoadingState<Never> {
|
||||||
const Empty();
|
// const Empty();
|
||||||
}
|
// }
|
||||||
|
|
||||||
class Success<T> extends LoadingState<T> {
|
class Success<T> extends LoadingState<T> {
|
||||||
final T response;
|
final T response;
|
||||||
|
|||||||
@@ -55,11 +55,7 @@ class UserHttp {
|
|||||||
'up_mid': mid,
|
'up_mid': mid,
|
||||||
});
|
});
|
||||||
if (res.data['code'] == 0) {
|
if (res.data['code'] == 0) {
|
||||||
if (res.data['data'] != null) {
|
return LoadingState.success(FavFolderData.fromJson(res.data['data']));
|
||||||
return LoadingState.success(FavFolderData.fromJson(res.data['data']));
|
|
||||||
} else {
|
|
||||||
return LoadingState.empty();
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
return LoadingState.error(res.data['message'] ?? '账号未登录');
|
return LoadingState.error(res.data['message'] ?? '账号未登录');
|
||||||
}
|
}
|
||||||
@@ -153,7 +149,7 @@ class UserHttp {
|
|||||||
var res = await Request().get(Api.seeYouLater);
|
var res = await Request().get(Api.seeYouLater);
|
||||||
if (res.data['code'] == 0) {
|
if (res.data['code'] == 0) {
|
||||||
if (res.data['data']['count'] == 0) {
|
if (res.data['data']['count'] == 0) {
|
||||||
return LoadingState.empty();
|
return LoadingState.success([]);
|
||||||
}
|
}
|
||||||
List<HotVideoItemModel> list = [];
|
List<HotVideoItemModel> list = [];
|
||||||
for (var i in res.data['data']['list']) {
|
for (var i in res.data['data']['list']) {
|
||||||
|
|||||||
@@ -67,11 +67,7 @@ class VideoHttp {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (list.isNotEmpty) {
|
return LoadingState.success(list);
|
||||||
return LoadingState.success(list);
|
|
||||||
} else {
|
|
||||||
return LoadingState.empty();
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
return LoadingState.error(res.data['message']);
|
return LoadingState.error(res.data['message']);
|
||||||
}
|
}
|
||||||
@@ -161,11 +157,7 @@ class VideoHttp {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (list.isNotEmpty) {
|
return LoadingState.success(list);
|
||||||
return LoadingState.success(list);
|
|
||||||
} else {
|
|
||||||
return LoadingState.empty();
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
return LoadingState.error(res.data['message']);
|
return LoadingState.error(res.data['message']);
|
||||||
}
|
}
|
||||||
@@ -189,11 +181,7 @@ class VideoHttp {
|
|||||||
list.add(HotVideoItemModel.fromJson(i));
|
list.add(HotVideoItemModel.fromJson(i));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (list.isNotEmpty) {
|
return LoadingState.success(list);
|
||||||
return LoadingState.success(list);
|
|
||||||
} else {
|
|
||||||
return LoadingState.empty();
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
return LoadingState.error(res.data['message']);
|
return LoadingState.error(res.data['message']);
|
||||||
}
|
}
|
||||||
@@ -210,11 +198,7 @@ class VideoHttp {
|
|||||||
list.add(item);
|
list.add(item);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (list.isNotEmpty) {
|
return LoadingState.success(list);
|
||||||
return LoadingState.success(list);
|
|
||||||
} else {
|
|
||||||
return LoadingState.empty();
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
return LoadingState.error(res['msg']);
|
return LoadingState.error(res['msg']);
|
||||||
}
|
}
|
||||||
@@ -357,11 +341,7 @@ class VideoHttp {
|
|||||||
list.add(videoItem);
|
list.add(videoItem);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (list.isNotEmpty) {
|
return LoadingState.success(list);
|
||||||
return LoadingState.success(list);
|
|
||||||
} else {
|
|
||||||
return LoadingState.empty();
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
return LoadingState.error(res.data['message']);
|
return LoadingState.error(res.data['message']);
|
||||||
}
|
}
|
||||||
@@ -970,11 +950,7 @@ class VideoHttp {
|
|||||||
list.add(HotVideoItemModel.fromJson(i));
|
list.add(HotVideoItemModel.fromJson(i));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (list.isNotEmpty) {
|
return LoadingState.success(list);
|
||||||
return LoadingState.success(list);
|
|
||||||
} else {
|
|
||||||
return LoadingState.empty();
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
return LoadingState.error(res.data['message']);
|
return LoadingState.error(res.data['message']);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -216,7 +216,7 @@ class MyApp extends StatelessWidget {
|
|||||||
centerTitle: false,
|
centerTitle: false,
|
||||||
scrolledUnderElevation: 0,
|
scrolledUnderElevation: 0,
|
||||||
backgroundColor: Platform.isIOS ? colorScheme.surface : null,
|
backgroundColor: Platform.isIOS ? colorScheme.surface : null,
|
||||||
titleTextStyle: Theme.of(context).textTheme.titleMedium,
|
titleTextStyle: TextStyle(fontSize: 16, color: colorScheme.onSurface),
|
||||||
),
|
),
|
||||||
navigationBarTheme: NavigationBarThemeData(
|
navigationBarTheme: NavigationBarThemeData(
|
||||||
surfaceTintColor: surfaceTintColor,
|
surfaceTintColor: surfaceTintColor,
|
||||||
|
|||||||
@@ -6,10 +6,5 @@ enum UpPanelPosition {
|
|||||||
}
|
}
|
||||||
|
|
||||||
extension UpPanelPositionDesc on UpPanelPosition {
|
extension UpPanelPositionDesc on UpPanelPosition {
|
||||||
String get values => ['left_fixed', 'right_fixed', 'left_drawer', 'right_drawer'][index];
|
String get labels => ['左侧常驻', '右侧常驻', '左侧抽屉', '右侧抽屉'][index];
|
||||||
String get labels => ['左侧常驻','右侧常驻','左侧抽屉','右侧抽屉'][index];
|
|
||||||
}
|
|
||||||
|
|
||||||
extension UpPanelPositionCode on UpPanelPosition {
|
|
||||||
int get code => [0, 1, 2, 3][index];
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -69,31 +69,32 @@ class _BangumiIntroPanelState extends State<BangumiIntroPanel>
|
|||||||
}
|
}
|
||||||
|
|
||||||
_buildBody(LoadingState loadingState) {
|
_buildBody(LoadingState loadingState) {
|
||||||
return loadingState is Success
|
return switch (loadingState) {
|
||||||
? BangumiInfo(
|
Loading() => BangumiInfo(
|
||||||
heroTag: widget.heroTag,
|
heroTag: widget.heroTag,
|
||||||
loadingStatus: false,
|
loadingStatus: true,
|
||||||
bangumiDetail: loadingState.response,
|
bangumiDetail: null,
|
||||||
cid: cid,
|
cid: cid,
|
||||||
showEpisodes: widget.showEpisodes,
|
showEpisodes: widget.showEpisodes,
|
||||||
showIntroDetail: () => widget.showIntroDetail(
|
showIntroDetail: widget.showIntroDetail,
|
||||||
loadingState.response,
|
),
|
||||||
bangumiIntroController.videoTags,
|
Success() => BangumiInfo(
|
||||||
),
|
heroTag: widget.heroTag,
|
||||||
)
|
loadingStatus: false,
|
||||||
: loadingState is Error
|
bangumiDetail: loadingState.response,
|
||||||
? HttpError(
|
cid: cid,
|
||||||
errMsg: loadingState.errMsg,
|
showEpisodes: widget.showEpisodes,
|
||||||
fn: bangumiIntroController.onReload,
|
showIntroDetail: () => widget.showIntroDetail(
|
||||||
)
|
loadingState.response,
|
||||||
: BangumiInfo(
|
bangumiIntroController.videoTags,
|
||||||
heroTag: widget.heroTag,
|
),
|
||||||
loadingStatus: true,
|
),
|
||||||
bangumiDetail: null,
|
Error() => HttpError(
|
||||||
cid: cid,
|
errMsg: loadingState.errMsg,
|
||||||
showEpisodes: widget.showEpisodes,
|
callback: bangumiIntroController.onReload,
|
||||||
showIntroDetail: widget.showIntroDetail,
|
),
|
||||||
);
|
LoadingState() => throw UnimplementedError(),
|
||||||
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -109,17 +109,10 @@ class _BangumiPageState extends State<BangumiPage>
|
|||||||
),
|
),
|
||||||
SizedBox(
|
SizedBox(
|
||||||
height: Grid.maxRowWidth * 1,
|
height: Grid.maxRowWidth * 1,
|
||||||
child: Obx(() =>
|
child: Obx(
|
||||||
_bangumiController.followState.value is Empty
|
() => _buildFollowBody(
|
||||||
? const SizedBox(
|
_bangumiController.followState.value),
|
||||||
child: Center(
|
),
|
||||||
child: Text('还没有追番'),
|
|
||||||
),
|
|
||||||
)
|
|
||||||
: _bangumiController.followState.value is Success
|
|
||||||
? _buildFollowList(_bangumiController
|
|
||||||
.followState.value as Success)
|
|
||||||
: const SizedBox()),
|
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
@@ -144,19 +137,7 @@ class _BangumiPageState extends State<BangumiPage>
|
|||||||
padding: const EdgeInsets.fromLTRB(
|
padding: const EdgeInsets.fromLTRB(
|
||||||
StyleString.safeSpace, 0, StyleString.safeSpace, 0),
|
StyleString.safeSpace, 0, StyleString.safeSpace, 0),
|
||||||
sliver: Obx(
|
sliver: Obx(
|
||||||
() => _bangumiController.loadingState.value is Loading
|
() => _buildBody(_bangumiController.loadingState.value),
|
||||||
? contentGrid([])
|
|
||||||
: _bangumiController.loadingState.value is Success
|
|
||||||
? contentGrid(
|
|
||||||
(_bangumiController.loadingState.value as Success)
|
|
||||||
.response)
|
|
||||||
: HttpError(
|
|
||||||
errMsg: _bangumiController.loadingState.value is Error
|
|
||||||
? (_bangumiController.loadingState.value as Error)
|
|
||||||
.errMsg
|
|
||||||
: '没有相关数据',
|
|
||||||
fn: _bangumiController.onReload,
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
@@ -164,6 +145,40 @@ class _BangumiPageState extends State<BangumiPage>
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Widget _buildBody(LoadingState loadingState) {
|
||||||
|
return switch (loadingState) {
|
||||||
|
Loading() => const SliverToBoxAdapter(),
|
||||||
|
Success() => (loadingState.response as List?)?.isNotEmpty == true
|
||||||
|
? SliverGrid(
|
||||||
|
gridDelegate: SliverGridDelegateWithExtentAndRatio(
|
||||||
|
// 行间距
|
||||||
|
mainAxisSpacing: StyleString.cardSpace - 2,
|
||||||
|
// 列间距
|
||||||
|
crossAxisSpacing: StyleString.cardSpace,
|
||||||
|
// 最大宽度
|
||||||
|
maxCrossAxisExtent: Grid.maxRowWidth / 3 * 2,
|
||||||
|
childAspectRatio: 0.65,
|
||||||
|
mainAxisExtent: MediaQuery.textScalerOf(context).scale(60),
|
||||||
|
),
|
||||||
|
delegate: SliverChildBuilderDelegate(
|
||||||
|
(BuildContext context, int index) {
|
||||||
|
return BangumiCardV(
|
||||||
|
bangumiItem: loadingState.response[index]);
|
||||||
|
},
|
||||||
|
childCount: loadingState.response.length,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
: HttpError(
|
||||||
|
callback: _bangumiController.onReload,
|
||||||
|
),
|
||||||
|
Error() => HttpError(
|
||||||
|
errMsg: loadingState.errMsg,
|
||||||
|
callback: _bangumiController.onReload,
|
||||||
|
),
|
||||||
|
LoadingState() => throw UnimplementedError(),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
Widget _buildFollowList(Success loadingState) {
|
Widget _buildFollowList(Success loadingState) {
|
||||||
return ListView.builder(
|
return ListView.builder(
|
||||||
scrollDirection: Axis.horizontal,
|
scrollDirection: Axis.horizontal,
|
||||||
@@ -185,24 +200,14 @@ class _BangumiPageState extends State<BangumiPage>
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
Widget contentGrid(List list) {
|
Widget _buildFollowBody(LoadingState loadingState) {
|
||||||
return SliverGrid(
|
return switch (loadingState) {
|
||||||
gridDelegate: SliverGridDelegateWithExtentAndRatio(
|
Loading() => nil,
|
||||||
// 行间距
|
Success() => (loadingState.response as List?)?.isNotEmpty == true
|
||||||
mainAxisSpacing: StyleString.cardSpace - 2,
|
? _buildFollowList(loadingState)
|
||||||
// 列间距
|
: const Center(child: Text('还没有追番')),
|
||||||
crossAxisSpacing: StyleString.cardSpace,
|
Error() => Center(child: Text(loadingState.errMsg)),
|
||||||
// 最大宽度
|
LoadingState() => throw UnimplementedError(),
|
||||||
maxCrossAxisExtent: Grid.maxRowWidth / 3 * 2,
|
};
|
||||||
childAspectRatio: 0.65,
|
|
||||||
mainAxisExtent: MediaQuery.textScalerOf(context).scale(60),
|
|
||||||
),
|
|
||||||
delegate: SliverChildBuilderDelegate(
|
|
||||||
(BuildContext context, int index) {
|
|
||||||
return list.isNotEmpty ? BangumiCardV(bangumiItem: list[index]) : nil;
|
|
||||||
},
|
|
||||||
childCount: list.isNotEmpty ? list.length : 10,
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
import 'package:PiliPalaX/common/widgets/loading_widget.dart';
|
||||||
import 'package:PiliPalaX/common/widgets/refresh_indicator.dart';
|
import 'package:PiliPalaX/common/widgets/refresh_indicator.dart';
|
||||||
import 'package:PiliPalaX/http/loading_state.dart';
|
import 'package:PiliPalaX/http/loading_state.dart';
|
||||||
import 'package:PiliPalaX/pages/common/common_controller.dart';
|
import 'package:PiliPalaX/pages/common/common_controller.dart';
|
||||||
@@ -5,7 +6,6 @@ import 'package:flutter/material.dart';
|
|||||||
import 'package:flutter_smart_dialog/flutter_smart_dialog.dart';
|
import 'package:flutter_smart_dialog/flutter_smart_dialog.dart';
|
||||||
import 'package:get/get.dart';
|
import 'package:get/get.dart';
|
||||||
import 'package:hive/hive.dart';
|
import 'package:hive/hive.dart';
|
||||||
import 'package:PiliPalaX/common/widgets/http_error.dart';
|
|
||||||
import 'package:PiliPalaX/common/widgets/network_img_layer.dart';
|
import 'package:PiliPalaX/common/widgets/network_img_layer.dart';
|
||||||
import 'package:PiliPalaX/http/black.dart';
|
import 'package:PiliPalaX/http/black.dart';
|
||||||
import 'package:PiliPalaX/utils/storage.dart';
|
import 'package:PiliPalaX/utils/storage.dart';
|
||||||
@@ -63,51 +63,52 @@ class _BlackListPageState extends State<BlackListPage> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Widget _buildBody(LoadingState loadingState) {
|
Widget _buildBody(LoadingState loadingState) {
|
||||||
return loadingState is Success
|
return switch (loadingState) {
|
||||||
? ListView.builder(
|
Loading() => loadingWidget,
|
||||||
controller: _blackListController.scrollController,
|
Success() => (loadingState.response as List?)?.isNotEmpty == true
|
||||||
itemCount: loadingState.response.length,
|
? ListView.builder(
|
||||||
itemBuilder: (BuildContext context, int index) {
|
controller: _blackListController.scrollController,
|
||||||
return ListTile(
|
itemCount: loadingState.response.length,
|
||||||
onTap: () {},
|
itemBuilder: (BuildContext context, int index) {
|
||||||
leading: NetworkImgLayer(
|
return ListTile(
|
||||||
width: 45,
|
onTap: () {},
|
||||||
height: 45,
|
leading: NetworkImgLayer(
|
||||||
type: 'avatar',
|
width: 45,
|
||||||
src: loadingState.response[index].face,
|
height: 45,
|
||||||
),
|
type: 'avatar',
|
||||||
title: Text(
|
src: loadingState.response[index].face,
|
||||||
loadingState.response[index].uname!,
|
),
|
||||||
maxLines: 1,
|
title: Text(
|
||||||
overflow: TextOverflow.ellipsis,
|
loadingState.response[index].uname!,
|
||||||
style: const TextStyle(fontSize: 14),
|
maxLines: 1,
|
||||||
),
|
overflow: TextOverflow.ellipsis,
|
||||||
subtitle: Text(
|
style: const TextStyle(fontSize: 14),
|
||||||
Utils.dateFormat(loadingState.response[index].mtime),
|
),
|
||||||
maxLines: 1,
|
subtitle: Text(
|
||||||
style:
|
Utils.dateFormat(loadingState.response[index].mtime),
|
||||||
TextStyle(color: Theme.of(context).colorScheme.outline),
|
maxLines: 1,
|
||||||
overflow: TextOverflow.ellipsis,
|
style:
|
||||||
),
|
TextStyle(color: Theme.of(context).colorScheme.outline),
|
||||||
dense: true,
|
overflow: TextOverflow.ellipsis,
|
||||||
trailing: TextButton(
|
),
|
||||||
onPressed: () => _blackListController
|
dense: true,
|
||||||
.removeBlack(loadingState.response[index].mid),
|
trailing: TextButton(
|
||||||
child: const Text('移除'),
|
onPressed: () => _blackListController
|
||||||
),
|
.removeBlack(loadingState.response[index].mid),
|
||||||
);
|
child: const Text('移除'),
|
||||||
},
|
),
|
||||||
)
|
);
|
||||||
: loadingState is Error
|
},
|
||||||
? CustomScrollView(
|
)
|
||||||
slivers: [
|
: errorWidget(
|
||||||
HttpError(
|
callback: _blackListController.onReload,
|
||||||
errMsg: loadingState.errMsg,
|
),
|
||||||
fn: _blackListController.onReload,
|
Error() => errorWidget(
|
||||||
)
|
errMsg: loadingState.errMsg,
|
||||||
],
|
callback: _blackListController.onReload,
|
||||||
)
|
),
|
||||||
: const SizedBox();
|
LoadingState() => throw UnimplementedError(),
|
||||||
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -130,9 +131,7 @@ class BlackListController extends CommonController {
|
|||||||
List dataList = currentPage == 1
|
List dataList = currentPage == 1
|
||||||
? response.response.list
|
? response.response.list
|
||||||
: currentList + response.response.list;
|
: currentList + response.response.list;
|
||||||
loadingState.value = dataList.isNotEmpty
|
loadingState.value = LoadingState.success(dataList);
|
||||||
? LoadingState.success(dataList)
|
|
||||||
: LoadingState.empty();
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -72,21 +72,21 @@ abstract class ReplyController extends CommonController {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
cursor = replies.cursor;
|
cursor = replies.cursor;
|
||||||
if (replies.replies.isNotEmpty) {
|
|
||||||
noMore.value = '加载中...';
|
|
||||||
if (replies.cursor.isEnd) {
|
|
||||||
noMore.value = '没有更多了';
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// 未登录状态replies可能返回null
|
|
||||||
noMore.value = currentPage == 1 ? '还没有评论' : '没有更多了';
|
|
||||||
}
|
|
||||||
if (currentPage != 1) {
|
if (currentPage != 1) {
|
||||||
List<ReplyInfo> list = loadingState.value is Success
|
List<ReplyInfo> list = loadingState.value is Success
|
||||||
? (loadingState.value as Success).response.replies
|
? (loadingState.value as Success).response.replies
|
||||||
: <ReplyInfo>[];
|
: <ReplyInfo>[];
|
||||||
replies.replies.insertAll(0, list);
|
replies.replies.insertAll(0, list);
|
||||||
}
|
}
|
||||||
|
if (replies.replies.isNotEmpty) {
|
||||||
|
noMore.value = '加载中...';
|
||||||
|
if (replies.cursor.isEnd || replies.replies.length >= count.value) {
|
||||||
|
noMore.value = '没有更多了';
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// 未登录状态replies可能返回null
|
||||||
|
noMore.value = currentPage == 1 ? '还没有评论' : '没有更多了';
|
||||||
|
}
|
||||||
loadingState.value = LoadingState.success(replies);
|
loadingState.value = LoadingState.success(replies);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -349,63 +349,68 @@ class _DynamicDetailPageState extends State<DynamicDetailPage>
|
|||||||
}
|
}
|
||||||
|
|
||||||
Widget replyList(LoadingState loadingState) {
|
Widget replyList(LoadingState loadingState) {
|
||||||
return loadingState is Success
|
return switch (loadingState) {
|
||||||
? SliverList(
|
Loading() => SliverList(
|
||||||
delegate: SliverChildBuilderDelegate(
|
delegate: SliverChildBuilderDelegate(
|
||||||
(context, index) {
|
(context, index) {
|
||||||
if (index == loadingState.response.replies.length) {
|
return const VideoReplySkeleton();
|
||||||
return Container(
|
},
|
||||||
padding: EdgeInsets.only(
|
childCount: 8,
|
||||||
bottom: MediaQuery.of(context).padding.bottom),
|
),
|
||||||
height: MediaQuery.of(context).padding.bottom + 100,
|
),
|
||||||
child: Center(
|
Success() => (loadingState.response.replies as List?)?.isNotEmpty == true
|
||||||
child: Obx(
|
? SliverList(
|
||||||
() => Text(
|
delegate: SliverChildBuilderDelegate(
|
||||||
_dynamicDetailController.noMore.value,
|
(context, index) {
|
||||||
style: TextStyle(
|
if (index == loadingState.response.replies.length) {
|
||||||
fontSize: 12,
|
return Container(
|
||||||
color: Theme.of(context).colorScheme.outline,
|
padding: EdgeInsets.only(
|
||||||
|
bottom: MediaQuery.of(context).padding.bottom),
|
||||||
|
height: MediaQuery.of(context).padding.bottom + 100,
|
||||||
|
child: Center(
|
||||||
|
child: Obx(
|
||||||
|
() => Text(
|
||||||
|
_dynamicDetailController.noMore.value,
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 12,
|
||||||
|
color: Theme.of(context).colorScheme.outline,
|
||||||
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
);
|
||||||
);
|
} else {
|
||||||
} else {
|
return ReplyItemGrpc(
|
||||||
return ReplyItemGrpc(
|
replyItem: loadingState.response.replies[index],
|
||||||
replyItem: loadingState.response.replies[index],
|
showReplyRow: true,
|
||||||
showReplyRow: true,
|
replyLevel: '1',
|
||||||
replyLevel: '1',
|
replyReply: replyReply,
|
||||||
replyReply: replyReply,
|
replyType: ReplyType.values[replyType],
|
||||||
replyType: ReplyType.values[replyType],
|
onReply: () {
|
||||||
onReply: () {
|
_dynamicDetailController.onReply(
|
||||||
_dynamicDetailController.onReply(
|
context,
|
||||||
context,
|
replyItem: loadingState.response.replies[index],
|
||||||
replyItem: loadingState.response.replies[index],
|
index: index,
|
||||||
index: index,
|
);
|
||||||
);
|
},
|
||||||
},
|
onDelete: _dynamicDetailController.onMDelete,
|
||||||
onDelete: _dynamicDetailController.onMDelete,
|
isTop: _dynamicDetailController.hasUpTop && index == 0,
|
||||||
isTop: _dynamicDetailController.hasUpTop && index == 0,
|
upMid: loadingState.response.subjectControl.upMid,
|
||||||
upMid: loadingState.response.subjectControl.upMid,
|
);
|
||||||
);
|
}
|
||||||
}
|
},
|
||||||
},
|
childCount: loadingState.response.replies.length + 1,
|
||||||
childCount: loadingState.response.replies.length + 1,
|
),
|
||||||
|
)
|
||||||
|
: HttpError(
|
||||||
|
callback: _dynamicDetailController.onReload,
|
||||||
),
|
),
|
||||||
)
|
Error() => HttpError(
|
||||||
: loadingState is Error
|
errMsg: loadingState.errMsg,
|
||||||
? HttpError(
|
callback: _dynamicDetailController.onReload,
|
||||||
errMsg: loadingState.errMsg,
|
),
|
||||||
fn: _dynamicDetailController.onReload,
|
LoadingState() => throw UnimplementedError(),
|
||||||
)
|
};
|
||||||
: SliverList(
|
|
||||||
delegate: SliverChildBuilderDelegate(
|
|
||||||
(context, index) {
|
|
||||||
return const VideoReplySkeleton();
|
|
||||||
},
|
|
||||||
childCount: 8,
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -55,11 +55,7 @@ class DynamicsTabController extends CommonController {
|
|||||||
if (res['status']) {
|
if (res['status']) {
|
||||||
List list = (loadingState.value as Success).response;
|
List list = (loadingState.value as Success).response;
|
||||||
list.removeWhere((item) => item.idStr == dynamicId);
|
list.removeWhere((item) => item.idStr == dynamicId);
|
||||||
if (list.isNotEmpty) {
|
loadingState.value = LoadingState.success(list);
|
||||||
loadingState.value = LoadingState.success(list);
|
|
||||||
} else {
|
|
||||||
loadingState.value = LoadingState.empty();
|
|
||||||
}
|
|
||||||
SmartDialog.showToast('删除成功');
|
SmartDialog.showToast('删除成功');
|
||||||
} else {
|
} else {
|
||||||
SmartDialog.showToast(res['msg']);
|
SmartDialog.showToast(res['msg']);
|
||||||
|
|||||||
@@ -10,7 +10,6 @@ import 'package:flutter/rendering.dart';
|
|||||||
import 'package:get/get.dart';
|
import 'package:get/get.dart';
|
||||||
import 'package:PiliPalaX/common/constants.dart';
|
import 'package:PiliPalaX/common/constants.dart';
|
||||||
import 'package:PiliPalaX/common/widgets/http_error.dart';
|
import 'package:PiliPalaX/common/widgets/http_error.dart';
|
||||||
import 'package:PiliPalaX/common/widgets/no_data.dart';
|
|
||||||
import 'package:waterfall_flow/waterfall_flow.dart';
|
import 'package:waterfall_flow/waterfall_flow.dart';
|
||||||
|
|
||||||
import '../../../common/skeleton/dynamic_card.dart';
|
import '../../../common/skeleton/dynamic_card.dart';
|
||||||
@@ -146,71 +145,74 @@ class _DynamicsTabPageState extends State<DynamicsTabPage>
|
|||||||
}
|
}
|
||||||
|
|
||||||
Widget _buildBody(LoadingState loadingState) {
|
Widget _buildBody(LoadingState loadingState) {
|
||||||
return loadingState is Success
|
return switch (loadingState) {
|
||||||
? dynamicsWaterfallFlow
|
Loading() => skeleton(),
|
||||||
? SliverWaterfallFlow.extent(
|
Success() => (loadingState.response as List?)?.isNotEmpty == true
|
||||||
maxCrossAxisExtent: Grid.maxRowWidth * 2,
|
? dynamicsWaterfallFlow
|
||||||
//cacheExtent: 0.0,
|
? SliverWaterfallFlow.extent(
|
||||||
crossAxisSpacing: StyleString.cardSpace / 2,
|
maxCrossAxisExtent: Grid.maxRowWidth * 2,
|
||||||
mainAxisSpacing: StyleString.cardSpace / 2,
|
//cacheExtent: 0.0,
|
||||||
|
crossAxisSpacing: StyleString.cardSpace / 2,
|
||||||
|
mainAxisSpacing: StyleString.cardSpace / 2,
|
||||||
|
|
||||||
lastChildLayoutTypeBuilder: (index) =>
|
lastChildLayoutTypeBuilder: (index) =>
|
||||||
index == loadingState.response.length
|
index == loadingState.response.length
|
||||||
? LastChildLayoutType.foot
|
? LastChildLayoutType.foot
|
||||||
: LastChildLayoutType.none,
|
: LastChildLayoutType.none,
|
||||||
children: [
|
children: [
|
||||||
if (dynamicsController.tabController.index == 4 &&
|
if (dynamicsController.tabController.index == 4 &&
|
||||||
dynamicsController.mid.value != -1) ...[
|
dynamicsController.mid.value != -1) ...[
|
||||||
for (var i in loadingState.response)
|
for (var i in loadingState.response)
|
||||||
DynamicPanel(
|
|
||||||
item: i,
|
|
||||||
onRemove: _dynamicsTabController.onRemove,
|
|
||||||
),
|
|
||||||
] else ...[
|
|
||||||
for (var i in loadingState.response)
|
|
||||||
if (!dynamicsController.tempBannedList
|
|
||||||
.contains(i.modules?.moduleAuthor?.mid))
|
|
||||||
DynamicPanel(
|
DynamicPanel(
|
||||||
item: i,
|
item: i,
|
||||||
onRemove: _dynamicsTabController.onRemove,
|
onRemove: _dynamicsTabController.onRemove,
|
||||||
),
|
),
|
||||||
]
|
] else ...[
|
||||||
],
|
for (var i in loadingState.response)
|
||||||
)
|
if (!dynamicsController.tempBannedList
|
||||||
: SliverCrossAxisGroup(
|
.contains(i.modules?.moduleAuthor?.mid))
|
||||||
slivers: [
|
DynamicPanel(
|
||||||
const SliverFillRemaining(),
|
item: i,
|
||||||
SliverConstrainedCrossAxis(
|
onRemove: _dynamicsTabController.onRemove,
|
||||||
maxExtent: Grid.maxRowWidth * 2,
|
),
|
||||||
sliver: SliverList(
|
]
|
||||||
delegate: SliverChildBuilderDelegate(
|
],
|
||||||
(context, index) {
|
)
|
||||||
if ((dynamicsController.tabController.index == 4 &&
|
: SliverCrossAxisGroup(
|
||||||
dynamicsController.mid.value != -1) ||
|
slivers: [
|
||||||
!dynamicsController.tempBannedList.contains(
|
const SliverFillRemaining(),
|
||||||
loadingState.response[index].modules
|
SliverConstrainedCrossAxis(
|
||||||
?.moduleAuthor?.mid)) {
|
maxExtent: Grid.maxRowWidth * 2,
|
||||||
return DynamicPanel(
|
sliver: SliverList(
|
||||||
item: loadingState.response[index],
|
delegate: SliverChildBuilderDelegate(
|
||||||
onRemove: _dynamicsTabController.onRemove,
|
(context, index) {
|
||||||
);
|
if ((dynamicsController.tabController.index == 4 &&
|
||||||
}
|
dynamicsController.mid.value != -1) ||
|
||||||
return const SizedBox();
|
!dynamicsController.tempBannedList.contains(
|
||||||
},
|
loadingState.response[index].modules
|
||||||
childCount: loadingState.response.length,
|
?.moduleAuthor?.mid)) {
|
||||||
|
return DynamicPanel(
|
||||||
|
item: loadingState.response[index],
|
||||||
|
onRemove: _dynamicsTabController.onRemove,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return const SizedBox();
|
||||||
|
},
|
||||||
|
childCount: loadingState.response.length,
|
||||||
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
const SliverFillRemaining(),
|
||||||
const SliverFillRemaining(),
|
],
|
||||||
],
|
)
|
||||||
)
|
: HttpError(
|
||||||
: loadingState is Empty
|
callback: _dynamicsTabController.onReload,
|
||||||
? const NoData()
|
),
|
||||||
: loadingState is Error
|
Error() => HttpError(
|
||||||
? HttpError(
|
errMsg: loadingState.errMsg,
|
||||||
errMsg: loadingState.errMsg,
|
callback: _dynamicsTabController.onReload,
|
||||||
fn: _dynamicsTabController.onReload,
|
),
|
||||||
)
|
LoadingState() => throw UnimplementedError(),
|
||||||
: skeleton();
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ import 'package:PiliPalaX/utils/feed_back.dart';
|
|||||||
import 'package:PiliPalaX/utils/storage.dart';
|
import 'package:PiliPalaX/utils/storage.dart';
|
||||||
import 'package:image_picker/image_picker.dart';
|
import 'package:image_picker/image_picker.dart';
|
||||||
import 'package:intl/intl.dart';
|
import 'package:intl/intl.dart';
|
||||||
|
import 'package:nil/nil.dart';
|
||||||
|
|
||||||
import 'controller.dart';
|
import 'controller.dart';
|
||||||
import 'widgets/up_panel.dart';
|
import 'widgets/up_panel.dart';
|
||||||
@@ -98,7 +99,7 @@ class _DynamicsPageState extends State<DynamicsPage>
|
|||||||
});
|
});
|
||||||
upPanelPosition = UpPanelPosition.values[setting.get(
|
upPanelPosition = UpPanelPosition.values[setting.get(
|
||||||
SettingBoxKey.upPanelPosition,
|
SettingBoxKey.upPanelPosition,
|
||||||
defaultValue: UpPanelPosition.leftFixed.code)];
|
defaultValue: UpPanelPosition.leftFixed.index)];
|
||||||
debugPrint('upPanelPosition: $upPanelPosition');
|
debugPrint('upPanelPosition: $upPanelPosition');
|
||||||
if (GStorage.setting
|
if (GStorage.setting
|
||||||
.get(SettingBoxKey.dynamicsShowAllFollowedUp, defaultValue: false)) {
|
.get(SettingBoxKey.dynamicsShowAllFollowedUp, defaultValue: false)) {
|
||||||
@@ -128,7 +129,7 @@ class _DynamicsPageState extends State<DynamicsPage>
|
|||||||
padding: const EdgeInsets.symmetric(horizontal: 4),
|
padding: const EdgeInsets.symmetric(horizontal: 4),
|
||||||
child: Container(
|
child: Container(
|
||||||
//抽屉模式增加底色
|
//抽屉模式增加底色
|
||||||
color: upPanelPosition.code > 1
|
color: upPanelPosition.index > 1
|
||||||
? Theme.of(context).colorScheme.surface
|
? Theme.of(context).colorScheme.surface
|
||||||
: Colors.transparent,
|
: Colors.transparent,
|
||||||
width: 56,
|
width: 56,
|
||||||
@@ -137,20 +138,27 @@ class _DynamicsPageState extends State<DynamicsPage>
|
|||||||
builder: (context, snapshot) {
|
builder: (context, snapshot) {
|
||||||
if (snapshot.connectionState == ConnectionState.done) {
|
if (snapshot.connectionState == ConnectionState.done) {
|
||||||
if (snapshot.data == null) {
|
if (snapshot.data == null) {
|
||||||
return const SizedBox();
|
return nil;
|
||||||
}
|
}
|
||||||
Map data = snapshot.data;
|
Map data = snapshot.data;
|
||||||
if (data['status']) {
|
if (data['status']) {
|
||||||
return Obx(() => UpPanel(_dynamicsController.upData.value,
|
return Obx(() => UpPanel(_dynamicsController.upData.value,
|
||||||
_dynamicsController.scrollController));
|
_dynamicsController.scrollController));
|
||||||
} else {
|
} else {
|
||||||
return const SizedBox();
|
return Center(
|
||||||
|
child: IconButton(
|
||||||
|
icon: Icon(Icons.refresh),
|
||||||
|
onPressed: () {
|
||||||
|
setState(() {
|
||||||
|
_futureBuilderFutureUp =
|
||||||
|
_dynamicsController.queryFollowUp();
|
||||||
|
});
|
||||||
|
},
|
||||||
|
),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
return const SizedBox(
|
return nil;
|
||||||
width: 56,
|
|
||||||
child: UpPanelSkeleton(),
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
import 'package:PiliPalaX/common/widgets/loading_widget.dart';
|
||||||
import 'package:PiliPalaX/http/loading_state.dart';
|
import 'package:PiliPalaX/http/loading_state.dart';
|
||||||
import 'package:PiliPalaX/models/video/reply/emote.dart';
|
import 'package:PiliPalaX/models/video/reply/emote.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
@@ -28,90 +29,99 @@ class _EmotePanelState extends State<EmotePanel>
|
|||||||
}
|
}
|
||||||
|
|
||||||
Widget _buildBody(LoadingState loadingState) {
|
Widget _buildBody(LoadingState loadingState) {
|
||||||
return loadingState is Success
|
return switch (loadingState) {
|
||||||
? Column(
|
Loading() => loadingWidget,
|
||||||
children: [
|
Success() => (loadingState.response as List?)?.isNotEmpty == true
|
||||||
Expanded(
|
? Column(
|
||||||
child: TabBarView(
|
children: [
|
||||||
controller: _emotePanelController.tabController,
|
Expanded(
|
||||||
children: (loadingState.response as List<Packages>).map(
|
child: TabBarView(
|
||||||
(e) {
|
controller: _emotePanelController.tabController,
|
||||||
int size = e.emote!.first.meta!.size!;
|
children: (loadingState.response as List<Packages>).map(
|
||||||
int type = e.type!;
|
(e) {
|
||||||
return Padding(
|
int size = e.emote!.first.meta!.size!;
|
||||||
padding: const EdgeInsets.fromLTRB(12, 6, 12, 0),
|
int type = e.type!;
|
||||||
child: GridView.builder(
|
return Padding(
|
||||||
gridDelegate:
|
padding: const EdgeInsets.fromLTRB(12, 6, 12, 0),
|
||||||
SliverGridDelegateWithMaxCrossAxisExtent(
|
child: GridView.builder(
|
||||||
maxCrossAxisExtent:
|
gridDelegate:
|
||||||
type == 4 ? 100 : (size == 1 ? 40 : 60),
|
SliverGridDelegateWithMaxCrossAxisExtent(
|
||||||
crossAxisSpacing: 8,
|
maxCrossAxisExtent:
|
||||||
mainAxisSpacing: 8,
|
type == 4 ? 100 : (size == 1 ? 40 : 60),
|
||||||
mainAxisExtent: size == 1 ? 40 : 60,
|
crossAxisSpacing: 8,
|
||||||
),
|
mainAxisSpacing: 8,
|
||||||
itemCount: e.emote!.length,
|
mainAxisExtent: size == 1 ? 40 : 60,
|
||||||
itemBuilder: (context, index) {
|
),
|
||||||
return Material(
|
itemCount: e.emote!.length,
|
||||||
color: Colors.transparent,
|
itemBuilder: (context, index) {
|
||||||
child: InkWell(
|
return Material(
|
||||||
borderRadius: BorderRadius.circular(8),
|
color: Colors.transparent,
|
||||||
onTap: () {
|
child: InkWell(
|
||||||
widget.onChoose(e, e.emote![index]);
|
borderRadius: BorderRadius.circular(8),
|
||||||
},
|
onTap: () {
|
||||||
child: Padding(
|
widget.onChoose(e, e.emote![index]);
|
||||||
padding: const EdgeInsets.all(6),
|
},
|
||||||
child: type == 4
|
child: Padding(
|
||||||
? Center(
|
padding: const EdgeInsets.all(6),
|
||||||
child: Text(
|
child: type == 4
|
||||||
e.emote![index].text!,
|
? Center(
|
||||||
overflow: TextOverflow.clip,
|
child: Text(
|
||||||
maxLines: 1,
|
e.emote![index].text!,
|
||||||
|
overflow: TextOverflow.clip,
|
||||||
|
maxLines: 1,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
: NetworkImgLayer(
|
||||||
|
src: e.emote![index].url!,
|
||||||
|
width: size * 38,
|
||||||
|
height: size * 38,
|
||||||
|
semanticsLabel:
|
||||||
|
e.emote![index].text!,
|
||||||
|
type: 'emote',
|
||||||
),
|
),
|
||||||
)
|
),
|
||||||
: NetworkImgLayer(
|
|
||||||
src: e.emote![index].url!,
|
|
||||||
width: size * 38,
|
|
||||||
height: size * 38,
|
|
||||||
semanticsLabel: e.emote![index].text!,
|
|
||||||
type: 'emote',
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
),
|
);
|
||||||
);
|
},
|
||||||
},
|
),
|
||||||
),
|
);
|
||||||
);
|
},
|
||||||
},
|
).toList(),
|
||||||
).toList(),
|
),
|
||||||
),
|
),
|
||||||
),
|
Divider(
|
||||||
Divider(
|
height: 1,
|
||||||
height: 1,
|
color: Theme.of(context).dividerColor.withOpacity(0.1),
|
||||||
color: Theme.of(context).dividerColor.withOpacity(0.1),
|
),
|
||||||
),
|
TabBar(
|
||||||
TabBar(
|
controller: _emotePanelController.tabController,
|
||||||
controller: _emotePanelController.tabController,
|
dividerColor: Colors.transparent,
|
||||||
dividerColor: Colors.transparent,
|
isScrollable: true,
|
||||||
isScrollable: true,
|
tabs: (loadingState.response as List<Packages>)
|
||||||
tabs: (loadingState.response as List<Packages>)
|
.map(
|
||||||
.map(
|
(e) => Padding(
|
||||||
(e) => Padding(
|
padding: const EdgeInsets.all(8),
|
||||||
padding: const EdgeInsets.all(8),
|
child: NetworkImgLayer(
|
||||||
child: NetworkImgLayer(
|
width: 24,
|
||||||
width: 24,
|
height: 24,
|
||||||
height: 24,
|
type: 'emote',
|
||||||
type: 'emote',
|
src: e.url,
|
||||||
src: e.url,
|
),
|
||||||
),
|
),
|
||||||
),
|
)
|
||||||
)
|
.toList(),
|
||||||
.toList(),
|
),
|
||||||
),
|
SizedBox(height: MediaQuery.of(context).padding.bottom),
|
||||||
SizedBox(height: MediaQuery.of(context).padding.bottom),
|
],
|
||||||
],
|
)
|
||||||
)
|
: errorWidget(
|
||||||
: loadingState is Error
|
callback: _emotePanelController.onReload,
|
||||||
? Center(child: Text(loadingState.errMsg))
|
),
|
||||||
: const Center(child: Text('加载中...'));
|
Error() => errorWidget(
|
||||||
|
errMsg: loadingState.errMsg,
|
||||||
|
callback: _emotePanelController.onReload,
|
||||||
|
),
|
||||||
|
LoadingState() => throw UnimplementedError(),
|
||||||
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,7 +4,6 @@ import 'package:easy_debounce/easy_throttle.dart';
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:get/get.dart';
|
import 'package:get/get.dart';
|
||||||
import 'package:PiliPalaX/common/widgets/http_error.dart';
|
import 'package:PiliPalaX/common/widgets/http_error.dart';
|
||||||
import 'package:PiliPalaX/common/widgets/no_data.dart';
|
|
||||||
|
|
||||||
import '../../common/constants.dart';
|
import '../../common/constants.dart';
|
||||||
import '../../utils/grid.dart';
|
import '../../utils/grid.dart';
|
||||||
@@ -67,33 +66,32 @@ class _FansPageState extends State<FansPage> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Widget _buildBody(LoadingState loadingState) {
|
Widget _buildBody(LoadingState loadingState) {
|
||||||
return loadingState is Success
|
return switch (loadingState) {
|
||||||
? loadingState.response.isNotEmpty
|
Loading() => HttpError(
|
||||||
? SliverGrid(
|
callback: _fansController.onReload,
|
||||||
gridDelegate: SliverGridDelegateWithMaxCrossAxisExtent(
|
),
|
||||||
mainAxisSpacing: StyleString.cardSpace,
|
Success() => (loadingState.response as List?)?.isNotEmpty == true
|
||||||
crossAxisSpacing: StyleString.safeSpace,
|
? SliverGrid(
|
||||||
maxCrossAxisExtent: Grid.maxRowWidth * 2,
|
gridDelegate: SliverGridDelegateWithMaxCrossAxisExtent(
|
||||||
mainAxisExtent: 56),
|
mainAxisSpacing: StyleString.cardSpace,
|
||||||
delegate: SliverChildBuilderDelegate(
|
crossAxisSpacing: StyleString.safeSpace,
|
||||||
(BuildContext context, int index) {
|
maxCrossAxisExtent: Grid.maxRowWidth * 2,
|
||||||
return fanItem(item: loadingState.response[index]);
|
mainAxisExtent: 56),
|
||||||
},
|
delegate: SliverChildBuilderDelegate(
|
||||||
childCount: loadingState.response.length,
|
(BuildContext context, int index) {
|
||||||
))
|
return fanItem(item: loadingState.response[index]);
|
||||||
: const NoData()
|
},
|
||||||
: loadingState is Error
|
childCount: loadingState.response.length,
|
||||||
? HttpError(
|
),
|
||||||
errMsg: loadingState.errMsg,
|
)
|
||||||
fn: _fansController.onReload,
|
: HttpError(
|
||||||
)
|
callback: _fansController.onReload,
|
||||||
: const SliverToBoxAdapter(
|
),
|
||||||
child: SizedBox(
|
Error() => HttpError(
|
||||||
height: 200,
|
errMsg: loadingState.errMsg,
|
||||||
child: Center(
|
callback: _fansController.onReload,
|
||||||
child: CircularProgressIndicator(),
|
),
|
||||||
),
|
LoadingState() => throw UnimplementedError(),
|
||||||
),
|
};
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -108,63 +108,68 @@ class _FavPageState extends State<FavPage> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Widget _buildBody(LoadingState loadingState) {
|
Widget _buildBody(LoadingState loadingState) {
|
||||||
return loadingState is Success
|
return switch (loadingState) {
|
||||||
? SliverGrid(
|
Loading() => SliverGrid(
|
||||||
gridDelegate: SliverGridDelegateWithExtentAndRatio(
|
gridDelegate: SliverGridDelegateWithExtentAndRatio(
|
||||||
mainAxisSpacing: StyleString.cardSpace,
|
mainAxisSpacing: StyleString.cardSpace,
|
||||||
crossAxisSpacing: StyleString.safeSpace,
|
crossAxisSpacing: StyleString.safeSpace,
|
||||||
maxCrossAxisExtent: Grid.maxRowWidth * 2,
|
maxCrossAxisExtent: Grid.maxRowWidth * 2,
|
||||||
childAspectRatio: StyleString.aspectRatio * 2.4,
|
childAspectRatio: StyleString.aspectRatio * 2.4,
|
||||||
mainAxisExtent: 0),
|
mainAxisExtent: 0),
|
||||||
delegate: SliverChildBuilderDelegate(
|
delegate: SliverChildBuilderDelegate(
|
||||||
childCount: loadingState.response.length,
|
(BuildContext context, int index) {
|
||||||
(BuildContext context, int index) {
|
return const VideoCardHSkeleton();
|
||||||
String heroTag =
|
},
|
||||||
Utils.makeHeroTag(loadingState.response[index].fid);
|
childCount: 10,
|
||||||
return FavItem(
|
),
|
||||||
heroTag: heroTag,
|
),
|
||||||
favFolderItem: loadingState.response[index],
|
Success() => (loadingState.response as List?)?.isNotEmpty == true
|
||||||
onTap: () {
|
? SliverGrid(
|
||||||
Get.toNamed(
|
gridDelegate: SliverGridDelegateWithExtentAndRatio(
|
||||||
'/favDetail',
|
mainAxisSpacing: StyleString.cardSpace,
|
||||||
arguments: loadingState.response[index],
|
crossAxisSpacing: StyleString.safeSpace,
|
||||||
parameters: {
|
maxCrossAxisExtent: Grid.maxRowWidth * 2,
|
||||||
'heroTag': heroTag,
|
childAspectRatio: StyleString.aspectRatio * 2.4,
|
||||||
'mediaId': loadingState.response[index].id.toString(),
|
mainAxisExtent: 0),
|
||||||
},
|
delegate: SliverChildBuilderDelegate(
|
||||||
)?.then((res) {
|
childCount: loadingState.response.length,
|
||||||
if (res == true) {
|
(BuildContext context, int index) {
|
||||||
List list =
|
String heroTag =
|
||||||
(_favController.loadingState.value as Success)
|
Utils.makeHeroTag(loadingState.response[index].fid);
|
||||||
.response;
|
return FavItem(
|
||||||
list.removeAt(index);
|
heroTag: heroTag,
|
||||||
_favController.loadingState.value =
|
favFolderItem: loadingState.response[index],
|
||||||
LoadingState.success(list);
|
onTap: () {
|
||||||
}
|
Get.toNamed(
|
||||||
});
|
'/favDetail',
|
||||||
},
|
arguments: loadingState.response[index],
|
||||||
);
|
parameters: {
|
||||||
},
|
'heroTag': heroTag,
|
||||||
|
'mediaId': loadingState.response[index].id.toString(),
|
||||||
|
},
|
||||||
|
)?.then((res) {
|
||||||
|
if (res == true) {
|
||||||
|
List list =
|
||||||
|
(_favController.loadingState.value as Success)
|
||||||
|
.response;
|
||||||
|
list.removeAt(index);
|
||||||
|
_favController.loadingState.value =
|
||||||
|
LoadingState.success(list);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
)
|
||||||
|
: HttpError(
|
||||||
|
callback: _favController.onReload,
|
||||||
),
|
),
|
||||||
)
|
Error() => HttpError(
|
||||||
: loadingState is Error
|
errMsg: loadingState.errMsg,
|
||||||
? HttpError(
|
callback: _favController.onReload,
|
||||||
errMsg: loadingState.errMsg,
|
),
|
||||||
fn: _favController.onReload,
|
LoadingState() => throw UnimplementedError(),
|
||||||
)
|
};
|
||||||
: SliverGrid(
|
|
||||||
gridDelegate: SliverGridDelegateWithExtentAndRatio(
|
|
||||||
mainAxisSpacing: StyleString.cardSpace,
|
|
||||||
crossAxisSpacing: StyleString.safeSpace,
|
|
||||||
maxCrossAxisExtent: Grid.maxRowWidth * 2,
|
|
||||||
childAspectRatio: StyleString.aspectRatio * 2.4,
|
|
||||||
mainAxisExtent: 0),
|
|
||||||
delegate: SliverChildBuilderDelegate(
|
|
||||||
(BuildContext context, int index) {
|
|
||||||
return const VideoCardHSkeleton();
|
|
||||||
},
|
|
||||||
childCount: 10,
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -238,52 +238,27 @@ class _FavDetailPageState extends State<FavDetailPage> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Widget _buildBody(LoadingState loadingState) {
|
Widget _buildBody(LoadingState loadingState) {
|
||||||
return loadingState is Success
|
return switch (loadingState) {
|
||||||
? loadingState.response.isEmpty
|
Loading() => SliverGrid(
|
||||||
? const SliverToBoxAdapter(child: SizedBox())
|
gridDelegate: SliverGridDelegateWithExtentAndRatio(
|
||||||
: SliverPadding(
|
mainAxisSpacing: StyleString.cardSpace,
|
||||||
padding: EdgeInsets.only(
|
crossAxisSpacing: StyleString.safeSpace,
|
||||||
bottom: MediaQuery.of(context).padding.bottom),
|
maxCrossAxisExtent: Grid.maxRowWidth * 2,
|
||||||
sliver: SliverGrid(
|
childAspectRatio: StyleString.aspectRatio * 2.4,
|
||||||
gridDelegate: SliverGridDelegateWithExtentAndRatio(
|
mainAxisExtent: 0,
|
||||||
mainAxisSpacing: StyleString.cardSpace,
|
),
|
||||||
crossAxisSpacing: StyleString.safeSpace,
|
delegate: SliverChildBuilderDelegate(
|
||||||
maxCrossAxisExtent: Grid.maxRowWidth * 2,
|
(context, index) {
|
||||||
childAspectRatio: StyleString.aspectRatio * 2.4,
|
return const VideoCardHSkeleton();
|
||||||
mainAxisExtent: 0,
|
},
|
||||||
),
|
childCount: 10,
|
||||||
delegate: SliverChildBuilderDelegate(
|
),
|
||||||
(context, index) {
|
),
|
||||||
if (index == loadingState.response.length) {
|
Success() => (loadingState.response as List?)?.isNotEmpty == true
|
||||||
return Container(
|
? SliverPadding(
|
||||||
height: 60,
|
padding: EdgeInsets.only(
|
||||||
alignment: Alignment.center,
|
bottom: MediaQuery.of(context).padding.bottom),
|
||||||
child: Obx(
|
sliver: SliverGrid(
|
||||||
() => Text(
|
|
||||||
_favDetailController.loadingText.value,
|
|
||||||
style: TextStyle(
|
|
||||||
color: Theme.of(context).colorScheme.outline,
|
|
||||||
fontSize: 13),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
return FavVideoCardH(
|
|
||||||
videoItem: loadingState.response[index],
|
|
||||||
callFn: () => _favDetailController
|
|
||||||
.onCancelFav(loadingState.response[index].id),
|
|
||||||
);
|
|
||||||
},
|
|
||||||
childCount: loadingState.response.length + 1,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
)
|
|
||||||
: loadingState is Error
|
|
||||||
? HttpError(
|
|
||||||
errMsg: loadingState.errMsg,
|
|
||||||
fn: _favDetailController.onReload,
|
|
||||||
)
|
|
||||||
: SliverGrid(
|
|
||||||
gridDelegate: SliverGridDelegateWithExtentAndRatio(
|
gridDelegate: SliverGridDelegateWithExtentAndRatio(
|
||||||
mainAxisSpacing: StyleString.cardSpace,
|
mainAxisSpacing: StyleString.cardSpace,
|
||||||
crossAxisSpacing: StyleString.safeSpace,
|
crossAxisSpacing: StyleString.safeSpace,
|
||||||
@@ -293,10 +268,38 @@ class _FavDetailPageState extends State<FavDetailPage> {
|
|||||||
),
|
),
|
||||||
delegate: SliverChildBuilderDelegate(
|
delegate: SliverChildBuilderDelegate(
|
||||||
(context, index) {
|
(context, index) {
|
||||||
return const VideoCardHSkeleton();
|
if (index == loadingState.response.length) {
|
||||||
|
return Container(
|
||||||
|
height: 60,
|
||||||
|
alignment: Alignment.center,
|
||||||
|
child: Obx(
|
||||||
|
() => Text(
|
||||||
|
_favDetailController.loadingText.value,
|
||||||
|
style: TextStyle(
|
||||||
|
color: Theme.of(context).colorScheme.outline,
|
||||||
|
fontSize: 13),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return FavVideoCardH(
|
||||||
|
videoItem: loadingState.response[index],
|
||||||
|
callFn: () => _favDetailController
|
||||||
|
.onCancelFav(loadingState.response[index].id),
|
||||||
|
);
|
||||||
},
|
},
|
||||||
childCount: 10,
|
childCount: loadingState.response.length + 1,
|
||||||
),
|
),
|
||||||
);
|
),
|
||||||
|
)
|
||||||
|
: HttpError(
|
||||||
|
callback: _favDetailController.onReload,
|
||||||
|
),
|
||||||
|
Error() => HttpError(
|
||||||
|
errMsg: loadingState.errMsg,
|
||||||
|
callback: _favDetailController.onReload,
|
||||||
|
),
|
||||||
|
LoadingState() => throw UnimplementedError(),
|
||||||
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import 'package:PiliPalaX/common/constants.dart';
|
import 'package:PiliPalaX/common/constants.dart';
|
||||||
import 'package:PiliPalaX/common/widgets/http_error.dart';
|
import 'package:PiliPalaX/common/widgets/loading_widget.dart';
|
||||||
import 'package:PiliPalaX/http/loading_state.dart';
|
import 'package:PiliPalaX/http/loading_state.dart';
|
||||||
import 'package:PiliPalaX/pages/follow/widgets/follow_item.dart';
|
import 'package:PiliPalaX/pages/follow/widgets/follow_item.dart';
|
||||||
import 'package:PiliPalaX/pages/history/widgets/item.dart';
|
import 'package:PiliPalaX/pages/history/widgets/item.dart';
|
||||||
@@ -7,7 +7,6 @@ import 'package:PiliPalaX/utils/grid.dart';
|
|||||||
import 'package:easy_debounce/easy_throttle.dart';
|
import 'package:easy_debounce/easy_throttle.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:get/get.dart';
|
import 'package:get/get.dart';
|
||||||
import 'package:PiliPalaX/common/widgets/no_data.dart';
|
|
||||||
import 'package:PiliPalaX/pages/fav_detail/widget/fav_video_card.dart';
|
import 'package:PiliPalaX/pages/fav_detail/widget/fav_video_card.dart';
|
||||||
|
|
||||||
import 'controller.dart';
|
import 'controller.dart';
|
||||||
@@ -83,88 +82,76 @@ class _FavSearchPageState extends State<FavSearchPage> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Widget _buildBody(LoadingState loadingState) {
|
Widget _buildBody(LoadingState loadingState) {
|
||||||
return loadingState is Success
|
return switch (loadingState) {
|
||||||
? loadingState.response.isEmpty
|
Loading() => loadingWidget,
|
||||||
? CustomScrollView(
|
Success() => (loadingState.response as List?)?.isNotEmpty == true
|
||||||
slivers: <Widget>[
|
? _favSearchCtr.searchType == SearchType.fav
|
||||||
HttpError(
|
? ListView.builder(
|
||||||
errMsg: '没有数据',
|
controller: _favSearchCtr.scrollController,
|
||||||
fn: _favSearchCtr.onReload,
|
itemCount: loadingState.response.length + 1,
|
||||||
),
|
itemBuilder: (context, index) {
|
||||||
],
|
if (index == loadingState.response.length) {
|
||||||
)
|
return Container(
|
||||||
: _favSearchCtr.searchType == SearchType.fav
|
height: MediaQuery.of(context).padding.bottom + 60,
|
||||||
? ListView.builder(
|
padding: EdgeInsets.only(
|
||||||
controller: _favSearchCtr.scrollController,
|
bottom: MediaQuery.of(context).padding.bottom,
|
||||||
itemCount: loadingState.response.length + 1,
|
),
|
||||||
itemBuilder: (context, index) {
|
);
|
||||||
if (index == loadingState.response.length) {
|
} else {
|
||||||
return Container(
|
return FavVideoCardH(
|
||||||
height: MediaQuery.of(context).padding.bottom + 60,
|
videoItem: loadingState.response[index],
|
||||||
padding: EdgeInsets.only(
|
searchType: _favSearchCtr.type,
|
||||||
bottom: MediaQuery.of(context).padding.bottom,
|
callFn: () => _favSearchCtr.type != 1
|
||||||
),
|
? _favSearchCtr
|
||||||
|
.onCancelFav(loadingState.response[index].id!)
|
||||||
|
: {},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
)
|
||||||
|
: _favSearchCtr.searchType == SearchType.follow
|
||||||
|
? ListView.builder(
|
||||||
|
controller: _favSearchCtr.scrollController,
|
||||||
|
itemCount: loadingState.response.length,
|
||||||
|
itemBuilder: ((context, index) {
|
||||||
|
return FollowItem(
|
||||||
|
item: loadingState.response[index],
|
||||||
);
|
);
|
||||||
} else {
|
}),
|
||||||
return FavVideoCardH(
|
)
|
||||||
videoItem: loadingState.response[index],
|
: CustomScrollView(
|
||||||
searchType: _favSearchCtr.type,
|
physics: const AlwaysScrollableScrollPhysics(),
|
||||||
callFn: () => _favSearchCtr.type != 1
|
controller: _favSearchCtr.scrollController,
|
||||||
? _favSearchCtr
|
slivers: [
|
||||||
.onCancelFav(loadingState.response[index].id!)
|
SliverGrid(
|
||||||
: {},
|
gridDelegate: SliverGridDelegateWithExtentAndRatio(
|
||||||
);
|
mainAxisSpacing: StyleString.cardSpace,
|
||||||
}
|
crossAxisSpacing: StyleString.safeSpace,
|
||||||
},
|
maxCrossAxisExtent: Grid.maxRowWidth * 2,
|
||||||
)
|
childAspectRatio: StyleString.aspectRatio * 2.4,
|
||||||
: _favSearchCtr.searchType == SearchType.follow
|
mainAxisExtent: 0),
|
||||||
? ListView.builder(
|
delegate: SliverChildBuilderDelegate(
|
||||||
controller: _favSearchCtr.scrollController,
|
(context, index) {
|
||||||
itemCount: loadingState.response.length,
|
return HistoryItem(
|
||||||
itemBuilder: ((context, index) {
|
videoItem: loadingState.response[index],
|
||||||
return FollowItem(
|
ctr: _favSearchCtr,
|
||||||
item: loadingState.response[index],
|
onChoose: null,
|
||||||
);
|
onUpdateMultiple: () => null,
|
||||||
}),
|
);
|
||||||
)
|
},
|
||||||
: CustomScrollView(
|
childCount: loadingState.response.length,
|
||||||
physics: const AlwaysScrollableScrollPhysics(),
|
|
||||||
controller: _favSearchCtr.scrollController,
|
|
||||||
slivers: [
|
|
||||||
SliverGrid(
|
|
||||||
gridDelegate: SliverGridDelegateWithExtentAndRatio(
|
|
||||||
mainAxisSpacing: StyleString.cardSpace,
|
|
||||||
crossAxisSpacing: StyleString.safeSpace,
|
|
||||||
maxCrossAxisExtent: Grid.maxRowWidth * 2,
|
|
||||||
childAspectRatio: StyleString.aspectRatio * 2.4,
|
|
||||||
mainAxisExtent: 0),
|
|
||||||
delegate: SliverChildBuilderDelegate(
|
|
||||||
(context, index) {
|
|
||||||
return HistoryItem(
|
|
||||||
videoItem: loadingState.response[index],
|
|
||||||
ctr: _favSearchCtr,
|
|
||||||
onChoose: null,
|
|
||||||
onUpdateMultiple: () => null,
|
|
||||||
);
|
|
||||||
},
|
|
||||||
childCount: loadingState.response.length,
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
],
|
),
|
||||||
)
|
],
|
||||||
: loadingState is Error
|
)
|
||||||
? CustomScrollView(
|
: errorWidget(
|
||||||
slivers: <Widget>[
|
callback: _favSearchCtr.onReload,
|
||||||
HttpError(
|
),
|
||||||
errMsg: loadingState.errMsg,
|
Error() => errorWidget(
|
||||||
fn: _favSearchCtr.onReload,
|
errMsg: loadingState.errMsg,
|
||||||
),
|
callback: _favSearchCtr.onReload,
|
||||||
],
|
),
|
||||||
)
|
LoadingState() => throw UnimplementedError(),
|
||||||
: const CustomScrollView(
|
};
|
||||||
slivers: <Widget>[
|
|
||||||
NoData(),
|
|
||||||
],
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,9 +1,8 @@
|
|||||||
|
import 'package:PiliPalaX/common/widgets/loading_widget.dart';
|
||||||
import 'package:PiliPalaX/common/widgets/refresh_indicator.dart';
|
import 'package:PiliPalaX/common/widgets/refresh_indicator.dart';
|
||||||
import 'package:easy_debounce/easy_throttle.dart';
|
import 'package:easy_debounce/easy_throttle.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:get/get.dart';
|
import 'package:get/get.dart';
|
||||||
import 'package:PiliPalaX/common/widgets/http_error.dart';
|
|
||||||
import 'package:PiliPalaX/common/widgets/no_data.dart';
|
|
||||||
import 'package:PiliPalaX/models/follow/result.dart';
|
import 'package:PiliPalaX/models/follow/result.dart';
|
||||||
import 'package:PiliPalaX/pages/follow/index.dart';
|
import 'package:PiliPalaX/pages/follow/index.dart';
|
||||||
|
|
||||||
@@ -92,16 +91,14 @@ class _FollowListState extends State<FollowList> {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
: const CustomScrollView(slivers: [NoData()]),
|
: errorWidget(
|
||||||
|
callback: () => widget.ctr.queryFollowings('init'),
|
||||||
|
),
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
return CustomScrollView(
|
return errorWidget(
|
||||||
slivers: [
|
errMsg: data['msg'],
|
||||||
HttpError(
|
callback: () => widget.ctr.queryFollowings('init'),
|
||||||
errMsg: data['msg'],
|
|
||||||
fn: () => widget.ctr.queryFollowings('init'),
|
|
||||||
)
|
|
||||||
],
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -1,9 +1,8 @@
|
|||||||
|
import 'package:PiliPalaX/common/widgets/loading_widget.dart';
|
||||||
import 'package:PiliPalaX/common/widgets/refresh_indicator.dart';
|
import 'package:PiliPalaX/common/widgets/refresh_indicator.dart';
|
||||||
import 'package:easy_debounce/easy_throttle.dart';
|
import 'package:easy_debounce/easy_throttle.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:get/get.dart';
|
import 'package:get/get.dart';
|
||||||
import 'package:PiliPalaX/common/widgets/http_error.dart';
|
|
||||||
import 'package:PiliPalaX/common/widgets/no_data.dart';
|
|
||||||
import 'package:PiliPalaX/http/member.dart';
|
import 'package:PiliPalaX/http/member.dart';
|
||||||
import 'package:PiliPalaX/models/follow/result.dart';
|
import 'package:PiliPalaX/models/follow/result.dart';
|
||||||
import 'package:PiliPalaX/models/member/tags.dart';
|
import 'package:PiliPalaX/models/member/tags.dart';
|
||||||
@@ -110,16 +109,14 @@ class _OwnerFollowListState extends State<OwnerFollowList>
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
: const CustomScrollView(slivers: [NoData()]),
|
: errorWidget(
|
||||||
|
callback: () => widget.ctr.queryFollowings('init'),
|
||||||
|
),
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
return CustomScrollView(
|
return errorWidget(
|
||||||
slivers: [
|
errMsg: data['msg'],
|
||||||
HttpError(
|
callback: () => widget.ctr.queryFollowings('init'),
|
||||||
errMsg: data['msg'],
|
|
||||||
fn: () => widget.ctr.queryFollowings('init'),
|
|
||||||
)
|
|
||||||
],
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -1,11 +1,10 @@
|
|||||||
|
import 'package:PiliPalaX/common/widgets/http_error.dart';
|
||||||
import 'package:PiliPalaX/common/widgets/refresh_indicator.dart';
|
import 'package:PiliPalaX/common/widgets/refresh_indicator.dart';
|
||||||
import 'package:PiliPalaX/pages/fav_search/view.dart' show SearchType;
|
import 'package:PiliPalaX/pages/fav_search/view.dart' show SearchType;
|
||||||
import 'package:easy_debounce/easy_throttle.dart';
|
import 'package:easy_debounce/easy_throttle.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:get/get.dart';
|
import 'package:get/get.dart';
|
||||||
import 'package:PiliPalaX/common/skeleton/video_card_h.dart';
|
import 'package:PiliPalaX/common/skeleton/video_card_h.dart';
|
||||||
import 'package:PiliPalaX/common/widgets/http_error.dart';
|
|
||||||
import 'package:PiliPalaX/common/widgets/no_data.dart';
|
|
||||||
import 'package:PiliPalaX/pages/history/index.dart';
|
import 'package:PiliPalaX/pages/history/index.dart';
|
||||||
|
|
||||||
import '../../common/constants.dart';
|
import '../../common/constants.dart';
|
||||||
@@ -215,12 +214,20 @@ class _HistoryPageState extends State<HistoryPage> {
|
|||||||
? const SliverToBoxAdapter(
|
? const SliverToBoxAdapter(
|
||||||
child: Center(child: Text('加载中')),
|
child: Center(child: Text('加载中')),
|
||||||
)
|
)
|
||||||
: const NoData(),
|
: HttpError(
|
||||||
|
callback: () => setState(() {
|
||||||
|
_futureBuilderFuture =
|
||||||
|
_historyController.queryHistoryList();
|
||||||
|
}),
|
||||||
|
),
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
return HttpError(
|
return HttpError(
|
||||||
errMsg: data['msg'],
|
errMsg: data['msg'],
|
||||||
fn: () => setState(() {}),
|
callback: () => setState(() {
|
||||||
|
_futureBuilderFuture =
|
||||||
|
_historyController.queryHistoryList();
|
||||||
|
}),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -91,7 +91,7 @@ class _HotPageState extends State<HotPage> with AutomaticKeepAliveClientMixin {
|
|||||||
? (_hotController.loadingState.value as Error)
|
? (_hotController.loadingState.value as Error)
|
||||||
.errMsg
|
.errMsg
|
||||||
: '没有相关数据',
|
: '没有相关数据',
|
||||||
fn: _hotController.onReload,
|
callback: _hotController.onReload,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|||||||
@@ -320,59 +320,64 @@ class _HtmlRenderPageState extends State<HtmlRenderPage>
|
|||||||
}
|
}
|
||||||
|
|
||||||
Widget replyList(LoadingState loadingState) {
|
Widget replyList(LoadingState loadingState) {
|
||||||
return loadingState is Success
|
return switch (loadingState) {
|
||||||
? SliverList.builder(
|
Loading() => SliverList.builder(
|
||||||
itemCount: loadingState.response.replies.length + 1,
|
itemCount: 5,
|
||||||
itemBuilder: (context, index) {
|
itemBuilder: (context, index) {
|
||||||
if (index == loadingState.response.replies.length) {
|
return const VideoReplySkeleton();
|
||||||
return Container(
|
},
|
||||||
padding: EdgeInsets.only(
|
),
|
||||||
bottom: MediaQuery.of(context).padding.bottom),
|
Success() => (loadingState.response.replies as List?)?.isNotEmpty == true
|
||||||
height: MediaQuery.of(context).padding.bottom + 100,
|
? SliverList.builder(
|
||||||
child: Center(
|
itemCount: loadingState.response.replies.length + 1,
|
||||||
child: Obx(
|
itemBuilder: (context, index) {
|
||||||
() => Text(
|
if (index == loadingState.response.replies.length) {
|
||||||
_htmlRenderCtr.noMore.value,
|
return Container(
|
||||||
style: TextStyle(
|
padding: EdgeInsets.only(
|
||||||
fontSize: 12,
|
bottom: MediaQuery.of(context).padding.bottom),
|
||||||
color: Theme.of(context).colorScheme.outline,
|
height: MediaQuery.of(context).padding.bottom + 100,
|
||||||
|
child: Center(
|
||||||
|
child: Obx(
|
||||||
|
() => Text(
|
||||||
|
_htmlRenderCtr.noMore.value,
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 12,
|
||||||
|
color: Theme.of(context).colorScheme.outline,
|
||||||
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
);
|
||||||
);
|
} else {
|
||||||
} else {
|
return ReplyItemGrpc(
|
||||||
return ReplyItemGrpc(
|
replyItem: loadingState.response.replies[index],
|
||||||
replyItem: loadingState.response.replies[index],
|
showReplyRow: true,
|
||||||
showReplyRow: true,
|
replyLevel: '1',
|
||||||
replyLevel: '1',
|
replyReply: replyReply,
|
||||||
replyReply: replyReply,
|
replyType: ReplyType.values[type],
|
||||||
replyType: ReplyType.values[type],
|
onReply: () {
|
||||||
onReply: () {
|
_htmlRenderCtr.onReply(
|
||||||
_htmlRenderCtr.onReply(
|
context,
|
||||||
context,
|
replyItem: loadingState.response.replies[index],
|
||||||
replyItem: loadingState.response.replies[index],
|
index: index,
|
||||||
index: index,
|
);
|
||||||
);
|
},
|
||||||
},
|
onDelete: _htmlRenderCtr.onMDelete,
|
||||||
onDelete: _htmlRenderCtr.onMDelete,
|
isTop: _htmlRenderCtr.hasUpTop && index == 0,
|
||||||
isTop: _htmlRenderCtr.hasUpTop && index == 0,
|
upMid: loadingState.response.subjectControl.upMid,
|
||||||
upMid: loadingState.response.subjectControl.upMid,
|
);
|
||||||
);
|
}
|
||||||
}
|
},
|
||||||
},
|
)
|
||||||
)
|
: HttpError(
|
||||||
: loadingState is Error
|
callback: _htmlRenderCtr.onReload,
|
||||||
? HttpError(
|
),
|
||||||
errMsg: loadingState.errMsg,
|
Error() => HttpError(
|
||||||
fn: _htmlRenderCtr.onReload,
|
errMsg: loadingState.errMsg,
|
||||||
)
|
callback: _htmlRenderCtr.onReload,
|
||||||
: SliverList.builder(
|
),
|
||||||
itemCount: 5,
|
LoadingState() => throw UnimplementedError(),
|
||||||
itemBuilder: (context, index) {
|
};
|
||||||
return const VideoReplySkeleton();
|
|
||||||
},
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Container replyHeader() {
|
Container replyHeader() {
|
||||||
|
|||||||
@@ -88,7 +88,7 @@ class LaterController extends CommonController {
|
|||||||
onPressed: () async {
|
onPressed: () async {
|
||||||
var res = await UserHttp.toViewClear();
|
var res = await UserHttp.toViewClear();
|
||||||
if (res['status']) {
|
if (res['status']) {
|
||||||
loadingState.value = LoadingState.empty();
|
loadingState.value = LoadingState.success([]);
|
||||||
}
|
}
|
||||||
Get.back();
|
Get.back();
|
||||||
SmartDialog.showToast(res['msg']);
|
SmartDialog.showToast(res['msg']);
|
||||||
|
|||||||
@@ -3,7 +3,6 @@ import 'package:flutter/material.dart';
|
|||||||
import 'package:get/get.dart';
|
import 'package:get/get.dart';
|
||||||
import 'package:PiliPalaX/common/skeleton/video_card_h.dart';
|
import 'package:PiliPalaX/common/skeleton/video_card_h.dart';
|
||||||
import 'package:PiliPalaX/common/widgets/http_error.dart';
|
import 'package:PiliPalaX/common/widgets/http_error.dart';
|
||||||
import 'package:PiliPalaX/common/widgets/no_data.dart';
|
|
||||||
import 'package:PiliPalaX/common/widgets/video_card_h.dart';
|
import 'package:PiliPalaX/common/widgets/video_card_h.dart';
|
||||||
import 'package:PiliPalaX/pages/later/index.dart';
|
import 'package:PiliPalaX/pages/later/index.dart';
|
||||||
|
|
||||||
@@ -74,48 +73,51 @@ class _LaterPageState extends State<LaterPage> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Widget _buildBody(LoadingState loadingState) {
|
Widget _buildBody(LoadingState loadingState) {
|
||||||
return loadingState is Success
|
return switch (loadingState) {
|
||||||
? SliverGrid(
|
Loading() => SliverGrid(
|
||||||
gridDelegate: SliverGridDelegateWithExtentAndRatio(
|
gridDelegate: SliverGridDelegateWithExtentAndRatio(
|
||||||
mainAxisSpacing: StyleString.safeSpace,
|
mainAxisSpacing: StyleString.safeSpace,
|
||||||
crossAxisSpacing: StyleString.safeSpace,
|
crossAxisSpacing: StyleString.safeSpace,
|
||||||
maxCrossAxisExtent: Grid.maxRowWidth * 2,
|
maxCrossAxisExtent: Grid.maxRowWidth * 2,
|
||||||
childAspectRatio: StyleString.aspectRatio * 2.4,
|
childAspectRatio: StyleString.aspectRatio * 2.4,
|
||||||
mainAxisExtent: 0,
|
mainAxisExtent: 0,
|
||||||
|
),
|
||||||
|
delegate: SliverChildBuilderDelegate(
|
||||||
|
(context, index) {
|
||||||
|
return const VideoCardHSkeleton();
|
||||||
|
},
|
||||||
|
childCount: 10,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
Success() => (loadingState.response as List?)?.isNotEmpty == true
|
||||||
|
? SliverGrid(
|
||||||
|
gridDelegate: SliverGridDelegateWithExtentAndRatio(
|
||||||
|
mainAxisSpacing: StyleString.safeSpace,
|
||||||
|
crossAxisSpacing: StyleString.safeSpace,
|
||||||
|
maxCrossAxisExtent: Grid.maxRowWidth * 2,
|
||||||
|
childAspectRatio: StyleString.aspectRatio * 2.4,
|
||||||
|
mainAxisExtent: 0,
|
||||||
|
),
|
||||||
|
delegate: SliverChildBuilderDelegate(
|
||||||
|
(context, index) {
|
||||||
|
var videoItem = loadingState.response[index];
|
||||||
|
return VideoCardH(
|
||||||
|
videoItem: videoItem,
|
||||||
|
source: 'later',
|
||||||
|
longPress: () => _laterController.toViewDel(context,
|
||||||
|
aid: videoItem.aid));
|
||||||
|
},
|
||||||
|
childCount: loadingState.response.length,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
: HttpError(
|
||||||
|
callback: _laterController.onReload,
|
||||||
),
|
),
|
||||||
delegate: SliverChildBuilderDelegate(
|
Error() => HttpError(
|
||||||
(context, index) {
|
errMsg: loadingState.errMsg,
|
||||||
var videoItem = loadingState.response[index];
|
callback: _laterController.onReload,
|
||||||
return VideoCardH(
|
),
|
||||||
videoItem: videoItem,
|
LoadingState() => throw UnimplementedError(),
|
||||||
source: 'later',
|
};
|
||||||
longPress: () => _laterController.toViewDel(context,
|
|
||||||
aid: videoItem.aid));
|
|
||||||
},
|
|
||||||
childCount: loadingState.response.length,
|
|
||||||
),
|
|
||||||
)
|
|
||||||
: loadingState is Empty
|
|
||||||
? const NoData()
|
|
||||||
: loadingState is Error
|
|
||||||
? HttpError(
|
|
||||||
errMsg: loadingState.errMsg,
|
|
||||||
fn: _laterController.onReload,
|
|
||||||
)
|
|
||||||
: SliverGrid(
|
|
||||||
gridDelegate: SliverGridDelegateWithExtentAndRatio(
|
|
||||||
mainAxisSpacing: StyleString.safeSpace,
|
|
||||||
crossAxisSpacing: StyleString.safeSpace,
|
|
||||||
maxCrossAxisExtent: Grid.maxRowWidth * 2,
|
|
||||||
childAspectRatio: StyleString.aspectRatio * 2.4,
|
|
||||||
mainAxisExtent: 0,
|
|
||||||
),
|
|
||||||
delegate: SliverChildBuilderDelegate(
|
|
||||||
(context, index) {
|
|
||||||
return const VideoCardHSkeleton();
|
|
||||||
},
|
|
||||||
childCount: 10,
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import 'package:PiliPalaX/common/constants.dart';
|
import 'package:PiliPalaX/common/constants.dart';
|
||||||
|
import 'package:PiliPalaX/common/widgets/loading_widget.dart';
|
||||||
import 'package:PiliPalaX/common/widgets/refresh_indicator.dart';
|
import 'package:PiliPalaX/common/widgets/refresh_indicator.dart';
|
||||||
import 'package:PiliPalaX/common/widgets/http_error.dart';
|
|
||||||
import 'package:PiliPalaX/common/widgets/network_img_layer.dart';
|
import 'package:PiliPalaX/common/widgets/network_img_layer.dart';
|
||||||
import 'package:PiliPalaX/http/loading_state.dart';
|
import 'package:PiliPalaX/http/loading_state.dart';
|
||||||
import 'package:PiliPalaX/models/space_article/item.dart';
|
import 'package:PiliPalaX/models/space_article/item.dart';
|
||||||
@@ -40,79 +40,75 @@ class _MemberArticleState extends State<MemberArticle>
|
|||||||
}
|
}
|
||||||
|
|
||||||
_buildBody(LoadingState loadingState) {
|
_buildBody(LoadingState loadingState) {
|
||||||
return loadingState is Success
|
return switch (loadingState) {
|
||||||
? MediaQuery.removePadding(
|
Loading() => loadingWidget,
|
||||||
context: context,
|
Success() => (loadingState.response as List?)?.isNotEmpty == true
|
||||||
removeTop: true,
|
? MediaQuery.removePadding(
|
||||||
child: refreshIndicator(
|
context: context,
|
||||||
onRefresh: () async {
|
removeTop: true,
|
||||||
await _controller.onRefresh();
|
child: refreshIndicator(
|
||||||
},
|
onRefresh: () async {
|
||||||
child: ListView.separated(
|
await _controller.onRefresh();
|
||||||
itemCount: loadingState.response.length,
|
|
||||||
itemBuilder: (_, index) {
|
|
||||||
if (index == loadingState.response.length - 1) {
|
|
||||||
_controller.onLoadMore();
|
|
||||||
}
|
|
||||||
Item item = loadingState.response[index];
|
|
||||||
return ListTile(
|
|
||||||
dense: true,
|
|
||||||
onTap: () {
|
|
||||||
PiliScheme.routePush(Uri.parse(item.uri ?? ''));
|
|
||||||
},
|
|
||||||
leading: item.originImageUrls?.isNotEmpty == true
|
|
||||||
? Container(
|
|
||||||
margin: const EdgeInsets.symmetric(vertical: 6),
|
|
||||||
child: LayoutBuilder(
|
|
||||||
builder: (_, constraints) {
|
|
||||||
return NetworkImgLayer(
|
|
||||||
radius: 6,
|
|
||||||
src: item.originImageUrls!.first,
|
|
||||||
width: constraints.maxHeight *
|
|
||||||
StyleString.aspectRatio,
|
|
||||||
height: constraints.maxHeight,
|
|
||||||
);
|
|
||||||
},
|
|
||||||
),
|
|
||||||
)
|
|
||||||
: null,
|
|
||||||
title: Text(
|
|
||||||
item.title ?? '',
|
|
||||||
style: TextStyle(
|
|
||||||
fontSize: 15,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
subtitle: item.summary?.isNotEmpty == true
|
|
||||||
? Text(
|
|
||||||
item.summary!,
|
|
||||||
maxLines: 2,
|
|
||||||
overflow: TextOverflow.ellipsis,
|
|
||||||
style: TextStyle(
|
|
||||||
fontSize: 13,
|
|
||||||
color: Theme.of(context).colorScheme.outline,
|
|
||||||
),
|
|
||||||
)
|
|
||||||
: null,
|
|
||||||
);
|
|
||||||
},
|
},
|
||||||
separatorBuilder: (_, index) => Divider(height: 1),
|
child: ListView.separated(
|
||||||
),
|
itemCount: loadingState.response.length,
|
||||||
),
|
itemBuilder: (_, index) {
|
||||||
)
|
if (index == loadingState.response.length - 1) {
|
||||||
: loadingState is Error
|
_controller.onLoadMore();
|
||||||
? Center(
|
}
|
||||||
child: CustomScrollView(
|
Item item = loadingState.response[index];
|
||||||
shrinkWrap: true,
|
return ListTile(
|
||||||
slivers: [
|
dense: true,
|
||||||
HttpError(
|
onTap: () {
|
||||||
errMsg: loadingState.errMsg,
|
PiliScheme.routePush(Uri.parse(item.uri ?? ''));
|
||||||
fn: _controller.onReload,
|
},
|
||||||
),
|
leading: item.originImageUrls?.isNotEmpty == true
|
||||||
],
|
? Container(
|
||||||
|
margin: const EdgeInsets.symmetric(vertical: 6),
|
||||||
|
child: LayoutBuilder(
|
||||||
|
builder: (_, constraints) {
|
||||||
|
return NetworkImgLayer(
|
||||||
|
radius: 6,
|
||||||
|
src: item.originImageUrls!.first,
|
||||||
|
width: constraints.maxHeight *
|
||||||
|
StyleString.aspectRatio,
|
||||||
|
height: constraints.maxHeight,
|
||||||
|
);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
)
|
||||||
|
: null,
|
||||||
|
title: Text(
|
||||||
|
item.title ?? '',
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 15,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
subtitle: item.summary?.isNotEmpty == true
|
||||||
|
? Text(
|
||||||
|
item.summary!,
|
||||||
|
maxLines: 2,
|
||||||
|
overflow: TextOverflow.ellipsis,
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 13,
|
||||||
|
color: Theme.of(context).colorScheme.outline,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
: null,
|
||||||
|
);
|
||||||
|
},
|
||||||
|
separatorBuilder: (_, index) => Divider(height: 1),
|
||||||
),
|
),
|
||||||
)
|
),
|
||||||
: Center(
|
)
|
||||||
child: CircularProgressIndicator(),
|
: errorWidget(
|
||||||
);
|
callback: _controller.onReload,
|
||||||
|
),
|
||||||
|
Error() => errorWidget(
|
||||||
|
errMsg: loadingState.errMsg,
|
||||||
|
callback: _controller.onReload,
|
||||||
|
),
|
||||||
|
LoadingState() => throw UnimplementedError(),
|
||||||
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import 'package:PiliPalaX/common/constants.dart';
|
import 'package:PiliPalaX/common/constants.dart';
|
||||||
|
import 'package:PiliPalaX/common/widgets/loading_widget.dart';
|
||||||
import 'package:PiliPalaX/common/widgets/refresh_indicator.dart';
|
import 'package:PiliPalaX/common/widgets/refresh_indicator.dart';
|
||||||
import 'package:PiliPalaX/common/widgets/http_error.dart';
|
|
||||||
import 'package:PiliPalaX/http/loading_state.dart';
|
import 'package:PiliPalaX/http/loading_state.dart';
|
||||||
import 'package:PiliPalaX/pages/bangumi/widgets/bangumi_card_v_member_home.dart';
|
import 'package:PiliPalaX/pages/bangumi/widgets/bangumi_card_v_member_home.dart';
|
||||||
import 'package:PiliPalaX/pages/member/new/content/member_contribute/content/bangumi/member_bangumi_ctr.dart';
|
import 'package:PiliPalaX/pages/member/new/content/member_contribute/content/bangumi/member_bangumi_ctr.dart';
|
||||||
@@ -42,60 +42,56 @@ class _MemberBangumiState extends State<MemberBangumi>
|
|||||||
}
|
}
|
||||||
|
|
||||||
_buildBody(LoadingState loadingState) {
|
_buildBody(LoadingState loadingState) {
|
||||||
return loadingState is Success
|
return switch (loadingState) {
|
||||||
? refreshIndicator(
|
Loading() => loadingWidget,
|
||||||
onRefresh: () async {
|
Success() => (loadingState.response as List?)?.isNotEmpty == true
|
||||||
await _controller.onRefresh();
|
? refreshIndicator(
|
||||||
},
|
onRefresh: () async {
|
||||||
child: CustomScrollView(
|
await _controller.onRefresh();
|
||||||
slivers: [
|
},
|
||||||
SliverPadding(
|
child: CustomScrollView(
|
||||||
padding: EdgeInsets.only(
|
slivers: [
|
||||||
left: StyleString.safeSpace,
|
SliverPadding(
|
||||||
right: StyleString.safeSpace,
|
padding: EdgeInsets.only(
|
||||||
top: StyleString.safeSpace,
|
left: StyleString.safeSpace,
|
||||||
bottom: StyleString.safeSpace +
|
right: StyleString.safeSpace,
|
||||||
MediaQuery.of(context).padding.bottom,
|
top: StyleString.safeSpace,
|
||||||
),
|
bottom: StyleString.safeSpace +
|
||||||
sliver: SliverGrid(
|
MediaQuery.of(context).padding.bottom,
|
||||||
gridDelegate: SliverGridDelegateWithExtentAndRatio(
|
|
||||||
mainAxisSpacing: StyleString.cardSpace - 2,
|
|
||||||
crossAxisSpacing: StyleString.cardSpace,
|
|
||||||
maxCrossAxisExtent: Grid.maxRowWidth / 3 * 2,
|
|
||||||
childAspectRatio: 0.65,
|
|
||||||
mainAxisExtent:
|
|
||||||
MediaQuery.textScalerOf(context).scale(60),
|
|
||||||
),
|
),
|
||||||
delegate: SliverChildBuilderDelegate(
|
sliver: SliverGrid(
|
||||||
(context, index) {
|
gridDelegate: SliverGridDelegateWithExtentAndRatio(
|
||||||
if (index == loadingState.response.length - 1) {
|
mainAxisSpacing: StyleString.cardSpace - 2,
|
||||||
_controller.onLoadMore();
|
crossAxisSpacing: StyleString.cardSpace,
|
||||||
}
|
maxCrossAxisExtent: Grid.maxRowWidth / 3 * 2,
|
||||||
return BangumiCardVMemberHome(
|
childAspectRatio: 0.65,
|
||||||
bangumiItem: loadingState.response[index],
|
mainAxisExtent:
|
||||||
);
|
MediaQuery.textScalerOf(context).scale(60),
|
||||||
},
|
),
|
||||||
childCount: loadingState.response.length,
|
delegate: SliverChildBuilderDelegate(
|
||||||
|
(context, index) {
|
||||||
|
if (index == loadingState.response.length - 1) {
|
||||||
|
_controller.onLoadMore();
|
||||||
|
}
|
||||||
|
return BangumiCardVMemberHome(
|
||||||
|
bangumiItem: loadingState.response[index],
|
||||||
|
);
|
||||||
|
},
|
||||||
|
childCount: loadingState.response.length,
|
||||||
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
],
|
||||||
],
|
),
|
||||||
|
)
|
||||||
|
: errorWidget(
|
||||||
|
callback: _controller.onReload,
|
||||||
),
|
),
|
||||||
)
|
Error() => errorWidget(
|
||||||
: loadingState is Error
|
errMsg: loadingState.errMsg,
|
||||||
? Center(
|
callback: _controller.onReload,
|
||||||
child: CustomScrollView(
|
),
|
||||||
shrinkWrap: true,
|
LoadingState() => throw UnimplementedError(),
|
||||||
slivers: [
|
};
|
||||||
HttpError(
|
|
||||||
errMsg: loadingState.errMsg,
|
|
||||||
fn: _controller.onReload,
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
)
|
|
||||||
: Center(
|
|
||||||
child: CircularProgressIndicator(),
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import 'package:PiliPalaX/common/constants.dart';
|
import 'package:PiliPalaX/common/constants.dart';
|
||||||
import 'package:PiliPalaX/common/widgets/badge.dart';
|
import 'package:PiliPalaX/common/widgets/badge.dart';
|
||||||
|
import 'package:PiliPalaX/common/widgets/loading_widget.dart';
|
||||||
import 'package:PiliPalaX/common/widgets/refresh_indicator.dart';
|
import 'package:PiliPalaX/common/widgets/refresh_indicator.dart';
|
||||||
import 'package:PiliPalaX/common/widgets/http_error.dart';
|
|
||||||
import 'package:PiliPalaX/common/widgets/network_img_layer.dart';
|
import 'package:PiliPalaX/common/widgets/network_img_layer.dart';
|
||||||
import 'package:PiliPalaX/http/loading_state.dart';
|
import 'package:PiliPalaX/http/loading_state.dart';
|
||||||
import 'package:PiliPalaX/models/space_fav/datum.dart';
|
import 'package:PiliPalaX/models/space_fav/datum.dart';
|
||||||
@@ -44,54 +44,50 @@ class _MemberFavoriteState extends State<MemberFavorite>
|
|||||||
}
|
}
|
||||||
|
|
||||||
_buildBody(LoadingState loadingState) {
|
_buildBody(LoadingState loadingState) {
|
||||||
return loadingState is Success
|
return switch (loadingState) {
|
||||||
? refreshIndicator(
|
Loading() => loadingWidget,
|
||||||
onRefresh: () async {
|
Success() => (loadingState.response as List?)?.isNotEmpty == true
|
||||||
await _controller.onRefresh();
|
? refreshIndicator(
|
||||||
},
|
onRefresh: () async {
|
||||||
child: CustomScrollView(
|
await _controller.onRefresh();
|
||||||
slivers: [
|
},
|
||||||
SliverToBoxAdapter(
|
child: CustomScrollView(
|
||||||
child: Obx(
|
slivers: [
|
||||||
() => _controller.first.value.mediaListResponse?.list
|
SliverToBoxAdapter(
|
||||||
?.isNotEmpty ==
|
child: Obx(
|
||||||
true
|
() => _controller.first.value.mediaListResponse?.list
|
||||||
? _buildItem(_controller.first.value, true)
|
?.isNotEmpty ==
|
||||||
: const SizedBox.shrink(),
|
true
|
||||||
),
|
? _buildItem(_controller.first.value, true)
|
||||||
),
|
: const SizedBox.shrink(),
|
||||||
SliverToBoxAdapter(
|
|
||||||
child: Obx(
|
|
||||||
() => _controller.second.value.mediaListResponse?.list
|
|
||||||
?.isNotEmpty ==
|
|
||||||
true
|
|
||||||
? _buildItem(_controller.second.value, false)
|
|
||||||
: const SizedBox.shrink(),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
SliverToBoxAdapter(
|
|
||||||
child: SizedBox(
|
|
||||||
height: 12 + MediaQuery.of(context).padding.bottom,
|
|
||||||
),
|
|
||||||
)
|
|
||||||
],
|
|
||||||
),
|
|
||||||
)
|
|
||||||
: loadingState is Error
|
|
||||||
? Center(
|
|
||||||
child: CustomScrollView(
|
|
||||||
shrinkWrap: true,
|
|
||||||
slivers: [
|
|
||||||
HttpError(
|
|
||||||
errMsg: loadingState.errMsg,
|
|
||||||
fn: _controller.onReload,
|
|
||||||
),
|
),
|
||||||
],
|
),
|
||||||
),
|
SliverToBoxAdapter(
|
||||||
)
|
child: Obx(
|
||||||
: Center(
|
() => _controller.second.value.mediaListResponse?.list
|
||||||
child: CircularProgressIndicator(),
|
?.isNotEmpty ==
|
||||||
);
|
true
|
||||||
|
? _buildItem(_controller.second.value, false)
|
||||||
|
: const SizedBox.shrink(),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
SliverToBoxAdapter(
|
||||||
|
child: SizedBox(
|
||||||
|
height: 12 + MediaQuery.of(context).padding.bottom,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
],
|
||||||
|
),
|
||||||
|
)
|
||||||
|
: errorWidget(
|
||||||
|
callback: _controller.onReload,
|
||||||
|
),
|
||||||
|
Error() => errorWidget(
|
||||||
|
errMsg: loadingState.errMsg,
|
||||||
|
callback: _controller.onReload,
|
||||||
|
),
|
||||||
|
LoadingState() => throw UnimplementedError(),
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
_buildItem(Datum data, bool isFirst) {
|
_buildItem(Datum data, bool isFirst) {
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import 'package:PiliPalaX/common/constants.dart';
|
import 'package:PiliPalaX/common/constants.dart';
|
||||||
|
import 'package:PiliPalaX/common/widgets/loading_widget.dart';
|
||||||
import 'package:PiliPalaX/common/widgets/refresh_indicator.dart';
|
import 'package:PiliPalaX/common/widgets/refresh_indicator.dart';
|
||||||
import 'package:PiliPalaX/common/widgets/http_error.dart';
|
|
||||||
import 'package:PiliPalaX/common/widgets/video_card_h_member_video.dart';
|
import 'package:PiliPalaX/common/widgets/video_card_h_member_video.dart';
|
||||||
import 'package:PiliPalaX/http/loading_state.dart';
|
import 'package:PiliPalaX/http/loading_state.dart';
|
||||||
import 'package:PiliPalaX/pages/member/new/content/member_contribute/content/video/member_video_ctr.dart';
|
import 'package:PiliPalaX/pages/member/new/content/member_contribute/content/video/member_video_ctr.dart';
|
||||||
@@ -54,106 +54,100 @@ class _MemberVideoState extends State<MemberVideo>
|
|||||||
}
|
}
|
||||||
|
|
||||||
_buildBody(LoadingState loadingState) {
|
_buildBody(LoadingState loadingState) {
|
||||||
return loadingState is Success && loadingState.response is List
|
return switch (loadingState) {
|
||||||
? refreshIndicator(
|
Loading() => loadingWidget,
|
||||||
onRefresh: () async {
|
Success() => (loadingState.response as List?)?.isNotEmpty == true
|
||||||
await _controller.onRefresh();
|
? refreshIndicator(
|
||||||
},
|
onRefresh: () async {
|
||||||
child: CustomScrollView(
|
await _controller.onRefresh();
|
||||||
slivers: [
|
},
|
||||||
SliverPersistentHeader(
|
child: CustomScrollView(
|
||||||
pinned: false,
|
slivers: [
|
||||||
floating: true,
|
SliverPersistentHeader(
|
||||||
delegate: MySliverPersistentHeaderDelegate(
|
pinned: false,
|
||||||
child: Container(
|
floating: true,
|
||||||
height: 40,
|
delegate: MySliverPersistentHeaderDelegate(
|
||||||
padding: const EdgeInsets.fromLTRB(12, 0, 6, 0),
|
child: Container(
|
||||||
color: Theme.of(context).colorScheme.surface,
|
height: 40,
|
||||||
child: Row(
|
padding: const EdgeInsets.fromLTRB(12, 0, 6, 0),
|
||||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
color: Theme.of(context).colorScheme.surface,
|
||||||
children: [
|
child: Row(
|
||||||
Obx(
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||||
() => Text(
|
children: [
|
||||||
_controller.count.value != -1
|
Obx(
|
||||||
? '共${_controller.count.value}视频'
|
() => Text(
|
||||||
: '',
|
_controller.count.value != -1
|
||||||
style: const TextStyle(fontSize: 13),
|
? '共${_controller.count.value}视频'
|
||||||
),
|
: '',
|
||||||
),
|
style: const TextStyle(fontSize: 13),
|
||||||
SizedBox(
|
|
||||||
height: 35,
|
|
||||||
child: TextButton.icon(
|
|
||||||
onPressed: _controller.queryBySort,
|
|
||||||
icon: const Icon(Icons.sort, size: 16),
|
|
||||||
label: Obx(
|
|
||||||
() => Text(
|
|
||||||
widget.type == ContributeType.video
|
|
||||||
? _controller.order.value == 'pubdate'
|
|
||||||
? '最新发布'
|
|
||||||
: '最多播放'
|
|
||||||
: _controller.sort.value == 'desc'
|
|
||||||
? '默认'
|
|
||||||
: '倒序',
|
|
||||||
style: const TextStyle(fontSize: 13),
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
)
|
SizedBox(
|
||||||
],
|
height: 35,
|
||||||
|
child: TextButton.icon(
|
||||||
|
onPressed: _controller.queryBySort,
|
||||||
|
icon: const Icon(Icons.sort, size: 16),
|
||||||
|
label: Obx(
|
||||||
|
() => Text(
|
||||||
|
widget.type == ContributeType.video
|
||||||
|
? _controller.order.value == 'pubdate'
|
||||||
|
? '最新发布'
|
||||||
|
: '最多播放'
|
||||||
|
: _controller.sort.value == 'desc'
|
||||||
|
? '默认'
|
||||||
|
: '倒序',
|
||||||
|
style: const TextStyle(fontSize: 13),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
],
|
||||||
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
SliverPadding(
|
||||||
SliverPadding(
|
// 单列布局 EdgeInsets.zero
|
||||||
// 单列布局 EdgeInsets.zero
|
padding: EdgeInsets.fromLTRB(
|
||||||
padding: EdgeInsets.fromLTRB(
|
StyleString.safeSpace,
|
||||||
StyleString.safeSpace,
|
StyleString.safeSpace - 5,
|
||||||
StyleString.safeSpace - 5,
|
StyleString.safeSpace,
|
||||||
StyleString.safeSpace,
|
MediaQuery.of(context).padding.bottom + 10,
|
||||||
MediaQuery.of(context).padding.bottom + 10,
|
|
||||||
),
|
|
||||||
sliver: SliverGrid(
|
|
||||||
gridDelegate: SliverGridDelegateWithExtentAndRatio(
|
|
||||||
mainAxisSpacing: StyleString.safeSpace,
|
|
||||||
crossAxisSpacing: StyleString.safeSpace,
|
|
||||||
maxCrossAxisExtent: Grid.maxRowWidth * 2,
|
|
||||||
childAspectRatio: StyleString.aspectRatio * 2.4,
|
|
||||||
mainAxisExtent: 0,
|
|
||||||
),
|
),
|
||||||
delegate: SliverChildBuilderDelegate(
|
sliver: SliverGrid(
|
||||||
(context, index) {
|
gridDelegate: SliverGridDelegateWithExtentAndRatio(
|
||||||
if (widget.type != ContributeType.season &&
|
mainAxisSpacing: StyleString.safeSpace,
|
||||||
index == loadingState.response.length - 1) {
|
crossAxisSpacing: StyleString.safeSpace,
|
||||||
_controller.onLoadMore();
|
maxCrossAxisExtent: Grid.maxRowWidth * 2,
|
||||||
}
|
childAspectRatio: StyleString.aspectRatio * 2.4,
|
||||||
return VideoCardHMemberVideo(
|
mainAxisExtent: 0,
|
||||||
videoItem: loadingState.response[index],
|
),
|
||||||
showPubdate: true,
|
delegate: SliverChildBuilderDelegate(
|
||||||
);
|
(context, index) {
|
||||||
},
|
if (widget.type != ContributeType.season &&
|
||||||
childCount: loadingState.response.length,
|
index == loadingState.response.length - 1) {
|
||||||
|
_controller.onLoadMore();
|
||||||
|
}
|
||||||
|
return VideoCardHMemberVideo(
|
||||||
|
videoItem: loadingState.response[index],
|
||||||
|
showPubdate: true,
|
||||||
|
);
|
||||||
|
},
|
||||||
|
childCount: loadingState.response.length,
|
||||||
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
],
|
||||||
],
|
),
|
||||||
|
)
|
||||||
|
: errorWidget(
|
||||||
|
callback: _controller.onReload,
|
||||||
),
|
),
|
||||||
)
|
Error() => errorWidget(
|
||||||
: loadingState is Loading
|
errMsg: loadingState.errMsg,
|
||||||
? Center(
|
callback: _controller.onReload,
|
||||||
child: CircularProgressIndicator(),
|
),
|
||||||
)
|
LoadingState() => throw UnimplementedError(),
|
||||||
: Center(
|
};
|
||||||
child: CustomScrollView(
|
|
||||||
shrinkWrap: true,
|
|
||||||
slivers: [
|
|
||||||
HttpError(
|
|
||||||
errMsg: loadingState is Error
|
|
||||||
? (loadingState as Error?)?.errMsg
|
|
||||||
: 'EMPTY',
|
|
||||||
fn: _controller.onReload,
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
|
import 'package:PiliPalaX/common/widgets/loading_widget.dart';
|
||||||
import 'package:PiliPalaX/common/widgets/refresh_indicator.dart';
|
import 'package:PiliPalaX/common/widgets/refresh_indicator.dart';
|
||||||
import 'package:PiliPalaX/common/widgets/http_error.dart';
|
|
||||||
import 'package:PiliPalaX/http/loading_state.dart';
|
import 'package:PiliPalaX/http/loading_state.dart';
|
||||||
import 'package:PiliPalaX/pages/dynamics/widgets/dynamic_panel_grpc.dart';
|
import 'package:PiliPalaX/pages/dynamics/widgets/dynamic_panel_grpc.dart';
|
||||||
import 'package:PiliPalaX/pages/member/new/content/member_dynamic/member_dynamic_ctr.dart';
|
import 'package:PiliPalaX/pages/member/new/content/member_dynamic/member_dynamic_ctr.dart';
|
||||||
@@ -32,38 +32,34 @@ class _MemberDynamicState extends State<MemberDynamic>
|
|||||||
}
|
}
|
||||||
|
|
||||||
_buildBody(LoadingState loadingState) {
|
_buildBody(LoadingState loadingState) {
|
||||||
return loadingState is Success
|
return switch (loadingState) {
|
||||||
? refreshIndicator(
|
Loading() => loadingWidget,
|
||||||
onRefresh: () async {
|
Success() => (loadingState.response as List?)?.isNotEmpty == true
|
||||||
await _controller.onRefresh();
|
? refreshIndicator(
|
||||||
},
|
onRefresh: () async {
|
||||||
child: ListView.separated(
|
await _controller.onRefresh();
|
||||||
itemCount: loadingState.response.length,
|
|
||||||
itemBuilder: (_, index) {
|
|
||||||
if (index == loadingState.response.length - 1) {
|
|
||||||
_controller.onLoadMore();
|
|
||||||
}
|
|
||||||
return DynamicPanelGrpc(
|
|
||||||
item: loadingState.response[index],
|
|
||||||
);
|
|
||||||
},
|
},
|
||||||
separatorBuilder: (_, index) => const SizedBox(height: 10),
|
child: ListView.separated(
|
||||||
|
itemCount: loadingState.response.length,
|
||||||
|
itemBuilder: (_, index) {
|
||||||
|
if (index == loadingState.response.length - 1) {
|
||||||
|
_controller.onLoadMore();
|
||||||
|
}
|
||||||
|
return DynamicPanelGrpc(
|
||||||
|
item: loadingState.response[index],
|
||||||
|
);
|
||||||
|
},
|
||||||
|
separatorBuilder: (_, index) => const SizedBox(height: 10),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
: errorWidget(
|
||||||
|
callback: _controller.onReload,
|
||||||
),
|
),
|
||||||
)
|
Error() => errorWidget(
|
||||||
: loadingState is Error
|
errMsg: loadingState.errMsg,
|
||||||
? Center(
|
callback: _controller.onReload,
|
||||||
child: CustomScrollView(
|
),
|
||||||
shrinkWrap: true,
|
LoadingState() => throw UnimplementedError(),
|
||||||
slivers: [
|
};
|
||||||
HttpError(
|
|
||||||
errMsg: loadingState.errMsg,
|
|
||||||
fn: _controller.onReload,
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
)
|
|
||||||
: Center(
|
|
||||||
child: CircularProgressIndicator(),
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
import 'dart:math';
|
import 'dart:math';
|
||||||
|
|
||||||
import 'package:PiliPalaX/common/constants.dart';
|
import 'package:PiliPalaX/common/constants.dart';
|
||||||
|
import 'package:PiliPalaX/common/widgets/loading_widget.dart';
|
||||||
import 'package:PiliPalaX/common/widgets/network_img_layer.dart';
|
import 'package:PiliPalaX/common/widgets/network_img_layer.dart';
|
||||||
import 'package:PiliPalaX/common/widgets/video_card_v_member_home.dart';
|
import 'package:PiliPalaX/common/widgets/video_card_v_member_home.dart';
|
||||||
import 'package:PiliPalaX/http/loading_state.dart';
|
import 'package:PiliPalaX/http/loading_state.dart';
|
||||||
@@ -39,171 +40,183 @@ class _MemberHomeState extends State<MemberHome>
|
|||||||
}
|
}
|
||||||
|
|
||||||
Widget _buildBody(LoadingState loadingState) {
|
Widget _buildBody(LoadingState loadingState) {
|
||||||
return loadingState is Success && loadingState.response is Data
|
return switch (loadingState) {
|
||||||
? CustomScrollView(
|
Loading() => loadingWidget,
|
||||||
slivers: [
|
Success() => loadingState.response is Data
|
||||||
if (loadingState.response?.archive?.item?.isNotEmpty == true) ...[
|
? CustomScrollView(
|
||||||
_videoHeader(
|
slivers: [
|
||||||
title: '视频',
|
if (loadingState.response?.archive?.item?.isNotEmpty ==
|
||||||
param: 'contribute',
|
true) ...[
|
||||||
param1: 'video',
|
_videoHeader(
|
||||||
count: loadingState.response.archive.count,
|
title: '视频',
|
||||||
),
|
param: 'contribute',
|
||||||
SliverPadding(
|
param1: 'video',
|
||||||
padding: const EdgeInsets.symmetric(
|
count: loadingState.response.archive.count,
|
||||||
horizontal: StyleString.safeSpace,
|
|
||||||
),
|
),
|
||||||
sliver: SliverGrid(
|
SliverPadding(
|
||||||
gridDelegate: SliverGridDelegateWithExtentAndRatio(
|
padding: const EdgeInsets.symmetric(
|
||||||
mainAxisSpacing: StyleString.cardSpace,
|
horizontal: StyleString.safeSpace,
|
||||||
crossAxisSpacing: StyleString.cardSpace,
|
|
||||||
maxCrossAxisExtent: Grid.maxRowWidth,
|
|
||||||
childAspectRatio: StyleString.aspectRatio,
|
|
||||||
mainAxisExtent:
|
|
||||||
MediaQuery.textScalerOf(context).scale(90),
|
|
||||||
),
|
),
|
||||||
delegate: SliverChildBuilderDelegate(
|
sliver: SliverGrid(
|
||||||
(context, index) {
|
gridDelegate: SliverGridDelegateWithExtentAndRatio(
|
||||||
return VideoCardVMemberHome(
|
mainAxisSpacing: StyleString.cardSpace,
|
||||||
videoItem: loadingState.response.archive.item[index],
|
crossAxisSpacing: StyleString.cardSpace,
|
||||||
);
|
maxCrossAxisExtent: Grid.maxRowWidth,
|
||||||
},
|
childAspectRatio: StyleString.aspectRatio,
|
||||||
childCount:
|
mainAxisExtent:
|
||||||
min(4, loadingState.response.archive.item.length),
|
MediaQuery.textScalerOf(context).scale(90),
|
||||||
),
|
),
|
||||||
),
|
delegate: SliverChildBuilderDelegate(
|
||||||
),
|
(context, index) {
|
||||||
],
|
return VideoCardVMemberHome(
|
||||||
if (loadingState.response?.favourite2?.item?.isNotEmpty ==
|
videoItem:
|
||||||
true) ...[
|
loadingState.response.archive.item[index],
|
||||||
_videoHeader(
|
);
|
||||||
title: '收藏',
|
},
|
||||||
param: 'favorite',
|
childCount:
|
||||||
count: loadingState.response.favourite2.count,
|
min(4, loadingState.response.archive.item.length),
|
||||||
),
|
|
||||||
// TODO
|
|
||||||
],
|
|
||||||
if (loadingState.response?.coinArchive?.item?.isNotEmpty ==
|
|
||||||
true) ...[
|
|
||||||
_videoHeader(
|
|
||||||
title: '最近投币的视频',
|
|
||||||
param: 'coinArchive',
|
|
||||||
count: loadingState.response.coinArchive.count,
|
|
||||||
),
|
|
||||||
// TODO
|
|
||||||
],
|
|
||||||
if (loadingState.response?.likeArchive?.item?.isNotEmpty ==
|
|
||||||
true) ...[
|
|
||||||
_videoHeader(
|
|
||||||
title: '最近点赞的视频',
|
|
||||||
param: 'likeArchive',
|
|
||||||
count: loadingState.response.likeArchive.count,
|
|
||||||
),
|
|
||||||
// TODO
|
|
||||||
],
|
|
||||||
if (loadingState.response?.article?.item?.isNotEmpty == true) ...[
|
|
||||||
_videoHeader(
|
|
||||||
title: '专栏',
|
|
||||||
param: 'contribute',
|
|
||||||
param1: 'article',
|
|
||||||
count: loadingState.response.article.count,
|
|
||||||
),
|
|
||||||
SliverToBoxAdapter(
|
|
||||||
child: ListTile(
|
|
||||||
dense: true,
|
|
||||||
onTap: () {
|
|
||||||
PiliScheme.routePush(Uri.parse(
|
|
||||||
loadingState.response.article.item.first.uri ?? ''));
|
|
||||||
},
|
|
||||||
leading: loadingState.response.article.item.first
|
|
||||||
.originImageUrls?.isNotEmpty ==
|
|
||||||
true
|
|
||||||
? Container(
|
|
||||||
margin: const EdgeInsets.symmetric(vertical: 6),
|
|
||||||
child: LayoutBuilder(
|
|
||||||
builder: (_, constraints) {
|
|
||||||
return NetworkImgLayer(
|
|
||||||
radius: 6,
|
|
||||||
src: loadingState.response.article.item.first
|
|
||||||
.originImageUrls!.first,
|
|
||||||
width: constraints.maxHeight *
|
|
||||||
StyleString.aspectRatio,
|
|
||||||
height: constraints.maxHeight,
|
|
||||||
);
|
|
||||||
},
|
|
||||||
),
|
|
||||||
)
|
|
||||||
: null,
|
|
||||||
title: Text(
|
|
||||||
loadingState.response.article.item.first.title ?? '',
|
|
||||||
style: TextStyle(
|
|
||||||
fontSize: 15,
|
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
subtitle: loadingState.response.article.item.first.summary
|
|
||||||
?.isNotEmpty ==
|
|
||||||
true
|
|
||||||
? Text(
|
|
||||||
loadingState.response.article.item.first.summary!,
|
|
||||||
maxLines: 2,
|
|
||||||
overflow: TextOverflow.ellipsis,
|
|
||||||
style: TextStyle(
|
|
||||||
fontSize: 13,
|
|
||||||
color: Theme.of(context).colorScheme.outline,
|
|
||||||
),
|
|
||||||
)
|
|
||||||
: null,
|
|
||||||
),
|
),
|
||||||
),
|
],
|
||||||
],
|
if (loadingState.response?.favourite2?.item?.isNotEmpty ==
|
||||||
if (loadingState.response?.audios?.item?.isNotEmpty == true) ...[
|
true) ...[
|
||||||
_videoHeader(
|
_videoHeader(
|
||||||
title: '音频',
|
title: '收藏',
|
||||||
param: 'contribute',
|
param: 'favorite',
|
||||||
param1: 'audio',
|
count: loadingState.response.favourite2.count,
|
||||||
count: loadingState.response.audios.count,
|
|
||||||
),
|
|
||||||
// TODO
|
|
||||||
],
|
|
||||||
if (loadingState.response?.season?.item?.isNotEmpty == true) ...[
|
|
||||||
_videoHeader(
|
|
||||||
title: '追番',
|
|
||||||
param: 'bangumi',
|
|
||||||
count: loadingState.response.season.count,
|
|
||||||
),
|
|
||||||
SliverPadding(
|
|
||||||
padding: const EdgeInsets.symmetric(
|
|
||||||
horizontal: StyleString.safeSpace,
|
|
||||||
),
|
),
|
||||||
sliver: SliverGrid(
|
// TODO
|
||||||
gridDelegate: SliverGridDelegateWithExtentAndRatio(
|
],
|
||||||
mainAxisSpacing: StyleString.cardSpace - 2,
|
if (loadingState.response?.coinArchive?.item?.isNotEmpty ==
|
||||||
crossAxisSpacing: StyleString.cardSpace,
|
true) ...[
|
||||||
maxCrossAxisExtent: Grid.maxRowWidth / 3 * 2,
|
_videoHeader(
|
||||||
childAspectRatio: 0.65,
|
title: '最近投币的视频',
|
||||||
mainAxisExtent:
|
param: 'coinArchive',
|
||||||
MediaQuery.textScalerOf(context).scale(60),
|
count: loadingState.response.coinArchive.count,
|
||||||
),
|
),
|
||||||
delegate: SliverChildBuilderDelegate(
|
// TODO
|
||||||
(context, index) {
|
],
|
||||||
return BangumiCardVMemberHome(
|
if (loadingState.response?.likeArchive?.item?.isNotEmpty ==
|
||||||
bangumiItem: loadingState.response.season.item[index],
|
true) ...[
|
||||||
);
|
_videoHeader(
|
||||||
|
title: '最近点赞的视频',
|
||||||
|
param: 'likeArchive',
|
||||||
|
count: loadingState.response.likeArchive.count,
|
||||||
|
),
|
||||||
|
// TODO
|
||||||
|
],
|
||||||
|
if (loadingState.response?.article?.item?.isNotEmpty ==
|
||||||
|
true) ...[
|
||||||
|
_videoHeader(
|
||||||
|
title: '专栏',
|
||||||
|
param: 'contribute',
|
||||||
|
param1: 'article',
|
||||||
|
count: loadingState.response.article.count,
|
||||||
|
),
|
||||||
|
SliverToBoxAdapter(
|
||||||
|
child: ListTile(
|
||||||
|
dense: true,
|
||||||
|
onTap: () {
|
||||||
|
PiliScheme.routePush(Uri.parse(
|
||||||
|
loadingState.response.article.item.first.uri ??
|
||||||
|
''));
|
||||||
},
|
},
|
||||||
childCount:
|
leading: loadingState.response.article.item.first
|
||||||
min(3, loadingState.response.season.item.length),
|
.originImageUrls?.isNotEmpty ==
|
||||||
|
true
|
||||||
|
? Container(
|
||||||
|
margin: const EdgeInsets.symmetric(vertical: 6),
|
||||||
|
child: LayoutBuilder(
|
||||||
|
builder: (_, constraints) {
|
||||||
|
return NetworkImgLayer(
|
||||||
|
radius: 6,
|
||||||
|
src: loadingState.response.article.item
|
||||||
|
.first.originImageUrls!.first,
|
||||||
|
width: constraints.maxHeight *
|
||||||
|
StyleString.aspectRatio,
|
||||||
|
height: constraints.maxHeight,
|
||||||
|
);
|
||||||
|
},
|
||||||
|
),
|
||||||
|
)
|
||||||
|
: null,
|
||||||
|
title: Text(
|
||||||
|
loadingState.response.article.item.first.title ?? '',
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 15,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
subtitle: loadingState.response.article.item.first.summary
|
||||||
|
?.isNotEmpty ==
|
||||||
|
true
|
||||||
|
? Text(
|
||||||
|
loadingState.response.article.item.first.summary!,
|
||||||
|
maxLines: 2,
|
||||||
|
overflow: TextOverflow.ellipsis,
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 13,
|
||||||
|
color: Theme.of(context).colorScheme.outline,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
: null,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
],
|
||||||
|
if (loadingState.response?.audios?.item?.isNotEmpty ==
|
||||||
|
true) ...[
|
||||||
|
_videoHeader(
|
||||||
|
title: '音频',
|
||||||
|
param: 'contribute',
|
||||||
|
param1: 'audio',
|
||||||
|
count: loadingState.response.audios.count,
|
||||||
|
),
|
||||||
|
// TODO
|
||||||
|
],
|
||||||
|
if (loadingState.response?.season?.item?.isNotEmpty ==
|
||||||
|
true) ...[
|
||||||
|
_videoHeader(
|
||||||
|
title: '追番',
|
||||||
|
param: 'bangumi',
|
||||||
|
count: loadingState.response.season.count,
|
||||||
|
),
|
||||||
|
SliverPadding(
|
||||||
|
padding: const EdgeInsets.symmetric(
|
||||||
|
horizontal: StyleString.safeSpace,
|
||||||
|
),
|
||||||
|
sliver: SliverGrid(
|
||||||
|
gridDelegate: SliverGridDelegateWithExtentAndRatio(
|
||||||
|
mainAxisSpacing: StyleString.cardSpace - 2,
|
||||||
|
crossAxisSpacing: StyleString.cardSpace,
|
||||||
|
maxCrossAxisExtent: Grid.maxRowWidth / 3 * 2,
|
||||||
|
childAspectRatio: 0.65,
|
||||||
|
mainAxisExtent:
|
||||||
|
MediaQuery.textScalerOf(context).scale(60),
|
||||||
|
),
|
||||||
|
delegate: SliverChildBuilderDelegate(
|
||||||
|
(context, index) {
|
||||||
|
return BangumiCardVMemberHome(
|
||||||
|
bangumiItem:
|
||||||
|
loadingState.response.season.item[index],
|
||||||
|
);
|
||||||
|
},
|
||||||
|
childCount:
|
||||||
|
min(3, loadingState.response.season.item.length),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
SliverToBoxAdapter(
|
||||||
|
child: SizedBox(
|
||||||
|
height: 12 + MediaQuery.of(context).padding.bottom,
|
||||||
|
),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
SliverToBoxAdapter(
|
)
|
||||||
child: SizedBox(
|
: errorWidget(),
|
||||||
height: 12 + MediaQuery.of(context).padding.bottom,
|
Error() => errorWidget(),
|
||||||
),
|
LoadingState() => throw UnimplementedError(),
|
||||||
),
|
};
|
||||||
],
|
|
||||||
)
|
|
||||||
: const SizedBox.shrink();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Widget _videoHeader({
|
Widget _videoHeader({
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import 'dart:math';
|
import 'dart:math';
|
||||||
|
|
||||||
import 'package:PiliPalaX/common/widgets/dynamic_sliver_appbar.dart';
|
import 'package:PiliPalaX/common/widgets/dynamic_sliver_appbar.dart';
|
||||||
import 'package:PiliPalaX/common/widgets/http_error.dart';
|
import 'package:PiliPalaX/common/widgets/loading_widget.dart';
|
||||||
import 'package:PiliPalaX/http/loading_state.dart';
|
import 'package:PiliPalaX/http/loading_state.dart';
|
||||||
import 'package:PiliPalaX/pages/member/new/content/member_contribute/content/bangumi/member_bangumi.dart';
|
import 'package:PiliPalaX/pages/member/new/content/member_contribute/content/bangumi/member_bangumi.dart';
|
||||||
import 'package:PiliPalaX/pages/member/new/content/member_contribute/content/favorite/member_favorite.dart';
|
import 'package:PiliPalaX/pages/member/new/content/member_contribute/content/favorite/member_favorite.dart';
|
||||||
@@ -291,28 +291,19 @@ class _MemberPageNewState extends State<MemberPageNew>
|
|||||||
);
|
);
|
||||||
|
|
||||||
Widget _errorWidget(msg) {
|
Widget _errorWidget(msg) {
|
||||||
return CustomScrollView(
|
return errorWidget(
|
||||||
shrinkWrap: true,
|
errMsg: msg,
|
||||||
slivers: [
|
callback: () {
|
||||||
HttpError(
|
_userController.loadingState.value = LoadingState.loading();
|
||||||
errMsg: msg,
|
_userController.onRefresh();
|
||||||
fn: () {
|
},
|
||||||
_userController.loadingState.value = LoadingState.loading();
|
|
||||||
_userController.onRefresh();
|
|
||||||
},
|
|
||||||
)
|
|
||||||
],
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
Widget _buildUserInfo(LoadingState userState, [bool isV = true]) {
|
Widget _buildUserInfo(LoadingState userState, [bool isV = true]) {
|
||||||
switch (userState) {
|
return switch (userState) {
|
||||||
case Empty():
|
Loading() => const CircularProgressIndicator(),
|
||||||
return _errorWidget('EMPTY');
|
Success() => Obx(
|
||||||
case Error():
|
|
||||||
return _errorWidget(userState.errMsg);
|
|
||||||
case Success():
|
|
||||||
return Obx(
|
|
||||||
() => Padding(
|
() => Padding(
|
||||||
padding: EdgeInsets.only(
|
padding: EdgeInsets.only(
|
||||||
bottom: (_userController.tab2?.length ?? 0) > 1 ? 48 : 0),
|
bottom: (_userController.tab2?.length ?? 0) > 1 ? 48 : 0),
|
||||||
@@ -326,8 +317,9 @@ class _MemberPageNewState extends State<MemberPageNew>
|
|||||||
onFollow: () => _userController.onFollow(context),
|
onFollow: () => _userController.onFollow(context),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
);
|
),
|
||||||
}
|
Error() => _errorWidget(userState.errMsg),
|
||||||
return const CircularProgressIndicator();
|
LoadingState() => throw UnimplementedError(),
|
||||||
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import 'package:PiliPalaX/common/constants.dart';
|
import 'package:PiliPalaX/common/constants.dart';
|
||||||
import 'package:PiliPalaX/common/widgets/http_error.dart';
|
import 'package:PiliPalaX/common/widgets/loading_widget.dart';
|
||||||
import 'package:PiliPalaX/http/constants.dart';
|
import 'package:PiliPalaX/http/constants.dart';
|
||||||
import 'package:PiliPalaX/http/index.dart';
|
import 'package:PiliPalaX/http/index.dart';
|
||||||
import 'package:PiliPalaX/http/loading_state.dart';
|
import 'package:PiliPalaX/http/loading_state.dart';
|
||||||
@@ -99,19 +99,9 @@ class _EditProfilePageState extends State<EditProfilePage> {
|
|||||||
);
|
);
|
||||||
|
|
||||||
Widget _buildBody(LoadingState loadingState) {
|
Widget _buildBody(LoadingState loadingState) {
|
||||||
switch (loadingState) {
|
return switch (loadingState) {
|
||||||
case Error():
|
Loading() => loadingWidget,
|
||||||
return CustomScrollView(
|
Success() => SingleChildScrollView(
|
||||||
shrinkWrap: true,
|
|
||||||
slivers: [
|
|
||||||
HttpError(
|
|
||||||
errMsg: loadingState.errMsg,
|
|
||||||
fn: _getInfo,
|
|
||||||
),
|
|
||||||
],
|
|
||||||
);
|
|
||||||
case Success():
|
|
||||||
return SingleChildScrollView(
|
|
||||||
child: Column(
|
child: Column(
|
||||||
children: [
|
children: [
|
||||||
_item(
|
_item(
|
||||||
@@ -226,11 +216,13 @@ class _EditProfilePageState extends State<EditProfilePage> {
|
|||||||
_divider,
|
_divider,
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
);
|
),
|
||||||
}
|
Error() => errorWidget(
|
||||||
return Center(
|
errMsg: loadingState.errMsg,
|
||||||
child: CircularProgressIndicator(),
|
callback: _getInfo,
|
||||||
);
|
),
|
||||||
|
LoadingState() => throw UnimplementedError(),
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
Widget _sexDialog(int current) {
|
Widget _sexDialog(int current) {
|
||||||
|
|||||||
@@ -109,13 +109,13 @@ class _MemberArchivePageState extends State<MemberArchivePage> {
|
|||||||
} else {
|
} else {
|
||||||
return HttpError(
|
return HttpError(
|
||||||
errMsg: snapshot.data['msg'],
|
errMsg: snapshot.data['msg'],
|
||||||
fn: () {},
|
callback: () {},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
return HttpError(
|
return HttpError(
|
||||||
errMsg: "投稿页出现错误",
|
errMsg: "投稿页出现错误",
|
||||||
fn: () {},
|
callback: () {},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -72,72 +72,79 @@ class _MemberDynamicsPageState extends State<MemberDynamicsPage>
|
|||||||
);
|
);
|
||||||
|
|
||||||
_buildContent(LoadingState loadingState) {
|
_buildContent(LoadingState loadingState) {
|
||||||
return loadingState is Success
|
return switch (loadingState) {
|
||||||
? SliverPadding(
|
Loading() => HttpError(
|
||||||
padding: EdgeInsets.only(
|
callback: _memberDynamicController.onReload,
|
||||||
bottom: MediaQuery.paddingOf(context).bottom,
|
),
|
||||||
),
|
Success() => (loadingState.response as List?)?.isNotEmpty == true
|
||||||
sliver: dynamicsWaterfallFlow
|
? SliverPadding(
|
||||||
? SliverWaterfallFlow.extent(
|
padding: EdgeInsets.only(
|
||||||
maxCrossAxisExtent: Grid.maxRowWidth * 2,
|
bottom: MediaQuery.paddingOf(context).bottom,
|
||||||
//cacheExtent: 0.0,
|
),
|
||||||
crossAxisSpacing: StyleString.safeSpace,
|
sliver: dynamicsWaterfallFlow
|
||||||
mainAxisSpacing: StyleString.safeSpace,
|
? SliverWaterfallFlow.extent(
|
||||||
|
maxCrossAxisExtent: Grid.maxRowWidth * 2,
|
||||||
|
//cacheExtent: 0.0,
|
||||||
|
crossAxisSpacing: StyleString.safeSpace,
|
||||||
|
mainAxisSpacing: StyleString.safeSpace,
|
||||||
|
|
||||||
/// follow max child trailing layout offset and layout with full cross axis extend
|
/// follow max child trailing layout offset and layout with full cross axis extend
|
||||||
/// last child as loadmore item/no more item in [GridView] and [WaterfallFlow]
|
/// last child as loadmore item/no more item in [GridView] and [WaterfallFlow]
|
||||||
/// with full cross axis extend
|
/// with full cross axis extend
|
||||||
// LastChildLayoutType.fullCrossAxisExtend,
|
// LastChildLayoutType.fullCrossAxisExtend,
|
||||||
|
|
||||||
/// as foot at trailing and layout with full cross axis extend
|
/// as foot at trailing and layout with full cross axis extend
|
||||||
/// show no more item at trailing when children are not full of viewport
|
/// show no more item at trailing when children are not full of viewport
|
||||||
/// if children is full of viewport, it's the same as fullCrossAxisExtend
|
/// if children is full of viewport, it's the same as fullCrossAxisExtend
|
||||||
// LastChildLayoutType.foot,
|
// LastChildLayoutType.foot,
|
||||||
lastChildLayoutTypeBuilder: (index) {
|
lastChildLayoutTypeBuilder: (index) {
|
||||||
if (index == loadingState.response.length - 1) {
|
if (index == loadingState.response.length - 1) {
|
||||||
EasyThrottle.throttle('member_dynamics',
|
EasyThrottle.throttle('member_dynamics',
|
||||||
const Duration(milliseconds: 1000), () {
|
const Duration(milliseconds: 1000), () {
|
||||||
_memberDynamicController.onLoadMore();
|
_memberDynamicController.onLoadMore();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
return index == loadingState.response.length
|
return index == loadingState.response.length
|
||||||
? LastChildLayoutType.foot
|
? LastChildLayoutType.foot
|
||||||
: LastChildLayoutType.none;
|
: LastChildLayoutType.none;
|
||||||
},
|
},
|
||||||
children: (loadingState.response as List)
|
children: (loadingState.response as List)
|
||||||
.map((item) => DynamicPanel(item: item))
|
.map((item) => DynamicPanel(item: item))
|
||||||
.toList(),
|
.toList(),
|
||||||
)
|
)
|
||||||
: SliverCrossAxisGroup(
|
: SliverCrossAxisGroup(
|
||||||
slivers: [
|
slivers: [
|
||||||
const SliverFillRemaining(),
|
const SliverFillRemaining(),
|
||||||
SliverConstrainedCrossAxis(
|
SliverConstrainedCrossAxis(
|
||||||
maxExtent: Grid.maxRowWidth * 2,
|
maxExtent: Grid.maxRowWidth * 2,
|
||||||
sliver: SliverList(
|
sliver: SliverList(
|
||||||
delegate: SliverChildBuilderDelegate(
|
delegate: SliverChildBuilderDelegate(
|
||||||
(context, index) {
|
(context, index) {
|
||||||
if (index == loadingState.response.length - 1) {
|
if (index == loadingState.response.length - 1) {
|
||||||
EasyThrottle.throttle('member_dynamics',
|
EasyThrottle.throttle('member_dynamics',
|
||||||
const Duration(milliseconds: 1000), () {
|
const Duration(milliseconds: 1000), () {
|
||||||
_memberDynamicController.onLoadMore();
|
_memberDynamicController.onLoadMore();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
return DynamicPanel(
|
return DynamicPanel(
|
||||||
item: loadingState.response[index]);
|
item: loadingState.response[index]);
|
||||||
},
|
},
|
||||||
childCount: loadingState.response.length,
|
childCount: loadingState.response.length,
|
||||||
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
const SliverFillRemaining(),
|
||||||
const SliverFillRemaining(),
|
],
|
||||||
],
|
),
|
||||||
),
|
)
|
||||||
)
|
: HttpError(
|
||||||
: HttpError(
|
callback: _memberDynamicController.onReload,
|
||||||
errMsg: loadingState is Error ? loadingState.errMsg : null,
|
),
|
||||||
fn: () {
|
Error() => HttpError(
|
||||||
_memberDynamicController.onReload();
|
errMsg: loadingState.errMsg,
|
||||||
},
|
callback: _memberDynamicController.onReload,
|
||||||
);
|
),
|
||||||
|
LoadingState() => throw UnimplementedError(),
|
||||||
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,7 +3,6 @@ import 'package:flutter/material.dart';
|
|||||||
import 'package:get/get.dart';
|
import 'package:get/get.dart';
|
||||||
import 'package:PiliPalaX/common/skeleton/video_card_h.dart';
|
import 'package:PiliPalaX/common/skeleton/video_card_h.dart';
|
||||||
import 'package:PiliPalaX/common/widgets/http_error.dart';
|
import 'package:PiliPalaX/common/widgets/http_error.dart';
|
||||||
import 'package:PiliPalaX/common/widgets/no_data.dart';
|
|
||||||
import 'package:PiliPalaX/common/widgets/video_card_h.dart';
|
import 'package:PiliPalaX/common/widgets/video_card_h.dart';
|
||||||
|
|
||||||
import '../../common/constants.dart';
|
import '../../common/constants.dart';
|
||||||
@@ -148,12 +147,14 @@ class _MemberSearchPageState extends State<MemberSearchPage>
|
|||||||
(context, index) {
|
(context, index) {
|
||||||
return const VideoCardHSkeleton();
|
return const VideoCardHSkeleton();
|
||||||
}, childCount: 10))
|
}, childCount: 10))
|
||||||
: const NoData(),
|
: HttpError(
|
||||||
|
callback: () => setState(() {}),
|
||||||
|
),
|
||||||
));
|
));
|
||||||
} else {
|
} else {
|
||||||
return HttpError(
|
return HttpError(
|
||||||
errMsg: data['msg'],
|
errMsg: data['msg'],
|
||||||
fn: () => setState(() {}),
|
callback: () => setState(() {}),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -91,7 +91,7 @@ class _ZonePageState extends State<ZonePage>
|
|||||||
? (_zoneController.loadingState.value as Error)
|
? (_zoneController.loadingState.value as Error)
|
||||||
.errMsg
|
.errMsg
|
||||||
: '没有相关数据',
|
: '没有相关数据',
|
||||||
fn: _zoneController.onReload,
|
callback: _zoneController.onReload,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|||||||
@@ -102,7 +102,7 @@ class _RcmdPageState extends State<RcmdPage>
|
|||||||
errMsg: _controller.loadingState.value is Error
|
errMsg: _controller.loadingState.value is Error
|
||||||
? (_controller.loadingState.value as Error).errMsg
|
? (_controller.loadingState.value as Error).errMsg
|
||||||
: '没有相关数据',
|
: '没有相关数据',
|
||||||
fn: _controller.onReload,
|
callback: _controller.onReload,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|||||||
@@ -195,7 +195,7 @@ class _SearchPageState extends State<SearchPage> with RouteAware {
|
|||||||
slivers: [
|
slivers: [
|
||||||
HttpError(
|
HttpError(
|
||||||
errMsg: data['msg'],
|
errMsg: data['msg'],
|
||||||
fn: () => setState(() {
|
callback: () => setState(() {
|
||||||
_futureBuilderFuture =
|
_futureBuilderFuture =
|
||||||
_searchController.queryHotSearchList();
|
_searchController.queryHotSearchList();
|
||||||
}),
|
}),
|
||||||
|
|||||||
@@ -45,14 +45,14 @@ class SearchPanelController extends CommonController {
|
|||||||
if (dataList.isNotEmpty) {
|
if (dataList.isNotEmpty) {
|
||||||
loadingState.value = LoadingState.success(dataList);
|
loadingState.value = LoadingState.success(dataList);
|
||||||
} else {
|
} else {
|
||||||
loadingState.value = LoadingState.empty();
|
loadingState.value = LoadingState.success([]);
|
||||||
}
|
}
|
||||||
if (currentPage == 1) {
|
if (currentPage == 1) {
|
||||||
onPushDetail(response.response.list);
|
onPushDetail(response.response.list);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (currentPage == 1) {
|
if (currentPage == 1) {
|
||||||
loadingState.value = LoadingState.empty();
|
loadingState.value = LoadingState.success([]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
|
|||||||
@@ -206,7 +206,7 @@ Widget searchArticlePanel(BuildContext context, searchPanelCtr, loadingState) {
|
|||||||
)
|
)
|
||||||
: HttpError(
|
: HttpError(
|
||||||
errMsg: loadingState is Error ? loadingState.errMsg : '没有相关数据',
|
errMsg: loadingState is Error ? loadingState.errMsg : '没有相关数据',
|
||||||
fn: searchPanelCtr.onReload,
|
callback: searchPanelCtr.onReload,
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import 'package:PiliPalaX/common/widgets/http_error.dart';
|
import 'package:PiliPalaX/common/widgets/loading_widget.dart';
|
||||||
import 'package:PiliPalaX/http/loading_state.dart';
|
import 'package:PiliPalaX/http/loading_state.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:get/get.dart';
|
import 'package:get/get.dart';
|
||||||
@@ -8,36 +8,39 @@ import 'package:PiliPalaX/utils/utils.dart';
|
|||||||
|
|
||||||
import '../../../utils/grid.dart';
|
import '../../../utils/grid.dart';
|
||||||
|
|
||||||
Widget searchLivePanel(BuildContext context, ctr, loadingState) {
|
Widget searchLivePanel(BuildContext context, ctr, LoadingState loadingState) {
|
||||||
return loadingState is Success
|
return switch (loadingState) {
|
||||||
? GridView.builder(
|
Loading() => loadingWidget,
|
||||||
padding: const EdgeInsets.only(
|
Success() => (loadingState.response as List?)?.isNotEmpty == true
|
||||||
left: StyleString.safeSpace,
|
? GridView.builder(
|
||||||
right: StyleString.safeSpace,
|
padding: const EdgeInsets.only(
|
||||||
bottom: StyleString.safeSpace,
|
left: StyleString.safeSpace,
|
||||||
),
|
right: StyleString.safeSpace,
|
||||||
primary: false,
|
bottom: StyleString.safeSpace,
|
||||||
controller: ctr!.scrollController,
|
|
||||||
gridDelegate: SliverGridDelegateWithExtentAndRatio(
|
|
||||||
maxCrossAxisExtent: Grid.maxRowWidth,
|
|
||||||
crossAxisSpacing: StyleString.safeSpace,
|
|
||||||
mainAxisSpacing: StyleString.safeSpace,
|
|
||||||
childAspectRatio: StyleString.aspectRatio,
|
|
||||||
mainAxisExtent: MediaQuery.textScalerOf(context).scale(80),
|
|
||||||
),
|
|
||||||
itemCount: loadingState.response.length,
|
|
||||||
itemBuilder: (context, index) {
|
|
||||||
return LiveItem(liveItem: loadingState.response[index]);
|
|
||||||
},
|
|
||||||
)
|
|
||||||
: CustomScrollView(
|
|
||||||
slivers: [
|
|
||||||
HttpError(
|
|
||||||
errMsg: loadingState is Error ? loadingState.errMsg : '没有相关数据',
|
|
||||||
fn: ctr.onReload,
|
|
||||||
),
|
),
|
||||||
],
|
primary: false,
|
||||||
);
|
controller: ctr!.scrollController,
|
||||||
|
gridDelegate: SliverGridDelegateWithExtentAndRatio(
|
||||||
|
maxCrossAxisExtent: Grid.maxRowWidth,
|
||||||
|
crossAxisSpacing: StyleString.safeSpace,
|
||||||
|
mainAxisSpacing: StyleString.safeSpace,
|
||||||
|
childAspectRatio: StyleString.aspectRatio,
|
||||||
|
mainAxisExtent: MediaQuery.textScalerOf(context).scale(80),
|
||||||
|
),
|
||||||
|
itemCount: loadingState.response.length,
|
||||||
|
itemBuilder: (context, index) {
|
||||||
|
return LiveItem(liveItem: loadingState.response[index]);
|
||||||
|
},
|
||||||
|
)
|
||||||
|
: errorWidget(
|
||||||
|
callback: ctr.onReload,
|
||||||
|
),
|
||||||
|
Error() => errorWidget(
|
||||||
|
errMsg: loadingState.errMsg,
|
||||||
|
callback: ctr.onReload,
|
||||||
|
),
|
||||||
|
LoadingState() => throw UnimplementedError(),
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
class LiveItem extends StatelessWidget {
|
class LiveItem extends StatelessWidget {
|
||||||
|
|||||||
@@ -192,7 +192,7 @@ Widget searchBangumiPanel(BuildContext context, ctr, loadingState) {
|
|||||||
)
|
)
|
||||||
: HttpError(
|
: HttpError(
|
||||||
errMsg: loadingState is Error ? loadingState.errMsg : '没有相关数据',
|
errMsg: loadingState is Error ? loadingState.errMsg : '没有相关数据',
|
||||||
fn: ctr.onReload,
|
callback: ctr.onReload,
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -150,7 +150,7 @@ Widget searchUserPanel(BuildContext context, searchPanelCtr, loadingState) {
|
|||||||
)
|
)
|
||||||
: HttpError(
|
: HttpError(
|
||||||
errMsg: loadingState is Error ? loadingState.errMsg : '没有相关数据',
|
errMsg: loadingState is Error ? loadingState.errMsg : '没有相关数据',
|
||||||
fn: searchPanelCtr.onReload,
|
callback: searchPanelCtr.onReload,
|
||||||
)
|
)
|
||||||
],
|
],
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -123,7 +123,7 @@ class SearchVideoPanel extends StatelessWidget {
|
|||||||
)
|
)
|
||||||
: HttpError(
|
: HttpError(
|
||||||
errMsg: loadingState is Error ? loadingState.errMsg : '没有相关数据',
|
errMsg: loadingState is Error ? loadingState.errMsg : '没有相关数据',
|
||||||
fn: ctr.onReload,
|
callback: ctr.onReload,
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -64,7 +64,6 @@ class _SearchResultPageState extends State<SearchResultPage>
|
|||||||
const SizedBox(height: 4),
|
const SizedBox(height: 4),
|
||||||
Container(
|
Container(
|
||||||
width: double.infinity,
|
width: double.infinity,
|
||||||
padding: const EdgeInsets.only(left: 8),
|
|
||||||
color: Theme.of(context).colorScheme.surface,
|
color: Theme.of(context).colorScheme.surface,
|
||||||
child: Theme(
|
child: Theme(
|
||||||
data: ThemeData(
|
data: ThemeData(
|
||||||
@@ -72,6 +71,7 @@ class _SearchResultPageState extends State<SearchResultPage>
|
|||||||
highlightColor: Colors.transparent, // 点击时的背景高亮颜色设置为透明
|
highlightColor: Colors.transparent, // 点击时的背景高亮颜色设置为透明
|
||||||
),
|
),
|
||||||
child: TabBar(
|
child: TabBar(
|
||||||
|
padding: const EdgeInsets.symmetric(horizontal: 8),
|
||||||
controller: _tabController,
|
controller: _tabController,
|
||||||
tabs: SearchType.values
|
tabs: SearchType.values
|
||||||
.map(
|
.map(
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import 'dart:io';
|
import 'dart:io';
|
||||||
|
import 'package:PiliPalaX/common/widgets/loading_widget.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter/services.dart';
|
import 'package:flutter/services.dart';
|
||||||
import 'package:PiliPalaX/common/widgets/no_data.dart';
|
|
||||||
import 'package:url_launcher/url_launcher.dart';
|
import 'package:url_launcher/url_launcher.dart';
|
||||||
import '../../../services/loggeer.dart';
|
import '../../../services/loggeer.dart';
|
||||||
|
|
||||||
@@ -194,11 +194,7 @@ class _LogsPageState extends State<LogsPage> {
|
|||||||
);
|
);
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
: const CustomScrollView(
|
: errorWidget(),
|
||||||
slivers: <Widget>[
|
|
||||||
NoData(),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -105,6 +105,7 @@ class _RecommendSettingState extends State<RecommendSetting> {
|
|||||||
leading: Icon(Icons.refresh),
|
leading: Icon(Icons.refresh),
|
||||||
setKey: SettingBoxKey.enableSaveLastData,
|
setKey: SettingBoxKey.enableSaveLastData,
|
||||||
defaultVal: false,
|
defaultVal: false,
|
||||||
|
needReboot: true,
|
||||||
),
|
),
|
||||||
// 分割线
|
// 分割线
|
||||||
const Divider(height: 1),
|
const Divider(height: 1),
|
||||||
|
|||||||
@@ -44,7 +44,7 @@ class _StyleSettingState extends State<StyleSetting> {
|
|||||||
setting.get(SettingBoxKey.maxRowWidth, defaultValue: 240.0) as double;
|
setting.get(SettingBoxKey.maxRowWidth, defaultValue: 240.0) as double;
|
||||||
upPanelPosition = UpPanelPosition.values[setting.get(
|
upPanelPosition = UpPanelPosition.values[setting.get(
|
||||||
SettingBoxKey.upPanelPosition,
|
SettingBoxKey.upPanelPosition,
|
||||||
defaultValue: UpPanelPosition.leftFixed.code)];
|
defaultValue: UpPanelPosition.leftFixed.index)];
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
@@ -67,10 +67,10 @@ class _StyleSettingState extends State<StyleSetting> {
|
|||||||
callFn: (value) {
|
callFn: (value) {
|
||||||
if (value) {
|
if (value) {
|
||||||
autoScreen();
|
autoScreen();
|
||||||
SmartDialog.showToast('已开启横屏适配');
|
// SmartDialog.showToast('已开启横屏适配');
|
||||||
} else {
|
} else {
|
||||||
AutoOrientation.portraitUpMode();
|
AutoOrientation.portraitUpMode();
|
||||||
SmartDialog.showToast('已关闭横屏适配');
|
// SmartDialog.showToast('已关闭横屏适配');
|
||||||
}
|
}
|
||||||
}),
|
}),
|
||||||
const SetSwitchItem(
|
const SetSwitchItem(
|
||||||
@@ -171,7 +171,7 @@ class _StyleSettingState extends State<StyleSetting> {
|
|||||||
);
|
);
|
||||||
if (result != null) {
|
if (result != null) {
|
||||||
upPanelPosition = result;
|
upPanelPosition = result;
|
||||||
setting.put(SettingBoxKey.upPanelPosition, result.code);
|
setting.put(SettingBoxKey.upPanelPosition, result.index);
|
||||||
SmartDialog.showToast('重启生效');
|
SmartDialog.showToast('重启生效');
|
||||||
setState(() {});
|
setState(() {});
|
||||||
}
|
}
|
||||||
@@ -307,7 +307,7 @@ class _StyleSettingState extends State<StyleSetting> {
|
|||||||
if (result != null) {
|
if (result != null) {
|
||||||
_tempThemeValue = result;
|
_tempThemeValue = result;
|
||||||
settingController.themeType.value = result;
|
settingController.themeType.value = result;
|
||||||
setting.put(SettingBoxKey.themeMode, result.code);
|
setting.put(SettingBoxKey.themeMode, result.index);
|
||||||
Get.forceAppUpdate();
|
Get.forceAppUpdate();
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -80,7 +80,7 @@ class _SubPageState extends State<SubPage> {
|
|||||||
slivers: [
|
slivers: [
|
||||||
HttpError(
|
HttpError(
|
||||||
errMsg: data?['msg'],
|
errMsg: data?['msg'],
|
||||||
fn: () => setState(() {}),
|
callback: () => setState(() {}),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -6,7 +6,6 @@ import 'package:get/get.dart';
|
|||||||
import 'package:PiliPalaX/common/skeleton/video_card_h.dart';
|
import 'package:PiliPalaX/common/skeleton/video_card_h.dart';
|
||||||
import 'package:PiliPalaX/common/widgets/http_error.dart';
|
import 'package:PiliPalaX/common/widgets/http_error.dart';
|
||||||
import 'package:PiliPalaX/common/widgets/network_img_layer.dart';
|
import 'package:PiliPalaX/common/widgets/network_img_layer.dart';
|
||||||
import 'package:PiliPalaX/common/widgets/no_data.dart';
|
|
||||||
|
|
||||||
import '../../models/user/sub_folder.dart';
|
import '../../models/user/sub_folder.dart';
|
||||||
import '../../utils/utils.dart';
|
import '../../utils/utils.dart';
|
||||||
@@ -206,7 +205,12 @@ class _SubDetailPageState extends State<SubDetailPage> {
|
|||||||
Map data = snapshot.data;
|
Map data = snapshot.data;
|
||||||
if (data['status']) {
|
if (data['status']) {
|
||||||
if (_subDetailController.item.mediaCount == 0) {
|
if (_subDetailController.item.mediaCount == 0) {
|
||||||
return const NoData();
|
return HttpError(
|
||||||
|
callback: () => setState(() {
|
||||||
|
_futureBuilderFuture =
|
||||||
|
_subDetailController.queryUserSubFolderDetail();
|
||||||
|
}),
|
||||||
|
);
|
||||||
} else {
|
} else {
|
||||||
List subList = _subDetailController.subList;
|
List subList = _subDetailController.subList;
|
||||||
return Obx(
|
return Obx(
|
||||||
@@ -225,7 +229,10 @@ class _SubDetailPageState extends State<SubDetailPage> {
|
|||||||
} else {
|
} else {
|
||||||
return HttpError(
|
return HttpError(
|
||||||
errMsg: data['msg'],
|
errMsg: data['msg'],
|
||||||
fn: () => setState(() {}),
|
callback: () => setState(() {
|
||||||
|
_futureBuilderFuture =
|
||||||
|
_subDetailController.queryUserSubFolderDetail();
|
||||||
|
}),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -699,7 +699,10 @@ class VideoIntroController extends GetxController
|
|||||||
late RelatedController relatedCtr;
|
late RelatedController relatedCtr;
|
||||||
try {
|
try {
|
||||||
relatedCtr = Get.find<RelatedController>(tag: heroTag);
|
relatedCtr = Get.find<RelatedController>(tag: heroTag);
|
||||||
if (relatedCtr.loadingState.value is Empty) {
|
if (relatedCtr.loadingState.value is! Success) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if ((relatedCtr.loadingState.value as Success).response.isEmpty == true) {
|
||||||
SmartDialog.showToast('暂无相关视频,停止连播');
|
SmartDialog.showToast('暂无相关视频,停止连播');
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -101,7 +101,7 @@ class _CreateFavPageState extends State<CreateFavPage> {
|
|||||||
slivers: [
|
slivers: [
|
||||||
HttpError(
|
HttpError(
|
||||||
errMsg: _errMsg,
|
errMsg: _errMsg,
|
||||||
fn: _getFolderInfo,
|
callback: _getFolderInfo,
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
|
|||||||
@@ -147,7 +147,7 @@ class _FavPanelState extends State<FavPanel> {
|
|||||||
slivers: [
|
slivers: [
|
||||||
HttpError(
|
HttpError(
|
||||||
errMsg: data['msg'],
|
errMsg: data['msg'],
|
||||||
fn: () => setState(() {
|
callback: () => setState(() {
|
||||||
_futureBuilderFuture =
|
_futureBuilderFuture =
|
||||||
widget.ctr!.queryVideoInFolder();
|
widget.ctr!.queryVideoInFolder();
|
||||||
}),
|
}),
|
||||||
|
|||||||
@@ -144,7 +144,7 @@ class _GroupPanelState extends State<GroupPanel> {
|
|||||||
slivers: [
|
slivers: [
|
||||||
HttpError(
|
HttpError(
|
||||||
errMsg: data['msg'],
|
errMsg: data['msg'],
|
||||||
fn: () => setState(() {}),
|
callback: () => setState(() {}),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -43,54 +43,58 @@ class _RelatedVideoPanelState extends State<RelatedVideoPanel>
|
|||||||
}
|
}
|
||||||
|
|
||||||
Widget _buildBody(LoadingState loadingState) {
|
Widget _buildBody(LoadingState loadingState) {
|
||||||
return loadingState is Success
|
return switch (loadingState) {
|
||||||
? SliverGrid(
|
Loading() => SliverGrid(
|
||||||
gridDelegate: SliverGridDelegateWithExtentAndRatio(
|
gridDelegate: SliverGridDelegateWithExtentAndRatio(
|
||||||
mainAxisSpacing: StyleString.safeSpace,
|
mainAxisSpacing: StyleString.safeSpace,
|
||||||
crossAxisSpacing: StyleString.safeSpace,
|
crossAxisSpacing: StyleString.safeSpace,
|
||||||
maxCrossAxisExtent: Grid.maxRowWidth * 2,
|
maxCrossAxisExtent: Grid.maxRowWidth * 2,
|
||||||
childAspectRatio: StyleString.aspectRatio * 2.4,
|
childAspectRatio: StyleString.aspectRatio * 2.4,
|
||||||
mainAxisExtent: 0),
|
mainAxisExtent: 0),
|
||||||
delegate: SliverChildBuilderDelegate((context, index) {
|
delegate: SliverChildBuilderDelegate(
|
||||||
if (index == loadingState.response.length) {
|
(context, index) {
|
||||||
return SizedBox(height: MediaQuery.of(context).padding.bottom);
|
return const VideoCardHSkeleton();
|
||||||
} else {
|
},
|
||||||
return Material(
|
childCount: 5,
|
||||||
child: VideoCardH(
|
),
|
||||||
videoItem: loadingState.response[index],
|
),
|
||||||
showPubdate: true,
|
Success() => (loadingState.response as List?)?.isNotEmpty == true
|
||||||
longPress: () {
|
? SliverGrid(
|
||||||
_relatedController.popupDialog.add(
|
gridDelegate: SliverGridDelegateWithExtentAndRatio(
|
||||||
_createPopupDialog(loadingState.response[index]));
|
mainAxisSpacing: StyleString.safeSpace,
|
||||||
Overlay.of(context)
|
crossAxisSpacing: StyleString.safeSpace,
|
||||||
.insert(_relatedController.popupDialog.last!);
|
maxCrossAxisExtent: Grid.maxRowWidth * 2,
|
||||||
},
|
childAspectRatio: StyleString.aspectRatio * 2.4,
|
||||||
longPressEnd: _relatedController.removePopupDialog,
|
mainAxisExtent: 0),
|
||||||
),
|
delegate: SliverChildBuilderDelegate((context, index) {
|
||||||
);
|
if (index == loadingState.response.length) {
|
||||||
}
|
return SizedBox(
|
||||||
}, childCount: loadingState.response.length + 1),
|
height: MediaQuery.of(context).padding.bottom);
|
||||||
)
|
} else {
|
||||||
: loadingState is Error
|
return Material(
|
||||||
? HttpError(
|
child: VideoCardH(
|
||||||
errMsg: '出错了',
|
videoItem: loadingState.response[index],
|
||||||
fn: _relatedController.onReload,
|
showPubdate: true,
|
||||||
)
|
longPress: () {
|
||||||
: loadingState is Empty
|
_relatedController.popupDialog.add(
|
||||||
? const SliverToBoxAdapter(child: SizedBox.shrink())
|
_createPopupDialog(loadingState.response[index]));
|
||||||
: SliverGrid(
|
Overlay.of(context)
|
||||||
gridDelegate: SliverGridDelegateWithExtentAndRatio(
|
.insert(_relatedController.popupDialog.last!);
|
||||||
mainAxisSpacing: StyleString.safeSpace,
|
|
||||||
crossAxisSpacing: StyleString.safeSpace,
|
|
||||||
maxCrossAxisExtent: Grid.maxRowWidth * 2,
|
|
||||||
childAspectRatio: StyleString.aspectRatio * 2.4,
|
|
||||||
mainAxisExtent: 0),
|
|
||||||
delegate: SliverChildBuilderDelegate(
|
|
||||||
(context, index) {
|
|
||||||
return const VideoCardHSkeleton();
|
|
||||||
},
|
},
|
||||||
childCount: 5,
|
longPressEnd: _relatedController.removePopupDialog,
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
}
|
||||||
|
}, childCount: loadingState.response.length + 1),
|
||||||
|
)
|
||||||
|
: HttpError(
|
||||||
|
callback: _relatedController.onReload,
|
||||||
|
),
|
||||||
|
Error() => HttpError(
|
||||||
|
errMsg: loadingState.errMsg,
|
||||||
|
callback: _relatedController.onReload,
|
||||||
|
),
|
||||||
|
LoadingState() => throw UnimplementedError(),
|
||||||
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -200,63 +200,68 @@ class _VideoReplyPanelState extends State<VideoReplyPanel>
|
|||||||
}
|
}
|
||||||
|
|
||||||
Widget _buildBody(LoadingState loadingState) {
|
Widget _buildBody(LoadingState loadingState) {
|
||||||
return loadingState is Success
|
return switch (loadingState) {
|
||||||
? SliverList(
|
Loading() => SliverList(
|
||||||
delegate: SliverChildBuilderDelegate(
|
delegate: SliverChildBuilderDelegate(
|
||||||
(BuildContext context, index) {
|
(BuildContext context, index) {
|
||||||
double bottom = MediaQuery.of(context).padding.bottom;
|
return const VideoReplySkeleton();
|
||||||
if (index == loadingState.response.replies.length) {
|
},
|
||||||
return Container(
|
childCount: 5,
|
||||||
padding: EdgeInsets.only(bottom: bottom),
|
),
|
||||||
height: bottom + 100,
|
),
|
||||||
child: Center(
|
Success() => (loadingState.response.replies as List?)?.isNotEmpty == true
|
||||||
child: Obx(
|
? SliverList(
|
||||||
() => Text(
|
delegate: SliverChildBuilderDelegate(
|
||||||
_videoReplyController.noMore.value,
|
(BuildContext context, index) {
|
||||||
style: TextStyle(
|
double bottom = MediaQuery.of(context).padding.bottom;
|
||||||
fontSize: 12,
|
if (index == loadingState.response.replies.length) {
|
||||||
color: Theme.of(context).colorScheme.outline,
|
return Container(
|
||||||
|
padding: EdgeInsets.only(bottom: bottom),
|
||||||
|
height: bottom + 100,
|
||||||
|
child: Center(
|
||||||
|
child: Obx(
|
||||||
|
() => Text(
|
||||||
|
_videoReplyController.noMore.value,
|
||||||
|
style: TextStyle(
|
||||||
|
fontSize: 12,
|
||||||
|
color: Theme.of(context).colorScheme.outline,
|
||||||
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
);
|
||||||
);
|
} else {
|
||||||
} else {
|
return ReplyItemGrpc(
|
||||||
return ReplyItemGrpc(
|
replyItem: loadingState.response.replies[index],
|
||||||
replyItem: loadingState.response.replies[index],
|
showReplyRow: true,
|
||||||
showReplyRow: true,
|
replyLevel: replyLevel,
|
||||||
replyLevel: replyLevel,
|
replyReply: widget.replyReply,
|
||||||
replyReply: widget.replyReply,
|
replyType: ReplyType.video,
|
||||||
replyType: ReplyType.video,
|
onReply: () {
|
||||||
onReply: () {
|
_videoReplyController.onReply(
|
||||||
_videoReplyController.onReply(
|
context,
|
||||||
context,
|
replyItem: loadingState.response.replies[index],
|
||||||
replyItem: loadingState.response.replies[index],
|
index: index,
|
||||||
index: index,
|
);
|
||||||
);
|
},
|
||||||
},
|
onDelete: _videoReplyController.onMDelete,
|
||||||
onDelete: _videoReplyController.onMDelete,
|
isTop: _videoReplyController.hasUpTop && index == 0,
|
||||||
isTop: _videoReplyController.hasUpTop && index == 0,
|
upMid: loadingState.response.subjectControl.upMid,
|
||||||
upMid: loadingState.response.subjectControl.upMid,
|
);
|
||||||
);
|
}
|
||||||
}
|
},
|
||||||
},
|
childCount: loadingState.response.replies.length + 1,
|
||||||
childCount: loadingState.response.replies.length + 1,
|
),
|
||||||
|
)
|
||||||
|
: HttpError(
|
||||||
|
callback: _videoReplyController.onReload,
|
||||||
),
|
),
|
||||||
)
|
Error() => HttpError(
|
||||||
: loadingState is Error
|
errMsg: loadingState.errMsg,
|
||||||
? HttpError(
|
callback: _videoReplyController.onReload,
|
||||||
errMsg: loadingState.errMsg,
|
),
|
||||||
fn: _videoReplyController.onReload,
|
LoadingState() => throw UnimplementedError(),
|
||||||
)
|
};
|
||||||
: SliverList(
|
|
||||||
delegate: SliverChildBuilderDelegate(
|
|
||||||
(BuildContext context, index) {
|
|
||||||
return const VideoReplySkeleton();
|
|
||||||
},
|
|
||||||
childCount: 5,
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -146,10 +146,20 @@ class VideoReplyReplyController extends CommonController
|
|||||||
}
|
}
|
||||||
upMid ??= replies.subjectControl.upMid.toInt();
|
upMid ??= replies.subjectControl.upMid.toInt();
|
||||||
cursor = replies.cursor;
|
cursor = replies.cursor;
|
||||||
|
if (currentPage != 1) {
|
||||||
|
List<ReplyInfo> list = loadingState.value is Success
|
||||||
|
? (loadingState.value as Success).response
|
||||||
|
: <ReplyInfo>[];
|
||||||
|
if (isDialogue) {
|
||||||
|
replies.replies.insertAll(0, list);
|
||||||
|
} else {
|
||||||
|
replies.root.replies.insertAll(0, list);
|
||||||
|
}
|
||||||
|
}
|
||||||
if (isDialogue) {
|
if (isDialogue) {
|
||||||
if (replies.replies.isNotEmpty) {
|
if (replies.replies.isNotEmpty) {
|
||||||
noMore.value = '加载中...';
|
noMore.value = '加载中...';
|
||||||
if (replies.cursor.isEnd) {
|
if (replies.cursor.isEnd || count.value >= replies.replies.length) {
|
||||||
noMore.value = '没有更多了';
|
noMore.value = '没有更多了';
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@@ -159,7 +169,8 @@ class VideoReplyReplyController extends CommonController
|
|||||||
} else {
|
} else {
|
||||||
if (replies.root.replies.isNotEmpty) {
|
if (replies.root.replies.isNotEmpty) {
|
||||||
noMore.value = '加载中...';
|
noMore.value = '加载中...';
|
||||||
if (replies.cursor.isEnd) {
|
if (replies.cursor.isEnd ||
|
||||||
|
count.value >= replies.root.replies.length) {
|
||||||
noMore.value = '没有更多了';
|
noMore.value = '没有更多了';
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@@ -167,16 +178,6 @@ class VideoReplyReplyController extends CommonController
|
|||||||
noMore.value = currentPage == 1 ? '还没有评论' : '没有更多了';
|
noMore.value = currentPage == 1 ? '还没有评论' : '没有更多了';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (currentPage != 1) {
|
|
||||||
List<ReplyInfo> list = loadingState.value is Success
|
|
||||||
? (loadingState.value as Success).response
|
|
||||||
: <ReplyInfo>[];
|
|
||||||
if (isDialogue) {
|
|
||||||
replies.replies.insertAll(0, list);
|
|
||||||
} else {
|
|
||||||
replies.root.replies.insertAll(0, list);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (isDialogue) {
|
if (isDialogue) {
|
||||||
loadingState.value = LoadingState.success(replies.replies);
|
loadingState.value = LoadingState.success(replies.replies);
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -333,7 +333,7 @@ class _VideoReplyReplyPanelState extends State<VideoReplyReplyPanel> {
|
|||||||
slivers: [
|
slivers: [
|
||||||
HttpError(
|
HttpError(
|
||||||
errMsg: loadingState.errMsg,
|
errMsg: loadingState.errMsg,
|
||||||
fn: _videoReplyReplyController.onReload,
|
callback: _videoReplyReplyController.onReload,
|
||||||
)
|
)
|
||||||
],
|
],
|
||||||
);
|
);
|
||||||
|
|||||||
Reference in New Issue
Block a user