Show badge in more places

♻️ Refactor account image
This commit is contained in:
LittleSheep 2025-03-02 21:52:41 +08:00
parent 22fde6b400
commit 17e6b81f76
4 changed files with 60 additions and 25 deletions

View File

@ -28,6 +28,7 @@ class SnPostContentProvider {
Future<List<SnPost>> _preloadRelatedDataInBatch(List<SnPost> out) async { Future<List<SnPost>> _preloadRelatedDataInBatch(List<SnPost> out) async {
Set<String> rids = {}; Set<String> rids = {};
Set<int> uids = {};
for (var i = 0; i < out.length; i++) { for (var i = 0; i < out.length; i++) {
rids.addAll(out[i].body['attachments']?.cast<String>() ?? []); rids.addAll(out[i].body['attachments']?.cast<String>() ?? []);
if (out[i].body['thumbnail'] != null) { if (out[i].body['thumbnail'] != null) {
@ -41,6 +42,9 @@ class SnPostContentProvider {
repostTo: await _preloadRelatedDataSingle(out[i].repostTo!), repostTo: await _preloadRelatedDataSingle(out[i].repostTo!),
); );
} }
if (out[i].publisher.type == 0) {
uids.add(out[i].publisher.accountId);
}
} }
final attachments = await _attach.getMultiple(rids.toList()); final attachments = await _attach.getMultiple(rids.toList());
@ -65,15 +69,15 @@ class SnPostContentProvider {
); );
} }
await _ud.listAccount( uids.addAll(attachments.where((ele) => ele != null).map((ele) => ele!.accountId));
attachments.where((ele) => ele != null).map((ele) => ele!.accountId).toSet(), await _ud.listAccount(uids);
);
return out; return out;
} }
Future<SnPost> _preloadRelatedDataSingle(SnPost out) async { Future<SnPost> _preloadRelatedDataSingle(SnPost out) async {
Set<String> rids = {}; Set<String> rids = {};
Set<int> uids = {};
rids.addAll(out.body['attachments']?.cast<String>() ?? []); rids.addAll(out.body['attachments']?.cast<String>() ?? []);
if (out.body['thumbnail'] != null) { if (out.body['thumbnail'] != null) {
rids.add(out.body['thumbnail']); rids.add(out.body['thumbnail']);
@ -86,6 +90,9 @@ class SnPostContentProvider {
repostTo: await _preloadRelatedDataSingle(out.repostTo!), repostTo: await _preloadRelatedDataSingle(out.repostTo!),
); );
} }
if (out.publisher.type == 0) {
uids.add(out.publisher.accountId);
}
final attachments = await _attach.getMultiple(rids.toList()); final attachments = await _attach.getMultiple(rids.toList());
@ -108,6 +115,9 @@ class SnPostContentProvider {
), ),
); );
uids.addAll(attachments.where((ele) => ele != null).map((ele) => ele!.accountId));
await _ud.listAccount(uids);
return out; return out;
} }

View File

