diff --git a/lib/screens/chat/room.dart b/lib/screens/chat/room.dart index 314cfae..e85de18 100644 --- a/lib/screens/chat/room.dart +++ b/lib/screens/chat/room.dart @@ -1061,14 +1061,14 @@ class _ChatInput extends HookConsumerWidget { children: [ if (attachments.isNotEmpty) SizedBox( - height: 324, + height: 280, child: ListView.separated( padding: EdgeInsets.symmetric(horizontal: 12), scrollDirection: Axis.horizontal, itemCount: attachments.length, itemBuilder: (context, idx) { return SizedBox( - height: 320, + height: 280, width: 280, child: AttachmentPreview( item: attachments[idx], diff --git a/lib/screens/posts/compose.dart b/lib/screens/posts/compose.dart index 55fb76d..55a4dc9 100644 --- a/lib/screens/posts/compose.dart +++ b/lib/screens/posts/compose.dart @@ -367,63 +367,63 @@ class PostComposeScreen extends HookConsumerWidget { // Post content form Expanded( - child: SingleChildScrollView( - padding: const EdgeInsets.symmetric(vertical: 16), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - TextField( - controller: state.titleController, - decoration: InputDecoration( - hintText: 'postTitle'.tr(), - border: InputBorder.none, - isCollapsed: true, - contentPadding: const EdgeInsets.symmetric( - vertical: 8, - horizontal: 8, - ), - ), - style: theme.textTheme.titleMedium, - onTapOutside: - (_) => - FocusManager.instance.primaryFocus - ?.unfocus(), + child: KeyboardListener( + focusNode: FocusNode(), + onKeyEvent: + (event) => ComposeLogic.handleKeyPress( + event, + state, + ref, + context, + originalPost: originalPost, + repliedPost: repliedPost, + forwardedPost: forwardedPost, ), - TextField( - controller: state.descriptionController, - decoration: InputDecoration( - hintText: 'postDescription'.tr(), - border: InputBorder.none, - isCollapsed: true, - contentPadding: const EdgeInsets.fromLTRB( - 8, - 4, - 8, - 12, - ), - ), - style: theme.textTheme.bodyMedium, - minLines: 1, - maxLines: 3, - onTapOutside: - (_) => - FocusManager.instance.primaryFocus - ?.unfocus(), - ), - // Content field with borderless design - KeyboardListener( - focusNode: FocusNode(), - onKeyEvent: - (event) => ComposeLogic.handleKeyPress( - event, - state, - ref, - context, - originalPost: originalPost, - repliedPost: repliedPost, - forwardedPost: forwardedPost, + child: SingleChildScrollView( + padding: const EdgeInsets.symmetric(vertical: 16), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + TextField( + controller: state.titleController, + decoration: InputDecoration( + hintText: 'postTitle'.tr(), + border: InputBorder.none, + isCollapsed: true, + contentPadding: const EdgeInsets.symmetric( + vertical: 8, + horizontal: 8, ), - child: TextField( + ), + style: theme.textTheme.titleMedium, + onTapOutside: + (_) => + FocusManager.instance.primaryFocus + ?.unfocus(), + ), + TextField( + controller: state.descriptionController, + decoration: InputDecoration( + hintText: 'postDescription'.tr(), + border: InputBorder.none, + isCollapsed: true, + contentPadding: const EdgeInsets.fromLTRB( + 8, + 4, + 8, + 12, + ), + ), + style: theme.textTheme.bodyMedium, + minLines: 1, + maxLines: 3, + onTapOutside: + (_) => + FocusManager.instance.primaryFocus + ?.unfocus(), + ), + // Content field with borderless design + TextField( controller: state.contentController, style: theme.textTheme.bodyMedium, decoration: InputDecoration( @@ -441,23 +441,23 @@ class PostComposeScreen extends HookConsumerWidget { FocusManager.instance.primaryFocus ?.unfocus(), ), - ), - const Gap(8), + const Gap(8), - // Attachments preview - if (state.attachments.value.isNotEmpty) - LayoutBuilder( - builder: (context, constraints) { - final isWide = isWideScreen(context); - return isWide - ? buildWideAttachmentGrid() - : buildNarrowAttachmentList(); - }, - ) - else - const SizedBox.shrink(), - ], + // Attachments preview + if (state.attachments.value.isNotEmpty) + LayoutBuilder( + builder: (context, constraints) { + final isWide = isWideScreen(context); + return isWide + ? buildWideAttachmentGrid() + : buildNarrowAttachmentList(); + }, + ) + else + const SizedBox.shrink(), + ], + ), ), ), ), diff --git a/lib/widgets/content/attachment_preview.dart b/lib/widgets/content/attachment_preview.dart index 570aa30..713459d 100644 --- a/lib/widgets/content/attachment_preview.dart +++ b/lib/widgets/content/attachment_preview.dart @@ -272,8 +272,96 @@ class AttachmentPreview extends HookConsumerWidget { borderRadius: BorderRadius.circular(8), child: Container( color: Theme.of(context).colorScheme.surfaceContainer, - child: Column( + child: Stack( children: [ + AspectRatio( + aspectRatio: ratio, + child: Stack( + fit: StackFit.expand, + children: [ + Builder( + key: ValueKey(item.hashCode), + builder: (context) { + if (item.isOnCloud) { + return CloudFileWidget(item: item.data); + } else if (item.data is XFile) { + final file = item.data as XFile; + if (file.path.isEmpty) { + return FutureBuilder( + future: file.readAsBytes(), + builder: (context, snapshot) { + if (snapshot.hasData) { + return Image.memory(snapshot.data!); + } + return const Center( + child: CircularProgressIndicator(), + ); + }, + ); + } + + switch (item.type) { + case UniversalFileType.image: + return kIsWeb + ? Image.network(file.path) + : Image.file(File(file.path)); + default: + return Column( + children: [ + const Icon(Symbols.document_scanner), + Text(file.name), + ], + ); + } + } else if (item is List || item is Uint8List) { + switch (item.type) { + case UniversalFileType.image: + return Image.memory(item.data); + default: + return Column( + children: [const Icon(Symbols.document_scanner)], + ); + } + } + return Placeholder(); + }, + ), + if (progress != null) + Positioned.fill( + child: Container( + color: Colors.black.withOpacity(0.3), + padding: EdgeInsets.symmetric( + horizontal: 40, + vertical: 16, + ), + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + if (progress != null) + Text( + '${progress!.toStringAsFixed(2)}%', + style: TextStyle(color: Colors.white), + ) + else + Text( + 'uploading'.tr(), + style: TextStyle(color: Colors.white), + ), + Gap(6), + Center( + child: LinearProgressIndicator( + value: + progress != null ? progress! / 100.0 : null, + ), + ), + ], + ), + ), + ), + ], + ), + ), Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ @@ -397,94 +485,6 @@ class AttachmentPreview extends HookConsumerWidget { ), ], ).padding(horizontal: 12, vertical: 8), - AspectRatio( - aspectRatio: ratio, - child: Stack( - fit: StackFit.expand, - children: [ - Builder( - key: ValueKey(item.hashCode), - builder: (context) { - if (item.isOnCloud) { - return CloudFileWidget(item: item.data); - } else if (item.data is XFile) { - final file = item.data as XFile; - if (file.path.isEmpty) { - return FutureBuilder( - future: file.readAsBytes(), - builder: (context, snapshot) { - if (snapshot.hasData) { - return Image.memory(snapshot.data!); - } - return const Center( - child: CircularProgressIndicator(), - ); - }, - ); - } - - switch (item.type) { - case UniversalFileType.image: - return kIsWeb - ? Image.network(file.path) - : Image.file(File(file.path)); - default: - return Column( - children: [ - const Icon(Symbols.document_scanner), - Text(file.name), - ], - ); - } - } else if (item is List || item is Uint8List) { - switch (item.type) { - case UniversalFileType.image: - return Image.memory(item.data); - default: - return Column( - children: [const Icon(Symbols.document_scanner)], - ); - } - } - return Placeholder(); - }, - ), - if (progress != null) - Positioned.fill( - child: Container( - color: Colors.black.withOpacity(0.3), - padding: EdgeInsets.symmetric( - horizontal: 40, - vertical: 16, - ), - child: Column( - mainAxisAlignment: MainAxisAlignment.center, - crossAxisAlignment: CrossAxisAlignment.center, - children: [ - if (progress != null) - Text( - '${progress!.toStringAsFixed(2)}%', - style: TextStyle(color: Colors.white), - ) - else - Text( - 'uploading'.tr(), - style: TextStyle(color: Colors.white), - ), - Gap(6), - Center( - child: LinearProgressIndicator( - value: - progress != null ? progress! / 100.0 : null, - ), - ), - ], - ), - ), - ), - ], - ), - ), ], ), ), diff --git a/lib/widgets/post/compose_shared.dart b/lib/widgets/post/compose_shared.dart index 4afe6c2..38cc3c6 100644 --- a/lib/widgets/post/compose_shared.dart +++ b/lib/widgets/post/compose_shared.dart @@ -697,7 +697,7 @@ class ComposeLogic { SnPost? repliedPost, SnPost? forwardedPost, }) { - if (event is! RawKeyDownEvent) return; + if (event is! KeyDownEvent) return; final isPaste = event.logicalKey == LogicalKeyboardKey.keyV; final isSave = event.logicalKey == LogicalKeyboardKey.keyS;