💄 Use bottom modal sheet instead of popover

 Show strike on user profile page
This commit is contained in:
LittleSheep 2025-04-02 00:51:46 +08:00
parent cf34a285b4
commit d5cf2478d8
5 changed files with 234 additions and 203 deletions

View File

@ -15,6 +15,7 @@ import 'package:surface/providers/experience.dart';
import 'package:surface/providers/relationship.dart'; import 'package:surface/providers/relationship.dart';
import 'package:surface/providers/sn_network.dart'; import 'package:surface/providers/sn_network.dart';
import 'package:surface/screens/abuse_report.dart'; import 'package:surface/screens/abuse_report.dart';
import 'package:surface/screens/account/punishments.dart';
import 'package:surface/types/account.dart'; import 'package:surface/types/account.dart';
import 'package:surface/types/check_in.dart'; import 'package:surface/types/check_in.dart';
import 'package:surface/types/post.dart'; import 'package:surface/types/post.dart';
@ -457,7 +458,7 @@ class _UserScreenState extends State<UserScreen>
], ],
).padding(right: 8), ).padding(right: 8),
if (_account!.profile!.description.isNotEmpty) if (_account!.profile!.description.isNotEmpty)
const Gap(12) const Gap(4)
else else
const Gap(8), const Gap(8),
if (_account!.profile!.description.isNotEmpty) if (_account!.profile!.description.isNotEmpty)
@ -503,7 +504,8 @@ class _UserScreenState extends State<UserScreen>
], ],
).padding(vertical: 8, horizontal: 12), ).padding(vertical: 8, horizontal: 12),
), ),
const Gap(8), if (_account!.badges.isNotEmpty) const Gap(8),
if (_account!.badges.isNotEmpty)
Wrap( Wrap(
spacing: 4, spacing: 4,
runSpacing: 4, runSpacing: 4,
@ -619,6 +621,17 @@ class _UserScreenState extends State<UserScreen>
], ],
).padding(all: 16), ).padding(all: 16),
), ),
if (_account?.punishments.isNotEmpty ?? false)
SliverToBoxAdapter(child: const Divider()),
if (_account?.punishments.isNotEmpty ?? false)
SliverToBoxAdapter(
child: Column(
children: [
for (final ele in _account!.punishments)
PunishmentInfoCard(ele: ele),
],
),
),
if (_account?.profile?.links.isNotEmpty ?? false) if (_account?.profile?.links.isNotEmpty ?? false)
SliverToBoxAdapter(child: const Divider()), SliverToBoxAdapter(child: const Divider()),
if (_account?.profile?.links.isNotEmpty ?? false) if (_account?.profile?.links.isNotEmpty ?? false)

View File

@ -107,6 +107,28 @@ class _PunishmentsScreenState extends State<PunishmentsScreen> {
itemCount: _punishments?.length ?? 0, itemCount: _punishments?.length ?? 0,
itemBuilder: (context, index) { itemBuilder: (context, index) {
final ele = _punishments![index]; final ele = _punishments![index];
return PunishmentInfoCard(ele: ele);
},
separatorBuilder: (_, __) => const Gap(8),
),
),
),
],
),
);
}
}
class PunishmentInfoCard extends StatelessWidget {
const PunishmentInfoCard({
super.key,
required this.ele,
});
final SnPunishment ele;
@override
Widget build(BuildContext context) {
return Card( return Card(
margin: EdgeInsets.symmetric(horizontal: 8), margin: EdgeInsets.symmetric(horizontal: 8),
child: Column( child: Column(
@ -117,10 +139,8 @@ class _PunishmentsScreenState extends State<PunishmentsScreen> {
Icon(kPunishmentIcons[ele.type], size: 20), Icon(kPunishmentIcons[ele.type], size: 20),
const Gap(6), const Gap(6),
Expanded( Expanded(
child: Text('punishmentType${ele.type}') child:
.tr() Text('punishmentType${ele.type}').tr().fontSize(16).bold(),
.fontSize(16)
.bold(),
), ),
], ],
), ),
@ -175,13 +195,5 @@ class _PunishmentsScreenState extends State<PunishmentsScreen> {
], ],
).padding(horizontal: 24, vertical: 16), ).padding(horizontal: 24, vertical: 16),
); );
},
separatorBuilder: (_, __) => const Gap(8),
),
),
),
],
),
);
} }
} }

View File