@ -1,6 +1,7 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:material_symbols_icons/symbols.dart'; import 'package:material_symbols_icons/symbols.dart';
import 'package:provider/provider.dart'; import 'package:provider/provider.dart';
import 'package:styled_widget/styled_widget.dart';
import 'package:surface/providers/sn_network.dart'; import 'package:surface/providers/sn_network.dart';
import 'package:surface/widgets/universal_image.dart'; import 'package:surface/widgets/universal_image.dart';
@ -9,6 +10,7 @@ class AccountImage extends StatelessWidget {
final Color? backgroundColor; final Color? backgroundColor;
final Color? foregroundColor; final Color? foregroundColor;
final double? radius; final double? radius;
final double? borderRadius;
final Widget? fallbackWidget; final Widget? fallbackWidget;
final Widget? badge; final Widget? badge;
@ -18,6 +20,7 @@ class AccountImage extends StatelessWidget {
this.backgroundColor, this.backgroundColor,
this.foregroundColor, this.foregroundColor,
this.radius, this.radius,
this.borderRadius,
this.fallbackWidget, this.fallbackWidget,
this.badge, this.badge,
}); });
@ -27,29 +30,30 @@ class AccountImage extends StatelessWidget {
final sn = context.read<SnNetworkProvider>(); final sn = context.read<SnNetworkProvider>();
final url = sn.getAttachmentUrl(content ?? ''); final url = sn.getAttachmentUrl(content ?? '');
final devicePixelRatio = MediaQuery.of(context).devicePixelRatio;
return Stack( return Stack(
children: [ children: [
CircleAvatar( SizedBox(
key: Key('attachment-${content.hashCode}'), width: (radius != null ? radius! : 20) * 2,
radius: radius, height: (radius != null ? radius! : 20) * 2,
backgroundColor: backgroundColor, child: ClipRRect(
backgroundImage: (content?.isNotEmpty ?? false) borderRadius: BorderRadius.circular(borderRadius ?? radius ?? 20),
? ResizeImage( child: (content?.isEmpty ?? true)
UniversalImage.provider(url), ? Container(
width: ((radius ?? 20) * devicePixelRatio * 2).round(), color: backgroundColor ?? Theme.of(context).colorScheme.primaryContainer,
height: ((radius ?? 20) * devicePixelRatio * 2).round(), child: (fallbackWidget ??
policy: ResizeImagePolicy.fit, Icon(
) Symbols.account_circle,
: null, size: radius != null ? radius! * 1.2 : 24,
child: (content?.isEmpty ?? true) color: foregroundColor,
? (fallbackWidget ?? ))
Icon( .center(),
Symbols.account_circle, )
size: radius != null ? radius! * 1.2 : 24, : AutoResizeUniversalImage(
color: foregroundColor, sn.getAttachmentUrl(url),
)) key: Key('attachment-${content.hashCode}'),
: null, fit: BoxFit.cover,
),
),
), ),
if (badge != null) if (badge != null)
Positioned( Positioned(

View File

@ -117,7 +117,7 @@ class ChatMessage extends StatelessWidget {
Shadow( Shadow(
offset: Offset(1, 1), offset: Offset(1, 1),
blurRadius: 5.0, blurRadius: 5.0,
color: Color.fromARGB(150, 0, 0, 0), color: Color.fromARGB(255, 0, 0, 0),
), ),
], ],
) )

View File

@ -22,6 +22,7 @@ import 'package:share_plus/share_plus.dart';
import 'package:styled_widget/styled_widget.dart'; import 'package:styled_widget/styled_widget.dart';
import 'package:surface/providers/config.dart'; import 'package:surface/providers/config.dart';
import 'package:surface/providers/sn_network.dart'; import 'package:surface/providers/sn_network.dart';
import 'package:surface/providers/user_directory.dart';
import 'package:surface/providers/userinfo.dart'; import 'package:surface/providers/userinfo.dart';
import 'package:surface/screens/post/post_detail.dart'; import 'package:surface/screens/post/post_detail.dart';
import 'package:surface/types/attachment.dart'; import 'package:surface/types/attachment.dart';
@ -42,6 +43,8 @@ import 'package:surface/widgets/post/publisher_popover.dart';
import 'package:surface/widgets/universal_image.dart'; import 'package:surface/widgets/universal_image.dart';
import 'package:xml/xml.dart'; import 'package:xml/xml.dart';
import '../../screens/account/profile_page.dart' show kBadgesMeta;
class OpenablePostItem extends StatelessWidget { class OpenablePostItem extends StatelessWidget {
final SnPost data; final SnPost data;
final bool showReactions; final bool showReactions;
@ -867,12 +870,30 @@ class _PostContentHeader extends StatelessWidget {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
final ud = context.read<UserDirectoryProvider>();
final user = data.publisher.type == 0 ? ud.getAccountFromCache(data.publisher.accountId) : null;
return Row( return Row(
children: [ children: [
GestureDetector( GestureDetector(
child: AccountImage( child: AccountImage(
content: data.publisher.avatar, content: data.publisher.avatar,
radius: isCompact ? 12 : 20, radius: isCompact ? 12 : 20,
badge: (user?.badges.isNotEmpty ?? false)
? Icon(
kBadgesMeta[user!.badges.first.type]?.$2 ?? Symbols.question_mark,
color: kBadgesMeta[user.badges.first.type]?.$3,
fill: 1,
size: 18,
shadows: [
Shadow(
offset: Offset(1, 1),
blurRadius: 5.0,
color: Color.fromARGB(255, 0, 0, 0),
),
],
)
: null,
), ),
onTap: () { onTap: () {
showPopover( showPopover(