💄 Optimizations
This commit is contained in:
@@ -114,9 +114,9 @@ final apiClientProvider = Provider<Dio>((ref) {
|
|||||||
dio: dio,
|
dio: dio,
|
||||||
retries: 3,
|
retries: 3,
|
||||||
retryDelays: const [
|
retryDelays: const [
|
||||||
Duration(seconds: 1),
|
Duration(milliseconds: 300),
|
||||||
Duration(seconds: 2),
|
Duration(milliseconds: 500),
|
||||||
Duration(seconds: 3),
|
Duration(milliseconds: 1000),
|
||||||
],
|
],
|
||||||
retryEvaluator: (err, _) => err.requestOptions.method == 'GET',
|
retryEvaluator: (err, _) => err.requestOptions.method == 'GET',
|
||||||
),
|
),
|
||||||
|
@@ -469,24 +469,28 @@ class ChatInput extends HookConsumerWidget {
|
|||||||
),
|
),
|
||||||
UploadMenu(
|
UploadMenu(
|
||||||
items: [
|
items: [
|
||||||
MenuItemData(
|
UploadMenuItemData(
|
||||||
Symbols.add_a_photo,
|
Symbols.add_a_photo,
|
||||||
'addPhoto',
|
'addPhoto',
|
||||||
() => onPickFile(true),
|
() => onPickFile(true),
|
||||||
),
|
),
|
||||||
MenuItemData(
|
UploadMenuItemData(
|
||||||
Symbols.videocam,
|
Symbols.videocam,
|
||||||
'addVideo',
|
'addVideo',
|
||||||
() => onPickFile(false),
|
() => onPickFile(false),
|
||||||
),
|
),
|
||||||
MenuItemData(Symbols.mic, 'addAudio', onPickAudio),
|
UploadMenuItemData(
|
||||||
MenuItemData(
|
Symbols.mic,
|
||||||
|
'addAudio',
|
||||||
|
onPickAudio,
|
||||||
|
),
|
||||||
|
UploadMenuItemData(
|
||||||
Symbols.file_upload,
|
Symbols.file_upload,
|
||||||
'uploadFile',
|
'uploadFile',
|
||||||
onPickGeneralFile,
|
onPickGeneralFile,
|
||||||
),
|
),
|
||||||
if (onLinkAttachment != null)
|
if (onLinkAttachment != null)
|
||||||
MenuItemData(
|
UploadMenuItemData(
|
||||||
Symbols.attach_file,
|
Symbols.attach_file,
|
||||||
'linkAttachment',
|
'linkAttachment',
|
||||||
onLinkAttachment!,
|
onLinkAttachment!,
|
||||||
|
@@ -161,6 +161,7 @@ class MessageItem extends HookConsumerWidget {
|
|||||||
clipBehavior: Clip.none,
|
clipBehavior: Clip.none,
|
||||||
children: [
|
children: [
|
||||||
SwipeTo(
|
SwipeTo(
|
||||||
|
swipeSensitivity: 15,
|
||||||
rightSwipeWidget: Transform.flip(
|
rightSwipeWidget: Transform.flip(
|
||||||
flipX: true,
|
flipX: true,
|
||||||
child: Icon(Symbols.menu_open),
|
child: Icon(Symbols.menu_open),
|
||||||
@@ -477,6 +478,8 @@ class _MessageActionSheetState extends State<MessageActionSheet> {
|
|||||||
Navigator.pop(context);
|
Navigator.pop(context);
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
|
|
||||||
|
Gap(MediaQuery.of(context).padding.bottom),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
@@ -16,7 +16,6 @@ import 'package:island/widgets/post/compose_shared.dart';
|
|||||||
import 'package:material_symbols_icons/symbols.dart';
|
import 'package:material_symbols_icons/symbols.dart';
|
||||||
import 'package:riverpod_annotation/riverpod_annotation.dart';
|
import 'package:riverpod_annotation/riverpod_annotation.dart';
|
||||||
import 'package:styled_widget/styled_widget.dart';
|
import 'package:styled_widget/styled_widget.dart';
|
||||||
import 'package:textfield_tags/textfield_tags.dart';
|
|
||||||
|
|
||||||
part 'compose_settings_sheet.g.dart';
|
part 'compose_settings_sheet.g.dart';
|
||||||
|
|
||||||
@@ -37,98 +36,6 @@ Future<List<SnPostCategory>> postCategories(Ref ref) async {
|
|||||||
return uniqueCategories.values.toList();
|
return uniqueCategories.values.toList();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A reusable widget for tag input fields with chip display
|
|
||||||
class ChipTagInputField extends StatelessWidget {
|
|
||||||
final InputFieldValues inputFieldValues;
|
|
||||||
final String labelText;
|
|
||||||
final String hintText;
|
|
||||||
|
|
||||||
const ChipTagInputField({
|
|
||||||
super.key,
|
|
||||||
required this.inputFieldValues,
|
|
||||||
required this.labelText,
|
|
||||||
required this.hintText,
|
|
||||||
});
|
|
||||||
|
|
||||||
@override
|
|
||||||
Widget build(BuildContext context) {
|
|
||||||
return TextField(
|
|
||||||
controller: inputFieldValues.textEditingController,
|
|
||||||
focusNode: inputFieldValues.focusNode,
|
|
||||||
decoration: InputDecoration(
|
|
||||||
label: Text(labelText).tr(),
|
|
||||||
border: OutlineInputBorder(borderRadius: BorderRadius.circular(12)),
|
|
||||||
contentPadding: const EdgeInsets.all(16),
|
|
||||||
hintText: inputFieldValues.tags.isNotEmpty ? '' : hintText.tr(),
|
|
||||||
errorText: inputFieldValues.error,
|
|
||||||
prefixIconConstraints: BoxConstraints(
|
|
||||||
maxWidth: MediaQuery.of(context).size.width * 0.8,
|
|
||||||
),
|
|
||||||
prefixIcon:
|
|
||||||
inputFieldValues.tags.isNotEmpty
|
|
||||||
? SingleChildScrollView(
|
|
||||||
controller: inputFieldValues.tagScrollController,
|
|
||||||
scrollDirection: Axis.vertical,
|
|
||||||
child: Padding(
|
|
||||||
padding: const EdgeInsets.only(top: 8, bottom: 8, left: 8),
|
|
||||||
child: Wrap(
|
|
||||||
runSpacing: 4.0,
|
|
||||||
spacing: 4.0,
|
|
||||||
children:
|
|
||||||
inputFieldValues.tags.map<Widget>((dynamic tag) {
|
|
||||||
return Container(
|
|
||||||
decoration: BoxDecoration(
|
|
||||||
borderRadius: BorderRadius.all(
|
|
||||||
Radius.circular(20.0),
|
|
||||||
),
|
|
||||||
color: Theme.of(context).colorScheme.primary,
|
|
||||||
),
|
|
||||||
margin: const EdgeInsets.only(left: 5),
|
|
||||||
padding: const EdgeInsets.symmetric(
|
|
||||||
horizontal: 10.0,
|
|
||||||
vertical: 5.0,
|
|
||||||
),
|
|
||||||
child: Row(
|
|
||||||
mainAxisAlignment: MainAxisAlignment.start,
|
|
||||||
mainAxisSize: MainAxisSize.min,
|
|
||||||
children: [
|
|
||||||
InkWell(
|
|
||||||
child: Text(
|
|
||||||
'#$tag',
|
|
||||||
style: TextStyle(
|
|
||||||
color:
|
|
||||||
Theme.of(
|
|
||||||
context,
|
|
||||||
).colorScheme.onPrimary,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
const Gap(4),
|
|
||||||
InkWell(
|
|
||||||
child: const Icon(
|
|
||||||
Icons.cancel,
|
|
||||||
size: 14.0,
|
|
||||||
color: Color.fromARGB(255, 233, 233, 233),
|
|
||||||
),
|
|
||||||
onTap: () {
|
|
||||||
inputFieldValues.onTagRemoved(tag);
|
|
||||||
},
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}).toList(),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
)
|
|
||||||
: null,
|
|
||||||
),
|
|
||||||
onChanged: inputFieldValues.onTagChanged,
|
|
||||||
onSubmitted: inputFieldValues.onTagSubmitted,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class ComposeSettingsSheet extends HookConsumerWidget {
|
class ComposeSettingsSheet extends HookConsumerWidget {
|
||||||
final ComposeState state;
|
final ComposeState state;
|
||||||
|
|
||||||
|
@@ -82,10 +82,10 @@ class ComposeToolbar extends HookConsumerWidget {
|
|||||||
}
|
}
|
||||||
|
|
||||||
final uploadMenuItems = [
|
final uploadMenuItems = [
|
||||||
MenuItemData(Symbols.add_a_photo, 'addPhoto', pickPhotoMedia),
|
UploadMenuItemData(Symbols.add_a_photo, 'addPhoto', pickPhotoMedia),
|
||||||
MenuItemData(Symbols.videocam, 'addVideo', pickVideoMedia),
|
UploadMenuItemData(Symbols.videocam, 'addVideo', pickVideoMedia),
|
||||||
MenuItemData(Symbols.mic, 'addAudio', addAudio),
|
UploadMenuItemData(Symbols.mic, 'addAudio', addAudio),
|
||||||
MenuItemData(Symbols.file_upload, 'uploadFile', pickGeneralFile),
|
UploadMenuItemData(Symbols.file_upload, 'uploadFile', pickGeneralFile),
|
||||||
];
|
];
|
||||||
|
|
||||||
final colorScheme = Theme.of(context).colorScheme;
|
final colorScheme = Theme.of(context).colorScheme;
|
||||||
|
@@ -2,16 +2,16 @@ import 'package:easy_localization/easy_localization.dart';
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:material_symbols_icons/symbols.dart';
|
import 'package:material_symbols_icons/symbols.dart';
|
||||||
|
|
||||||
class MenuItemData {
|
class UploadMenuItemData {
|
||||||
final IconData icon;
|
final IconData icon;
|
||||||
final String textKey;
|
final String textKey;
|
||||||
final VoidCallback onPressed;
|
final VoidCallback onPressed;
|
||||||
|
|
||||||
const MenuItemData(this.icon, this.textKey, this.onPressed);
|
const UploadMenuItemData(this.icon, this.textKey, this.onPressed);
|
||||||
}
|
}
|
||||||
|
|
||||||
class UploadMenu extends StatelessWidget {
|
class UploadMenu extends StatelessWidget {
|
||||||
final List<MenuItemData> items;
|
final List<UploadMenuItemData> items;
|
||||||
final bool isCompact;
|
final bool isCompact;
|
||||||
final Color? iconColor;
|
final Color? iconColor;
|
||||||
|
|
||||||
@@ -51,6 +51,7 @@ class UploadMenu extends StatelessWidget {
|
|||||||
onPressed: item.onPressed,
|
onPressed: item.onPressed,
|
||||||
leadingIcon: Icon(item.icon),
|
leadingIcon: Icon(item.icon),
|
||||||
style: ButtonStyle(
|
style: ButtonStyle(
|
||||||
|
visualDensity: VisualDensity.compact,
|
||||||
padding: WidgetStatePropertyAll(
|
padding: WidgetStatePropertyAll(
|
||||||
EdgeInsets.only(left: 12, right: 16, top: 20, bottom: 20),
|
EdgeInsets.only(left: 12, right: 16, top: 20, bottom: 20),
|
||||||
),
|
),
|
||||||
|
Reference in New Issue
Block a user