@ -39,7 +39,9 @@ class AccountPopoverCard extends StatelessWidget {
), ),
), ),
), ),
).padding(all: 16), ).padding(all: 16)
else
const Gap(16),
// Top padding // Top padding
Row( Row(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
@ -89,7 +91,9 @@ class AccountPopoverCard extends StatelessWidget {
data.profile?.description ?? '', data.profile?.description ?? '',
maxLines: 2, maxLines: 2,
overflow: TextOverflow.ellipsis, overflow: TextOverflow.ellipsis,
).padding(horizontal: 26, bottom: 8), ).padding(horizontal: 26, bottom: 8)
else
const Gap(12),
Row( Row(
crossAxisAlignment: CrossAxisAlignment.center, crossAxisAlignment: CrossAxisAlignment.center,
children: [ children: [

View File

@ -12,7 +12,6 @@ import 'package:go_router/go_router.dart';
import 'package:google_fonts/google_fonts.dart'; import 'package:google_fonts/google_fonts.dart';
import 'package:material_symbols_icons/symbols.dart'; import 'package:material_symbols_icons/symbols.dart';
import 'package:path_provider/path_provider.dart'; import 'package:path_provider/path_provider.dart';
import 'package:popover/popover.dart';
import 'package:provider/provider.dart'; import 'package:provider/provider.dart';
import 'package:qr_flutter/qr_flutter.dart'; import 'package:qr_flutter/qr_flutter.dart';
import 'package:relative_time/relative_time.dart'; import 'package:relative_time/relative_time.dart';
@ -1274,20 +1273,11 @@ class _PostAvatar extends StatelessWidget {
), ),
), ),
onTap: () { onTap: () {
showPopover( showModalBottomSheet(
backgroundColor: Theme.of(context).colorScheme.surface,
context: context, context: context,
transition: PopoverTransition.other, builder: (context) => PublisherPopoverCard(
bodyBuilder: (context) => SizedBox(
width: math.min(400, MediaQuery.of(context).size.width - 10),
child: PublisherPopoverCard(
data: data.publisher, data: data.publisher,
), ),
),
direction: PopoverDirection.bottom,
arrowHeight: 5,
arrowWidth: 15,
arrowDxOffset: -190,
); );
}, },
); );

View File

@ -24,12 +24,14 @@ class PublisherPopoverCard extends StatelessWidget {
final user = data.type == 0 ? ud.getFromCache(data.accountId) : null; final user = data.type == 0 ? ud.getFromCache(data.accountId) : null;
return Column( return SingleChildScrollView(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
mainAxisSize: MainAxisSize.min,
children: [ children: [
if (data.banner.isNotEmpty) if (data.banner.isNotEmpty)
Container( ClipRRect(
borderRadius: BorderRadius.circular(16),
child: Container(
color: Theme.of(context).colorScheme.surfaceContainer, color: Theme.of(context).colorScheme.surfaceContainer,
child: AspectRatio( child: AspectRatio(
aspectRatio: 16 / 7, aspectRatio: 16 / 7,
@ -39,6 +41,8 @@ class PublisherPopoverCard extends StatelessWidget {
), ),
), ),
), ),
).padding(all: 16)
else
// Top padding // Top padding
Gap(16), Gap(16),
Row( Row(
@ -70,7 +74,8 @@ class PublisherPopoverCard extends StatelessWidget {
}, },
icon: const Icon(Symbols.chevron_right), icon: const Icon(Symbols.chevron_right),
padding: EdgeInsets.zero, padding: EdgeInsets.zero,
visualDensity: const VisualDensity(horizontal: -4, vertical: -4), visualDensity:
const VisualDensity(horizontal: -4, vertical: -4),
), ),
const Gap(8) const Gap(8)
], ],
@ -98,7 +103,10 @@ class PublisherPopoverCard extends StatelessWidget {
mainAxisSize: MainAxisSize.min, mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.center, crossAxisAlignment: CrossAxisAlignment.center,
children: [ children: [
Text('publisherSocialPoint').tr().fontSize(13).opacity(0.75), Text('publisherSocialPoint')
.tr()
.fontSize(13)
.opacity(0.75),
Text((data.totalUpvote - data.totalDownvote).toString()), Text((data.totalUpvote - data.totalDownvote).toString()),
], ],
), ),
@ -114,7 +122,10 @@ class PublisherPopoverCard extends StatelessWidget {
mainAxisSize: MainAxisSize.min, mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.center, crossAxisAlignment: CrossAxisAlignment.center,
children: [ children: [
Text('publisherTotalUpvote').tr().fontSize(13).opacity(0.75), Text('publisherTotalUpvote')
.tr()
.fontSize(13)
.opacity(0.75),
Text(data.totalUpvote.toString()), Text(data.totalUpvote.toString()),
], ],
), ),
@ -141,8 +152,9 @@ class PublisherPopoverCard extends StatelessWidget {
], ],
).padding(horizontal: 16), ).padding(horizontal: 16),
// Bottom padding // Bottom padding
const Gap(16), const Gap(64),
], ],
),
); );
} }
} }