💄 Better scrolling
This commit is contained in:
parent
d4cbabeb31
commit
5f06fc4f9d
@ -75,94 +75,76 @@ class _ContactScreenState extends State<ContactScreen> {
|
||||
);
|
||||
}
|
||||
|
||||
return SafeArea(
|
||||
child: NestedScrollView(
|
||||
headerSliverBuilder: (context, innerBoxIsScrolled) {
|
||||
return [
|
||||
SliverOverlapAbsorber(
|
||||
handle: NestedScrollView.sliverOverlapAbsorberHandleFor(
|
||||
context),
|
||||
sliver: SliverAppBar(
|
||||
title: Text('contact'.tr),
|
||||
centerTitle: false,
|
||||
titleSpacing:
|
||||
SolianTheme.isLargeScreen(context) ? null : 24,
|
||||
forceElevated: innerBoxIsScrolled,
|
||||
actions: [
|
||||
const NotificationButton(),
|
||||
PopupMenuButton(
|
||||
icon: const Icon(Icons.add_circle),
|
||||
itemBuilder: (BuildContext context) => [
|
||||
PopupMenuItem(
|
||||
child: ListTile(
|
||||
title: Text('channelOrganizeCommon'.tr),
|
||||
leading: const Icon(Icons.tag),
|
||||
contentPadding:
|
||||
const EdgeInsets.symmetric(horizontal: 8),
|
||||
),
|
||||
onTap: () {
|
||||
AppRouter.instance
|
||||
.pushNamed('channelOrganizing')
|
||||
.then(
|
||||
(value) {
|
||||
if (value != null) getChannels();
|
||||
},
|
||||
);
|
||||
return RefreshIndicator(
|
||||
onRefresh: () => getChannels(),
|
||||
child: CustomScrollView(
|
||||
slivers: [
|
||||
SliverAppBar(
|
||||
title: Text('contact'.tr),
|
||||
centerTitle: false,
|
||||
titleSpacing: SolianTheme.isLargeScreen(context) ? null : 24,
|
||||
actions: [
|
||||
const NotificationButton(),
|
||||
PopupMenuButton(
|
||||
icon: const Icon(Icons.add_circle),
|
||||
itemBuilder: (BuildContext context) => [
|
||||
PopupMenuItem(
|
||||
child: ListTile(
|
||||
title: Text('channelOrganizeCommon'.tr),
|
||||
leading: const Icon(Icons.tag),
|
||||
contentPadding:
|
||||
const EdgeInsets.symmetric(horizontal: 8),
|
||||
),
|
||||
onTap: () {
|
||||
AppRouter.instance
|
||||
.pushNamed('channelOrganizing')
|
||||
.then(
|
||||
(value) {
|
||||
if (value != null) getChannels();
|
||||
},
|
||||
),
|
||||
PopupMenuItem(
|
||||
child: ListTile(
|
||||
title: Text('channelOrganizeDirect'.tr),
|
||||
leading: const FaIcon(
|
||||
FontAwesomeIcons.userGroup,
|
||||
size: 16,
|
||||
),
|
||||
contentPadding:
|
||||
const EdgeInsets.symmetric(horizontal: 8),
|
||||
),
|
||||
onTap: () {
|
||||
final ChannelProvider provider = Get.find();
|
||||
provider
|
||||
.createDirectChannel(context, 'global')
|
||||
.then((resp) {
|
||||
if (resp != null) {
|
||||
getChannels();
|
||||
}
|
||||
});
|
||||
},
|
||||
),
|
||||
],
|
||||
);
|
||||
},
|
||||
),
|
||||
SizedBox(
|
||||
width: SolianTheme.isLargeScreen(context) ? 8 : 16,
|
||||
PopupMenuItem(
|
||||
child: ListTile(
|
||||
title: Text('channelOrganizeDirect'.tr),
|
||||
leading: const FaIcon(
|
||||
FontAwesomeIcons.userGroup,
|
||||
size: 16,
|
||||
),
|
||||
contentPadding:
|
||||
const EdgeInsets.symmetric(horizontal: 8),
|
||||
),
|
||||
onTap: () {
|
||||
final ChannelProvider provider = Get.find();
|
||||
provider
|
||||
.createDirectChannel(context, 'global')
|
||||
.then((resp) {
|
||||
if (resp != null) {
|
||||
getChannels();
|
||||
}
|
||||
});
|
||||
},
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
];
|
||||
},
|
||||
body: MediaQuery.removePadding(
|
||||
removeTop: true,
|
||||
context: context,
|
||||
child: Column(
|
||||
children: [
|
||||
if (_isBusy)
|
||||
const LinearProgressIndicator().animate().scaleX(),
|
||||
Expanded(
|
||||
child: RefreshIndicator(
|
||||
onRefresh: () => getChannels(),
|
||||
child: ListView.builder(
|
||||
itemCount: _channels.length,
|
||||
itemBuilder: (context, index) {
|
||||
final element = _channels[index];
|
||||
return buildItem(element);
|
||||
},
|
||||
),
|
||||
),
|
||||
SizedBox(
|
||||
width: SolianTheme.isLargeScreen(context) ? 8 : 16,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
if (_isBusy)
|
||||
SliverToBoxAdapter(
|
||||
child: const LinearProgressIndicator().animate().scaleX(),
|
||||
),
|
||||
SliverList.builder(
|
||||
itemCount: _channels.length,
|
||||
itemBuilder: (context, index) {
|
||||
final element = _channels[index];
|
||||
return buildItem(element);
|
||||
},
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
},
|
||||
|
@ -44,22 +44,25 @@ class _PostDetailScreenState extends State<PostDetailScreen> {
|
||||
);
|
||||
}
|
||||
|
||||
return ListView(
|
||||
children: [
|
||||
PostItem(
|
||||
item: item!,
|
||||
isClickable: true,
|
||||
isShowReply: false,
|
||||
return CustomScrollView(
|
||||
slivers: [
|
||||
SliverToBoxAdapter(
|
||||
child: PostItem(
|
||||
item: item!,
|
||||
isClickable: true,
|
||||
isShowReply: false,
|
||||
),
|
||||
),
|
||||
const Divider(thickness: 0.3, height: 0.3),
|
||||
Text(
|
||||
'postReplies'.tr,
|
||||
style: Theme.of(context).textTheme.headlineSmall,
|
||||
).paddingOnly(left: 24, right: 24, top: 16),
|
||||
PostReplyList(
|
||||
item: item!,
|
||||
shrinkWrap: true,
|
||||
const SliverToBoxAdapter(
|
||||
child: Divider(thickness: 0.3, height: 0.3),
|
||||
),
|
||||
SliverToBoxAdapter(
|
||||
child: Text(
|
||||
'postReplies'.tr,
|
||||
style: Theme.of(context).textTheme.headlineSmall,
|
||||
).paddingOnly(left: 24, right: 24, top: 16),
|
||||
),
|
||||
PostReplyList(item: item!),
|
||||
],
|
||||
);
|
||||
},
|
||||
|
@ -66,63 +66,43 @@ class _RealmListScreenState extends State<RealmListScreen> {
|
||||
);
|
||||
}
|
||||
|
||||
return SafeArea(
|
||||
child: NestedScrollView(
|
||||
headerSliverBuilder: (context, innerBoxIsScrolled) {
|
||||
return [
|
||||
SliverOverlapAbsorber(
|
||||
handle: NestedScrollView.sliverOverlapAbsorberHandleFor(
|
||||
context),
|
||||
sliver: SliverAppBar(
|
||||
title: Text('realm'.tr),
|
||||
centerTitle: false,
|
||||
titleSpacing:
|
||||
SolianTheme.isLargeScreen(context) ? null : 24,
|
||||
forceElevated: innerBoxIsScrolled,
|
||||
actions: [
|
||||
const NotificationButton(),
|
||||
IconButton(
|
||||
icon: const Icon(Icons.add_circle),
|
||||
onPressed: () {
|
||||
AppRouter.instance
|
||||
.pushNamed('realmOrganizing')
|
||||
.then(
|
||||
(value) {
|
||||
if (value != null) getRealms();
|
||||
},
|
||||
);
|
||||
return RefreshIndicator(
|
||||
onRefresh: () => getRealms(),
|
||||
child: CustomScrollView(
|
||||
slivers: [
|
||||
SliverAppBar(
|
||||
title: Text('realm'.tr),
|
||||
centerTitle: false,
|
||||
titleSpacing: SolianTheme.isLargeScreen(context) ? null : 24,
|
||||
actions: [
|
||||
const NotificationButton(),
|
||||
IconButton(
|
||||
icon: const Icon(Icons.add_circle),
|
||||
onPressed: () {
|
||||
AppRouter.instance.pushNamed('realmOrganizing').then(
|
||||
(value) {
|
||||
if (value != null) getRealms();
|
||||
},
|
||||
),
|
||||
SizedBox(
|
||||
width: SolianTheme.isLargeScreen(context) ? 8 : 16,
|
||||
),
|
||||
],
|
||||
);
|
||||
},
|
||||
),
|
||||
),
|
||||
];
|
||||
},
|
||||
body: MediaQuery.removePadding(
|
||||
removeTop: true,
|
||||
context: context,
|
||||
child: Column(
|
||||
children: [
|
||||
if (_isBusy)
|
||||
const LinearProgressIndicator().animate().scaleX(),
|
||||
Expanded(
|
||||
child: RefreshIndicator(
|
||||
onRefresh: () => getRealms(),
|
||||
child: ListView.builder(
|
||||
itemCount: _realms.length,
|
||||
itemBuilder: (context, index) {
|
||||
final element = _realms[index];
|
||||
return buildRealm(element);
|
||||
},
|
||||
),
|
||||
),
|
||||
SizedBox(
|
||||
width: SolianTheme.isLargeScreen(context) ? 8 : 16,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
if (_isBusy)
|
||||
SliverToBoxAdapter(
|
||||
child: const LinearProgressIndicator().animate().scaleX(),
|
||||
),
|
||||
SliverList.builder(
|
||||
itemCount: _realms.length,
|
||||
itemBuilder: (context, index) {
|
||||
final element = _realms[index];
|
||||
return buildRealm(element);
|
||||
},
|
||||
)
|
||||
],
|
||||
),
|
||||
);
|
||||
},
|
||||
|
@ -72,39 +72,24 @@ class _SocialScreenState extends State<SocialScreen> {
|
||||
}),
|
||||
body: Material(
|
||||
color: Theme.of(context).colorScheme.surface,
|
||||
child: SafeArea(
|
||||
child: NestedScrollView(
|
||||
headerSliverBuilder: (context, innerBoxIsScrolled) {
|
||||
return [
|
||||
SliverOverlapAbsorber(
|
||||
handle:
|
||||
NestedScrollView.sliverOverlapAbsorberHandleFor(context),
|
||||
sliver: SliverAppBar(
|
||||
title: Text('social'.tr),
|
||||
centerTitle: false,
|
||||
floating: true,
|
||||
snap: true,
|
||||
titleSpacing:
|
||||
SolianTheme.isLargeScreen(context) ? null : 24,
|
||||
forceElevated: innerBoxIsScrolled,
|
||||
actions: [
|
||||
const NotificationButton(),
|
||||
SizedBox(
|
||||
width: SolianTheme.isLargeScreen(context) ? 8 : 16,
|
||||
),
|
||||
],
|
||||
child: RefreshIndicator(
|
||||
onRefresh: () => Future.sync(() => _pagingController.refresh()),
|
||||
child: CustomScrollView(
|
||||
slivers: [
|
||||
SliverAppBar(
|
||||
title: Text('social'.tr),
|
||||
centerTitle: false,
|
||||
floating: true,
|
||||
titleSpacing: SolianTheme.isLargeScreen(context) ? null : 24,
|
||||
actions: [
|
||||
const NotificationButton(),
|
||||
SizedBox(
|
||||
width: SolianTheme.isLargeScreen(context) ? 8 : 16,
|
||||
),
|
||||
),
|
||||
];
|
||||
},
|
||||
body: MediaQuery.removePadding(
|
||||
removeTop: true,
|
||||
context: context,
|
||||
child: RefreshIndicator(
|
||||
onRefresh: () => Future.sync(() => _pagingController.refresh()),
|
||||
child: PostListWidget(controller: _pagingController),
|
||||
],
|
||||
),
|
||||
),
|
||||
PostListWidget(controller: _pagingController),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
|
@ -7,7 +7,6 @@ import 'package:solian/widgets/posts/post_action.dart';
|
||||
import 'package:solian/widgets/posts/post_item.dart';
|
||||
|
||||
class PostListWidget extends StatelessWidget {
|
||||
final bool shrinkWrap;
|
||||
final bool isShowEmbed;
|
||||
final bool isClickable;
|
||||
final bool isNestedClickable;
|
||||
@ -16,7 +15,6 @@ class PostListWidget extends StatelessWidget {
|
||||
const PostListWidget({
|
||||
super.key,
|
||||
required this.controller,
|
||||
this.shrinkWrap = false,
|
||||
this.isShowEmbed = true,
|
||||
this.isClickable = true,
|
||||
this.isNestedClickable = true,
|
||||
@ -24,8 +22,7 @@ class PostListWidget extends StatelessWidget {
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return PagedListView<int, Post>.separated(
|
||||
shrinkWrap: shrinkWrap,
|
||||
return PagedSliverList<int, Post>.separated(
|
||||
pagingController: controller,
|
||||
builderDelegate: PagedChildBuilderDelegate<Post>(
|
||||
itemBuilder: (context, item, index) {
|
||||
|
@ -8,12 +8,10 @@ import 'package:solian/widgets/posts/post_list.dart';
|
||||
|
||||
class PostReplyList extends StatefulWidget {
|
||||
final Post item;
|
||||
final bool shrinkWrap;
|
||||
|
||||
const PostReplyList({
|
||||
super.key,
|
||||
required this.item,
|
||||
this.shrinkWrap = false,
|
||||
});
|
||||
|
||||
@override
|
||||
@ -55,7 +53,6 @@ class _PostReplyListState extends State<PostReplyList> {
|
||||
Widget build(BuildContext context) {
|
||||
return PostListWidget(
|
||||
isShowEmbed: false,
|
||||
shrinkWrap: widget.shrinkWrap,
|
||||
controller: _pagingController,
|
||||
);
|
||||
}
|
||||
@ -76,8 +73,8 @@ class PostReplyListPopup extends StatelessWidget {
|
||||
style: Theme.of(context).textTheme.headlineSmall,
|
||||
).paddingOnly(left: 24, right: 24, top: 32, bottom: 16),
|
||||
Expanded(
|
||||
child: PostReplyList(
|
||||
item: item,
|
||||
child: CustomScrollView(
|
||||
slivers: [PostReplyList(item: item)],
|
||||
),
|
||||
),
|
||||
],
|
||||
|
Loading…
Reference in New Issue
Block a user