Compare commits

..

No commits in common. "cb05ff2e9ed6f273ea57f5c419f5d46aff5d59bc" and "a3c8dafff9599bf1aa5ecad1b5d92c342e9086b1" have entirely different histories.

7 changed files with 203 additions and 208 deletions

View File

@ -1,3 +0,0 @@
class StickerProvider {
}

View File

@ -281,7 +281,11 @@ class _ChatRoomScreenState extends State<ChatRoomScreen> {
Expanded( Expanded(
child: InfiniteList( child: InfiniteList(
reverse: true, reverse: true,
padding: const EdgeInsets.only(top: 12), padding: const EdgeInsets.only(
left: 12,
right: 12,
top: 12,
),
hasReachedMax: _messageController.isAllLoaded, hasReachedMax: _messageController.isAllLoaded,
itemCount: _messageController.messages.length, itemCount: _messageController.messages.length,
isLoading: _messageController.isLoading, isLoading: _messageController.isLoading,
@ -307,20 +311,23 @@ class _ChatRoomScreenState extends State<ChatRoomScreen> {
return Align( return Align(
alignment: Alignment.centerLeft, alignment: Alignment.centerLeft,
child: ChatMessage( child: Container(
data: message, constraints: BoxConstraints(maxWidth: 480),
isMerged: canMerge, child: ChatMessage(
hasMerged: canMergePrevious, data: message,
isPending: _messageController.unconfirmedMessages.contains(message.uuid), isMerged: canMerge,
onReply: (value) { hasMerged: canMergePrevious,
_inputGlobalKey.currentState?.setReply(value); isPending: _messageController.unconfirmedMessages.contains(message.uuid),
}, onReply: (value) {
onEdit: (value) { _inputGlobalKey.currentState?.setReply(value);
_inputGlobalKey.currentState?.setEdit(value); },
}, onEdit: (value) {
onDelete: (value) { _inputGlobalKey.currentState?.setEdit(value);
_inputGlobalKey.currentState?.deleteMessage(value); },
}, onDelete: (value) {
_inputGlobalKey.currentState?.deleteMessage(value);
},
),
), ),
); );
}, },

View File

@ -153,14 +153,9 @@ class _HomeDashUpdateWidget extends StatelessWidget {
} }
} }
class _HomeDashSpecialDayWidget extends StatefulWidget { class _HomeDashSpecialDayWidget extends StatelessWidget {
const _HomeDashSpecialDayWidget(); const _HomeDashSpecialDayWidget();
@override
State<_HomeDashSpecialDayWidget> createState() => _HomeDashSpecialDayWidgetState();
}
class _HomeDashSpecialDayWidgetState extends State<_HomeDashSpecialDayWidget> {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
final ua = context.watch<UserProvider>(); final ua = context.watch<UserProvider>();
@ -170,20 +165,21 @@ class _HomeDashSpecialDayWidgetState extends State<_HomeDashSpecialDayWidget> {
if (days.isNotEmpty) { if (days.isNotEmpty) {
return Column( return Column(
spacing: 8,
children: days.map((ele) { children: days.map((ele) {
return Card( return Card(
child: ListTile( child: ListTile(
leading: Text(kSpecialDaysSymbol[ele] ?? '🎉').fontSize(24), leading: Text(kSpecialDaysSymbol[ele] ?? '🎉').fontSize(24),
title: Text('celebrate$ele').tr(args: [ua.user?.nick ?? 'user']), title: Text('celebrate$ele').tr(args: [ua.user?.nick ?? 'user']),
subtitle: Text( subtitle: Text(
DateFormat('y/M/d').format(DateTime.now().copyWith( DateFormat('y/M/d').format(DateTime.now().copyWith(
month: kSpecialDays[ele]?.$1, month: kSpecialDays[ele]?.$1,
day: kSpecialDays[ele]?.$2, day: kSpecialDays[ele]?.$2,
)), )),
), ),
), ),
).padding(bottom: 8); ).padding(bottom: 8);
}).toList()); }).toList());
} }
final nextOne = dayz.getNextSpecialDay(); final nextOne = dayz.getNextSpecialDay();
@ -208,9 +204,6 @@ class _HomeDashSpecialDayWidgetState extends State<_HomeDashSpecialDayWidget> {
separatorType: SeparatorType.symbol, separatorType: SeparatorType.symbol,
decoration: BoxDecoration(), decoration: BoxDecoration(),
padding: EdgeInsets.zero, padding: EdgeInsets.zero,
onDone: () {
setState(() {});
},
), ),
const Gap(12), const Gap(12),
Expanded( Expanded(

View File

@ -106,38 +106,76 @@ class _AttachmentListState extends State<AttachmentList> {
} }
if (widget.gridded) { if (widget.gridded) {
return Container( return Padding(
margin: widget.padding ?? EdgeInsets.zero, padding: widget.padding ?? EdgeInsets.zero,
decoration: BoxDecoration( child: Container(
color: backgroundColor, decoration: BoxDecoration(
border: Border( color: backgroundColor,
top: borderSide, border: Border(
bottom: borderSide, top: borderSide,
bottom: borderSide,
),
borderRadius: AttachmentList.kDefaultRadius,
), ),
borderRadius: AttachmentList.kDefaultRadius, child: ClipRRect(
), borderRadius: AttachmentList.kDefaultRadius,
child: ClipRRect( child: StaggeredGrid.count(
borderRadius: AttachmentList.kDefaultRadius, crossAxisCount: math.min(widget.data.length, 2),
child: StaggeredGrid.count( crossAxisSpacing: 4,
crossAxisCount: math.min(widget.data.length, 2), mainAxisSpacing: 4,
crossAxisSpacing: 4, children: widget.data
mainAxisSpacing: 4, .mapIndexed(
children: widget.data (idx, ele) => GestureDetector(
.mapIndexed( child: Container(
(idx, ele) => GestureDetector( constraints: constraints,
child: Container( child: AttachmentItem(
constraints: constraints, data: ele,
child: AttachmentItem( heroTag: heroTags[idx],
data: ele, fit: BoxFit.cover,
heroTag: heroTags[idx], ),
fit: BoxFit.cover,
), ),
onTap: () {
if (widget.data[idx]!.mediaType != SnMediaType.image) return;
context.pushTransparentRoute(
AttachmentZoomView(
data: widget.data.where((ele) => ele != null).cast(),
initialIndex: idx,
heroTags: heroTags,
),
backgroundColor: Colors.black.withOpacity(0.7),
rootNavigator: true,
);
},
), ),
)
.toList(),
),
),
),
);
}
return AspectRatio(
aspectRatio: (widget.data.firstOrNull?.data['ratio'] ?? 1).toDouble(),
child: Container(
constraints: BoxConstraints(maxHeight: constraints.maxHeight),
child: ScrollConfiguration(
behavior: _AttachmentListScrollBehavior(),
child: ListView.separated(
shrinkWrap: true,
itemCount: widget.data.length,
itemBuilder: (context, idx) {
return Container(
constraints: constraints,
child: AspectRatio(
aspectRatio: (widget.data[idx]?.data['ratio'] ?? 1).toDouble(),
child: GestureDetector(
onTap: () { onTap: () {
if (widget.data[idx]!.mediaType != SnMediaType.image) return; if (widget.data[idx]?.mediaType != SnMediaType.image) return;
context.pushTransparentRoute( context.pushTransparentRoute(
AttachmentZoomView( AttachmentZoomView(
data: widget.data.where((ele) => ele != null).cast(), data:
widget.data.where((ele) => ele != null && ele.mediaType == SnMediaType.image).cast(),
initialIndex: idx, initialIndex: idx,
heroTags: heroTags, heroTags: heroTags,
), ),
@ -145,76 +183,44 @@ class _AttachmentListState extends State<AttachmentList> {
rootNavigator: true, rootNavigator: true,
); );
}, },
), child: Stack(
) fit: StackFit.expand,
.toList(), children: [
), Container(
), decoration: BoxDecoration(
); color: backgroundColor,
} border: Border(
top: borderSide,
return Container( bottom: borderSide,
constraints: BoxConstraints(maxHeight: constraints.maxHeight), ),
child: ScrollConfiguration( borderRadius: AttachmentList.kDefaultRadius,
behavior: _AttachmentListScrollBehavior(),
child: ListView.separated(
padding: widget.padding,
shrinkWrap: true,
itemCount: widget.data.length,
itemBuilder: (context, idx) {
return Container(
constraints: constraints.copyWith(maxWidth: widget.maxWidth),
child: AspectRatio(
aspectRatio: (widget.data[idx]?.data['ratio'] ?? 1).toDouble(),
child: GestureDetector(
onTap: () {
if (widget.data[idx]?.mediaType != SnMediaType.image) return;
context.pushTransparentRoute(
AttachmentZoomView(
data: widget.data.where((ele) => ele != null && ele.mediaType == SnMediaType.image).cast(),
initialIndex: idx,
heroTags: heroTags,
),
backgroundColor: Colors.black.withOpacity(0.7),
rootNavigator: true,
);
},
child: Stack(
fit: StackFit.expand,
children: [
Container(
decoration: BoxDecoration(
color: backgroundColor,
border: Border(
top: borderSide,
bottom: borderSide,
), ),
borderRadius: AttachmentList.kDefaultRadius, child: ClipRRect(
), borderRadius: AttachmentList.kDefaultRadius,
child: ClipRRect( child: AttachmentItem(
borderRadius: AttachmentList.kDefaultRadius, data: widget.data[idx],
child: AttachmentItem( heroTag: heroTags[idx],
data: widget.data[idx], ),
heroTag: heroTags[idx],
), ),
), ),
), Positioned(
Positioned( right: 8,
right: 8, bottom: 8,
bottom: 8, child: Chip(
child: Chip( label: Text('${idx + 1}/${widget.data.length}'),
label: Text('${idx + 1}/${widget.data.length}'), ),
), ),
), ],
], ),
), ),
), ),
), );
); },
}, separatorBuilder: (context, index) => const Gap(8),
separatorBuilder: (context, index) => const Gap(8), padding: widget.padding,
physics: const BouncingScrollPhysics(), physics: const BouncingScrollPhysics(),
scrollDirection: Axis.horizontal, scrollDirection: Axis.horizontal,
),
), ),
), ),
); );

View File

@ -231,7 +231,7 @@ class _AttachmentZoomViewState extends State<AttachmentZoomView> {
children: [ children: [
IgnorePointer( IgnorePointer(
child: AccountImage( child: AccountImage(
content: account?.avatar, content: account!.avatar,
radius: 19, radius: 19,
), ),
), ),
@ -246,7 +246,7 @@ class _AttachmentZoomViewState extends State<AttachmentZoomView> {
style: Theme.of(context).textTheme.bodySmall, style: Theme.of(context).textTheme.bodySmall,
), ),
Text( Text(
account?.nick ?? 'unknown'.tr(), account.nick,
style: Theme.of(context).textTheme.bodyMedium, style: Theme.of(context).textTheme.bodyMedium,
), ),
], ],

View File

@ -24,7 +24,6 @@ class ChatMessage extends StatelessWidget {
final Function(SnChatMessage)? onReply; final Function(SnChatMessage)? onReply;
final Function(SnChatMessage)? onEdit; final Function(SnChatMessage)? onEdit;
final Function(SnChatMessage)? onDelete; final Function(SnChatMessage)? onDelete;
final EdgeInsets padding;
const ChatMessage({ const ChatMessage({
super.key, super.key,
@ -36,7 +35,6 @@ class ChatMessage extends StatelessWidget {
this.onReply, this.onReply,
this.onEdit, this.onEdit,
this.onDelete, this.onDelete,
this.padding = const EdgeInsets.only(left: 12, right: 12),
}); });
@override @override
@ -89,89 +87,83 @@ class ChatMessage extends StatelessWidget {
child: Column( child: Column(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
Padding( Row(
padding: isCompact ? EdgeInsets.zero : padding, crossAxisAlignment: CrossAxisAlignment.start,
child: Row( children: [
crossAxisAlignment: CrossAxisAlignment.start, if (!isMerged && !isCompact)
children: [ AccountImage(
if (!isMerged && !isCompact) content: user?.avatar,
AccountImage(
content: user?.avatar,
)
else if (isMerged)
const Gap(40),
const Gap(8),
Expanded(
child: Container(
constraints: BoxConstraints(maxWidth: 480),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
if (!isMerged)
Row(
crossAxisAlignment: CrossAxisAlignment.center,
children: [
if (isCompact)
AccountImage(
content: user?.avatar,
radius: 12,
).padding(right: 8),
Text(
(data.sender.nick?.isNotEmpty ?? false) ? data.sender.nick! : user?.nick ?? 'unknown',
).bold(),
const Gap(8),
Text(
dateFormatter.format(data.createdAt.toLocal()),
).fontSize(13),
],
),
if (isCompact) const Gap(8),
if (data.preload?.quoteEvent != null)
StyledWidget(Container(
decoration: BoxDecoration(
borderRadius: const BorderRadius.all(Radius.circular(8)),
border: Border.all(
color: Theme.of(context).dividerColor,
width: 1,
),
),
padding: const EdgeInsets.only(
left: 4,
right: 4,
top: 8,
bottom: 6,
),
child: ChatMessage(
data: data.preload!.quoteEvent!,
isCompact: true,
onReply: onReply,
onEdit: onEdit,
onDelete: onDelete,
),
)).padding(bottom: 4, top: 4),
switch (data.type) {
'messages.new' => _ChatMessageText(data: data),
_ => _ChatMessageSystemNotify(data: data),
},
],
),
),
) )
], else if (isMerged)
).opacity(isPending ? 0.5 : 1), const Gap(40),
), const Gap(8),
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
if (!isMerged)
Row(
crossAxisAlignment: CrossAxisAlignment.center,
children: [
if (isCompact)
AccountImage(
content: user?.avatar,
radius: 12,
).padding(right: 8),
Text(
(data.sender.nick?.isNotEmpty ?? false) ? data.sender.nick! : user?.nick ?? 'unknown',
).bold(),
const Gap(8),
Text(
dateFormatter.format(data.createdAt.toLocal()),
).fontSize(13),
],
),
if (isCompact) const Gap(4),
if (data.preload?.quoteEvent != null)
StyledWidget(Container(
decoration: BoxDecoration(
borderRadius: const BorderRadius.all(Radius.circular(8)),
border: Border.all(
color: Theme.of(context).dividerColor,
width: 1,
),
),
padding: const EdgeInsets.only(
left: 4,
right: 4,
top: 8,
bottom: 6,
),
child: ChatMessage(
data: data.preload!.quoteEvent!,
isCompact: true,
onReply: onReply,
onEdit: onEdit,
onDelete: onDelete,
),
)).padding(bottom: 4, top: 4),
switch (data.type) {
'messages.new' => _ChatMessageText(data: data),
_ => _ChatMessageSystemNotify(data: data),
},
],
),
)
],
).opacity(isPending ? 0.5 : 1),
if (data.body['text'] != null && data.type == 'messages.new' && (data.body['text']?.isNotEmpty ?? false)) if (data.body['text'] != null && data.type == 'messages.new' && (data.body['text']?.isNotEmpty ?? false))
LinkPreviewWidget(text: data.body['text']!), LinkPreviewWidget(text: data.body['text']!),
if (data.preload?.attachments?.isNotEmpty ?? false) if (data.preload?.attachments?.isNotEmpty ?? false)
AttachmentList( AttachmentList(
data: data.preload!.attachments!, data: data.preload!.attachments!,
bordered: true, bordered: true,
// gridded: true,
maxHeight: 560, maxHeight: 560,
maxWidth: 480,
minWidth: 480, minWidth: 480,
padding: padding.copyWith(top: 8), padding: const EdgeInsets.only(top: 8),
), ),
if (!hasMerged && !isCompact) const Gap(12) else if (!isCompact) const Gap(8), if (!hasMerged && !isCompact) const Gap(12) else if (!isCompact) const Gap(6),
], ],
), ),
), ),

View File

@ -16,7 +16,7 @@ publish_to: "none" # Remove this line if you wish to publish to pub.dev
# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html # https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html
# In Windows, build-name is used as the major, minor, and patch parts # In Windows, build-name is used as the major, minor, and patch parts
# of the product and file versions while build-number is used as the build suffix. # of the product and file versions while build-number is used as the build suffix.
version: 2.2.1+44 version: 2.2.1+43
environment: environment:
sdk: ^3.5.4 sdk: ^3.5.4