diff --git a/lib/controllers/account_data_controller.dart b/lib/controllers/account_data_controller.dart index 125d7cf..0926e08 100644 --- a/lib/controllers/account_data_controller.dart +++ b/lib/controllers/account_data_controller.dart @@ -4,10 +4,10 @@ import "package:nexus/models/account_data.dart"; class AccountDataController extends Notifier> { @override - IMap build() => const IMap.empty(); + IMap build() => .new(); void update(IMap newData) => - state = IMap({...state.unlock, ...newData.unlock}); + state = .new({...state.unlock, ...newData.unlock}); static final provider = NotifierProvider>( diff --git a/lib/controllers/author_controller.dart b/lib/controllers/author_controller.dart index 70070e1..77202ca 100644 --- a/lib/controllers/author_controller.dart +++ b/lib/controllers/author_controller.dart @@ -1,7 +1,6 @@ import "dart:async"; import "package:flutter_riverpod/flutter_riverpod.dart"; import "package:nexus/controllers/user_controller.dart"; -import "package:nexus/models/configs/user_config.dart"; import "package:nexus/models/content/membership.dart"; import "package:nexus/models/event.dart"; @@ -13,11 +12,11 @@ class AuthorController extends AsyncNotifier { Future build() async { final member = await ref.watch( UserController.provider( - UserConfig(roomId: event.roomId, userId: event.sender), + .new(roomId: event.roomId, userId: event.sender), ).future, ); - return MembershipContent( + return .new( status: member.status, avatarUrl: event.pmp?.avatarUrl ?? member.avatarUrl, displayName: event.pmp?.displayName ?? member.displayName, diff --git a/lib/controllers/client_controller.dart b/lib/controllers/client_controller.dart index f1ff6a6..5558beb 100644 --- a/lib/controllers/client_controller.dart +++ b/lib/controllers/client_controller.dart @@ -14,7 +14,6 @@ import "package:nexus/controllers/sync_status_controller.dart"; import "package:nexus/controllers/top_level_spaces_controller.dart"; import "package:nexus/helpers/extensions/gomuks_buffer.dart"; import "package:nexus/main.dart"; -import "package:nexus/models/client_state.dart"; import "package:nexus/models/event.dart"; import "package:nexus/models/paginate.dart"; import "package:nexus/models/requests/get_event_request.dart"; @@ -31,7 +30,6 @@ import "package:nexus/models/requests/send_message_request.dart"; import "package:nexus/models/requests/set_membership_request.dart"; import "package:nexus/models/room.dart"; import "package:nexus/models/sync_data.dart"; -import "package:nexus/models/sync_status.dart"; import "package:nexus/src/third_party/gomuks.g.dart"; import "package:flutter_riverpod/flutter_riverpod.dart"; import "package:path_provider/path_provider.dart"; @@ -66,12 +64,12 @@ class ClientController extends AsyncNotifier { case "client_state": ref .watch(ClientStateController.provider.notifier) - .set(ClientState.fromJson(decodedMuksEvent)); + .set(.fromJson(decodedMuksEvent)); break; case "sync_status": ref .watch(SyncStatusController.provider.notifier) - .set(SyncStatus.fromJson(decodedMuksEvent)); + .set(.fromJson(decodedMuksEvent)); break; case "init_complete": ref.watch(InitCompleteController.provider.notifier).complete(); @@ -81,12 +79,10 @@ class ClientController extends AsyncNotifier { ref .watch(RoomsController.provider.notifier) .update( - { - event.roomId: Room( - events: {event.rowId: event}.toIMap(), - ), - }.toIMap(), - const ISet.empty(), + .new({ + event.roomId: .new(events: .new({event.rowId: event})), + }), + .new(), ); break; @@ -210,9 +206,11 @@ class ClientController extends AsyncNotifier { (await _sendCommand("get_room_state", request.toJson())) as List?; final response = await getState(request); - return (response ?? await getState(request.copyWith(refetch: true)) ?? []) - .map((event) => Event.fromJson(event)) - .toIList(); + return .new( + (response ?? await getState(request.copyWith(refetch: true)) ?? []).map( + (event) => .fromJson(event), + ), + ); } Future?> getRelatedEvents( @@ -220,20 +218,20 @@ class ClientController extends AsyncNotifier { ) async { final response = (await _sendCommand("get_related_events", request.toJson())) as List?; - return response?.map((event) => Event.fromJson(event)).toIList(); + return .new(response?.map((event) => .fromJson(event))); } Future getEvent(GetEventRequest request) async { final json = await _sendCommand("get_event", request.toJson()); - return json == null ? null : Event.fromJson(json); + return json == null ? null : .fromJson(json); } Future paginate(PaginateRequest request) async => - Paginate.fromJson(await _sendCommand("paginate", request.toJson())); + .fromJson(await _sendCommand("paginate", request.toJson())); Future getProfile(String userId) async { final json = await _sendCommand("get_profile", {"user_id": userId}); - return Profile.fromJsonWithCatch({...json, "id": userId}); + return .fromJsonWithCatch({...json, "id": userId}); } Future reportEvent(ReportRequest request) => diff --git a/lib/controllers/client_state_controller.dart b/lib/controllers/client_state_controller.dart index 998d4a1..1b77ecb 100644 --- a/lib/controllers/client_state_controller.dart +++ b/lib/controllers/client_state_controller.dart @@ -5,9 +5,7 @@ class ClientStateController extends Notifier { @override Null build() => null; - void set(ClientState newState) { - state = newState; - } + void set(ClientState newState) => state = newState; static final provider = NotifierProvider( ClientStateController.new, diff --git a/lib/controllers/cross_cache_controller.dart b/lib/controllers/cross_cache_controller.dart index 1d6d4b6..4d5611a 100644 --- a/lib/controllers/cross_cache_controller.dart +++ b/lib/controllers/cross_cache_controller.dart @@ -2,11 +2,8 @@ import "package:cross_cache/cross_cache.dart"; import "package:flutter_riverpod/flutter_riverpod.dart"; class CrossCacheController extends Notifier { - static const String spaceKey = "space"; - static const String roomKey = "room"; - @override - CrossCache build() => CrossCache(); + CrossCache build() => .new(); static final provider = NotifierProvider( CrossCacheController.new, diff --git a/lib/controllers/emoji_controller.dart b/lib/controllers/emoji_controller.dart index 358f98b..7d00ac6 100644 --- a/lib/controllers/emoji_controller.dart +++ b/lib/controllers/emoji_controller.dart @@ -12,10 +12,7 @@ class EmojiController extends AsyncNotifier { @override Future build() async { final response = await get( - Uri.https( - "github.com", - "github/gemoji/raw/refs/heads/master/db/emoji.json", - ), + .https("github.com", "github/gemoji/raw/refs/heads/master/db/emoji.json"), ); if (response.statusCode != 200) { @@ -30,19 +27,19 @@ class EmojiController extends AsyncNotifier { .toIList(); final categoryMap = entries.fold>>( - const IMap.empty(), + .new(), (acc, entry) => acc.update( entry.category, (list) => list.add(entry.emoji), - ifAbsent: () => IList([entry.emoji]), + ifAbsent: () => .new([entry.emoji]), ), ); final keywordMap = entries.fold>>( - const IMap.empty(), + .new(), (acc, entry) => acc.add( entry.emoji, - IList([...entry.tags, ...entry.aliases, entry.description]), + .new([...entry.tags, ...entry.aliases, entry.description]), ), ); @@ -71,9 +68,9 @@ class EmojiController extends AsyncNotifier { ); final customKeywords = IMap( - Map.fromEntries( + .fromEntries( keywordMap.entries.map( - (e) => MapEntry(e.key, e.value.toList(growable: false)), + (e) => .new(e.key, e.value.toList(growable: false)), ), ), ); diff --git a/lib/controllers/members_controller.dart b/lib/controllers/members_controller.dart index 64e1ef7..330785c 100644 --- a/lib/controllers/members_controller.dart +++ b/lib/controllers/members_controller.dart @@ -16,7 +16,7 @@ class MembersController extends AsyncNotifier> { RoomsController.provider.select((value) => value[roomId]), ); - if (room == null) return const ISet.empty(); + if (room == null) return .new(); if (!room.hasFetchedMembers) { final fetchedState = await ref @@ -38,7 +38,7 @@ class MembersController extends AsyncNotifier> { .map((rowId) => room.events[rowId]) .nonNulls .toISet() ?? - const ISet.empty(); + .new(); } static final provider = AsyncNotifierProvider.autoDispose diff --git a/lib/controllers/multi_provider_controller.dart b/lib/controllers/multi_provider_controller.dart index e23ecaa..52dd8d9 100644 --- a/lib/controllers/multi_provider_controller.dart +++ b/lib/controllers/multi_provider_controller.dart @@ -7,9 +7,8 @@ class MultiProviderController extends AsyncNotifier { final IList providers; @override - FutureOr build() async => await Future.wait( - providers.map((provider) => ref.watch(provider.future)), - ); + Future build() => + .wait(providers.map((provider) => ref.watch(provider.future))); static final provider = AsyncNotifierProvider.family< diff --git a/lib/controllers/power_level_controller.dart b/lib/controllers/power_level_controller.dart index 2539778..917ee31 100644 --- a/lib/controllers/power_level_controller.dart +++ b/lib/controllers/power_level_controller.dart @@ -4,7 +4,6 @@ import "package:nexus/controllers/rooms_controller.dart"; import "package:nexus/models/configs/power_level_config.dart"; import "package:nexus/models/content/content.dart"; import "package:nexus/models/content/power_levels.dart"; -import "package:nexus/models/requests/membership_action.dart"; class PowerLevelController extends Notifier { final PowerLevelConfig config; @@ -14,7 +13,7 @@ class PowerLevelController extends Notifier { bool build() { if (config case EventPowerLevelConfig(:final eventType)) { assert( - eventType != EventType.redaction, + eventType != .redaction, "Checking power level for a redaction should use [PowerLevelConfig.redaction].", ); } @@ -29,6 +28,7 @@ class PowerLevelController extends Notifier { final content = event?.content is PowerLevelsContent ? event!.content : PowerLevelsContent(); + final user = ref.watch( ClientStateController.provider.select((value) => value?.userId), ); @@ -45,15 +45,15 @@ class PowerLevelController extends Notifier { MembershipActionPowerLevelConfig(:final action, :final targetUser) => switch (action) { - MembershipAction.invite => userLevel >= content.invite, + .invite => userLevel >= content.invite, - MembershipAction.kick => + .kick => userLevel >= content.kick && userLevel > powerLevelOf(targetUser), - MembershipAction.ban => + .ban => userLevel >= content.ban && userLevel > powerLevelOf(targetUser), - MembershipAction.unban => userLevel >= content.ban, + .unban => userLevel >= content.ban, }, StatePowerLevelConfig(:final eventType) => diff --git a/lib/controllers/reactions_controller.dart b/lib/controllers/reactions_controller.dart index 8c199a9..db9af9b 100644 --- a/lib/controllers/reactions_controller.dart +++ b/lib/controllers/reactions_controller.dart @@ -4,7 +4,6 @@ import "package:nexus/controllers/client_controller.dart"; import "package:nexus/controllers/rooms_controller.dart"; import "package:nexus/models/configs/reactions_config.dart"; import "package:nexus/models/content/reaction.dart"; -import "package:nexus/models/requests/get_related_events_request.dart"; class ReactionsController extends AsyncNotifier>> { final ReactionsConfig config; @@ -23,7 +22,7 @@ class ReactionsController extends AsyncNotifier>> { ? await ref .watch(ClientController.provider.notifier) .getRelatedEvents( - GetRelatedEventsRequest( + .new( roomId: config.roomId, eventId: eventInfo!.$1, relationType: "m.annotation", @@ -33,18 +32,18 @@ class ReactionsController extends AsyncNotifier>> { return reactionEvents ?.where((event) => event.redactedBy == null) - .fold>>(IMap(), (acc, event) { + .fold>>(.new(), (acc, event) { if (event.content case ReactionContent(:final key?)) { return acc.update( key, (list) => list.add(event.sender), - ifAbsent: () => IList([event.sender]), + ifAbsent: () => .new([event.sender]), ); } return acc; }) ?? - const IMap.empty(); + .new(); } static final provider = diff --git a/lib/controllers/room_chat_controller.dart b/lib/controllers/room_chat_controller.dart index d8fea0c..03caa04 100644 --- a/lib/controllers/room_chat_controller.dart +++ b/lib/controllers/room_chat_controller.dart @@ -9,12 +9,8 @@ import "package:nexus/controllers/rooms_controller.dart"; import "package:nexus/models/content/content.dart"; import "package:nexus/models/content/reaction.dart"; import "package:nexus/models/event.dart"; -import "package:nexus/models/requests/get_related_events_request.dart"; -import "package:nexus/models/requests/get_room_state_request.dart"; -import "package:nexus/models/requests/paginate_request.dart"; import "package:nexus/models/requests/redact_event_request.dart"; import "package:nexus/models/relation_type.dart"; -import "package:nexus/models/requests/send_event_request.dart"; import "package:nexus/models/requests/send_message_request.dart"; import "package:nexus/models/room.dart"; @@ -28,12 +24,10 @@ class RoomChatController extends AsyncNotifier> { final room = ref.watch( RoomsController.provider.select((rooms) => rooms[roomId]), ); - if (room == null) return const IList.empty(); + if (room == null) return .new(); if (!room.hasFetchedState) { - final state = await client.getRoomState( - GetRoomStateRequest(roomId: roomId), - ); + final state = await client.getRoomState(.new(roomId: roomId)); await ref.read(RoomsController.provider.notifier).addState(roomId, state); } @@ -45,7 +39,7 @@ class RoomChatController extends AsyncNotifier> { } return IMap.fromValues( - keyMapper: (id) => 9999999 + (id ?? 0), + keyMapper: (id) => 9999999999 + (id ?? 0), values: room.sticky, ) .addAll(room.timeline) @@ -86,7 +80,7 @@ class RoomChatController extends AsyncNotifier> { final response = await ref .watch(ClientController.provider.notifier) .paginate( - PaginateRequest( + .new( roomId: roomId, maxTimelineId: timelineKeys?.isNotEmpty == true ? timelineKeys?.reduce(min) @@ -112,7 +106,7 @@ class RoomChatController extends AsyncNotifier> { ), ), }), - const ISet.empty(), + .new(), ); return response.hasMore; @@ -153,20 +147,20 @@ class RoomChatController extends AsyncNotifier> { text: taggedMessage, relation: relation == null ? null - : Relation(eventId: relation.eventId, relationType: relationType), + : .new(eventId: relation.eventId, relationType: relationType), ), ); ref .watch(RoomsController.provider.notifier) .update( - { - roomId: Room( - events: {event.rowId: event}.toIMap(), - sticky: {event.rowId}.toISet(), + .new({ + roomId: .new( + events: .new({event.rowId: event}), + sticky: .new({event.rowId}), ), - }.toIMap(), - const ISet.empty(), + }), + .new(), ); } @@ -177,7 +171,7 @@ class RoomChatController extends AsyncNotifier> { ) async { final client = ref.watch(ClientController.provider.notifier); final allReactionEvents = await client.getRelatedEvents( - GetRelatedEventsRequest( + .new( roomId: roomId, eventId: event.eventId, relationType: "m.annotation", @@ -199,9 +193,7 @@ class RoomChatController extends AsyncNotifier> { if (reactionEvent != null) { await ref .watch(ClientController.provider.notifier) - .redactEvent( - RedactEventRequest(eventId: reactionEvent.eventId, roomId: roomId), - ); + .redactEvent(.new(eventId: reactionEvent.eventId, roomId: roomId)); } } @@ -209,7 +201,7 @@ class RoomChatController extends AsyncNotifier> { final client = ref.watch(ClientController.provider.notifier); await client.sendEvent( - SendEventRequest( + .new( roomId: roomId, type: EventType.reaction.type, content: { diff --git a/lib/controllers/rooms_controller.dart b/lib/controllers/rooms_controller.dart index c4b36c1..d0c6eb9 100644 --- a/lib/controllers/rooms_controller.dart +++ b/lib/controllers/rooms_controller.dart @@ -1,33 +1,29 @@ import "dart:isolate"; - import "package:fast_immutable_collections/fast_immutable_collections.dart"; import "package:flutter_riverpod/flutter_riverpod.dart"; import "package:nexus/models/event.dart"; -import "package:nexus/models/read_receipt.dart"; import "package:nexus/models/room.dart"; class RoomsController extends Notifier> { @override - IMap build() => const IMap.empty(); + IMap build() => .new(); Future addState( String roomId, IList state, { bool isMembers = false, }) async => update( - { + .new({ roomId: Room( - events: IMap.fromEntries( - state.map((event) => MapEntry(event.rowId, event)), - ), + events: .fromEntries(state.map((event) => .new(event.rowId, event))), hasFetchedState: true, hasFetchedMembers: isMembers, state: await Isolate.run(() { - final newState = state.fold( - const IMap>.empty(), + final newState = state.fold>>( + .new(), (previousValue, stateEvent) => previousValue.add( stateEvent.type, - (previousValue[stateEvent.type] ?? const IMap.empty()).add( + (previousValue[stateEvent.type] ?? .new()).add( stateEvent.stateKey!, stateEvent.rowId, ), @@ -36,8 +32,8 @@ class RoomsController extends Notifier> { return newState; }), ), - }.toIMap(), - const ISet.empty(), + }), + .new(), ); void update(IMap rooms, ISet leftRooms) { @@ -65,9 +61,7 @@ class RoomsController extends Notifier> { existing.state, (previousValue, event) => previousValue.add( event.key, - (previousValue[event.key] ?? const IMap.empty()).addAll( - event.value, - ), + (previousValue[event.key] ?? .new()).addAll(event.value), ), ), reset: false, @@ -82,9 +76,7 @@ class RoomsController extends Notifier> { existing.receipts, (receiptAcc, event) => receiptAcc.add( event.key, - (receiptAcc[event.key] ?? IList()).addAll( - event.value, - ), + (receiptAcc[event.key] ?? .new()).addAll(event.value), ), ), ) ?? diff --git a/lib/controllers/shared_prefs_controller.dart b/lib/controllers/shared_prefs_controller.dart index f4dcdae..876fc47 100644 --- a/lib/controllers/shared_prefs_controller.dart +++ b/lib/controllers/shared_prefs_controller.dart @@ -3,7 +3,7 @@ import "package:shared_preferences/shared_preferences.dart"; class SharedPrefsController extends AsyncNotifier { @override - Future build() => SharedPreferences.getInstance(); + Future build() async => .getInstance(); static final provider = AsyncNotifierProvider( diff --git a/lib/controllers/space_edges_controller.dart b/lib/controllers/space_edges_controller.dart index 12694d6..81347c5 100644 --- a/lib/controllers/space_edges_controller.dart +++ b/lib/controllers/space_edges_controller.dart @@ -4,7 +4,7 @@ import "package:nexus/models/space_edge.dart"; class SpaceEdgesController extends Notifier>> { @override - IMap> build() => const IMap.empty(); + IMap> build() => .new(); void set(IMap> newEdges) => state = state.addAll(newEdges); diff --git a/lib/controllers/spaces_controller.dart b/lib/controllers/spaces_controller.dart index 7a503ad..548ff20 100644 --- a/lib/controllers/spaces_controller.dart +++ b/lib/controllers/spaces_controller.dart @@ -7,8 +7,6 @@ import "package:nexus/controllers/rooms_controller.dart"; import "package:nexus/controllers/top_level_spaces_controller.dart"; import "package:nexus/controllers/space_edges_controller.dart"; import "package:nexus/models/space.dart"; -import "package:nexus/models/room.dart"; -import "package:nexus/models/space_edge.dart"; class SpacesController extends Notifier> { @override @@ -20,15 +18,15 @@ class SpacesController extends Notifier> { final childRoomsBySpaceId = IMap.fromEntries( topLevelSpaceIds.map((spaceId) { ISet walk(String currentId) { - final children = spaceEdges[currentId] ?? IList(); + final children = spaceEdges[currentId] ?? .new(); - return children.fold>(const ISet.empty(), (acc, edge) { + return children.fold>(.new(), (acc, edge) { final childId = edge.childId; final isSpace = spaceEdges.containsKey(childId); return acc - .addAll(!isSpace ? ISet([childId]) : const ISet.empty()) - .addAll(isSpace ? walk(childId) : const ISet.empty()); + .addAll(!isSpace ? ISet([childId]) : const .empty()) + .addAll(isSpace ? walk(childId) : const .empty()); }); } @@ -88,7 +86,7 @@ class SpacesController extends Notifier> { final room = rooms[id]; if (room == null) return null; - final children = childRoomsBySpaceId[id] ?? IList(); + final children = childRoomsBySpaceId[id] ?? .new(); return Space( id: id, title: room.metadata?.name ?? "Unnamed Room", @@ -100,13 +98,13 @@ class SpacesController extends Notifier> { .toIList(); return [ - Space( + .new( id: "home", title: "Home", icon: Icons.home, children: homeRooms, ), - Space( + .new( id: "dms", title: "Direct Messages", icon: Icons.people, @@ -116,18 +114,19 @@ class SpacesController extends Notifier> { ] .map( (space) => space.copyWith( - children: space.children - .sortedBy( - (element) => - element - .metadata - ?.sortingTimestamp - .millisecondsSinceEpoch ?? - 0, - ) - .sortedBy((room) => room.metadata?.unreadMessages ?? 0) - .reversed - .toIList(), + children: .new( + space.children + .sortedBy( + (element) => + element + .metadata + ?.sortingTimestamp + .millisecondsSinceEpoch ?? + 0, + ) + .sortedBy((room) => room.metadata?.unreadMessages ?? 0) + .reversed, + ), ), ) .toIList(); diff --git a/lib/controllers/sync_status_controller.dart b/lib/controllers/sync_status_controller.dart index 8475d9d..256c8e2 100644 --- a/lib/controllers/sync_status_controller.dart +++ b/lib/controllers/sync_status_controller.dart @@ -7,7 +7,7 @@ class SyncStatusController extends Notifier { Null build() => null; void set(SyncStatus newStatus) { - if (newStatus.type == SyncStatusType.permanentlyFailed) { + if (newStatus.type == .permanentlyFailed) { showError(newStatus.error ?? "Syncing failed"); } state = newStatus; diff --git a/lib/controllers/top_level_spaces_controller.dart b/lib/controllers/top_level_spaces_controller.dart index e1f9c88..321e29d 100644 --- a/lib/controllers/top_level_spaces_controller.dart +++ b/lib/controllers/top_level_spaces_controller.dart @@ -3,7 +3,7 @@ import "package:flutter_riverpod/flutter_riverpod.dart"; class TopLevelSpacesController extends Notifier> { @override - IList build() => const IList.empty(); + IList build() => .new(); void set(IList newSpaces) => state = newSpaces; diff --git a/lib/controllers/url_preview_controller.dart b/lib/controllers/url_preview_controller.dart index e54ebff..bb5626a 100644 --- a/lib/controllers/url_preview_controller.dart +++ b/lib/controllers/url_preview_controller.dart @@ -19,7 +19,7 @@ class UrlPreviewController extends AsyncNotifier { if (homeserver != null && !link.contains("matrix.to")) { { final response = await get( - Uri.parse(homeserver) + .parse(homeserver) .resolve("/_matrix/client/v1/media/preview_url") .replace(queryParameters: {"url": link}), headers: await ref.watch(HeaderController.provider.future), @@ -34,7 +34,7 @@ class UrlPreviewController extends AsyncNotifier { ? null : Uri.tryParse(mxc)?.mxcToHttps(homeserver); - return OpenGraphData.fromJson(decodedValue).copyWith(imageUrl: image); + return .fromJson(decodedValue).copyWith(imageUrl: image); } } } diff --git a/lib/controllers/user_controller.dart b/lib/controllers/user_controller.dart index 5a47ba6..7d20e90 100644 --- a/lib/controllers/user_controller.dart +++ b/lib/controllers/user_controller.dart @@ -6,7 +6,6 @@ import "package:nexus/controllers/profile_controller.dart"; import "package:nexus/helpers/extensions/get_localpart.dart"; import "package:nexus/models/configs/user_config.dart"; import "package:nexus/models/content/membership.dart"; -import "package:nexus/models/membership_status.dart"; class UserController extends AsyncNotifier { final UserConfig config; @@ -31,8 +30,9 @@ class UserController extends AsyncNotifier { final profile = await ref.watch( ProfileController.provider(config.userId).future, ); - return MembershipContent( - status: MembershipStatus.leave, + + return .new( + status: .leave, avatarUrl: profile.avatarUrl, displayName: profile.displayName ?? config.userId.localpart, ); diff --git a/lib/controllers/via_controller.dart b/lib/controllers/via_controller.dart index 69e9f4a..0b5890a 100644 --- a/lib/controllers/via_controller.dart +++ b/lib/controllers/via_controller.dart @@ -5,7 +5,6 @@ import "package:nexus/controllers/client_state_controller.dart"; import "package:nexus/models/content/content.dart"; import "package:nexus/models/content/membership.dart"; import "package:nexus/models/content/power_levels.dart"; -import "package:nexus/models/membership_status.dart"; import "package:nexus/models/room.dart"; class ViaController extends Notifier { @@ -45,7 +44,7 @@ class ViaController extends Notifier { : room.events[membershipEventId]; if (member?.content case MembershipContent(:final status)) { - if (status == MembershipStatus.join) { + if (status == .join) { addUserId(member?.stateKey); } } diff --git a/lib/helpers/extensions/gomuks_buffer.dart b/lib/helpers/extensions/gomuks_buffer.dart index 88cfd5a..cc16b46 100644 --- a/lib/helpers/extensions/gomuks_buffer.dart +++ b/lib/helpers/extensions/gomuks_buffer.dart @@ -7,8 +7,8 @@ import "package:nexus/src/third_party/gomuks.g.dart"; extension GomuksOwnedBufferToX on GomuksOwnedBuffer { Uint8List toBytes() { try { - if (base == nullptr || length <= 0) return Uint8List(0); - return Uint8List.fromList(base.asTypedList(length)); + if (base == nullptr || length <= 0) return .new(0); + return .fromList(base.asTypedList(length)); } finally { calloc.free(base); } diff --git a/lib/helpers/extensions/mxc_to_https.dart b/lib/helpers/extensions/mxc_to_https.dart index 910f87d..b21f056 100644 --- a/lib/helpers/extensions/mxc_to_https.dart +++ b/lib/helpers/extensions/mxc_to_https.dart @@ -1,5 +1,4 @@ extension MxcToHttps on Uri { - Uri mxcToHttps(String homeserver) => Uri.parse( - homeserver, - ).resolve("_matrix/client/v1/media/download/$host$path"); + Uri mxcToHttps(String homeserver) => + .parse(homeserver).resolve("_matrix/client/v1/media/download/$host$path"); } diff --git a/lib/helpers/extensions/scheme_to_theme.dart b/lib/helpers/extensions/scheme_to_theme.dart index 7e2bea6..b7d7972 100644 --- a/lib/helpers/extensions/scheme_to_theme.dart +++ b/lib/helpers/extensions/scheme_to_theme.dart @@ -1,16 +1,16 @@ import "package:flutter/material.dart"; extension SchemeToTheme on ColorScheme { - ThemeData get theme => ThemeData.from(colorScheme: this).copyWith( - cardTheme: CardThemeData(color: primaryContainer), + ThemeData get theme => .from(colorScheme: this).copyWith( + cardTheme: .new(color: primaryContainer), + popupMenuTheme: .new( + shape: RoundedRectangleBorder(borderRadius: .circular(16)), + color: surfaceContainerHigh, + ), appBarTheme: AppBarTheme( titleSpacing: 0, backgroundColor: surfaceContainerLow, ), - popupMenuTheme: PopupMenuThemeData( - shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(16)), - color: surfaceContainerHigh, - ), textTheme: ThemeData( fontFamilyFallback: ["sans", "emoji"], brightness: brightness, diff --git a/lib/helpers/extensions/show_context_menu.dart b/lib/helpers/extensions/show_context_menu.dart index d2b1efd..c860115 100644 --- a/lib/helpers/extensions/show_context_menu.dart +++ b/lib/helpers/extensions/show_context_menu.dart @@ -9,8 +9,8 @@ extension ShowContextMenu on BuildContext { showMenu( context: this, - constraints: BoxConstraints.loose(Size.infinite), - position: RelativeRect.fromLTRB( + constraints: .loose(Size.infinite), + position: .fromLTRB( globalPosition.dx, globalPosition.dy, overlay.size.width - globalPosition.dx, diff --git a/lib/helpers/extensions/show_user_popover.dart b/lib/helpers/extensions/show_user_popover.dart index 1a5e7cb..e703721 100644 --- a/lib/helpers/extensions/show_user_popover.dart +++ b/lib/helpers/extensions/show_user_popover.dart @@ -14,9 +14,9 @@ extension ShowUserPopover on BuildContext { children: [ PopupMenuItem( enabled: false, - padding: EdgeInsets.symmetric(horizontal: 16, vertical: 8), + padding: .symmetric(horizontal: 16, vertical: 8), child: IconTheme( - data: IconThemeData(), + data: .new(), child: UserPopover(member, userId, roomId: roomId), ), ), diff --git a/lib/helpers/extensions/size_to_string.dart b/lib/helpers/extensions/size_to_string.dart index 654df9a..a9db345 100644 --- a/lib/helpers/extensions/size_to_string.dart +++ b/lib/helpers/extensions/size_to_string.dart @@ -2,14 +2,7 @@ import "package:fast_immutable_collections/fast_immutable_collections.dart"; extension SizeToString on int { String get sizeAsString { - const IListConst suffixes = IListConst([ - "B", - "KB", - "MB", - "GB", - "TB", - "PB", - ]); + const suffixes = IListConst(["B", "KB", "MB", "GB", "TB", "PB"]); var i = 0; var size = toDouble(); diff --git a/lib/helpers/launch_helper.dart b/lib/helpers/launch_helper.dart index f872ef7..575395f 100644 --- a/lib/helpers/launch_helper.dart +++ b/lib/helpers/launch_helper.dart @@ -10,9 +10,7 @@ class LaunchHelper { try { return await ul.launchUrl( url, - mode: useWebview - ? ul.LaunchMode.inAppBrowserView - : ul.LaunchMode.externalApplication, + mode: useWebview ? .inAppBrowserView : .externalApplication, ); } on PlatformException catch (_) { return false; diff --git a/lib/models/content/content.dart b/lib/models/content/content.dart index ab17db8..e7b1141 100644 --- a/lib/models/content/content.dart +++ b/lib/models/content/content.dart @@ -34,7 +34,7 @@ class Content { ?.contentFromJson ?? Content.fromJson)(json); } catch (error) { - if (error is Error) return Content(parseError: error); + if (error is Error) return .new(parseError: error); rethrow; } } diff --git a/lib/pages/chat_page.dart b/lib/pages/chat_page.dart index 3d6a35f..d90d3d4 100644 --- a/lib/pages/chat_page.dart +++ b/lib/pages/chat_page.dart @@ -35,7 +35,7 @@ class ChatPage extends ConsumerWidget { ) : Center( child: Column( - mainAxisSize: MainAxisSize.min, + mainAxisSize: .min, children: [Loading(), Text("Syncing...")], ), ), diff --git a/lib/pages/login_page.dart b/lib/pages/login_page.dart index d2153eb..58662f4 100644 --- a/lib/pages/login_page.dart +++ b/lib/pages/login_page.dart @@ -5,7 +5,6 @@ import "package:hooks_riverpod/hooks_riverpod.dart"; import "package:nexus/controllers/client_controller.dart"; import "package:nexus/helpers/launch_helper.dart"; import "package:nexus/models/homeserver.dart"; -import "package:nexus/models/requests/login_request.dart"; import "package:nexus/widgets/appbar.dart"; import "package:nexus/widgets/divider_text.dart"; import "package:nexus/widgets/loading.dart"; @@ -36,7 +35,7 @@ class LoginPage extends HookConsumerWidget { if (homeserver.value == null && context.mounted) { ScaffoldMessenger.of(context).showSnackBar( - SnackBar( + .new( content: Text( "Homeserver verification failed. Is your homeserver down?", style: TextStyle(color: theme.colorScheme.onErrorContainer), @@ -56,9 +55,9 @@ class LoginPage extends HookConsumerWidget { appBar: Appbar(), body: Center( child: ConstrainedBox( - constraints: BoxConstraints(maxWidth: 600), + constraints: .new(maxWidth: 600), child: ListView( - padding: EdgeInsets.symmetric(horizontal: 16, vertical: 64), + padding: .symmetric(horizontal: 16, vertical: 64), children: [ Row( children: [ @@ -66,23 +65,20 @@ class LoginPage extends HookConsumerWidget { SizedBox(width: 12), Expanded( child: Column( - crossAxisAlignment: CrossAxisAlignment.start, + crossAxisAlignment: .start, children: [ Text("Nexus", style: theme.textTheme.displayMedium), Text( "A Simple Matrix Client", style: theme.textTheme.headlineMedium, - overflow: TextOverflow.ellipsis, + overflow: .ellipsis, ), ], ), ), ], ), - Padding( - padding: EdgeInsetsGeometry.symmetric(vertical: 12), - child: Divider(), - ), + Padding(padding: .symmetric(vertical: 12), child: Divider()), DividerText("Enter a homeserver domain:"), Row( @@ -91,7 +87,7 @@ class LoginPage extends HookConsumerWidget { Expanded( child: TextField( controller: homeserverUrl, - decoration: InputDecoration( + decoration: .new( labelText: "Homeserver URL (e.g. matrix.org)", ), ), @@ -100,7 +96,7 @@ class LoginPage extends HookConsumerWidget { tooltip: "Confirm homeserver choice", onPressed: isLoading.value ? null - : () => setHomeserver(Uri.tryParse(homeserverUrl.text)), + : () => setHomeserver(.tryParse(homeserverUrl.text)), icon: Icon(Icons.check), ), ], @@ -108,26 +104,26 @@ class LoginPage extends HookConsumerWidget { DividerText("Or, choose from some popular homeservers:"), ...([ - Homeserver( + .new( name: "Matrix.org", description: "The Matrix.org Foundation offers the matrix.org homeserver as an easy entry point for anyone wanting to try out Matrix.", - url: Uri.https("matrix.org"), + url: .https("matrix.org"), iconUrl: "https://raw.githubusercontent.com/element-hq/logos/refs/heads/master/matrix/matrix-favicon${Theme.brightnessOf(context) == Brightness.dark ? "-white" : ""}.png", ), - Homeserver( + .new( name: "Federated Nexus", description: "Federated Nexus is a community resource hosting multiple FOSS (especially federated) services, including Matrix and Forgejo. By the same developers who made Nexus client.", - url: Uri.https("federated.nexus"), + url: .https("federated.nexus"), iconUrl: "https://federated.nexus/images/icon.png", ), - Homeserver( + .new( name: "Unredacted", description: "Unredacted is a 501(c)(3) non-profit organization that builds Internet infrastructure and services to help people evade censorship and protect their right to privacy.", - url: Uri.https("unredacted.org", "services/si/matrix"), + url: .https("unredacted.org", "services/si/matrix"), iconUrl: "https://unredacted.org/favicon.ico", ), ].map( @@ -153,21 +149,21 @@ class LoginPage extends HookConsumerWidget { )), SizedBox(height: 8), TextButton( - onPressed: () => launch(Uri.https("servers.joinmatrix.org")), + onPressed: () => launch(.https("servers.joinmatrix.org")), child: Text("See more homeservers..."), ), if (isLoading.value) - Padding(padding: EdgeInsets.only(top: 32), child: Loading()) + Padding(padding: .only(top: 32), child: Loading()) else if (homeserver.value != null) ...[ DividerText("Then, sign in:"), SizedBox(height: 4), TextField( - decoration: InputDecoration(label: Text("Username")), + decoration: .new(label: Text("Username")), controller: username, ), SizedBox(height: 12), TextField( - decoration: InputDecoration(label: Text("Password")), + decoration: .new(label: Text("Password")), controller: password, obscureText: true, ), @@ -176,7 +172,7 @@ class LoginPage extends HookConsumerWidget { onPressed: () async { isLoading.value = true; final error = await client.login( - LoginRequest( + .new( username: username.text, password: password.text, homeserverUrl: homeserver.value!, @@ -185,10 +181,10 @@ class LoginPage extends HookConsumerWidget { if (error != null && context.mounted) { ScaffoldMessenger.of(context).showSnackBar( - SnackBar( + .new( content: Text( "Login failed. Is your password right?\nError: $error", - style: TextStyle( + style: .new( color: theme.colorScheme.onErrorContainer, ), ), diff --git a/lib/pages/verify_page.dart b/lib/pages/verify_page.dart index 387c640..0469fa4 100644 --- a/lib/pages/verify_page.dart +++ b/lib/pages/verify_page.dart @@ -17,8 +17,8 @@ class VerifyPage extends HookConsumerWidget { body: AlertDialog( title: Text("Verify"), content: Column( - mainAxisSize: MainAxisSize.min, - crossAxisAlignment: CrossAxisAlignment.start, + mainAxisSize: .min, + crossAxisAlignment: .start, children: [ Text( "Enter your recovery key or passphrase below to unlock encrypted events.\nYour passphrase is usually not the same as your password.", @@ -41,11 +41,11 @@ class VerifyPage extends HookConsumerWidget { : () async { final scaffoldMessenger = ScaffoldMessenger.of(context); final snackbar = scaffoldMessenger.showSnackBar( - SnackBar( + .new( content: Text( "Attempting to verify with recovery key...", ), - duration: Duration(days: 999), + duration: .new(days: 999), ), ); @@ -60,13 +60,13 @@ class VerifyPage extends HookConsumerWidget { isVerifying.value = false; if (context.mounted) { scaffoldMessenger.showSnackBar( - SnackBar( + .new( backgroundColor: Theme.of( context, ).colorScheme.errorContainer, content: Text( "Verification failed. Is your passphrase correct?\nError: $error", - style: TextStyle( + style: .new( color: Theme.of( context, ).colorScheme.onErrorContainer, diff --git a/lib/widgets/appbar.dart b/lib/widgets/appbar.dart index 08c717b..811788a 100644 --- a/lib/widgets/appbar.dart +++ b/lib/widgets/appbar.dart @@ -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), diff --git a/lib/widgets/avatar_or_hash.dart b/lib/widgets/avatar_or_hash.dart index 5308ef7..641b8ad 100644 --- a/lib/widgets/avatar_or_hash.dart +++ b/lib/widgets/avatar_or_hash.dart @@ -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, diff --git a/lib/widgets/composer/composer.dart b/lib/widgets/composer/composer.dart index 9f37999..d090cac 100644 --- a/lib/widgets/composer/composer.dart +++ b/lib/widgets/composer/composer.dart @@ -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...", ), diff --git a/lib/widgets/composer/mention_overlay.dart b/lib/widgets/composer/mention_overlay.dart index b4af97a..ea5dc6a 100644 --- a/lib/widgets/composer/mention_overlay.dart +++ b/lib/widgets/composer/mention_overlay.dart @@ -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( diff --git a/lib/widgets/composer/relation_preview.dart b/lib/widgets/composer/relation_preview.dart index f2bcaf6..c9cc271 100644 --- a/lib/widgets/composer/relation_preview.dart +++ b/lib/widgets/composer/relation_preview.dart @@ -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, diff --git a/lib/widgets/divider_text.dart b/lib/widgets/divider_text.dart index ca78844..f53795d 100644 --- a/lib/widgets/divider_text.dart +++ b/lib/widgets/divider_text.dart @@ -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), ), ), diff --git a/lib/widgets/emoji_picker_button.dart b/lib/widgets/emoji_picker_button.dart index e8805ca..bbe1cdc 100644 --- a/lib/widgets/emoji_picker_button.dart +++ b/lib/widgets/emoji_picker_button.dart @@ -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); diff --git a/lib/widgets/event_preview.dart b/lib/widgets/event_preview.dart index 5a16fc7..7a40a75 100644 --- a/lib/widgets/event_preview.dart +++ b/lib/widgets/event_preview.dart @@ -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: [ diff --git a/lib/widgets/expandable_image.dart b/lib/widgets/expandable_image.dart index ac5bbe1..df4cbd0 100644 --- a/lib/widgets/expandable_image.dart +++ b/lib/widgets/expandable_image.dart @@ -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, diff --git a/lib/widgets/file_card.dart b/lib/widgets/file_card.dart index 7e3bb6f..afdad89 100644 --- a/lib/widgets/file_card.dart +++ b/lib/widgets/file_card.dart @@ -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)), diff --git a/lib/widgets/flash_wrapper.dart b/lib/widgets/flash_wrapper.dart index f52ea25..057565e 100644 --- a/lib/widgets/flash_wrapper.dart +++ b/lib/widgets/flash_wrapper.dart @@ -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, ), ); diff --git a/lib/widgets/form_text_input.dart b/lib/widgets/form_text_input.dart index 21b2e5c..8b48883 100644 --- a/lib/widgets/form_text_input.dart +++ b/lib/widgets/form_text_input.dart @@ -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, diff --git a/lib/widgets/html/code_block.dart b/lib/widgets/html/code_block.dart index 80950ce..a5c3dee 100644 --- a/lib/widgets/html/code_block.dart +++ b/lib/widgets/html/code_block.dart @@ -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"), ), ), ), diff --git a/lib/widgets/html/html.dart b/lib/widgets/html/html.dart index 449f400..85ec9ae 100644 --- a/lib/widgets/html/html.dart +++ b/lib/widgets/html/html.dart @@ -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?>( (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)), ); } diff --git a/lib/widgets/html/mention_chip.dart b/lib/widgets/html/mention_chip.dart index 28caa65..141d5a0 100644 --- a/lib/widgets/html/mention_chip.dart +++ b/lib/widgets/html/mention_chip.dart @@ -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, ), ), diff --git a/lib/widgets/html/quoted.dart b/lib/widgets/html/quoted.dart index 6640118..e582b06 100644 --- a/lib/widgets/html/quoted.dart +++ b/lib/widgets/html/quoted.dart @@ -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), ); } diff --git a/lib/widgets/html/spoiler_text.dart b/lib/widgets/html/spoiler_text.dart index 9a42bff..a7a457b 100644 --- a/lib/widgets/html/spoiler_text.dart +++ b/lib/widgets/html/spoiler_text.dart @@ -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), ), ), ); diff --git a/lib/widgets/join_dialog.dart b/lib/widgets/join_dialog.dart index e718200..e20ab2a 100644 --- a/lib/widgets/join_dialog.dart +++ b/lib/widgets/join_dialog.dart @@ -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, ), ), diff --git a/lib/widgets/lazy_loading/message_displayname.dart b/lib/widgets/lazy_loading/message_displayname.dart index 7ff4b09..ffa5dc0 100644 --- a/lib/widgets/lazy_loading/message_displayname.dart +++ b/lib/widgets/lazy_loading/message_displayname.dart @@ -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), + ), + }; } diff --git a/lib/widgets/linkified_text.dart b/lib/widgets/linkified_text.dart index c6f1c11..653248c 100644 --- a/lib/widgets/linkified_text.dart +++ b/lib/widgets/linkified_text.dart @@ -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, ); } diff --git a/lib/widgets/loading.dart b/lib/widgets/loading.dart index 9bb2858..fc84563 100644 --- a/lib/widgets/loading.dart +++ b/lib/widgets/loading.dart @@ -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()), ), ); diff --git a/lib/widgets/member_list.dart b/lib/widgets/member_list.dart index 3d7ecec..00633a7 100644 --- a/lib/widgets/member_list.dart +++ b/lib/widgets/member_list.dart @@ -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, ), ), ), diff --git a/lib/widgets/message_image.dart b/lib/widgets/message_image.dart index e2cc823..d92783a 100644 --- a/lib/widgets/message_image.dart +++ b/lib/widgets/message_image.dart @@ -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), ), ), ), diff --git a/lib/widgets/players/audio.dart b/lib/widgets/players/audio.dart index f75afe5..0c96579 100644 --- a/lib/widgets/players/audio.dart +++ b/lib/widgets/players/audio.dart @@ -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( diff --git a/lib/widgets/players/video.dart b/lib/widgets/players/video.dart index 9621e4f..8083860 100644 --- a/lib/widgets/players/video.dart +++ b/lib/widgets/players/video.dart @@ -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)); diff --git a/lib/widgets/reaction_row.dart b/lib/widgets/reaction_row.dart index 4935ed7..e41c2eb 100644 --- a/lib/widgets/reaction_row.dart +++ b/lib/widgets/reaction_row.dart @@ -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>? 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 diff --git a/lib/widgets/renderers/event.dart b/lib/widgets/renderers/event.dart index d1442bc..8cdbf4e 100644 --- a/lib/widgets/renderers/event.dart +++ b/lib/widgets/renderers/event.dart @@ -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), diff --git a/lib/widgets/renderers/generic_event.dart b/lib/widgets/renderers/generic_event.dart index 5efd724..4f4380a 100644 --- a/lib/widgets/renderers/generic_event.dart +++ b/lib/widgets/renderers/generic_event.dart @@ -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)), ], ), diff --git a/lib/widgets/renderers/membership.dart b/lib/widgets/renderers/membership.dart index c109aed..c8c91ba 100644 --- a/lib/widgets/renderers/membership.dart +++ b/lib/widgets/renderers/membership.dart @@ -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), diff --git a/lib/widgets/renderers/message.dart b/lib/widgets/renderers/message.dart index 0dc09e6..3470246 100644 --- a/lib/widgets/renderers/message.dart +++ b/lib/widgets/renderers/message.dart @@ -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), diff --git a/lib/widgets/room_appbar.dart b/lib/widgets/room_appbar.dart index b40f48d..d16c2df 100644 --- a/lib/widgets/room_appbar.dart +++ b/lib/widgets/room_appbar.dart @@ -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, ), diff --git a/lib/widgets/room_chat.dart b/lib/widgets/room_chat.dart index 733c5ba..95e7514 100644 --- a/lib/widgets/room_chat.dart +++ b/lib/widgets/room_chat.dart @@ -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() diff --git a/lib/widgets/room_menu.dart b/lib/widgets/room_menu.dart index 86ac5bd..f4313fa 100644 --- a/lib/widgets/room_menu.dart +++ b/lib/widgets/room_menu.dart @@ -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), ), diff --git a/lib/widgets/sidebar.dart b/lib/widgets/sidebar.dart index 8afe3c5..3217173 100644 --- a/lib/widgets/sidebar.dart +++ b/lib/widgets/sidebar.dart @@ -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( diff --git a/lib/widgets/url_preview.dart b/lib/widgets/url_preview.dart index 83c6604..669c756 100644 --- a/lib/widgets/url_preview.dart +++ b/lib/widgets/url_preview.dart @@ -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, ), ), ], diff --git a/lib/widgets/user_popover.dart b/lib/widgets/user_popover.dart index 165852e..65fff87 100644 --- a/lib/widgets/user_popover.dart +++ b/lib/widgets/user_popover.dart @@ -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,