treewide: use dot shorthands where possible

Now this feature is stable, we should use it. I might have missed some usecases, but these can be added in future commits.
This commit is contained in:
Henry Hiles 2026-06-02 11:53:14 -04:00
commit d2ec5f035b
Signed by: Henry-Hiles
SSH key fingerprint: SHA256:VKQUdS31Q90KvX7EkKMHMBpUspcmItAh86a+v7PGiIs
67 changed files with 391 additions and 534 deletions

View file

@ -18,11 +18,11 @@ class Appbar extends StatelessWidget implements PreferredSizeWidget {
this.backgroundColor,
this.scrolledUnderElevation,
this.leading,
this.actions = const IList.empty(),
this.actions = const .empty(),
});
@override
Size get preferredSize => const Size.fromHeight(kToolbarHeight);
Size get preferredSize => const .fromHeight(kToolbarHeight);
@override
Widget build(BuildContext context) {
@ -42,7 +42,7 @@ class Appbar extends StatelessWidget implements PreferredSizeWidget {
leading: InkWell(onTap: onTap, child: leading),
backgroundColor: backgroundColor,
scrolledUnderElevation: scrolledUnderElevation,
actionsPadding: const EdgeInsets.symmetric(horizontal: 8),
actionsPadding: const .symmetric(horizontal: 8),
title: InkWell(
onTap: onTap,
child: IgnorePointer(child: title),

View file

@ -48,7 +48,7 @@ class AvatarOrHash extends ConsumerWidget {
smallSize: 12,
backgroundColor: Theme.of(context).colorScheme.primary,
child: ClipRRect(
borderRadius: BorderRadius.all(Radius.circular((height - 8) / 2.5)),
borderRadius: .all(.circular((height - 8) / 2.5)),
child: SizedBox(
width: height,
height: height,
@ -60,7 +60,7 @@ class AvatarOrHash extends ConsumerWidget {
ref.watch(CrossCacheController.provider),
headers: ref.headers,
),
fit: BoxFit.cover,
fit: .cover,
loadingBuilder: (_, child, loadingProgress) =>
loadingProgress == null ? child : box,
errorBuilder: (_, _, _) => box,

View file

@ -4,8 +4,6 @@ import "package:flutter_hooks/flutter_hooks.dart";
import "package:fluttertagger/fluttertagger.dart";
import "package:hooks_riverpod/hooks_riverpod.dart";
import "package:nexus/controllers/power_level_controller.dart";
import "package:nexus/models/configs/power_level_config.dart";
import "package:nexus/models/content/content.dart";
import "package:nexus/models/event.dart";
import "package:nexus/models/relation_type.dart";
import "package:nexus/widgets/composer/mention_overlay.dart";
@ -42,7 +40,7 @@ class Composer extends HookConsumerWidget {
final shouldMention = useState(true);
final query = useState("");
if (relationType == RelationType.edit && controller.value.text.isEmpty) {
if (relationType == .edit && controller.value.text.isEmpty) {
controller.value.text = relatedEvent?.localContent?.editSource ?? "";
}
@ -51,7 +49,7 @@ class Composer extends HookConsumerWidget {
onSend(
controller.value.formattedText,
shouldMention: shouldMention.value,
tags: controller.value.tags.toIList(),
tags: .new(controller.value.tags),
);
onDismiss();
@ -60,13 +58,13 @@ class Composer extends HookConsumerWidget {
final style = TextStyle(
color: theme.colorScheme.primary,
fontWeight: FontWeight.bold,
fontWeight: .bold,
);
return Padding(
padding: EdgeInsetsGeometry.all(12),
padding: .all(12),
child: ClipRRect(
borderRadius: BorderRadius.all(Radius.circular(12)),
borderRadius: .all(.circular(12)),
child: Column(
children: [
RelationPreview(
@ -79,17 +77,14 @@ class Composer extends HookConsumerWidget {
),
Container(
color: theme.colorScheme.surfaceContainerHighest,
padding: EdgeInsets.symmetric(horizontal: 8),
padding: .symmetric(horizontal: 8),
child: Row(
spacing: 8,
mainAxisAlignment: MainAxisAlignment.center,
mainAxisAlignment: .center,
children:
ref.watch(
PowerLevelController.provider(
PowerLevelConfig(
eventType: EventType.message,
roomId: roomId,
),
.new(eventType: .message, roomId: roomId),
),
)
? [
@ -124,7 +119,7 @@ class Composer extends HookConsumerWidget {
),
Expanded(
child: FlutterTagger(
triggerStrategy: TriggerStrategy.eager,
triggerStrategy: .eager,
overlay: MentionOverlay(
roomId,
query: query.value,
@ -144,16 +139,16 @@ class Composer extends HookConsumerWidget {
maxLines: 12,
minLines: 1,
autofocus: true,
decoration: InputDecoration(
decoration: .new(
hintText: "Your message here...",
border: InputBorder.none,
border: .none,
),
controller: controller.value,
key: key,
onSubmitted: (_) => send(),
// Don't defocus on submit
onEditingComplete: () {},
textInputAction: TextInputAction.done,
textInputAction: .done,
focusNode: node,
),
),
@ -167,10 +162,7 @@ class Composer extends HookConsumerWidget {
: [
Expanded(
child: Padding(
padding: EdgeInsetsGeometry.symmetric(
horizontal: 8,
vertical: 12,
),
padding: .symmetric(horizontal: 8, vertical: 12),
child: Text(
"You don't have permission to send messages in this room...",
),

View file

@ -5,9 +5,7 @@ import "package:nexus/controllers/rooms_controller.dart";
import "package:nexus/controllers/via_controller.dart";
import "package:nexus/helpers/extensions/better_when.dart";
import "package:nexus/helpers/extensions/get_localpart.dart";
import "package:nexus/models/configs/members_by_status_config.dart";
import "package:nexus/models/content/membership.dart";
import "package:nexus/models/membership_status.dart";
import "package:nexus/widgets/avatar_or_hash.dart";
import "package:nexus/widgets/loading.dart";
@ -29,21 +27,18 @@ class MentionOverlay extends ConsumerWidget {
final rooms = ref.watch(RoomsController.provider);
return Padding(
padding: EdgeInsets.all(8),
padding: .all(8),
child: ClipRRect(
borderRadius: BorderRadius.all(Radius.circular(12)),
borderRadius: .all(.circular(12)),
child: Container(
color: Theme.of(context).colorScheme.surfaceContainerHigh,
padding: EdgeInsets.all(8),
padding: .all(8),
child: switch (triggerCharacter) {
"@" =>
ref
.watch(
MembersByStatusController.provider(
MembersByStatusConfig(
roomId: roomId,
status: MembershipStatus.join,
),
.new(roomId: roomId, status: .join),
),
)
.betterWhen(

View file

@ -27,38 +27,34 @@ class RelationPreview extends ConsumerWidget {
return Container(
color: theme.colorScheme.surfaceContainerHigh,
padding: EdgeInsets.symmetric(horizontal: 12),
padding: .symmetric(horizontal: 12),
child: Row(
spacing: 8,
children: [
if (relationType == RelationType.edit)
Text(
"Editing message:",
style: TextStyle(fontWeight: FontWeight.bold),
),
if (relationType == .edit)
Text("Editing message:", style: .new(fontWeight: .bold)),
Expanded(
child: Padding(
padding: EdgeInsets.symmetric(vertical: 8),
padding: .symmetric(vertical: 8),
child: EventPreview(relatedEvent!),
),
),
if (relationType == RelationType.reply)
if (relationType == .reply)
TextButton(
onPressed: toggleShouldMention,
child: Text(
shouldMention ? "@On" : "@Off",
style: TextStyle(
fontWeight: FontWeight.w900,
fontWeight: .w900,
color: shouldMention ? null : Theme.of(context).disabledColor,
),
),
),
IconButton(
tooltip:
"Cancel ${relationType == RelationType.edit ? "edit" : "reply"}",
tooltip: "Cancel ${relationType == .edit ? "edit" : "reply"}",
onPressed: onDismiss,
icon: const Icon(Icons.close),
iconSize: 20,

View file

@ -14,9 +14,9 @@ class DividerText extends StatelessWidget {
child: Divider(color: Theme.of(context).colorScheme.onSurface),
),
ConstrainedBox(
constraints: BoxConstraints(maxWidth: constraints.maxWidth - 32),
constraints: .new(maxWidth: constraints.maxWidth - 32),
child: Padding(
padding: const EdgeInsets.all(8),
padding: const .all(8),
child: Text(text, style: Theme.of(context).textTheme.labelLarge),
),
),

View file

@ -20,14 +20,14 @@ class EmojiPickerButton extends HookConsumerWidget {
Widget build(_, WidgetRef ref) => IconButton(
onPressed: () async {
onPressed?.call();
final controller = this.controller ?? TextEditingController();
final controller = this.controller ?? .new();
final emojis = await ref.watch(EmojiController.provider.future);
if (context.mounted) {
showModalBottomSheet(
context: context,
builder: (context) => EmojiKeyboardView(
config: EmojiViewConfig(
config: .new(
showRecentTab: false,
customCategories: emojis.$1.unlock,
customKeywords: emojis.$2.unlock,
@ -37,7 +37,8 @@ class EmojiPickerButton extends HookConsumerWidget {
textController: controller
..addListener(() {
// Without this, there will sometimes be a debugLocked is not true error sometimes
Future.delayed(Duration.zero, () {
// It might be preferable to use a microtask instead of a `Future.delayed`.
Future.delayed(.zero, () {
if (context.mounted) Navigator.of(context).pop();
});
onSelection?.call(controller.text);

View file

@ -12,16 +12,16 @@ class EventPreview extends StatelessWidget {
@override
Widget build(BuildContext context) => IgnorePointer(
child: Padding(
padding: EdgeInsets.symmetric(vertical: 4),
padding: .symmetric(vertical: 4),
child: Row(
mainAxisSize: MainAxisSize.min,
mainAxisSize: .min,
spacing: 12,
children: [
if (event.content is MessageContent) MessageAvatar(event),
Flexible(
child: Wrap(
crossAxisAlignment: WrapCrossAlignment.center,
crossAxisAlignment: .center,
spacing: 8,
runSpacing: 2,
children: [

View file

@ -20,14 +20,12 @@ class ExpandableImage extends ConsumerWidget {
builder: (_) => LayoutBuilder(
builder: (context, constraints) => Dialog(
backgroundColor: Colors.transparent,
insetPadding: EdgeInsets.all(constraints.maxWidth / 100),
insetPadding: .all(constraints.maxWidth / 100),
child: ConstrainedBox(
constraints: BoxConstraints(
minWidth: min(constraints.maxWidth, 1000),
),
constraints: .new(minWidth: min(constraints.maxWidth, 1000)),
child: InteractiveViewer(
child: Image(
fit: BoxFit.contain,
fit: .contain,
errorBuilder: (_, error, stackTrace) => ErrorDialog(
"Loading failed for $source\nError: $error",
stackTrace,

View file

@ -15,11 +15,7 @@ class FileCard extends StatelessWidget {
color: Theme.of(context).colorScheme.surfaceContainer,
child: ListTile(
leading: Icon(Icons.file_copy),
title: Text(
filename ?? "file",
maxLines: 1,
overflow: TextOverflow.ellipsis,
),
title: Text(filename ?? "file", maxLines: 1, overflow: .ellipsis),
subtitle: info?.size == null ? null : Text(info!.size!.sizeAsString),
// TODO: Downloading files
trailing: IconButton(onPressed: null, icon: Icon(Icons.download)),

View file

@ -7,13 +7,13 @@ class FlashWrapper extends StatelessWidget {
@override
Widget build(BuildContext context) => ClipRRect(
borderRadius: BorderRadius.all(Radius.circular(12)),
borderRadius: .all(.circular(12)),
child: AnimatedContainer(
padding: isFlashing ? EdgeInsets.all(8) : EdgeInsets.all(0),
padding: isFlashing ? .all(8) : .all(0),
color: isFlashing
? Theme.of(context).colorScheme.onSurface.withAlpha(50)
: Colors.transparent,
duration: Duration(milliseconds: 250),
duration: .new(milliseconds: 250),
child: child,
),
);

View file

@ -55,14 +55,12 @@ class FormTextInput extends StatelessWidget {
maxLines: maxLines,
maxLength: maxLength,
inputFormatters: formatters,
textCapitalization: capitalize
? TextCapitalization.sentences
: TextCapitalization.none,
textCapitalization: capitalize ? .sentences : .none,
initialValue: initialValue,
autocorrect: autocorrect,
obscureText: obscure,
onTap: onTap,
decoration: InputDecoration(
decoration: .new(
labelText: title,
border: border ?? (outlined ? null : const UnderlineInputBorder()),
suffixIcon: trailing,

View file

@ -11,20 +11,20 @@ class CodeBlock extends StatelessWidget {
Widget build(BuildContext context) {
final theme = Theme.of(context);
return ClipRRect(
borderRadius: BorderRadius.all(Radius.circular(16)),
borderRadius: .all(.circular(16)),
child: ColoredBox(
color: theme.colorScheme.surfaceContainerHighest,
child: IntrinsicWidth(
child: Column(
children: [
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
mainAxisAlignment: .spaceBetween,
children: [
Padding(
padding: EdgeInsets.symmetric(horizontal: 8),
padding: .symmetric(horizontal: 8),
child: Text(
lang.substring(0, min(lang.length, 15)),
style: TextStyle(fontFamily: "monospace"),
style: .new(fontFamily: "monospace"),
),
),
TextButton.icon(
@ -37,13 +37,13 @@ class CodeBlock extends StatelessWidget {
ColoredBox(
color: theme.colorScheme.surfaceContainerHigh,
child: Container(
constraints: BoxConstraints(minWidth: 250),
padding: EdgeInsets.all(8),
constraints: .new(minWidth: 250),
padding: .all(8),
child: SelectableText(
code,
minLines: 1,
maxLines: 99,
style: TextStyle(fontFamily: "monospace"),
style: .new(fontFamily: "monospace"),
),
),
),

View file

@ -86,9 +86,7 @@ class Html extends ConsumerWidget {
),
errorBuilder: (_, error, _) => Text(
"Image Failed to Load",
style: TextStyle(
color: Theme.of(context).colorScheme.error,
),
style: .new(color: Theme.of(context).colorScheme.error),
),
height: height.toDouble(),
width: width?.toDouble(),
@ -146,15 +144,14 @@ class Html extends ConsumerWidget {
element.attributes
.mapTo<MapEntry<String, String>?>(
(key, value) => switch (key) {
"data-mx-color" => MapEntry("color", value),
"data-mx-bg-color" => MapEntry("background-color", value),
"data-mx-color" => .new("color", value),
"data-mx-bg-color" => .new("background-color", value),
_ => null,
},
)
.nonNulls,
),
},
onTapUrl: (url) =>
ref.watch(LaunchHelper.provider).launchUrl(Uri.parse(url)),
onTapUrl: (url) => ref.watch(LaunchHelper.provider).launchUrl(.parse(url)),
);
}

View file

@ -3,7 +3,6 @@ import "package:flutter_riverpod/flutter_riverpod.dart";
import "package:nexus/controllers/user_controller.dart";
import "package:nexus/helpers/extensions/link_to_mention.dart";
import "package:nexus/helpers/extensions/show_user_popover.dart";
import "package:nexus/models/configs/user_config.dart";
class MentionChip extends ConsumerWidget {
final String? roomId;
@ -16,9 +15,7 @@ class MentionChip extends ConsumerWidget {
final membership = mention?.startsWith("@") == true
? ref
.watch(
UserController.provider(
UserConfig(roomId: roomId, userId: mention!),
),
UserController.provider(.new(roomId: roomId, userId: mention!)),
)
.whenOrNull(data: (data) => data)
: null;
@ -41,8 +38,8 @@ class MentionChip extends ConsumerWidget {
label: Text(
(membership == null ? null : "@${membership.displayName}") ??
mention,
style: TextStyle(
fontWeight: FontWeight.bold,
style: .new(
fontWeight: .bold,
color: Theme.of(context).colorScheme.onPrimary,
),
),

View file

@ -8,9 +8,9 @@ class Quoted extends StatelessWidget {
Widget build(BuildContext context) => Container(
decoration: BoxDecoration(
border: Border(
left: BorderSide(width: 4, color: Theme.of(context).dividerColor),
left: .new(width: 4, color: Theme.of(context).dividerColor),
),
),
child: Padding(padding: EdgeInsets.only(left: 8), child: child),
child: Padding(padding: .only(left: 8), child: child),
);
}

View file

@ -13,15 +13,15 @@ class SpoilerText extends HookWidget {
return InkWell(
onTap: () => revealed.value = !revealed.value,
child: AnimatedContainer(
duration: const Duration(milliseconds: 100),
padding: const EdgeInsets.symmetric(horizontal: 4, vertical: 2),
duration: const .new(milliseconds: 100),
padding: const .symmetric(horizontal: 4, vertical: 2),
decoration: BoxDecoration(
color: revealed.value ? Colors.transparent : Colors.blueGrey,
borderRadius: BorderRadius.circular(4),
borderRadius: .circular(4),
),
child: Text(
text,
style: TextStyle(color: revealed.value ? null : Colors.transparent),
style: .new(color: revealed.value ? null : Colors.transparent),
),
),
);

View file

@ -1,5 +1,4 @@
import "package:collection/collection.dart";
import "package:fast_immutable_collections/fast_immutable_collections.dart";
import "package:flutter/material.dart";
import "package:flutter_hooks/flutter_hooks.dart";
import "package:hooks_riverpod/hooks_riverpod.dart";
@ -7,7 +6,6 @@ import "package:nexus/controllers/client_controller.dart";
import "package:nexus/controllers/key_controller.dart";
import "package:nexus/controllers/spaces_controller.dart";
import "package:nexus/helpers/extensions/link_to_mention.dart";
import "package:nexus/models/requests/join_room_request.dart";
import "package:nexus/widgets/form_text_input.dart";
class JoinDialog extends HookWidget {
@ -20,8 +18,8 @@ class JoinDialog extends HookWidget {
return AlertDialog(
title: Text("Join a Room"),
content: Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisSize: .min,
crossAxisAlignment: .start,
children: [
Text("Enter the room alias, Matrix URI, or Matrix.to link."),
SizedBox(height: 12),
@ -45,7 +43,7 @@ class JoinDialog extends HookWidget {
final scaffoldMessenger = ScaffoldMessenger.of(context);
final snackbar = scaffoldMessenger.showSnackBar(
SnackBar(
.new(
content: Text("Joining room $roomIdOrAlias."),
duration: Duration(days: 999),
),
@ -55,9 +53,9 @@ class JoinDialog extends HookWidget {
final id = await ref
.watch(ClientController.provider.notifier)
.joinRoom(
JoinRoomRequest(
.new(
roomIdOrAlias: roomIdOrAlias,
via: IList(
via: .new(
Uri.tryParse(
roomAlias.text.replaceAll("/#", ""),
)?.queryParametersAll["via"] ??
@ -69,9 +67,9 @@ class JoinDialog extends HookWidget {
snackbar.close();
scaffoldMessenger.showSnackBar(
SnackBar(
.new(
content: Text("Room $roomIdOrAlias successfully joined."),
action: SnackBarAction(
action: .new(
label: "Open",
onPressed: () async {
final spaces = ref.watch(SpacesController.provider);
@ -113,13 +111,13 @@ class JoinDialog extends HookWidget {
snackbar.close();
if (context.mounted) {
scaffoldMessenger.showSnackBar(
SnackBar(
.new(
backgroundColor: Theme.of(
context,
).colorScheme.errorContainer,
content: Text(
error.toString(),
style: TextStyle(
style: .new(
color: Theme.of(context).colorScheme.onErrorContainer,
),
),

View file

@ -18,52 +18,46 @@ class MessageDisplayname extends ConsumerWidget {
});
@override
Widget build(BuildContext context, WidgetRef ref) =>
switch (ref.watch(AuthorController.provider(event))) {
AsyncData(:final value) || AsyncLoading(:final value?) => InkWell(
onTapUp: clickable
? (details) => context.showUserPopover(
value,
event.sender,
roomId: event.roomId,
globalPosition: details.globalPosition,
)
: null,
child: Wrap(
spacing: 4,
crossAxisAlignment: WrapCrossAlignment.center,
children: [
Text(
value.displayName ?? event.sender.localpart,
style:
style ??
TextStyle(
color: event.sender.colorHash,
fontWeight: FontWeight.bold,
),
maxLines: 1,
overflow: TextOverflow.ellipsis,
),
Widget build(BuildContext context, WidgetRef ref) => switch (ref.watch(
AuthorController.provider(event),
)) {
AsyncData(:final value) || AsyncLoading(:final value?) => InkWell(
onTapUp: clickable
? (details) => context.showUserPopover(
value,
event.sender,
roomId: event.roomId,
globalPosition: details.globalPosition,
)
: null,
child: Wrap(
spacing: 4,
crossAxisAlignment: .center,
children: [
Text(
value.displayName ?? event.sender.localpart,
style:
style ?? .new(color: event.sender.colorHash, fontWeight: .bold),
maxLines: 1,
overflow: .ellipsis,
),
if (event.pmp != null)
Text(
"(via ${event.sender})",
style: Theme.of(context).textTheme.labelSmall?.copyWith(
color: event.sender.colorHash,
fontWeight: FontWeight.bold,
),
maxLines: 1,
overflow: TextOverflow.ellipsis,
),
],
),
),
_ => Text(
event.sender.localpart,
style: TextStyle(
color: event.sender.colorHash,
fontWeight: FontWeight.bold,
),
),
};
if (event.pmp != null)
Text(
"(via ${event.sender})",
style: Theme.of(context).textTheme.labelSmall?.copyWith(
color: event.sender.colorHash,
fontWeight: .bold,
),
maxLines: 1,
overflow: .ellipsis,
),
],
),
),
_ => Text(
event.sender.localpart,
style: .new(color: event.sender.colorHash, fontWeight: .bold),
),
};
}

View file

@ -14,10 +14,10 @@ class LinkifiedText extends ConsumerWidget {
text: text,
maxLines: maxLines,
style: style,
options: LinkifyOptions(humanize: false),
options: .new(humanize: false),
onOpen: (link) =>
ref.watch(LaunchHelper.provider).launchUrl(Uri.parse(link.url)),
linkStyle: TextStyle(color: Theme.of(context).colorScheme.primary),
overflow: maxLines == null ? null : TextOverflow.ellipsis,
ref.watch(LaunchHelper.provider).launchUrl(.parse(link.url)),
linkStyle: .new(color: Theme.of(context).colorScheme.primary),
overflow: maxLines == null ? null : .ellipsis,
);
}

View file

@ -7,7 +7,7 @@ class Loading extends StatelessWidget {
@override
Widget build(BuildContext context) => Center(
child: Padding(
padding: EdgeInsets.all(16),
padding: .all(16),
child: SizedBox(height: height, child: CircularProgressIndicator()),
),
);

View file

@ -5,7 +5,6 @@ import "package:nexus/controllers/members_by_status_controller.dart";
import "package:nexus/helpers/extensions/get_localpart.dart";
import "package:nexus/helpers/extensions/show_user_popover.dart";
import "package:nexus/helpers/extensions/string_to_color.dart";
import "package:nexus/models/configs/members_by_status_config.dart";
import "package:nexus/models/content/membership.dart";
import "package:nexus/models/membership_status.dart";
import "package:nexus/widgets/avatar_or_hash.dart";
@ -21,7 +20,7 @@ class MemberList extends HookConsumerWidget {
final status = useState(MembershipStatus.join);
final membersProvider = ref.watch(
MembersByStatusController.provider(
MembersByStatusConfig(roomId: roomId, status: status.value),
.new(roomId: roomId, status: status.value),
),
);
@ -33,7 +32,7 @@ class MemberList extends HookConsumerWidget {
scrolledUnderElevation: 0,
leading: Icon(Icons.people),
title: Text("Members"),
actionsPadding: EdgeInsets.only(right: 4),
actionsPadding: .only(right: 4),
actions: [
if (Scaffold.of(context).hasEndDrawer)
IconButton(
@ -44,24 +43,24 @@ class MemberList extends HookConsumerWidget {
],
),
Wrap(
alignment: WrapAlignment.center,
alignment: .center,
spacing: 8,
runSpacing: 8,
children: [
FilterChip(
label: Text("Joined"),
onSelected: (value) => status.value = MembershipStatus.join,
selected: status.value == MembershipStatus.join,
onSelected: (value) => status.value = .join,
selected: status.value == .join,
),
FilterChip(
label: Text("Invited"),
onSelected: (value) => status.value = MembershipStatus.invite,
selected: status.value == MembershipStatus.invite,
onSelected: (value) => status.value = .invite,
selected: status.value == .invite,
),
FilterChip(
label: Text("Banned"),
onSelected: (value) => status.value = MembershipStatus.ban,
selected: status.value == MembershipStatus.ban,
onSelected: (value) => status.value = .ban,
selected: status.value == .ban,
),
],
),
@ -93,15 +92,15 @@ class MemberList extends HookConsumerWidget {
),
title: Text(
displayName ?? member.stateKey!.localpart,
overflow: TextOverflow.ellipsis,
style: TextStyle(
overflow: .ellipsis,
style: .new(
color: member.stateKey!.colorHash,
fontWeight: FontWeight.bold,
fontWeight: .bold,
),
),
subtitle: Text(
member.stateKey!,
overflow: TextOverflow.ellipsis,
overflow: .ellipsis,
),
),
),

View file

@ -17,7 +17,7 @@ class MessageImage extends ConsumerWidget {
Widget build(BuildContext context, WidgetRef ref) => ExpandableImage(
url.toString(),
child: ClipRRect(
borderRadius: BorderRadius.all(Radius.circular(8)),
borderRadius: .all(.circular(8)),
child: Image(
image: CachedNetworkImage(
url.toString(),
@ -47,7 +47,7 @@ class MessageImage extends ConsumerWidget {
errorBuilder: (context, error, stackTrace) => Center(
child: Text(
"Image Failed to Load",
style: TextStyle(color: Theme.of(context).colorScheme.error),
style: .new(color: Theme.of(context).colorScheme.error),
),
),
),

View file

@ -16,9 +16,7 @@ class AudioPlayer extends HookConsumerWidget {
@override
Widget build(BuildContext context, WidgetRef ref) {
final player = useMemoized(
() => Player(
configuration: PlayerConfiguration(bufferSize: 128 * 1024 * 1024),
),
() => Player(configuration: .new(bufferSize: 128 * 1024 * 1024)),
);
final playing = useState(false);
@ -66,7 +64,7 @@ class AudioPlayer extends HookConsumerWidget {
child: Card(
color: Theme.of(context).colorScheme.surfaceContainer,
child: Padding(
padding: EdgeInsetsGeometry.only(left: 8, right: 16),
padding: .only(left: 8, right: 16),
child: Row(
children: [
IconButton(
@ -88,7 +86,7 @@ class AudioPlayer extends HookConsumerWidget {
: duration.value.inMilliseconds.toDouble(),
value: position.value.inMilliseconds.toDouble(),
onChanged: (value) =>
player.seek(Duration(milliseconds: value.toInt())),
player.seek(.new(milliseconds: value.toInt())),
),
),
Text(

View file

@ -16,9 +16,7 @@ class VideoPlayer extends HookConsumerWidget {
@override
Widget build(BuildContext context, WidgetRef ref) {
final player = useMemoized(
() => Player(
configuration: PlayerConfiguration(bufferSize: 128 * 1024 * 1024),
),
() => Player(configuration: .new(bufferSize: 128 * 1024 * 1024)),
);
final controller = useMemoized(() => VideoController(player));

View file

@ -8,7 +8,6 @@ import "package:nexus/controllers/reactions_controller.dart";
import "package:nexus/controllers/room_chat_controller.dart";
import "package:nexus/helpers/extensions/get_headers.dart";
import "package:nexus/helpers/extensions/mxc_to_https.dart";
import "package:nexus/models/configs/reactions_config.dart";
import "package:nexus/models/event.dart";
import "package:nexus/widgets/error_dialog.dart";
import "package:nexus/main.dart";
@ -24,7 +23,7 @@ class ReactionRow extends ConsumerWidget {
return switch (ref.watch(
ReactionsController.provider(
ReactionsConfig(roomId: event.roomId, eventRowId: event.rowId),
.new(roomId: event.roomId, eventRowId: event.rowId),
),
)) {
AsyncData(value: final IMap<String, IList<String>>? reactors) ||
@ -47,7 +46,7 @@ class ReactionRow extends ConsumerWidget {
showCheckmark: false,
selected: selected,
label: Row(
mainAxisSize: MainAxisSize.min,
mainAxisSize: .min,
spacing: 8,
children: [
Flexible(
@ -64,15 +63,9 @@ class ReactionRow extends ConsumerWidget {
ref.watch(CrossCacheController.provider),
),
)
: Text(
reaction,
overflow: TextOverflow.ellipsis,
),
),
Text(
count.toString(),
overflow: TextOverflow.ellipsis,
: Text(reaction, overflow: .ellipsis),
),
Text(count.toString(), overflow: .ellipsis),
],
),
onSelected: enabled.value

View file

@ -64,12 +64,11 @@ class EventRenderer extends ConsumerWidget {
textOnly: textOnly,
),
MembershipContent content =>
event.previousContent is MembershipContent &&
(event.previousContent as MembershipContent).status ==
content.status
? null
: MembershipRenderer(event),
MembershipContent content => switch (event.previousContent) {
MembershipContent(:final status) =>
status == content.status ? null : MembershipRenderer(event),
_ => null,
},
AvatarContent() => GenericEventRenderer(Icons.interests, [
MessageDisplayname(event),
@ -101,10 +100,10 @@ class EventRenderer extends ConsumerWidget {
MessageDisplayname(event),
Text(
"changed the room's history visibility to ${switch (historyVisibility) {
HistoryVisibility.invited => "since invited",
HistoryVisibility.joined => "since joined",
HistoryVisibility.shared => "all history visible (shared)",
HistoryVisibility.worldReadable => "all history visible (world readable)",
.invited => "since invited",
.joined => "since joined",
.shared => "all history visible (shared)",
.worldReadable => "all history visible (world readable)",
}}",
),
]),
@ -158,7 +157,7 @@ class EventRenderer extends ConsumerWidget {
);
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
crossAxisAlignment: .start,
children: [
if (child != null) ...[
if (textOnly)
@ -168,7 +167,7 @@ class EventRenderer extends ConsumerWidget {
onSecondaryTapUp: contextMenuCallback,
onLongPressStart: contextMenuCallback,
child: Padding(
padding: isGrouped ? EdgeInsets.zero : EdgeInsets.only(top: 8),
padding: isGrouped ? .zero : .only(top: 8),
child: child,
),
),
@ -183,12 +182,7 @@ class EventRenderer extends ConsumerWidget {
color: theme.colorScheme.error,
),
),
].map(
(child) => Padding(
padding: EdgeInsetsGeometry.only(left: 4),
child: child,
),
),
].map((child) => Padding(padding: .only(left: 4), child: child)),
],
] else if (textOnly)
Text("Unknown event type", style: errorStyle),

View file

@ -7,14 +7,11 @@ class GenericEventRenderer extends StatelessWidget {
@override
Widget build(BuildContext context) => Padding(
padding: EdgeInsets.only(bottom: 8),
padding: .only(bottom: 8),
child: Row(
spacing: 8,
children: [
Padding(
padding: EdgeInsets.symmetric(horizontal: 4),
child: Icon(icon),
),
Padding(padding: .symmetric(horizontal: 4), child: Icon(icon)),
Expanded(child: Wrap(spacing: 4, children: children)),
],
),

View file

@ -4,7 +4,6 @@ import "package:nexus/helpers/extensions/show_user_popover.dart";
import "package:nexus/helpers/extensions/string_to_color.dart";
import "package:nexus/models/content/membership.dart";
import "package:nexus/models/event.dart";
import "package:nexus/models/membership_status.dart";
import "package:nexus/widgets/lazy_loading/message_displayname.dart";
import "package:nexus/widgets/renderers/generic_event.dart";
@ -29,24 +28,21 @@ class MembershipRenderer extends StatelessWidget {
globalPosition: details.globalPosition,
),
child: Text(
overflow: TextOverflow.ellipsis,
overflow: .ellipsis,
content.displayName ?? event.stateKey!.localpart,
maxLines: 1,
style: TextStyle(
color: event.sender.colorHash,
fontWeight: FontWeight.bold,
),
style: .new(color: event.sender.colorHash, fontWeight: .bold),
),
),
Text(
overflow: TextOverflow.ellipsis,
overflow: .ellipsis,
maxLines: 1,
"${switch (content.status) {
MembershipStatus.invite => "was invited to",
MembershipStatus.join => "joined",
MembershipStatus.leave => event.sender == event.stateKey ? "left" : (event.unsigned["prev_content"]?["membership"] == "ban" ? "was unbanned from" : "was kicked from"),
MembershipStatus.ban => "was banned from",
MembershipStatus.knock => "asked to join",
.invite => "was invited to",
.join => "joined",
.leave => event.sender == event.stateKey ? "left" : (event.unsigned["prev_content"]?["membership"] == "ban" ? "was unbanned from" : "was kicked from"),
.ban => "was banned from",
.knock => "asked to join",
}} the room${event.sender == event.stateKey ? "" : " by "}",
),
if (event.sender != event.stateKey) MessageDisplayname(event),

View file

@ -9,7 +9,6 @@ import "package:nexus/models/content/encrypted.dart";
import "package:nexus/models/content/message.dart";
import "package:nexus/models/content/sticker.dart";
import "package:nexus/models/event.dart";
import "package:nexus/models/requests/get_event_request.dart";
import "package:nexus/widgets/file_card.dart";
import "package:nexus/widgets/html/html.dart";
import "package:nexus/widgets/lazy_loading/message_avatar.dart";
@ -49,19 +48,19 @@ class MessageRenderer extends ConsumerWidget {
child: Text(
format(event.timestamp),
maxLines: 1,
overflow: TextOverflow.ellipsis,
overflow: .ellipsis,
style: theme.textTheme.labelSmall?.copyWith(color: Colors.grey),
),
);
final textStyle = TextStyle(
fontSize: event.localContent?.bigEmoji == true ? 32 : null,
fontStyle: event.content is EmoteMessageContent ? FontStyle.italic : null,
fontStyle: event.content is EmoteMessageContent ? .italic : null,
);
return Row(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: .start,
mainAxisSize: .min,
spacing: 8,
children: [
if (!textOnly)
@ -72,7 +71,7 @@ class MessageRenderer extends ConsumerWidget {
Flexible(
child: Column(
spacing: 4,
crossAxisAlignment: CrossAxisAlignment.start,
crossAxisAlignment: .start,
children: [
if (!isGrouped && !textOnly)
Row(
@ -83,7 +82,7 @@ class MessageRenderer extends ConsumerWidget {
],
),
Card(
margin: textOnly ? EdgeInsets.zero : EdgeInsets.only(bottom: 4),
margin: textOnly ? .zero : .only(bottom: 4),
color: textOnly
? Colors.transparent
: ref.watch(
@ -99,24 +98,21 @@ class MessageRenderer extends ConsumerWidget {
elevation: textOnly ? 0 : null,
child: Padding(
padding: textOnly ? EdgeInsets.zero : EdgeInsets.all(12),
padding: textOnly ? .zero : .all(12),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
crossAxisAlignment: .start,
children: [
if (!textOnly && event.replyTo != null)
Card(
margin: EdgeInsets.only(bottom: 8),
margin: .only(bottom: 8),
color: theme.colorScheme.surfaceContainerHigh,
child: InkWell(
onTap: onTapReply,
child: Padding(
padding: EdgeInsetsGeometry.symmetric(
vertical: 8,
horizontal: 12,
),
padding: .symmetric(vertical: 8, horizontal: 12),
child: switch (ref.watch(
EventController.provider(
GetEventRequest(
.new(
roomId: event.roomId,
eventId: event.replyTo!,
),
@ -145,12 +141,10 @@ class MessageRenderer extends ConsumerWidget {
? Text(
body,
maxLines: maxLines,
overflow: TextOverflow.ellipsis,
overflow: .ellipsis,
)
: ConstrainedBox(
constraints: BoxConstraints.loose(
Size.square(200),
),
constraints: .loose(.square(200)),
child: MessageImage(
url.mxcToHttps(
ref.watch(
@ -199,9 +193,9 @@ class MessageRenderer extends ConsumerWidget {
:final formattedBody,
:final format,
) => Column(
crossAxisAlignment: CrossAxisAlignment.start,
crossAxisAlignment: .start,
children: [
format == MessageFormat.html && !textOnly
format == .html && !textOnly
? Html(
roomId: event.roomId,
textStyle: textStyle,
@ -243,9 +237,7 @@ class MessageRenderer extends ConsumerWidget {
),
)) {
final url? => ConstrainedBox(
constraints: BoxConstraints.loose(
Size.square(500),
),
constraints: .loose(.square(500)),
child: switch (event.content) {
VideoMessageContent(:final info) =>
VideoPlayer(url, info),
@ -286,7 +278,7 @@ class MessageRenderer extends ConsumerWidget {
),
MessageContent(:final body) => Row(
spacing: 8,
mainAxisSize: MainAxisSize.min,
mainAxisSize: .min,
children: [
Text("Unknown message type:", style: errorStyle),
Text(body),

View file

@ -38,17 +38,17 @@ class RoomAppbar extends ConsumerWidget implements PreferredSizeWidget {
: () => showDialog(
context: context,
builder: (context) => Dialog(
constraints: BoxConstraints.loose(Size.fromWidth(400)),
constraints: .loose(.fromWidth(400)),
child: Padding(
padding: EdgeInsetsGeometry.all(24),
padding: .all(24),
child: Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisSize: .min,
crossAxisAlignment: .start,
spacing: 8,
children: [
Row(
spacing: 12,
mainAxisSize: MainAxisSize.min,
mainAxisSize: .min,
children: [
if (room.metadata?.avatar != null)
ExpandableImage(
@ -71,7 +71,7 @@ class RoomAppbar extends ConsumerWidget implements PreferredSizeWidget {
Expanded(
child: Text(
room.metadata?.name ?? "Unnamed Room",
overflow: TextOverflow.ellipsis,
overflow: .ellipsis,
maxLines: 3,
style: Theme.of(context).textTheme.headlineSmall,
),
@ -105,18 +105,18 @@ class RoomAppbar extends ConsumerWidget implements PreferredSizeWidget {
title: room == null
? null
: Column(
crossAxisAlignment: CrossAxisAlignment.start,
crossAxisAlignment: .start,
children: [
Text(
room.metadata?.name ?? "Unnamed Room",
overflow: TextOverflow.ellipsis,
overflow: .ellipsis,
maxLines: 1,
),
if (room.metadata?.topic?.isNotEmpty == true)
Text(
room.metadata!.topic!,
maxLines: 1,
overflow: TextOverflow.ellipsis,
overflow: .ellipsis,
style: Theme.of(context).textTheme.labelMedium?.copyWith(
color: Theme.of(context).colorScheme.onSurfaceVariant,
),

View file

@ -12,11 +12,9 @@ import "package:nexus/controllers/rooms_controller.dart";
import "package:nexus/controllers/room_chat_controller.dart";
import "package:nexus/controllers/via_controller.dart";
import "package:nexus/models/configs/power_level_config.dart";
import "package:nexus/models/content/content.dart";
import "package:nexus/models/content/message.dart";
import "package:nexus/models/event.dart";
import "package:nexus/models/relation_type.dart";
import "package:nexus/models/requests/report_request.dart";
import "package:nexus/widgets/composer/composer.dart";
import "package:nexus/widgets/emoji_picker_button.dart";
import "package:nexus/widgets/renderers/event.dart";
@ -102,8 +100,7 @@ class RoomChat extends HookConsumerWidget {
final composerNode = useFocusNode(
onKeyEvent: (_, event) {
if (event is KeyDownEvent &&
event.logicalKey == LogicalKeyboardKey.escape) {
if (event is KeyDownEvent && event.logicalKey == .escape) {
relatedEvent.value = null;
return KeyEventResult.handled;
}
@ -118,7 +115,7 @@ class RoomChat extends HookConsumerWidget {
return [
if (ref.watch(
PowerLevelController.provider(
PowerLevelConfig(eventType: EventType.reaction, roomId: roomId),
.new(eventType: .reaction, roomId: roomId),
),
))
PopupMenuItem(
@ -134,7 +131,7 @@ class RoomChat extends HookConsumerWidget {
value["m.recent_emoji"]
?.content["recent_emoji"] ??
[],
).map((entry) => entry["emoji"]),
).map((entry) => entry["emoji"]).toIList(),
),
),
"👍",
@ -167,13 +164,13 @@ class RoomChat extends HookConsumerWidget {
),
if (ref.watch(
PowerLevelController.provider(
PowerLevelConfig(eventType: EventType.message, roomId: roomId),
PowerLevelConfig(eventType: .message, roomId: roomId),
),
))
PopupMenuItem(
onTap: () {
relatedEvent.value = event;
relationType.value = RelationType.reply;
relationType.value = .reply;
composerNode.requestFocus();
},
child: ListTile(leading: Icon(Icons.reply), title: Text("Reply")),
@ -182,7 +179,7 @@ class RoomChat extends HookConsumerWidget {
PopupMenuItem(
onTap: () {
relatedEvent.value = event;
relationType.value = RelationType.edit;
relationType.value = .edit;
composerNode.requestFocus();
},
child: ListTile(leading: Icon(Icons.edit), title: Text("Edit")),
@ -207,10 +204,7 @@ class RoomChat extends HookConsumerWidget {
),
if (ref.watch(
PowerLevelController.provider(
PowerLevelConfig.redaction(
targetUser: event.sender,
roomId: roomId,
),
.redaction(targetUser: event.sender, roomId: roomId),
),
))
PopupMenuItem(
@ -222,8 +216,8 @@ class RoomChat extends HookConsumerWidget {
return AlertDialog(
title: Text("Delete Message"),
content: Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisSize: .min,
crossAxisAlignment: .start,
children: [
Text(
"Are you sure you want to delete this message? This can not be reversed.",
@ -261,7 +255,7 @@ class RoomChat extends HookConsumerWidget {
),
child: ListTile(
leading: Icon(Icons.delete, color: danger),
title: Text("Delete", style: TextStyle(color: danger)),
title: Text("Delete", style: .new(color: danger)),
),
),
PopupMenuItem(
@ -273,8 +267,8 @@ class RoomChat extends HookConsumerWidget {
return AlertDialog(
title: Text("Report"),
content: Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisSize: .min,
crossAxisAlignment: .start,
children: [
Text(
"Report this event to your server administrators, who can take action like banning this server or room.",
@ -297,7 +291,7 @@ class RoomChat extends HookConsumerWidget {
TextButton(
onPressed: () {
client.reportEvent(
ReportRequest(
.new(
roomId: roomId,
eventId: event.eventId,
reason: reasonController.text.isEmpty
@ -316,7 +310,7 @@ class RoomChat extends HookConsumerWidget {
),
child: ListTile(
leading: Icon(Icons.report, color: danger),
title: Text("Report", style: TextStyle(color: danger)),
title: Text("Report", style: .new(color: danger)),
),
),
].toIList();
@ -341,7 +335,7 @@ class RoomChat extends HookConsumerWidget {
children: [
Positioned.fill(
child: Padding(
padding: EdgeInsets.symmetric(horizontal: 12),
padding: .symmetric(horizontal: 12),
child: switch (controllerData) {
AsyncData(:final value) ||
AsyncLoading(:final value?) => CustomScrollView(
@ -349,9 +343,7 @@ class RoomChat extends HookConsumerWidget {
controller: scrollController,
slivers: [
SliverPadding(
padding: EdgeInsetsGeometry.only(
bottom: composerSize.value,
),
padding: .only(bottom: composerSize.value),
),
SuperSliverList.builder(
@ -371,19 +363,15 @@ class RoomChat extends HookConsumerWidget {
),
scrollController: scrollController,
alignment: 0.5,
duration: (_) =>
Duration(milliseconds: 700),
duration: (_) => .new(milliseconds: 700),
curve: (_) => Curves.easeInOut,
);
flashingEvent.value = replyId;
await Future.delayed(
Duration(seconds: 1),
() {
if (flashingEvent.value == replyId) {
flashingEvent.value = null;
}
},
);
await Future.delayed(.new(seconds: 1), () {
if (flashingEvent.value == replyId) {
flashingEvent.value = null;
}
});
},
getEventOptions: getEventOptions,
isGrouped:
@ -403,7 +391,7 @@ class RoomChat extends HookConsumerWidget {
SliverToBoxAdapter(
child: Padding(
padding: EdgeInsets.symmetric(vertical: 36),
padding: .symmetric(vertical: 36),
child: Center(
child: controllerData is AsyncLoading
? Loading()

View file

@ -34,7 +34,7 @@ class RoomMenu extends ConsumerWidget {
final vias = ref.watch(ViaController.provider(room!));
await Clipboard.setData(
ClipboardData(
.new(
text:
"matrix:roomid/${room!.metadata?.id.substring(1)}$vias)",
),
@ -63,7 +63,7 @@ class RoomMenu extends ConsumerWidget {
Navigator.of(context).pop();
final snackbar = ScaffoldMessenger.of(context)
.showSnackBar(
SnackBar(
.new(
content: Text("Leaving room..."),
duration: Duration(days: 1),
),

View file

@ -74,14 +74,14 @@ class Sidebar extends HookConsumerWidget {
),
),
label: Text(space.title),
padding: EdgeInsets.only(top: 4),
padding: .only(top: 4),
),
)
.toList(),
selectedIndex: selectedIndex,
trailingAtBottom: true,
trailing: Padding(
padding: EdgeInsets.symmetric(vertical: 16),
padding: .symmetric(vertical: 16),
child: Column(
spacing: 8,
children: [
@ -136,10 +136,7 @@ class Sidebar extends HookConsumerWidget {
selectedSpace.title,
),
title: Text(
selectedSpace.title,
overflow: TextOverflow.ellipsis,
),
title: Text(selectedSpace.title, overflow: .ellipsis),
backgroundColor: Colors.transparent,
actions: [
RoomMenu(

View file

@ -13,25 +13,24 @@ class UrlPreview extends ConsumerWidget {
@override
Widget build(BuildContext context, WidgetRef ref) => ConstrainedBox(
constraints: BoxConstraints.loose(Size.fromWidth(400)),
constraints: .loose(.fromWidth(400)),
child: ref
.watch(UrlPreviewController.provider(link))
.betterWhen(
data: (preview) => preview == null
? SizedBox.shrink()
: InkWell(
onTap: () => ref
.watch(LaunchHelper.provider)
.launchUrl(Uri.parse(link)),
onTap: () =>
ref.watch(LaunchHelper.provider).launchUrl(.parse(link)),
child: Card(
margin: EdgeInsets.symmetric(vertical: 4),
margin: .symmetric(vertical: 4),
color: Theme.of(
context,
).colorScheme.surfaceContainerHighest,
child: Padding(
padding: EdgeInsetsGeometry.all(16),
padding: .all(16),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
crossAxisAlignment: .start,
spacing: 4,
children: [
if (preview.title != null)
@ -45,9 +44,7 @@ class UrlPreview extends ConsumerWidget {
],
if (preview.imageUrl != null)
ClipRRect(
borderRadius: BorderRadius.all(
Radius.circular(8),
),
borderRadius: .all(.circular(8)),
child: Image(
errorBuilder: (_, _, _) => SizedBox.shrink(),
width: preview.width,
@ -56,7 +53,7 @@ class UrlPreview extends ConsumerWidget {
ref.watch(CrossCacheController.provider),
headers: ref.headers,
),
fit: BoxFit.fitWidth,
fit: .fitWidth,
),
),
],

View file

@ -9,11 +9,8 @@ import "package:nexus/controllers/profile_controller.dart";
import "package:nexus/helpers/extensions/better_when.dart";
import "package:nexus/helpers/extensions/get_localpart.dart";
import "package:nexus/helpers/extensions/mxc_to_https.dart";
import "package:nexus/models/configs/power_level_config.dart";
import "package:nexus/models/content/membership.dart";
import "package:nexus/models/membership_status.dart";
import "package:nexus/models/requests/membership_action.dart";
import "package:nexus/models/requests/set_membership_request.dart";
import "package:nexus/widgets/avatar_or_hash.dart";
import "package:nexus/main.dart";
import "package:nexus/widgets/expandable_image.dart";
@ -39,8 +36,8 @@ class UserPopover extends ConsumerWidget {
return AlertDialog(
title: Text("${toBeginningOfSentenceCase(action.name)} $userId"),
content: Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisSize: .min,
crossAxisAlignment: .start,
children: [
Text("Are you sure you want to ${action.name} $userId?"),
SizedBox(height: 12),
@ -62,7 +59,7 @@ class UserPopover extends ConsumerWidget {
Navigator.of(context).pop();
client
.setMembership(
SetMembershipRequest(
.new(
userId: userId,
roomId: roomId!,
action: action,
@ -80,20 +77,18 @@ class UserPopover extends ConsumerWidget {
);
final actionButton = ButtonStyle(
padding: WidgetStatePropertyAll(
EdgeInsets.symmetric(horizontal: 24, vertical: 18),
),
padding: WidgetStatePropertyAll(.symmetric(horizontal: 24, vertical: 18)),
shape: WidgetStatePropertyAll(
RoundedRectangleBorder(borderRadius: BorderRadius.circular(8)),
RoundedRectangleBorder(borderRadius: .circular(8)),
),
);
return Column(
spacing: 16,
crossAxisAlignment: CrossAxisAlignment.stretch,
crossAxisAlignment: .stretch,
children: [
Wrap(
alignment: WrapAlignment.center,
alignment: .center,
spacing: 16,
runSpacing: 8,
children: [
@ -126,7 +121,7 @@ class UserPopover extends ConsumerWidget {
.betterWhen(
loading: SizedBox.shrink,
data: (profile) => Wrap(
alignment: WrapAlignment.center,
alignment: .center,
spacing: 4,
runSpacing: 4,
children: [
@ -135,7 +130,7 @@ class UserPopover extends ConsumerWidget {
))
Chip(
label: Text(pronoun.summary),
labelStyle: TextStyle(
labelStyle: .new(
color: theme.colorScheme.onPrimary,
),
color: WidgetStatePropertyAll(
@ -145,7 +140,7 @@ class UserPopover extends ConsumerWidget {
if (profile.timezone != null)
Chip(
label: Text(profile.timezone!),
labelStyle: TextStyle(
labelStyle: .new(
color: theme.colorScheme.onPrimary,
),
color: WidgetStatePropertyAll(
@ -162,7 +157,7 @@ class UserPopover extends ConsumerWidget {
if (userId != ref.watch(ClientStateController.provider)?.userId &&
roomId != null)
Wrap(
alignment: WrapAlignment.center,
alignment: .center,
spacing: 8,
runSpacing: 8,
children: [
@ -175,17 +170,17 @@ class UserPopover extends ConsumerWidget {
if (ref.watch(
PowerLevelController.provider(
PowerLevelConfig.membershipAction(
action: MembershipAction.kick,
.membershipAction(
action: .kick,
roomId: roomId!,
targetUser: userId,
),
),
) &&
member.status == MembershipStatus.join ||
member.status == MembershipStatus.invite)
member.status == .join ||
member.status == .invite)
FilledButton.icon(
onPressed: () => showMembershipDialog(MembershipAction.kick),
onPressed: () => showMembershipDialog(.kick),
label: Text("Kick"),
style: actionButton.copyWith(
backgroundColor: WidgetStatePropertyAll(
@ -199,23 +194,19 @@ class UserPopover extends ConsumerWidget {
),
if (ref.watch(
PowerLevelController.provider(
PowerLevelConfig.membershipAction(
.membershipAction(
roomId: roomId!,
action: MembershipAction.ban,
action: .ban,
targetUser: userId,
),
),
))
ElevatedButton.icon(
onPressed: () => showMembershipDialog(
member.status == MembershipStatus.ban
? MembershipAction.unban
: MembershipAction.ban,
member.status == .ban ? .unban : .ban,
),
icon: Icon(Icons.gavel),
label: Text(
member.status == MembershipStatus.ban ? "Unban" : "Ban",
),
label: Text(member.status == .ban ? "Unban" : "Ban"),
style: actionButton.copyWith(
backgroundColor: WidgetStatePropertyAll(
theme.colorScheme.errorContainer,