Files
.github
android
api
assets
buildtools
debian
drift_schemas
ios
lib
controllers
database
providers
screens
types
widgets
account
attachment
chat
feed
navigation
post
fediverse_post_item.dart
post_comment_list.dart
post_item.dart
post_media_pending_list.dart
post_meta_editor.dart
post_mini_editor.dart
post_poll.dart
post_poll_editor.dart
post_reaction.dart
post_tags_field.dart
publisher_popover.dart
realm
about.dart
app_bar_leading.dart
connection_indicator.dart
context_menu.dart
dialog.dart
html.dart
link_preview.dart
loading_indicator.dart
markdown_content.dart
menu_bar.dart
notify_indicator.dart
unauthorized_hint.dart
universal_image.dart
updater.dart
version_label.dart
firebase_options.dart
logger.dart
main.dart
router.dart
theme.dart
linux
macos
snap
test
web
windows
.gitignore
.metadata
.roadsignrc
CODE_OF_CONDUCT.md
README.md
analysis_options.yaml
build.yaml
devtools_options.yaml
firebase.json
pubspec.lock
pubspec.yaml
roadsign.toml
App/lib/widgets/post/publisher_popover.dart
LittleSheep d5cf2478d8 💄 Use bottom modal sheet instead of popover
 Show strike on user profile page
2025-04-02 00:52:03 +08:00

161 lines
5.4 KiB
Dart

import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/material.dart';
import 'package:gap/gap.dart';
import 'package:go_router/go_router.dart';
import 'package:material_symbols_icons/symbols.dart';
import 'package:provider/provider.dart';
import 'package:styled_widget/styled_widget.dart';
import 'package:surface/providers/sn_network.dart';
import 'package:surface/providers/user_directory.dart';
import 'package:surface/types/post.dart';
import 'package:surface/widgets/account/account_image.dart';
import 'package:surface/widgets/account/badge.dart';
import 'package:surface/widgets/universal_image.dart';
class PublisherPopoverCard extends StatelessWidget {
final SnPublisher data;
const PublisherPopoverCard({super.key, required this.data});
@override
Widget build(BuildContext context) {
final sn = context.read<SnNetworkProvider>();
final ud = context.read<UserDirectoryProvider>();
final user = data.type == 0 ? ud.getFromCache(data.accountId) : null;
return SingleChildScrollView(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
if (data.banner.isNotEmpty)
ClipRRect(
borderRadius: BorderRadius.circular(16),
child: Container(
color: Theme.of(context).colorScheme.surfaceContainer,
child: AspectRatio(
aspectRatio: 16 / 7,
child: AutoResizeUniversalImage(
sn.getAttachmentUrl(data.banner),
fit: BoxFit.cover,
),
),
),
).padding(all: 16)
else
// Top padding
Gap(16),
Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
AccountImage(
content: data.avatar,
radius: 20,
borderRadius: data.type == 1 ? 8 : 20,
),
Gap(16),
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisSize: MainAxisSize.min,
children: [
Text(data.nick).bold(),
Text('@${data.name}').fontSize(13).opacity(0.75),
],
),
),
IconButton(
onPressed: () {
Navigator.pop(context);
GoRouter.of(context).pushNamed(
'postPublisher',
pathParameters: {'name': data.name},
);
},
icon: const Icon(Symbols.chevron_right),
padding: EdgeInsets.zero,
visualDensity:
const VisualDensity(horizontal: -4, vertical: -4),
),
const Gap(8)
],
).padding(horizontal: 16),
if (user != null && user.badges.isNotEmpty)
Wrap(
spacing: 4,
children: user.badges
.map(
(ele) => AccountBadge(badge: ele),
)
.toList(),
).padding(horizontal: 24, top: 16),
const Gap(16),
if (data.description.isNotEmpty)
Text(
data.description,
maxLines: 2,
overflow: TextOverflow.ellipsis,
).padding(horizontal: 26, bottom: 20),
Row(
children: [
Expanded(
child: Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Text('publisherSocialPoint')
.tr()
.fontSize(13)
.opacity(0.75),
Text((data.totalUpvote - data.totalDownvote).toString()),
],
),
),
SizedBox(
height: 20,
child: const VerticalDivider(
thickness: 1,
),
).padding(horizontal: 8),
Expanded(
child: Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Text('publisherTotalUpvote')
.tr()
.fontSize(13)
.opacity(0.75),
Text(data.totalUpvote.toString()),
],
),
),
SizedBox(
height: 20,
child: const VerticalDivider(
thickness: 1,
),
).padding(horizontal: 8),
Expanded(
child: Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Text('publisherTotalDownvote')
.tr()
.fontSize(13)
.opacity(0.75),
Text(data.totalDownvote.toString()),
],
),
),
],
).padding(horizontal: 16),
// Bottom padding
const Gap(64),
],
),
);
}
}