mirror of
https://github.com/bggRGjQaUbCoE/PiliPlus.git
synced 2026-06-01 08:38:18 +08:00
@@ -19,14 +19,8 @@ class HttpError extends StatelessWidget {
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return isSliver
|
||||
? SliverToBoxAdapter(child: content(context))
|
||||
: SizedBox(width: double.infinity, child: content(context));
|
||||
}
|
||||
|
||||
Widget content(BuildContext context) {
|
||||
final theme = Theme.of(context);
|
||||
return Column(
|
||||
final child = Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
crossAxisAlignment: CrossAxisAlignment.center,
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
@@ -63,5 +57,9 @@ class HttpError extends StatelessWidget {
|
||||
SizedBox(height: 40 + MediaQuery.viewPaddingOf(context).bottom),
|
||||
],
|
||||
);
|
||||
|
||||
return isSliver
|
||||
? SliverToBoxAdapter(child: child)
|
||||
: SizedBox(width: double.infinity, child: child);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,17 +1,14 @@
|
||||
import 'package:PiliPlus/common/widgets/loading_widget/http_error.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
Widget get loadingWidget => const Center(child: CircularProgressIndicator());
|
||||
const Widget circularLoading = Center(child: CircularProgressIndicator());
|
||||
|
||||
Widget get linearLoading =>
|
||||
const SliverToBoxAdapter(child: LinearProgressIndicator());
|
||||
|
||||
Widget errorWidget({String? errMsg, VoidCallback? onReload}) => HttpError(
|
||||
isSliver: false,
|
||||
errMsg: errMsg,
|
||||
onReload: onReload,
|
||||
const Widget linearLoading = SliverToBoxAdapter(
|
||||
child: LinearProgressIndicator(),
|
||||
);
|
||||
|
||||
const Widget scrollableError = CustomScrollView(slivers: [HttpError()]);
|
||||
|
||||
Widget scrollErrorWidget({
|
||||
String? errMsg,
|
||||
VoidCallback? onReload,
|
||||
|
||||
@@ -340,6 +340,7 @@ class Common {
|
||||
int? style;
|
||||
String? subType;
|
||||
String? title;
|
||||
String? titlePrefix;
|
||||
|
||||
Common.fromJson(Map<String, dynamic> json) {
|
||||
cover = json['cover'];
|
||||
@@ -352,6 +353,7 @@ class Common {
|
||||
style = json['style'];
|
||||
subType = json['sub_type'];
|
||||
title = json['title'];
|
||||
titlePrefix = json['title_prefix'];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -82,7 +82,7 @@ class _DanmakuBlockPageState extends State<DanmakuBlockPage> {
|
||||
|
||||
Widget tabViewBuilder(final int tabIndex, List<SimpleRule> list) {
|
||||
if (list.isEmpty) {
|
||||
return scrollErrorWidget();
|
||||
return scrollableError;
|
||||
}
|
||||
return ListView.builder(
|
||||
itemCount: list.length,
|
||||
|
||||
@@ -153,13 +153,12 @@ Widget module(
|
||||
spacing: 2,
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
if (common.title?.isNotEmpty ?? false)
|
||||
Text(
|
||||
common.title!,
|
||||
style: TextStyle(color: theme.colorScheme.primary),
|
||||
maxLines: 1,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
),
|
||||
Text(
|
||||
'${common.titlePrefix ?? ''}${common.title ?? ''}',
|
||||
style: TextStyle(color: theme.colorScheme.primary),
|
||||
maxLines: 1,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
),
|
||||
if (common.desc?.isNotEmpty ?? false)
|
||||
Text(
|
||||
common.desc!,
|
||||
|
||||
@@ -234,8 +234,8 @@ class _DynMentionPanelState
|
||||
LoadingState<List<MentionGroup>?> loadingState,
|
||||
) {
|
||||
return switch (loadingState) {
|
||||
Loading() => SliverPadding(
|
||||
padding: const EdgeInsets.only(top: 8),
|
||||
Loading() => const SliverPadding(
|
||||
padding: EdgeInsets.only(top: 8),
|
||||
sliver: linearLoading,
|
||||
),
|
||||
Success<List<MentionGroup>?>(:final response) =>
|
||||
|
||||
@@ -188,7 +188,7 @@ class _SelectTopicPanelState
|
||||
LoadingState<List<TopicItem>?> loadingState,
|
||||
) {
|
||||
return switch (loadingState) {
|
||||
Loading() => loadingWidget,
|
||||
Loading() => circularLoading,
|
||||
Success<List<TopicItem>?>(:final response) =>
|
||||
response != null && response.isNotEmpty
|
||||
? ListView.builder(
|
||||
|
||||
@@ -50,7 +50,7 @@ class _EmotePanelState extends State<EmotePanel>
|
||||
Get.currentRoute.startsWith('/whisperDetail') ? 8 : 2,
|
||||
);
|
||||
return switch (loadingState) {
|
||||
Loading() => loadingWidget,
|
||||
Loading() => circularLoading,
|
||||
Success(:final response) =>
|
||||
response != null && response.isNotEmpty
|
||||
? Column(
|
||||
|
||||
@@ -2,6 +2,8 @@ import 'package:PiliPlus/common/constants.dart';
|
||||
import 'package:PiliPlus/common/widgets/dialog/dialog.dart';
|
||||
import 'package:PiliPlus/common/widgets/flutter/refresh_indicator.dart';
|
||||
import 'package:PiliPlus/common/widgets/loading_widget/http_error.dart';
|
||||
import 'package:PiliPlus/common/widgets/loading_widget/loading_widget.dart'
|
||||
show circularLoading;
|
||||
import 'package:PiliPlus/http/loading_state.dart';
|
||||
import 'package:PiliPlus/models_new/fav/fav_topic/topic_item.dart';
|
||||
import 'package:PiliPlus/pages/fav/topic/controller.dart';
|
||||
@@ -66,9 +68,7 @@ class _FavTopicPageState extends State<FavTopicPage>
|
||||
Loading() => const SliverToBoxAdapter(
|
||||
child: SizedBox(
|
||||
height: 125,
|
||||
child: Center(
|
||||
child: CircularProgressIndicator(),
|
||||
),
|
||||
child: circularLoading,
|
||||
),
|
||||
),
|
||||
Success(:final response) =>
|
||||
|
||||
@@ -107,7 +107,7 @@ class _CreateFavPageState extends State<CreateFavPage> {
|
||||
? _buildBody(theme)
|
||||
: _errMsg?.isNotEmpty == true
|
||||
? scrollErrorWidget(errMsg: _errMsg, onReload: _getFolderInfo)
|
||||
: const Center(child: CircularProgressIndicator())
|
||||
: circularLoading
|
||||
: _buildBody(theme),
|
||||
);
|
||||
}
|
||||
|
||||
@@ -41,7 +41,7 @@ class _FavPanelState extends State<FavPanel> {
|
||||
Widget get _buildBody {
|
||||
late final list = widget.ctr.favFolderData.value.list!;
|
||||
return switch (loadingState) {
|
||||
Loading() => loadingWidget,
|
||||
Loading() => circularLoading,
|
||||
Success() => ListView.builder(
|
||||
controller: widget.scrollController,
|
||||
itemCount: list.length,
|
||||
|
||||
@@ -109,7 +109,7 @@ class _FollowPageState extends State<FollowPage> {
|
||||
|
||||
Widget _buildBody(LoadingState loadingState) {
|
||||
return switch (loadingState) {
|
||||
Loading() => loadingWidget,
|
||||
Loading() => circularLoading,
|
||||
Success() => Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
|
||||
@@ -68,7 +68,7 @@ class _GroupPanelState extends State<GroupPanel> {
|
||||
|
||||
Widget get _buildBody {
|
||||
return switch (loadingState) {
|
||||
Loading() => loadingWidget,
|
||||
Loading() => circularLoading,
|
||||
Success(:final response) => ListView.builder(
|
||||
controller: widget.scrollController,
|
||||
itemCount: response.length,
|
||||
|
||||
@@ -157,7 +157,7 @@ class _LiveDmBlockPageState extends State<LiveDmBlockPage> {
|
||||
|
||||
Widget _buildKeyword(List list) {
|
||||
if (list.isEmpty) {
|
||||
return scrollErrorWidget();
|
||||
return scrollableError;
|
||||
}
|
||||
return SingleChildScrollView(
|
||||
padding: EdgeInsets.only(
|
||||
|
||||
@@ -57,7 +57,7 @@ class _LiveEmotePanelState extends State<LiveEmotePanel>
|
||||
2,
|
||||
);
|
||||
return switch (loadingState) {
|
||||
Loading() => loadingWidget,
|
||||
Loading() => circularLoading,
|
||||
Success(:final response) =>
|
||||
response != null && response.isNotEmpty
|
||||
? Column(
|
||||
|
||||
@@ -2,6 +2,7 @@ import 'dart:io';
|
||||
import 'dart:ui';
|
||||
|
||||
import 'package:PiliPlus/common/constants.dart';
|
||||
import 'package:PiliPlus/common/widgets/loading_widget/http_error.dart';
|
||||
import 'package:PiliPlus/common/widgets/loading_widget/loading_widget.dart';
|
||||
import 'package:PiliPlus/common/widgets/scroll_physics.dart';
|
||||
import 'package:PiliPlus/http/loading_state.dart';
|
||||
@@ -96,15 +97,12 @@ class _LoginPageState extends State<LoginPage> {
|
||||
),
|
||||
RepaintBoundary(
|
||||
key: globalKey,
|
||||
child: Obx(() {
|
||||
return switch (_loginPageCtr.codeInfo.value) {
|
||||
Loading() => Container(
|
||||
child: Obx(
|
||||
() => switch (_loginPageCtr.codeInfo.value) {
|
||||
Loading() => const SizedBox(
|
||||
height: 200,
|
||||
width: 200,
|
||||
alignment: Alignment.center,
|
||||
child: const CircularProgressIndicator(
|
||||
semanticsLabel: '二维码加载中',
|
||||
),
|
||||
child: circularLoading,
|
||||
),
|
||||
Success(:final response) => Container(
|
||||
width: 200,
|
||||
@@ -120,12 +118,13 @@ class _LoginPageState extends State<LoginPage> {
|
||||
),
|
||||
),
|
||||
),
|
||||
Error(:final errMsg) => errorWidget(
|
||||
Error(:final errMsg) => HttpError(
|
||||
isSliver: false,
|
||||
errMsg: errMsg,
|
||||
onReload: _loginPageCtr.refreshQRCode,
|
||||
),
|
||||
};
|
||||
}),
|
||||
},
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 10),
|
||||
Obx(
|
||||
|
||||
@@ -5,7 +5,6 @@ import 'package:PiliPlus/common/widgets/dynamic_sliver_app_bar/dynamic_sliver_ap
|
||||
import 'package:PiliPlus/common/widgets/loading_widget/loading_widget.dart';
|
||||
import 'package:PiliPlus/common/widgets/scroll_physics.dart';
|
||||
import 'package:PiliPlus/http/loading_state.dart';
|
||||
import 'package:PiliPlus/models_new/space/space/data.dart';
|
||||
import 'package:PiliPlus/pages/coin_log/controller.dart';
|
||||
import 'package:PiliPlus/pages/exp_log/controller.dart';
|
||||
import 'package:PiliPlus/pages/log_table/view.dart';
|
||||
@@ -68,48 +67,74 @@ class _MemberPageState extends State<MemberPage> {
|
||||
return Material(
|
||||
color: theme.surface,
|
||||
child: Obx(
|
||||
() {
|
||||
if (_userController.loadingState.value.isSuccess) {
|
||||
return ExtendedNestedScrollView(
|
||||
key: _userController.key,
|
||||
onlyOneScrollInBody: true,
|
||||
pinnedHeaderSliverHeightBuilder: () =>
|
||||
kToolbarHeight + MediaQuery.viewPaddingOf(context).top,
|
||||
headerSliverBuilder: (context, innerBoxIsScrolled) {
|
||||
() => switch (_userController.loadingState.value) {
|
||||
Loading() => circularLoading,
|
||||
Success(:final response) => ExtendedNestedScrollView(
|
||||
key: _userController.key,
|
||||
onlyOneScrollInBody: true,
|
||||
pinnedHeaderSliverHeightBuilder: () =>
|
||||
kToolbarHeight + MediaQuery.viewPaddingOf(context).top,
|
||||
headerSliverBuilder: (context, innerBoxIsScrolled) {
|
||||
if (response != null) {
|
||||
return [
|
||||
_buildUserInfo(theme, _userController.loadingState.value),
|
||||
];
|
||||
},
|
||||
body: _userController.tab2?.isNotEmpty == true
|
||||
? Padding(
|
||||
padding: EdgeInsets.only(
|
||||
left: padding.left,
|
||||
right: padding.right,
|
||||
DynamicSliverAppBar.medium(
|
||||
actions: _actions(theme),
|
||||
title: Text(_userController.username ?? ''),
|
||||
flexibleSpace: Obx(
|
||||
() => UserInfoCard(
|
||||
isOwner:
|
||||
_userController.mid == _userController.account.mid,
|
||||
relation: _userController.relation.value,
|
||||
card: response.card!,
|
||||
images: response.images!,
|
||||
onFollow: () => _userController.onFollow(context),
|
||||
live: _userController.live,
|
||||
silence: _userController.silence,
|
||||
headerControllerBuilder: getHeaderController,
|
||||
),
|
||||
child: Column(
|
||||
children: [
|
||||
if ((_userController.tab2?.length ?? 0) > 1)
|
||||
SizedBox(
|
||||
height: 45,
|
||||
child: TabBar(
|
||||
controller: _userController.tabController,
|
||||
tabs: _userController.tabs,
|
||||
onTap: _userController.onTapTab,
|
||||
dividerColor: theme.outline.withValues(
|
||||
alpha: 0.2,
|
||||
),
|
||||
),
|
||||
),
|
||||
];
|
||||
}
|
||||
return [
|
||||
SliverAppBar(
|
||||
pinned: true,
|
||||
actions: _actions(theme),
|
||||
title: GestureDetector(
|
||||
onTap: _userController.onReload,
|
||||
behavior: HitTestBehavior.opaque,
|
||||
child: Text(_userController.username ?? ''),
|
||||
),
|
||||
),
|
||||
];
|
||||
},
|
||||
body: _userController.tab2?.isNotEmpty == true
|
||||
? Padding(
|
||||
padding: .only(left: padding.left, right: padding.right),
|
||||
child: Column(
|
||||
children: [
|
||||
if ((_userController.tab2?.length ?? 0) > 1)
|
||||
SizedBox(
|
||||
height: 45,
|
||||
child: TabBar(
|
||||
controller: _userController.tabController,
|
||||
tabs: _userController.tabs,
|
||||
onTap: _userController.onTapTab,
|
||||
dividerColor: theme.outline.withValues(
|
||||
alpha: 0.2,
|
||||
),
|
||||
),
|
||||
Expanded(child: _buildBody),
|
||||
],
|
||||
),
|
||||
)
|
||||
: const Center(child: Text('EMPTY')),
|
||||
);
|
||||
}
|
||||
return Center(
|
||||
child: _buildUserInfo(theme, _userController.loadingState.value),
|
||||
);
|
||||
),
|
||||
Expanded(child: _buildBody),
|
||||
],
|
||||
),
|
||||
)
|
||||
: scrollableError,
|
||||
),
|
||||
Error(:final errMsg) => scrollErrorWidget(
|
||||
errMsg: errMsg,
|
||||
onReload: _userController.onReload,
|
||||
),
|
||||
},
|
||||
),
|
||||
);
|
||||
@@ -346,47 +371,4 @@ class _MemberPageState extends State<MemberPage> {
|
||||
};
|
||||
}).toList(),
|
||||
);
|
||||
|
||||
Widget _buildUserInfo(
|
||||
ColorScheme theme,
|
||||
LoadingState<SpaceData?> userState,
|
||||
) {
|
||||
switch (userState) {
|
||||
case Loading():
|
||||
return const CircularProgressIndicator();
|
||||
case Success<SpaceData?>(:final response):
|
||||
if (response != null) {
|
||||
return DynamicSliverAppBar.medium(
|
||||
actions: _actions(theme),
|
||||
title: Text(_userController.username ?? ''),
|
||||
flexibleSpace: Obx(
|
||||
() => UserInfoCard(
|
||||
isOwner: _userController.mid == _userController.account.mid,
|
||||
relation: _userController.relation.value,
|
||||
card: response.card!,
|
||||
images: response.images!,
|
||||
onFollow: () => _userController.onFollow(context),
|
||||
live: _userController.live,
|
||||
silence: _userController.silence,
|
||||
headerControllerBuilder: getHeaderController,
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
return SliverAppBar(
|
||||
pinned: true,
|
||||
actions: _actions(theme),
|
||||
title: GestureDetector(
|
||||
onTap: _userController.onReload,
|
||||
behavior: HitTestBehavior.opaque,
|
||||
child: Text(_userController.username ?? ''),
|
||||
),
|
||||
);
|
||||
case Error(:final errMsg):
|
||||
return scrollErrorWidget(
|
||||
errMsg: errMsg,
|
||||
onReload: _userController.onReload,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -93,7 +93,7 @@ class _MemberContributeState extends State<MemberContribute>
|
||||
)
|
||||
: _controller.items?.isNotEmpty == true
|
||||
? _getPageFromType(_controller.items!.first)
|
||||
: scrollErrorWidget();
|
||||
: scrollableError;
|
||||
}
|
||||
|
||||
Widget _getPageFromType(SpaceTab2Item item) {
|
||||
|
||||
@@ -73,7 +73,7 @@ class _MemberHomeState extends State<MemberHome>
|
||||
final isOwner = setting != null;
|
||||
final color = Theme.of(context).colorScheme.outline;
|
||||
return switch (loadingState) {
|
||||
Loading() => loadingWidget,
|
||||
Loading() => circularLoading,
|
||||
Success(response: final res) =>
|
||||
res != null
|
||||
? CustomScrollView(
|
||||
@@ -257,7 +257,7 @@ class _MemberHomeState extends State<MemberHome>
|
||||
),
|
||||
],
|
||||
)
|
||||
: scrollErrorWidget(),
|
||||
: scrollableError,
|
||||
Error(:final errMsg) => scrollErrorWidget(errMsg: errMsg),
|
||||
};
|
||||
}
|
||||
|
||||
@@ -127,7 +127,7 @@ class _EditProfilePageState extends State<EditProfilePage> {
|
||||
);
|
||||
|
||||
return switch (loadingState) {
|
||||
Loading() => loadingWidget,
|
||||
Loading() => circularLoading,
|
||||
Success(:final response) => ListView(
|
||||
padding: EdgeInsets.only(
|
||||
bottom: MediaQuery.viewPaddingOf(context).bottom + 25,
|
||||
|
||||
@@ -83,7 +83,7 @@ class _PgcPageState extends State<PgcPage> with AutomaticKeepAliveClientMixin {
|
||||
ThemeData theme,
|
||||
LoadingState<List<TimelineResult>?> loadingState,
|
||||
) => switch (loadingState) {
|
||||
Loading() => loadingWidget,
|
||||
Loading() => circularLoading,
|
||||
Success(:final response) =>
|
||||
response != null && response.isNotEmpty
|
||||
? Builder(
|
||||
@@ -397,7 +397,7 @@ class _PgcPageState extends State<PgcPage> with AutomaticKeepAliveClientMixin {
|
||||
|
||||
Widget _buildFollowBody(LoadingState<List<FavPgcItemModel>?> loadingState) {
|
||||
return switch (loadingState) {
|
||||
Loading() => loadingWidget,
|
||||
Loading() => circularLoading,
|
||||
Success(:final response) =>
|
||||
response != null && response.isNotEmpty
|
||||
? ListView.builder(
|
||||
|
||||
@@ -58,7 +58,7 @@ class _PgcIndexPageState extends State<PgcIndexPage>
|
||||
) {
|
||||
final padding = MediaQuery.viewPaddingOf(context);
|
||||
return switch (loadingState) {
|
||||
Loading() => loadingWidget,
|
||||
Loading() => circularLoading,
|
||||
Success(:final response) => Builder(
|
||||
builder: (context) {
|
||||
int count =
|
||||
|
||||
@@ -184,7 +184,7 @@ class _LogsPageState extends State<LogsPage> {
|
||||
],
|
||||
),
|
||||
)
|
||||
: scrollErrorWidget(),
|
||||
: scrollableError,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -81,7 +81,7 @@ class _HorizontalMemberPageState extends State<HorizontalMemberPage> {
|
||||
|
||||
Widget _buildUserPage(ThemeData theme, LoadingState userState) {
|
||||
return switch (userState) {
|
||||
Loading() => loadingWidget,
|
||||
Loading() => circularLoading,
|
||||
Success(:final response) => Column(
|
||||
children: [
|
||||
_buildUserInfo(theme, response),
|
||||
|
||||
@@ -2,7 +2,7 @@ import 'dart:async';
|
||||
import 'dart:math';
|
||||
|
||||
import 'package:PiliPlus/common/widgets/button/icon_button.dart';
|
||||
import 'package:PiliPlus/common/widgets/loading_widget/loading_widget.dart';
|
||||
import 'package:PiliPlus/common/widgets/loading_widget/http_error.dart';
|
||||
import 'package:PiliPlus/common/widgets/pair.dart';
|
||||
import 'package:PiliPlus/http/loading_state.dart';
|
||||
import 'package:PiliPlus/http/sponsor_block.dart';
|
||||
@@ -249,7 +249,7 @@ class _PostPanelState extends State<PostPanel>
|
||||
@override
|
||||
Widget buildList(ThemeData theme) {
|
||||
if (list.isEmpty) {
|
||||
return errorWidget();
|
||||
return const HttpError(isSliver: false);
|
||||
}
|
||||
final bottom = MediaQuery.viewPaddingOf(context).bottom;
|
||||
Widget child = ListView.builder(
|
||||
|
||||
@@ -37,7 +37,7 @@ class _WhisperBlockPageState extends State<WhisperBlockPage> {
|
||||
LoadingState<List<KeywordBlockingItem>?> loadingState,
|
||||
) {
|
||||
return switch (loadingState) {
|
||||
Loading() => loadingWidget,
|
||||
Loading() => circularLoading,
|
||||
Success(:final response) =>
|
||||
response != null && response.isNotEmpty
|
||||
? Column(
|
||||
|
||||
@@ -151,7 +151,7 @@ class _WhisperDetailPageState
|
||||
|
||||
Widget _buildBody(LoadingState<List<Msg>?> loadingState) {
|
||||
return switch (loadingState) {
|
||||
Loading() => loadingWidget,
|
||||
Loading() => circularLoading,
|
||||
Success(:final response) =>
|
||||
response != null && response.isNotEmpty
|
||||
? ChatListView.separated(
|
||||
|
||||
Reference in New Issue
Block a user