💄 Optimzation and fixes
This commit is contained in:
@ -9,9 +9,9 @@ import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||
import 'package:island/pods/userinfo.dart';
|
||||
import 'package:island/pods/websocket.dart';
|
||||
import 'package:island/route.dart';
|
||||
import 'package:island/services/responsive.dart';
|
||||
import 'package:material_symbols_icons/material_symbols_icons.dart';
|
||||
import 'package:path_provider/path_provider.dart';
|
||||
import 'package:responsive_framework/responsive_framework.dart';
|
||||
import 'package:styled_widget/styled_widget.dart';
|
||||
|
||||
class WindowScaffold extends HookConsumerWidget {
|
||||
@ -109,7 +109,7 @@ class AppScaffold extends StatelessWidget {
|
||||
final AppBar? appBar;
|
||||
final DrawerCallback? onDrawerChanged;
|
||||
final DrawerCallback? onEndDrawerChanged;
|
||||
final bool noBackground;
|
||||
final bool? noBackground;
|
||||
|
||||
const AppScaffold({
|
||||
super.key,
|
||||
@ -124,7 +124,7 @@ class AppScaffold extends StatelessWidget {
|
||||
this.endDrawer,
|
||||
this.onDrawerChanged,
|
||||
this.onEndDrawerChanged,
|
||||
this.noBackground = false,
|
||||
this.noBackground,
|
||||
});
|
||||
|
||||
@override
|
||||
@ -132,6 +132,8 @@ class AppScaffold extends StatelessWidget {
|
||||
final appBarHeight = appBar?.preferredSize.height ?? 0;
|
||||
final safeTop = MediaQuery.of(context).padding.top;
|
||||
|
||||
final noBackground = this.noBackground ?? isWideScreen(context);
|
||||
|
||||
final content = Column(
|
||||
children: [
|
||||
IgnorePointer(
|
||||
@ -208,7 +210,7 @@ class AppBackground extends ConsumerWidget {
|
||||
Widget build(BuildContext context, WidgetRef ref) {
|
||||
final imageFileAsync = ref.watch(backgroundImageFileProvider);
|
||||
|
||||
if (isRoot || ResponsiveBreakpoints.of(context).smallerOrEqualTo(MOBILE)) {
|
||||
if (isRoot || !isWideScreen(context)) {
|
||||
return imageFileAsync.when(
|
||||
data: (file) {
|
||||
if (file != null) {
|
||||
@ -254,6 +256,20 @@ class AppBackground extends ConsumerWidget {
|
||||
}
|
||||
}
|
||||
|
||||
class EmptyPageHolder extends HookConsumerWidget {
|
||||
const EmptyPageHolder({super.key});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context, WidgetRef ref) {
|
||||
final hasBackground =
|
||||
ref.watch(backgroundImageFileProvider).valueOrNull != null;
|
||||
if (hasBackground) {
|
||||
return const SizedBox.shrink();
|
||||
}
|
||||
return Container(color: Theme.of(context).scaffoldBackgroundColor);
|
||||
}
|
||||
}
|
||||
|
||||
class _WebSocketIndicator extends HookConsumerWidget {
|
||||
const _WebSocketIndicator();
|
||||
|
||||
|
@ -5,6 +5,7 @@ import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||
import 'package:island/database/message.dart';
|
||||
import 'package:island/models/chat.dart';
|
||||
import 'package:island/screens/chat/room.dart';
|
||||
import 'package:island/widgets/app_scaffold.dart';
|
||||
import 'package:island/widgets/content/cloud_file_collection.dart';
|
||||
import 'package:island/widgets/content/cloud_files.dart';
|
||||
import 'package:island/widgets/content/markdown.dart';
|
||||
@ -50,6 +51,9 @@ class MessageItem extends HookConsumerWidget {
|
||||
containerColor,
|
||||
);
|
||||
|
||||
final hasBackground =
|
||||
ref.watch(backgroundImageFileProvider).valueOrNull != null;
|
||||
|
||||
final remoteMessage = message.toRemoteMessage();
|
||||
final sender = remoteMessage.sender;
|
||||
|
||||
@ -93,7 +97,10 @@ class MessageItem extends HookConsumerWidget {
|
||||
);
|
||||
},
|
||||
child: Material(
|
||||
color: Theme.of(context).colorScheme.surface,
|
||||
color:
|
||||
hasBackground
|
||||
? Colors.transparent
|
||||
: Theme.of(context).colorScheme.surface,
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 4),
|
||||
child: Column(
|
||||
@ -115,7 +122,21 @@ class MessageItem extends HookConsumerWidget {
|
||||
spacing: 2,
|
||||
children: [
|
||||
Text(
|
||||
DateFormat.Hm().format(message.createdAt.toLocal()),
|
||||
DateTime.now().difference(message.createdAt).inDays >
|
||||
365
|
||||
? DateFormat(
|
||||
'yyyy/MM/dd HH:mm',
|
||||
).format(message.createdAt.toLocal())
|
||||
: DateTime.now()
|
||||
.difference(message.createdAt)
|
||||
.inDays >
|
||||
0
|
||||
? DateFormat(
|
||||
'MM/dd HH:mm',
|
||||
).format(message.createdAt.toLocal())
|
||||
: DateFormat(
|
||||
'HH:mm',
|
||||
).format(message.createdAt.toLocal()),
|
||||
style: TextStyle(fontSize: 10, color: textColor),
|
||||
),
|
||||
Row(
|
||||
@ -151,77 +172,96 @@ class MessageItem extends HookConsumerWidget {
|
||||
crossAxisAlignment: CrossAxisAlignment.end,
|
||||
children: [
|
||||
Flexible(
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
if (remoteMessage.repliedMessageId != null)
|
||||
MessageQuoteWidget(
|
||||
message: message,
|
||||
textColor: textColor,
|
||||
isReply: true,
|
||||
),
|
||||
if (remoteMessage.forwardedMessageId != null)
|
||||
MessageQuoteWidget(
|
||||
message: message,
|
||||
textColor: textColor,
|
||||
isReply: false,
|
||||
),
|
||||
if (remoteMessage.content?.isNotEmpty ?? false)
|
||||
MarkdownTextContent(
|
||||
content: remoteMessage.content!,
|
||||
isSelectable: true,
|
||||
linkStyle: TextStyle(color: linkColor),
|
||||
textStyle: TextStyle(
|
||||
color: textColor,
|
||||
fontSize: 14,
|
||||
child: Container(
|
||||
decoration: BoxDecoration(
|
||||
color: containerColor,
|
||||
borderRadius: BorderRadius.circular(16),
|
||||
),
|
||||
padding: const EdgeInsets.symmetric(
|
||||
horizontal: 12,
|
||||
vertical: 6,
|
||||
),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
if (remoteMessage.repliedMessageId != null)
|
||||
MessageQuoteWidget(
|
||||
message: message,
|
||||
textColor: textColor,
|
||||
isReply: true,
|
||||
).padding(vertical: 4),
|
||||
if (remoteMessage.forwardedMessageId != null)
|
||||
MessageQuoteWidget(
|
||||
message: message,
|
||||
textColor: textColor,
|
||||
isReply: false,
|
||||
).padding(vertical: 4),
|
||||
if (remoteMessage.content?.isNotEmpty ?? false)
|
||||
MarkdownTextContent(
|
||||
content: remoteMessage.content!,
|
||||
isSelectable: true,
|
||||
linkStyle: TextStyle(color: linkColor),
|
||||
textStyle: TextStyle(
|
||||
color: textColor,
|
||||
fontSize: 14,
|
||||
),
|
||||
),
|
||||
),
|
||||
if (remoteMessage.attachments.isNotEmpty)
|
||||
CloudFileList(
|
||||
files: remoteMessage.attachments,
|
||||
maxWidth: MediaQuery.of(context).size.width * 0.8,
|
||||
).padding(top: 4),
|
||||
if (progress != null && progress!.isNotEmpty)
|
||||
Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.stretch,
|
||||
spacing: 8,
|
||||
children: [
|
||||
if ((remoteMessage.content?.isNotEmpty ?? false))
|
||||
if (remoteMessage.attachments.isNotEmpty)
|
||||
LayoutBuilder(
|
||||
builder: (context, constraints) {
|
||||
return CloudFileList(
|
||||
files: remoteMessage.attachments,
|
||||
maxWidth: constraints.maxWidth,
|
||||
).padding(vertical: 4);
|
||||
},
|
||||
),
|
||||
if (progress != null && progress!.isNotEmpty)
|
||||
Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.stretch,
|
||||
spacing: 8,
|
||||
children: [
|
||||
if ((remoteMessage.content?.isNotEmpty ??
|
||||
false))
|
||||
const Gap(0),
|
||||
for (var entry in progress!.entries)
|
||||
Column(
|
||||
crossAxisAlignment:
|
||||
CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
'fileUploadingProgress'.tr(
|
||||
args: [
|
||||
(entry.key + 1).toString(),
|
||||
entry.value.toStringAsFixed(1),
|
||||
],
|
||||
),
|
||||
style: TextStyle(
|
||||
fontSize: 12,
|
||||
color: textColor.withOpacity(0.8),
|
||||
),
|
||||
),
|
||||
const Gap(4),
|
||||
LinearProgressIndicator(
|
||||
value: entry.value / 100,
|
||||
backgroundColor:
|
||||
Theme.of(
|
||||
context,
|
||||
).colorScheme.surfaceVariant,
|
||||
valueColor:
|
||||
AlwaysStoppedAnimation<Color>(
|
||||
Theme.of(
|
||||
context,
|
||||
).colorScheme.primary,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
const Gap(0),
|
||||
for (var entry in progress!.entries)
|
||||
Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
'fileUploadingProgress'.tr(
|
||||
args: [
|
||||
(entry.key + 1).toString(),
|
||||
entry.value.toStringAsFixed(1),
|
||||
],
|
||||
),
|
||||
style: TextStyle(
|
||||
fontSize: 12,
|
||||
color: textColor.withOpacity(0.8),
|
||||
),
|
||||
),
|
||||
const Gap(4),
|
||||
LinearProgressIndicator(
|
||||
value: entry.value / 100,
|
||||
backgroundColor:
|
||||
Theme.of(
|
||||
context,
|
||||
).colorScheme.surfaceVariant,
|
||||
valueColor: AlwaysStoppedAnimation<Color>(
|
||||
Theme.of(context).colorScheme.primary,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
const Gap(0),
|
||||
],
|
||||
),
|
||||
],
|
||||
).padding(left: 40),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
_buildMessageIndicators(
|
||||
context,
|
||||
@ -333,6 +373,7 @@ class MessageQuoteWidget extends HookConsumerWidget {
|
||||
children: [
|
||||
if (isReply)
|
||||
Row(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
spacing: 4,
|
||||
children: [
|
||||
Icon(Symbols.reply, size: 16, color: textColor),
|
||||
@ -340,9 +381,10 @@ class MessageQuoteWidget extends HookConsumerWidget {
|
||||
'Replying to ${snapshot.data!.toRemoteMessage().sender.account.nick}',
|
||||
).textColor(textColor).bold(),
|
||||
],
|
||||
)
|
||||
).padding(right: 8)
|
||||
else
|
||||
Row(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
spacing: 4,
|
||||
children: [
|
||||
Icon(Symbols.forward, size: 16, color: textColor),
|
||||
@ -350,7 +392,7 @@ class MessageQuoteWidget extends HookConsumerWidget {
|
||||
'Forwarded from ${snapshot.data!.toRemoteMessage().sender.account.nick}',
|
||||
).textColor(textColor).bold(),
|
||||
],
|
||||
),
|
||||
).padding(right: 8),
|
||||
if (snapshot.data!.toRemoteMessage().content?.isNotEmpty ??
|
||||
false)
|
||||
Text(
|
||||
|
@ -12,6 +12,7 @@ import 'package:island/pods/userinfo.dart';
|
||||
import 'package:island/route.gr.dart';
|
||||
import 'package:island/services/responsive.dart';
|
||||
import 'package:island/widgets/alert.dart';
|
||||
import 'package:island/widgets/app_scaffold.dart';
|
||||
import 'package:island/widgets/content/cloud_file_collection.dart';
|
||||
import 'package:island/widgets/content/cloud_files.dart';
|
||||
import 'package:island/widgets/content/markdown.dart';
|
||||
@ -47,6 +48,9 @@ class PostItem extends HookConsumerWidget {
|
||||
[user],
|
||||
);
|
||||
|
||||
final hasBackground =
|
||||
ref.watch(backgroundImageFileProvider).valueOrNull != null;
|
||||
|
||||
return ContextMenuWidget(
|
||||
menuProvider: (_) {
|
||||
return Menu(
|
||||
@ -101,7 +105,7 @@ class PostItem extends HookConsumerWidget {
|
||||
);
|
||||
},
|
||||
child: Material(
|
||||
color: backgroundColor,
|
||||
color: hasBackground ? Colors.transparent : backgroundColor,
|
||||
child: Padding(
|
||||
padding: renderingPadding,
|
||||
child: Column(
|
||||
|
Reference in New Issue
Block a user