treewide: use primary constructors where helpful

This isn't working as you can no longer instantiate any of these classes.
This commit is contained in:
Henry Hiles 2026-08-17 16:01:15 -04:00
commit 1a43da1573
Signed by: Henry-Hiles
SSH key fingerprint: SHA256:VKQUdS31Q90KvX7EkKMHMBpUspcmItAh86a+v7PGiIs
135 changed files with 797 additions and 1110 deletions

View file

@ -6,10 +6,8 @@ import "package:nexus/models/content/content.dart";
import "package:nexus/models/content/message.dart"; import "package:nexus/models/content/message.dart";
import "package:path/path.dart"; import "package:path/path.dart";
class AttachmentController extends Notifier<(String, MessageContent?)?> { class AttachmentController(final String roomId)
final String roomId; extends Notifier<(String, MessageContent?)?> {
AttachmentController(this.roomId);
@override @override
Null build() => null; Null build() => null;

View file

@ -4,10 +4,8 @@ import "package:nexus/controllers/client_id.dart";
import "package:nexus/models/oauth_auth_code_response.dart"; import "package:nexus/models/oauth_auth_code_response.dart";
import "package:nexus/models/requests/oauth/get_auth_url.dart"; import "package:nexus/models/requests/oauth/get_auth_url.dart";
class AuthUrlController extends AsyncNotifier<OAuthAuthCodeResponse> { class AuthUrlController(final Uri homeserver)
final Uri homeserver; extends AsyncNotifier<OAuthAuthCodeResponse> {
AuthUrlController(this.homeserver);
@override @override
Future<OAuthAuthCodeResponse> build() async => ref Future<OAuthAuthCodeResponse> build() async => ref
.watch(ClientController.provider.notifier) .watch(ClientController.provider.notifier)

View file

@ -1,19 +1,17 @@
import "dart:async"; import "dart:async";
import "package:flutter_riverpod/flutter_riverpod.dart"; import "package:flutter_riverpod/flutter_riverpod.dart";
import "package:nexus/controllers/user.dart"; import "package:nexus/controllers/user.dart";
import "package:nexus/models/content/membership.dart"; import "package:nexus/models/content/membership.dart";
import "package:nexus/models/event.dart"; import "package:nexus/models/event.dart";
class AuthorController extends AsyncNotifier<MembershipContent> { class AuthorController(final Event event)
final Event event; extends AsyncNotifier<MembershipContent> {
AuthorController(this.event);
@override @override
Future<MembershipContent> build() async { Future<MembershipContent> build() async {
final member = await ref.watch( final member = await ref.watch(
UserController.provider( UserController.provider(.new(roomId: event.roomId, userId: event.sender))
.new(roomId: event.roomId, userId: event.sender), .future,
).future,
); );
return .new( return .new(

View file

@ -1,10 +1,7 @@
import "package:flutter_riverpod/flutter_riverpod.dart"; import "package:flutter_riverpod/flutter_riverpod.dart";
import "package:nexus/controllers/client.dart"; import "package:nexus/controllers/client.dart";
class ClientIdController extends AsyncNotifier<String> { class ClientIdController(final Uri homeserver) extends AsyncNotifier<String> {
final Uri homeserver;
ClientIdController(this.homeserver);
@override @override
Future<String> build() => ref Future<String> build() => ref
.watch(ClientController.provider.notifier) .watch(ClientController.provider.notifier)

View file

@ -5,10 +5,8 @@ import "package:nexus/controllers/rooms.dart";
import "package:nexus/models/event.dart"; import "package:nexus/models/event.dart";
import "package:nexus/models/requests/get_event.dart"; import "package:nexus/models/requests/get_event.dart";
class EventController extends AsyncNotifier<Event?> { class EventController(final GetEventRequest request)
final GetEventRequest request; extends AsyncNotifier<Event?> {
EventController(this.request);
@override @override
Future<Event?> build() async { Future<Event?> build() async {
final room = ref.watch( final room = ref.watch(

View file

@ -1,10 +1,7 @@
import "package:flutter_riverpod/flutter_riverpod.dart"; import "package:flutter_riverpod/flutter_riverpod.dart";
import "package:nexus/controllers/shared_prefs.dart"; import "package:nexus/controllers/shared_prefs.dart";
class KeyController extends Notifier<String?> { class KeyController(final String key) extends Notifier<String?> {
final String key;
KeyController(this.key);
static const String spaceKey = "space"; static const String spaceKey = "space";
static const String roomKey = "room"; static const String roomKey = "room";

View file

@ -6,10 +6,8 @@ import "package:nexus/models/content/content.dart";
import "package:nexus/models/event.dart"; import "package:nexus/models/event.dart";
import "package:nexus/models/requests/get_room_state.dart"; import "package:nexus/models/requests/get_room_state.dart";
class MembersController extends AsyncNotifier<ISet<Event>> { class MembersController(final String roomId)
final String roomId; extends AsyncNotifier<ISet<Event>> {
MembersController(this.roomId);
@override @override
Future<ISet<Event>> build() async { Future<ISet<Event>> build() async {
final room = ref.watch( final room = ref.watch(

View file

@ -5,10 +5,8 @@ import "package:nexus/models/configs/members_by_status.dart";
import "package:nexus/models/content/membership.dart"; import "package:nexus/models/content/membership.dart";
import "package:nexus/models/event.dart"; import "package:nexus/models/event.dart";
class MembersByStatusController extends AsyncNotifier<ISet<Event>> { class MembersByStatusController(final MembersByStatusConfig config)
final MembersByStatusConfig config; extends AsyncNotifier<ISet<Event>> {
MembersByStatusController(this.config);
@override @override
Future<ISet<Event>> build() => ref.watch( Future<ISet<Event>> build() => ref.watch(
MembersController.provider(config.roomId).selectAsync( MembersController.provider(config.roomId).selectAsync(

View file

@ -8,11 +8,8 @@ import "package:nexus/models/content/content.dart";
import "package:nexus/models/content/power_levels.dart"; import "package:nexus/models/content/power_levels.dart";
import "package:nexus/models/event.dart"; import "package:nexus/models/event.dart";
class MembersGroupedController class MembersGroupedController(final MembersByStatusConfig config)
extends AsyncNotifier<IList<MapEntry<int?, ISet<Event>>>> { extends AsyncNotifier<IList<MapEntry<int?, ISet<Event>>>> {
final MembersByStatusConfig config;
MembersGroupedController(this.config);
@override @override
Future<IList<MapEntry<int?, ISet<Event>>>> build() async { Future<IList<MapEntry<int?, ISet<Event>>>> build() async {
final room = ref.watch( final room = ref.watch(

View file

@ -1,11 +1,10 @@
import "dart:async"; import "dart:async";
import "package:fast_immutable_collections/fast_immutable_collections.dart"; import "package:fast_immutable_collections/fast_immutable_collections.dart";
import "package:flutter_riverpod/flutter_riverpod.dart"; import "package:flutter_riverpod/flutter_riverpod.dart";
class MultiProviderController extends AsyncNotifier<void> { class MultiProviderController(final IList<AsyncNotifierProvider> providers)
MultiProviderController(this.providers); extends AsyncNotifier<void> {
final IList<AsyncNotifierProvider> providers;
@override @override
Future<void> build() => Future<void> build() =>
.wait(providers.map((provider) => ref.watch(provider.future))); .wait(providers.map((provider) => ref.watch(provider.future)));

View file

@ -4,10 +4,8 @@ import "package:nexus/controllers/event.dart";
import "package:nexus/controllers/pinned_ids.dart"; import "package:nexus/controllers/pinned_ids.dart";
import "package:nexus/models/event.dart"; import "package:nexus/models/event.dart";
class PinnedEventsController extends AsyncNotifier<IList<Event>> { class PinnedEventsController(final String roomId)
final String roomId; extends AsyncNotifier<IList<Event>> {
PinnedEventsController(this.roomId);
@override @override
Future<IList<Event>> build() async { Future<IList<Event>> build() async {
final pinIds = ref.watch(PinnedIdsController.provider(roomId)); final pinIds = ref.watch(PinnedIdsController.provider(roomId));
@ -15,9 +13,8 @@ class PinnedEventsController extends AsyncNotifier<IList<Event>> {
return (await Future.wait( return (await Future.wait(
pinIds.map( pinIds.map(
(eventId) => ref.watch( (eventId) => ref.watch(
EventController.provider( EventController.provider(.new(eventId: eventId, roomId: roomId))
.new(eventId: eventId, roomId: roomId), .future,
).future,
), ),
), ),
)).nonNulls.toIList(); )).nonNulls.toIList();

View file

@ -5,10 +5,7 @@ import "package:nexus/controllers/rooms.dart";
import "package:nexus/models/content/content.dart"; import "package:nexus/models/content/content.dart";
import "package:nexus/models/content/pinned_events.dart"; import "package:nexus/models/content/pinned_events.dart";
class PinnedIdsController extends Notifier<IList<String>> { class PinnedIdsController(final String roomId) extends Notifier<IList<String>> {
final String roomId;
PinnedIdsController(this.roomId);
@override @override
IList<String> build() { IList<String> build() {
final room = ref.watch( final room = ref.watch(

View file

@ -6,10 +6,8 @@ import "package:nexus/models/configs/power_level.dart";
import "package:nexus/models/content/content.dart"; import "package:nexus/models/content/content.dart";
import "package:nexus/models/content/power_levels.dart"; import "package:nexus/models/content/power_levels.dart";
class PowerLevelController extends Notifier<bool> { class PowerLevelController(final PowerLevelConfig config)
final PowerLevelConfig config; extends Notifier<bool> {
PowerLevelController(this.config);
@override @override
bool build() { bool build() {
if (config case EventPowerLevelConfig(:final eventType)) { if (config case EventPowerLevelConfig(:final eventType)) {

View file

@ -2,10 +2,8 @@ import "package:flutter_riverpod/flutter_riverpod.dart";
import "package:nexus/controllers/client.dart"; import "package:nexus/controllers/client.dart";
import "package:nexus/models/profile_response.dart"; import "package:nexus/models/profile_response.dart";
class ProfileController extends AsyncNotifier<ProfileResponse> { class ProfileController(final String userId)
final String userId; extends AsyncNotifier<ProfileResponse> {
ProfileController(this.userId);
@override @override
Future<ProfileResponse> build() { Future<ProfileResponse> build() {
final client = ref.watch(ClientController.provider.notifier); final client = ref.watch(ClientController.provider.notifier);

View file

@ -5,10 +5,8 @@ import "package:nexus/controllers/rooms.dart";
import "package:nexus/models/configs/reactions.dart"; import "package:nexus/models/configs/reactions.dart";
import "package:nexus/models/content/reaction.dart"; import "package:nexus/models/content/reaction.dart";
class ReactionsController extends AsyncNotifier<IMap<String, IList<String>>> { class ReactionsController(final ReactionsConfig config)
final ReactionsConfig config; extends AsyncNotifier<IMap<String, IList<String>>> {
ReactionsController(this.config);
@override @override
Future<IMap<String, IList<String>>> build() async { Future<IMap<String, IList<String>>> build() async {
final eventInfo = ref.watch( final eventInfo = ref.watch(

View file

@ -1,5 +1,6 @@
import "dart:async"; import "dart:async";
import "dart:math"; import "dart:math";
import "package:collection/collection.dart"; import "package:collection/collection.dart";
import "package:fast_immutable_collections/fast_immutable_collections.dart"; import "package:fast_immutable_collections/fast_immutable_collections.dart";
import "package:flutter_riverpod/flutter_riverpod.dart"; import "package:flutter_riverpod/flutter_riverpod.dart";
@ -15,10 +16,8 @@ import "package:nexus/models/relation_type.dart";
import "package:nexus/models/requests/send_message.dart"; import "package:nexus/models/requests/send_message.dart";
import "package:nexus/models/room.dart"; import "package:nexus/models/room.dart";
class RoomChatController extends AsyncNotifier<IList<Event>?> { class RoomChatController(final String roomId)
final String roomId; extends AsyncNotifier<IList<Event>?> {
RoomChatController(this.roomId);
@override @override
Future<IList<Event>?> build() async { Future<IList<Event>?> build() async {
final client = ref.watch(ClientController.provider.notifier); final client = ref.watch(ClientController.provider.notifier);

View file

@ -4,10 +4,7 @@ import "package:nexus/models/content/content.dart";
import "package:nexus/models/content/create.dart"; import "package:nexus/models/content/create.dart";
import "package:nexus/models/room.dart"; import "package:nexus/models/room.dart";
class RoomCreatorsController extends Notifier<IList<String>> { class RoomCreatorsController(final Room room) extends Notifier<IList<String>> {
final Room room;
RoomCreatorsController(this.room);
@override @override
IList<String> build() { IList<String> build() {
final createRowId = room.state[EventType.create.type]?[""]; final createRowId = room.state[EventType.create.type]?[""];

View file

@ -3,10 +3,8 @@ import "package:nexus/controllers/client.dart";
import "package:nexus/models/requests/join_room.dart"; import "package:nexus/models/requests/join_room.dart";
import "package:nexus/models/room_summary.dart"; import "package:nexus/models/room_summary.dart";
class RoomSummaryController extends AsyncNotifier<RoomSummary> { class RoomSummaryController(final JoinRoomRequest request)
final JoinRoomRequest request; extends AsyncNotifier<RoomSummary> {
RoomSummaryController(this.request);
@override @override
Future<RoomSummary> build() => Future<RoomSummary> build() =>
ref.watch(ClientController.provider.notifier).getRoomSummary(request); ref.watch(ClientController.provider.notifier).getRoomSummary(request);

View file

@ -3,10 +3,8 @@ import "package:flutter_riverpod/flutter_riverpod.dart";
import "package:nexus/controllers/client.dart"; import "package:nexus/controllers/client.dart";
import "package:nexus/models/open_graph_data.dart"; import "package:nexus/models/open_graph_data.dart";
class UrlPreviewController extends AsyncNotifier<OpenGraphData?> { class UrlPreviewController(final Uri url)
final Uri url; extends AsyncNotifier<OpenGraphData?> {
UrlPreviewController(this.url);
@override @override
Future<OpenGraphData?> build() async { Future<OpenGraphData?> build() async {
if (url.host == "matrix.to") return null; if (url.host == "matrix.to") return null;

View file

@ -7,10 +7,7 @@ import "package:nexus/models/content/membership.dart";
import "package:nexus/models/content/power_levels.dart"; import "package:nexus/models/content/power_levels.dart";
import "package:nexus/models/room.dart"; import "package:nexus/models/room.dart";
class ViaController extends Notifier<String> { class ViaController(final Room room) extends Notifier<String> {
final Room room;
ViaController(this.room);
@override @override
String build() { String build() {
final servers = <String>{}; final servers = <String>{};

View file

@ -2,10 +2,7 @@ import "package:flutter/services.dart";
import "package:flutter_riverpod/flutter_riverpod.dart"; import "package:flutter_riverpod/flutter_riverpod.dart";
import "package:url_launcher/url_launcher.dart" as ul; import "package:url_launcher/url_launcher.dart" as ul;
class LaunchHelper { class LaunchHelper(Ref ref) {
final Ref ref;
LaunchHelper(this.ref);
Future<bool> launchUrl(Uri url, {bool useWebview = false}) async { Future<bool> launchUrl(Uri url, {bool useWebview = false}) async {
try { try {
return await ul.launchUrl( return await ul.launchUrl(

View file

@ -1,14 +1,12 @@
import "dart:ui"; import "dart:ui";
import "package:flutter/widgets.dart"; import "package:flutter/widgets.dart";
import "package:flutter_riverpod/flutter_riverpod.dart"; import "package:flutter_riverpod/flutter_riverpod.dart";
import "package:nexus/controllers/client.dart"; import "package:nexus/controllers/client.dart";
import "package:nexus/models/requests/download_media.dart"; import "package:nexus/models/requests/download_media.dart";
class MxcImage extends ImageProvider<MxcImage> { class MxcImage(final WidgetRef ref, final DownloadMediaRequest request)
final WidgetRef ref; extends ImageProvider<MxcImage> {
final DownloadMediaRequest request;
const MxcImage(this.ref, this.request);
@override @override
Future<MxcImage> obtainKey(ImageConfiguration configuration) => Future<MxcImage> obtainKey(ImageConfiguration configuration) =>
Future.value(this); Future.value(this);

View file

@ -1,4 +1,5 @@
import "dart:io"; import "dart:io";
import "package:dynamic_color/dynamic_color.dart"; import "package:dynamic_color/dynamic_color.dart";
import "package:fast_immutable_collections/fast_immutable_collections.dart"; import "package:fast_immutable_collections/fast_immutable_collections.dart";
import "package:flutter/foundation.dart"; import "package:flutter/foundation.dart";
@ -94,9 +95,7 @@ void main() async {
); );
} }
class App extends StatelessWidget { class const App({super.key}) extends StatelessWidget {
const App({super.key});
@override @override
Widget build(BuildContext context) => DynamicColorBuilder( Widget build(BuildContext context) => DynamicColorBuilder(
builder: (lightDynamic, darkDynamic) => Consumer( builder: (lightDynamic, darkDynamic) => Consumer(

View file

@ -1,11 +1,25 @@
import "package:fast_immutable_collections/fast_immutable_collections.dart"; import "package:fast_immutable_collections/fast_immutable_collections.dart";
import "package:freezed_annotation/freezed_annotation.dart"; import "package:freezed_annotation/freezed_annotation.dart";
part "account_data.freezed.dart"; part "account_data.freezed.dart";
part "account_data.g.dart"; part "account_data.g.dart";
@freezed @freezed
abstract class AccountData with _$AccountData { sealed class const AccountData({
const AccountData._(); @JsonKey(name: AccountData.invitePermissionConfigKey)
InvitePermissionConfig invitePermissionConfig =
const _InvitePermissionConfig(),
@JsonKey(name: AccountData.directKey)
IMap<String, IList<String>> directMessages = const IMap.empty(),
@JsonKey(
name: AccountData.recentEmojiKey,
readValue: AccountData.readRecentEmojiValue,
toJson: AccountData.recentEmojiToJson,
)
IList<RecentEmoji> recentEmoji = const IList.empty(),
}) with _$AccountData {
static List<dynamic>? readRecentEmojiValue( static List<dynamic>? readRecentEmojiValue(
Map<dynamic, dynamic> json, Map<dynamic, dynamic> json,
String key, String key,
@ -19,45 +33,22 @@ abstract class AccountData with _$AccountData {
static const directKey = "m.direct"; static const directKey = "m.direct";
static const recentEmojiKey = "m.recent_emoji"; static const recentEmojiKey = "m.recent_emoji";
const factory AccountData({
@JsonKey(name: AccountData.invitePermissionConfigKey)
@Default(InvitePermissionConfig())
InvitePermissionConfig invitePermissionConfig,
@JsonKey(name: AccountData.directKey)
@Default(IMap.empty())
IMap<String, IList<String>> directMessages,
@JsonKey(
name: AccountData.recentEmojiKey,
readValue: AccountData.readRecentEmojiValue,
toJson: AccountData.recentEmojiToJson,
)
@Default(IList.empty())
IList<RecentEmoji> recentEmoji,
}) = _AccountData;
factory AccountData.fromJson(Map<String, Object?> json) => factory AccountData.fromJson(Map<String, Object?> json) =>
_$AccountDataFromJson(json); _$AccountDataFromJson(json);
} }
@freezed @freezed
abstract class InvitePermissionConfig with _$InvitePermissionConfig { sealed class const InvitePermissionConfig({
const factory InvitePermissionConfig({
@JsonKey(unknownEnumValue: DefaultInviteAction.allow) @JsonKey(unknownEnumValue: DefaultInviteAction.allow)
@Default(DefaultInviteAction.allow) DefaultInviteAction defaultAction = DefaultInviteAction.allow,
DefaultInviteAction defaultAction, }) with _$InvitePermissionConfig {
}) = _InvitePermissionConfig;
factory InvitePermissionConfig.fromJson(Map<String, Object?> json) => factory InvitePermissionConfig.fromJson(Map<String, Object?> json) =>
_$InvitePermissionConfigFromJson(json); _$InvitePermissionConfigFromJson(json);
} }
@freezed @freezed
abstract class RecentEmoji with _$RecentEmoji { sealed class const RecentEmoji({required String emoji, required int total})
const factory RecentEmoji({required String emoji, required int total}) = with _$RecentEmoji {
_RecentEmoji;
factory RecentEmoji.fromJson(Map<String, Object?> json) => factory RecentEmoji.fromJson(Map<String, Object?> json) =>
_$RecentEmojiFromJson(json); _$RecentEmojiFromJson(json);
} }

View file

@ -1,17 +1,16 @@
import "package:freezed_annotation/freezed_annotation.dart"; import "package:freezed_annotation/freezed_annotation.dart";
part "client_state.freezed.dart"; part "client_state.freezed.dart";
part "client_state.g.dart"; part "client_state.g.dart";
@freezed @freezed
abstract class ClientState with _$ClientState { sealed class const ClientState({
const factory ClientState({
required bool isInitialized, required bool isInitialized,
required bool isLoggedIn, required bool isLoggedIn,
required bool isVerified, required bool isVerified,
required String? userId, required String? userId,
required String? homeserverUrl, required String? homeserverUrl,
}) = _ClientState; }) with _$ClientState {
factory ClientState.fromJson(Map<String, Object?> json) => factory ClientState.fromJson(Map<String, Object?> json) =>
_$ClientStateFromJson(json); _$ClientStateFromJson(json);
} }

View file

@ -1,15 +1,14 @@
import "package:freezed_annotation/freezed_annotation.dart"; import "package:freezed_annotation/freezed_annotation.dart";
import "package:nexus/models/membership_status.dart"; import "package:nexus/models/membership_status.dart";
part "members_by_status.freezed.dart"; part "members_by_status.freezed.dart";
part "members_by_status.g.dart"; part "members_by_status.g.dart";
@freezed @freezed
abstract class MembersByStatusConfig with _$MembersByStatusConfig { sealed class const MembersByStatusConfig({
const factory MembersByStatusConfig({
required String roomId, required String roomId,
required MembershipStatus status, required MembershipStatus status,
}) = _MembersByStatusConfig; }) with _$MembersByStatusConfig {
factory MembersByStatusConfig.fromJson(Map<String, Object?> json) => factory MembersByStatusConfig.fromJson(Map<String, Object?> json) =>
_$MembersByStatusConfigFromJson(json); _$MembersByStatusConfigFromJson(json);
} }

View file

@ -1,6 +1,7 @@
import "package:freezed_annotation/freezed_annotation.dart"; import "package:freezed_annotation/freezed_annotation.dart";
import "package:nexus/models/content/content.dart"; import "package:nexus/models/content/content.dart";
import "package:nexus/models/membership_action.dart"; import "package:nexus/models/membership_action.dart";
part "power_level.freezed.dart"; part "power_level.freezed.dart";
@freezed @freezed

View file

@ -1,14 +1,13 @@
import "package:freezed_annotation/freezed_annotation.dart"; import "package:freezed_annotation/freezed_annotation.dart";
part "reactions.freezed.dart"; part "reactions.freezed.dart";
part "reactions.g.dart"; part "reactions.g.dart";
@freezed @freezed
abstract class ReactionsConfig with _$ReactionsConfig { sealed class const ReactionsConfig({
const factory ReactionsConfig({
required String roomId, required String roomId,
required int eventRowId, required int eventRowId,
}) = _ReactionsConfig; }) with _$ReactionsConfig {
factory ReactionsConfig.fromJson(Map<String, Object?> json) => factory ReactionsConfig.fromJson(Map<String, Object?> json) =>
_$ReactionsConfigFromJson(json); _$ReactionsConfigFromJson(json);
} }

View file

@ -1,12 +1,11 @@
import "package:freezed_annotation/freezed_annotation.dart"; import "package:freezed_annotation/freezed_annotation.dart";
part "user.freezed.dart"; part "user.freezed.dart";
part "user.g.dart"; part "user.g.dart";
@freezed @freezed
abstract class UserConfig with _$UserConfig { sealed class const UserConfig({String? roomId, required String userId})
const factory UserConfig({required String? roomId, required String userId}) = with _$UserConfig {
_UserConfig;
factory UserConfig.fromJson(Map<String, Object?> json) => factory UserConfig.fromJson(Map<String, Object?> json) =>
_$UserConfigFromJson(json); _$UserConfigFromJson(json);
} }

View file

@ -5,7 +5,7 @@ part "avatar.freezed.dart";
part "avatar.g.dart"; part "avatar.g.dart";
@freezed @freezed
abstract class AvatarContent extends Content with _$AvatarContent { sealed class AvatarContent extends Content with _$AvatarContent {
AvatarContent._(); AvatarContent._();
factory AvatarContent({ImageInfo? info, Uri? url}) = _AvatarContent; factory AvatarContent({ImageInfo? info, Uri? url}) = _AvatarContent;

View file

@ -5,7 +5,7 @@ part "canonical_alias.freezed.dart";
part "canonical_alias.g.dart"; part "canonical_alias.g.dart";
@freezed @freezed
abstract class CanonicalAliasContent extends Content sealed class CanonicalAliasContent extends Content
with _$CanonicalAliasContent { with _$CanonicalAliasContent {
CanonicalAliasContent._(); CanonicalAliasContent._();
factory CanonicalAliasContent({ factory CanonicalAliasContent({

View file

@ -19,9 +19,11 @@ import "package:nexus/models/content/history_visibility.dart";
class Content { class Content {
final Error? parseError; final Error? parseError;
Content({this.parseError});
factory Content.fromJson(Map<String, dynamic> json) => Content(); const Content({this.parseError});
factory Content.fromJson(Map<String, dynamic> json) => const Content();
Map<String, dynamic> toJson() => {}; Map<String, dynamic> toJson() => {};
static Map<String, dynamic> readValue(Map<dynamic, dynamic> json, _) => static Map<String, dynamic> readValue(Map<dynamic, dynamic> json, _) =>
@ -34,13 +36,16 @@ class Content {
?.contentFromJson ?? ?.contentFromJson ??
Content.fromJson)(json); Content.fromJson)(json);
} catch (error) { } catch (error) {
if (error is Error) return .new(parseError: error); if (error is Error) return Content(parseError: error);
rethrow; rethrow;
} }
} }
} }
enum EventType { enum EventType(
final String type,
final Content Function(Map<String, dynamic> json) contentFromJson,
) {
encrypted("m.room.encrypted", EncryptedContent.fromJson), encrypted("m.room.encrypted", EncryptedContent.fromJson),
redaction("m.room.redaction", RedactionContent.fromJson), redaction("m.room.redaction", RedactionContent.fromJson),
encryption("m.room.encryption", EncryptionContent.fromJson), encryption("m.room.encryption", EncryptionContent.fromJson),
@ -61,8 +66,4 @@ enum EventType {
reaction("m.reaction", ReactionContent.fromJson), reaction("m.reaction", ReactionContent.fromJson),
pinnedEvents("m.room.pinned_events", PinnedEventsContent.fromJson), pinnedEvents("m.room.pinned_events", PinnedEventsContent.fromJson),
message("m.room.message", MessageContent.fromJson); message("m.room.message", MessageContent.fromJson);
final String type;
final Content Function(Map<String, dynamic> json) contentFromJson;
const EventType(this.type, this.contentFromJson);
} }

View file

@ -5,7 +5,7 @@ part "create.freezed.dart";
part "create.g.dart"; part "create.g.dart";
@freezed @freezed
abstract class CreateContent extends Content with _$CreateContent { sealed class CreateContent extends Content with _$CreateContent {
CreateContent._(); CreateContent._();
factory CreateContent({ factory CreateContent({
@JsonKey(name: "additional_creators") @JsonKey(name: "additional_creators")
@ -31,9 +31,7 @@ enum RoomType {
} }
@freezed @freezed
abstract class PreviousRoom with _$PreviousRoom { sealed class const PreviousRoom({required String roomId}) with _$PreviousRoom {
const factory PreviousRoom({required String roomId}) = _PreviousRoom;
factory PreviousRoom.fromJson(Map<String, Object?> json) => factory PreviousRoom.fromJson(Map<String, Object?> json) =>
_$PreviousRoomFromJson(json); _$PreviousRoomFromJson(json);
} }

View file

@ -4,7 +4,7 @@ part "encrypted.freezed.dart";
part "encrypted.g.dart"; part "encrypted.g.dart";
@freezed @freezed
abstract class EncryptedContent extends Content with _$EncryptedContent { sealed class EncryptedContent extends Content with _$EncryptedContent {
EncryptedContent._(); EncryptedContent._();
factory EncryptedContent() = _EncryptedContent; factory EncryptedContent() = _EncryptedContent;

View file

@ -4,7 +4,7 @@ part "encryption.freezed.dart";
part "encryption.g.dart"; part "encryption.g.dart";
@freezed @freezed
abstract class EncryptionContent extends Content with _$EncryptionContent { sealed class EncryptionContent extends Content with _$EncryptionContent {
EncryptionContent._(); EncryptionContent._();
factory EncryptionContent({ factory EncryptionContent({
required String algorithm, required String algorithm,

View file

@ -4,7 +4,7 @@ part "history_visibility.freezed.dart";
part "history_visibility.g.dart"; part "history_visibility.g.dart";
@freezed @freezed
abstract class HistoryVisibilityContent extends Content sealed class HistoryVisibilityContent extends Content
with _$HistoryVisibilityContent { with _$HistoryVisibilityContent {
HistoryVisibilityContent._(); HistoryVisibilityContent._();
factory HistoryVisibilityContent({ factory HistoryVisibilityContent({

View file

@ -6,7 +6,7 @@ part "join_rules.freezed.dart";
part "join_rules.g.dart"; part "join_rules.g.dart";
@freezed @freezed
abstract class JoinRulesContent extends Content with _$JoinRulesContent { sealed class JoinRulesContent extends Content with _$JoinRulesContent {
JoinRulesContent._(); JoinRulesContent._();
factory JoinRulesContent({ factory JoinRulesContent({
required JoinRule joinRule, required JoinRule joinRule,
@ -18,12 +18,10 @@ abstract class JoinRulesContent extends Content with _$JoinRulesContent {
} }
@freezed @freezed
abstract class AllowCondition with _$AllowCondition { sealed class const AllowCondition({
const factory AllowCondition({
String? roomId, String? roomId,
required AllowConditionType type, required AllowConditionType type,
}) = _AllowCondition; }) with _$AllowCondition {
factory AllowCondition.fromJson(Map<String, Object?> json) => factory AllowCondition.fromJson(Map<String, Object?> json) =>
_$AllowConditionFromJson(json); _$AllowConditionFromJson(json);
} }

View file

@ -5,7 +5,7 @@ part "membership.freezed.dart";
part "membership.g.dart"; part "membership.g.dart";
@freezed @freezed
abstract class MembershipContent extends Content with _$MembershipContent { sealed class MembershipContent extends Content with _$MembershipContent {
MembershipContent._(); MembershipContent._();
static String? displaynameFromJson(String? displayName) => static String? displaynameFromJson(String? displayName) =>

View file

@ -10,7 +10,7 @@ part "message.g.dart";
typedef EncryptedFile = Map<String, dynamic>; typedef EncryptedFile = Map<String, dynamic>;
@Freezed(unionKey: "msgtype", fallbackUnion: "default") @Freezed(unionKey: "msgtype", fallbackUnion: "default")
abstract class MessageContent extends Content with _$MessageContent { sealed class MessageContent extends Content with _$MessageContent {
MessageContent._(); MessageContent._();
static String? mediaUrlFromJson(Map<dynamic, dynamic> json, String key) => static String? mediaUrlFromJson(Map<dynamic, dynamic> json, String key) =>
json[key] ?? json["file"]?[key]; json[key] ?? json["file"]?[key];

View file

@ -4,7 +4,7 @@ part "name.freezed.dart";
part "name.g.dart"; part "name.g.dart";
@freezed @freezed
abstract class NameContent extends Content with _$NameContent { sealed class NameContent extends Content with _$NameContent {
NameContent._(); NameContent._();
factory NameContent({required String name}) = _NameContent; factory NameContent({required String name}) = _NameContent;

View file

@ -5,7 +5,7 @@ part "pinned_events.freezed.dart";
part "pinned_events.g.dart"; part "pinned_events.g.dart";
@freezed @freezed
abstract class PinnedEventsContent extends Content with _$PinnedEventsContent { sealed class PinnedEventsContent extends Content with _$PinnedEventsContent {
PinnedEventsContent._(); PinnedEventsContent._();
factory PinnedEventsContent({ factory PinnedEventsContent({
@Default(IList.empty()) @JsonKey(name: "pinned") IList<String> pinnedEvents, @Default(IList.empty()) @JsonKey(name: "pinned") IList<String> pinnedEvents,

View file

@ -5,7 +5,7 @@ part "power_levels.freezed.dart";
part "power_levels.g.dart"; part "power_levels.g.dart";
@freezed @freezed
abstract class PowerLevelsContent extends Content with _$PowerLevelsContent { sealed class PowerLevelsContent extends Content with _$PowerLevelsContent {
PowerLevelsContent._(); PowerLevelsContent._();
factory PowerLevelsContent({ factory PowerLevelsContent({
@Default(IMap.empty()) IMap<String, int> events, @Default(IMap.empty()) IMap<String, int> events,
@ -25,12 +25,10 @@ abstract class PowerLevelsContent extends Content with _$PowerLevelsContent {
} }
@freezed @freezed
abstract class Notifications with _$Notifications { sealed class const Notifications({
const factory Notifications({ int room = 50,
@Default(50) int room, IMap<String, int> other = const IMap.empty(),
@Default(IMapConst({})) IMap<String, int> other, }) with _$Notifications {
}) = _Notifications;
factory Notifications.fromJson(Map<String, Object?> json) => factory Notifications.fromJson(Map<String, Object?> json) =>
_$NotificationsFromJson(json); _$NotificationsFromJson(json);
} }

View file

@ -4,7 +4,7 @@ part "reaction.freezed.dart";
part "reaction.g.dart"; part "reaction.g.dart";
@Freezed(toJson: false) @Freezed(toJson: false)
abstract class ReactionContent extends Content with _$ReactionContent { sealed class ReactionContent extends Content with _$ReactionContent {
ReactionContent._(); ReactionContent._();
static String? keyJsonFromJson(Map<dynamic, dynamic> json, String key) => static String? keyJsonFromJson(Map<dynamic, dynamic> json, String key) =>
json["m.relates_to"]?["key"]; json["m.relates_to"]?["key"];

View file

@ -4,7 +4,7 @@ part "redaction.freezed.dart";
part "redaction.g.dart"; part "redaction.g.dart";
@freezed @freezed
abstract class RedactionContent extends Content with _$RedactionContent { sealed class RedactionContent extends Content with _$RedactionContent {
RedactionContent._(); RedactionContent._();
factory RedactionContent({String? reason, String? redacts}) = factory RedactionContent({String? reason, String? redacts}) =
_RedactionContent; _RedactionContent;

View file

@ -5,7 +5,7 @@ part "server_acl.freezed.dart";
part "server_acl.g.dart"; part "server_acl.g.dart";
@freezed @freezed
abstract class ServerACLContent extends Content with _$ServerACLContent { sealed class ServerACLContent extends Content with _$ServerACLContent {
ServerACLContent._(); ServerACLContent._();
factory ServerACLContent({ factory ServerACLContent({
@Default(IList.empty()) IList<String> allow, @Default(IList.empty()) IList<String> allow,

View file

@ -5,7 +5,7 @@ part "sticker.freezed.dart";
part "sticker.g.dart"; part "sticker.g.dart";
@freezed @freezed
abstract class StickerContent extends Content with _$StickerContent { sealed class StickerContent extends Content with _$StickerContent {
StickerContent._(); StickerContent._();
factory StickerContent({ factory StickerContent({
required String body, required String body,

View file

@ -1,11 +1,12 @@
import "package:fast_immutable_collections/fast_immutable_collections.dart"; import "package:fast_immutable_collections/fast_immutable_collections.dart";
import "package:freezed_annotation/freezed_annotation.dart"; import "package:freezed_annotation/freezed_annotation.dart";
import "package:nexus/models/content/content.dart"; import "package:nexus/models/content/content.dart";
part "topic.freezed.dart"; part "topic.freezed.dart";
part "topic.g.dart"; part "topic.g.dart";
@freezed @freezed
abstract class TopicContent extends Content with _$TopicContent { sealed class TopicContent extends Content with _$TopicContent {
TopicContent._(); TopicContent._();
factory TopicContent({ factory TopicContent({
required String topic, required String topic,
@ -17,24 +18,18 @@ abstract class TopicContent extends Content with _$TopicContent {
} }
@freezed @freezed
abstract class TopicContentBlock with _$TopicContentBlock { sealed class const TopicContentBlock({
factory TopicContentBlock({ IList<TextualRepresentation> representations = const IList.empty(),
@Default(IList.empty()) }) with _$TopicContentBlock {
@JsonKey(name: "m.text")
IList<TextualRepresentation> representations,
}) = _TopicContentBlock;
factory TopicContentBlock.fromJson(Map<String, Object?> json) => factory TopicContentBlock.fromJson(Map<String, Object?> json) =>
_$TopicContentBlockFromJson(json); _$TopicContentBlockFromJson(json);
} }
@freezed @freezed
abstract class TextualRepresentation with _$TextualRepresentation { sealed class const TextualRepresentation({
factory TextualRepresentation({
required String body, required String body,
@Default("text/plain") String mimetype, String mimetype = "text/plain",
}) = _TextualRepresentation; }) with _$TextualRepresentation {
factory TextualRepresentation.fromJson(Map<String, Object?> json) => factory TextualRepresentation.fromJson(Map<String, Object?> json) =>
_$TextualRepresentationFromJson(json); _$TextualRepresentationFromJson(json);
} }

View file

@ -1,17 +0,0 @@
import "package:fast_immutable_collections/fast_immutable_collections.dart";
import "package:freezed_annotation/freezed_annotation.dart";
part "emoji.freezed.dart";
part "emoji.g.dart";
@freezed
abstract class Emoji with _$Emoji {
const factory Emoji({
required String emoji,
required String category,
required IList<String> aliases,
required String description,
required IList<String> tags,
}) = _Emoji;
factory Emoji.fromJson(Map<String, Object?> json) => _$EmojiFromJson(json);
}

View file

@ -3,11 +3,36 @@ import "package:freezed_annotation/freezed_annotation.dart";
import "package:nexus/models/content/content.dart"; import "package:nexus/models/content/content.dart";
import "package:nexus/models/epoch_date_time_converter.dart"; import "package:nexus/models/epoch_date_time_converter.dart";
import "package:nexus/models/profile_response.dart"; import "package:nexus/models/profile_response.dart";
part "event.freezed.dart"; part "event.freezed.dart";
part "event.g.dart"; part "event.g.dart";
@freezed @freezed
abstract class Event with _$Event { sealed class const Event({
@JsonKey(name: "rowid") required int rowId,
@JsonKey(name: "timeline_rowid") required int timelineRowId,
required String roomId,
required String eventId,
required String sender,
@JsonKey(readValue: Event.typeJsonFromJson) required String type,
String? stateKey,
@EpochDateTimeConverter() required DateTime timestamp,
IMap<String, dynamic> unsigned = const IMap.empty(),
LocalContent? localContent,
String? transactionId,
String? redactedBy,
String? relatesTo,
String? relationType,
String? replyTo,
String? decryptionError,
String? sendError,
IMap<String, int> reactions = const IMap.empty(),
@JsonKey(name: "last_edit_rowid") int lastEditRowId = 0,
@UnreadTypeConverter() UnreadType? unreadType,
Profile? pmp,
required Content content,
required Content? previousContent,
}) with _$Event {
static String typeJsonFromJson(Map<dynamic, dynamic> json, _) => static String typeJsonFromJson(Map<dynamic, dynamic> json, _) =>
json["decrypted_type"] ?? json["type"]; json["decrypted_type"] ?? json["type"];
@ -25,32 +50,6 @@ abstract class Event with _$Event {
} }
} }
const factory Event({
@JsonKey(name: "rowid") required int rowId,
@JsonKey(name: "timeline_rowid") required int timelineRowId,
required String roomId,
required String eventId,
required String sender,
@JsonKey(readValue: Event.typeJsonFromJson) required String type,
String? stateKey,
@EpochDateTimeConverter() required DateTime timestamp,
@Default(IMap.empty()) IMap<String, dynamic> unsigned,
LocalContent? localContent,
String? transactionId,
String? redactedBy,
String? relatesTo,
String? relationType,
String? replyTo,
String? decryptionError,
String? sendError,
@Default(IMap.empty()) IMap<String, int> reactions,
@JsonKey(name: "last_edit_rowid") @Default(0) int lastEditRowId,
@UnreadTypeConverter() UnreadType? unreadType,
Profile? pmp,
required Content content,
required Content? previousContent,
}) = _Event;
factory Event.fromJson(Map<String, dynamic> json) => factory Event.fromJson(Map<String, dynamic> json) =>
_$EventFromJson(json).copyWith( _$EventFromJson(json).copyWith(
replyTo: replyToFromJson(getContentFromJson(json)), replyTo: replyToFromJson(getContentFromJson(json)),
@ -73,16 +72,14 @@ abstract class Event with _$Event {
} }
@freezed @freezed
abstract class LocalContent with _$LocalContent { sealed class const LocalContent({
const factory LocalContent({
String? sanitizedHtml, String? sanitizedHtml,
String? editSource, String? editSource,
bool? wasPlaintext, bool? wasPlaintext,
bool? bigEmoji, bool? bigEmoji,
bool? hasMath, bool? hasMath,
bool? replyFallbackRemoved, bool? replyFallbackRemoved,
}) = _LocalContent; }) with _$LocalContent {
factory LocalContent.fromJson(Map<String, Object?> json) => factory LocalContent.fromJson(Map<String, Object?> json) =>
_$LocalContentFromJson(json); _$LocalContentFromJson(json);
} }

View file

@ -1,12 +1,11 @@
import "package:freezed_annotation/freezed_annotation.dart"; import "package:freezed_annotation/freezed_annotation.dart";
part "homeserver.freezed.dart"; part "homeserver.freezed.dart";
@freezed @freezed
abstract class Homeserver with _$Homeserver { sealed class const Homeserver({
const factory Homeserver({
required String name, required String name,
required String description, required String description,
required Uri url, required Uri url,
required String iconUrl, required String iconUrl,
}) = _Homeserver; }) with _$Homeserver;
}

View file

@ -1,17 +1,15 @@
import "package:freezed_annotation/freezed_annotation.dart"; import "package:freezed_annotation/freezed_annotation.dart";
import "package:nexus/models/ms_duration.dart"; import "package:nexus/models/ms_duration.dart";
part "audio.freezed.dart"; part "audio.freezed.dart";
part "audio.g.dart"; part "audio.g.dart";
@freezed @freezed
abstract class AudioInfo with _$AudioInfo { sealed class const AudioInfo({
/// Information for images, [size] is in bytes.
const factory AudioInfo({
@MSDuration() Duration? duration, @MSDuration() Duration? duration,
@JsonKey(name: "mimetype") String? mimeType, @JsonKey(name: "mimetype") String? mimeType,
int? size, int? size,
}) = _AudioInfo; }) with _$AudioInfo {
factory AudioInfo.fromJson(Map<String, Object?> json) => factory AudioInfo.fromJson(Map<String, Object?> json) =>
_$AudioInfoFromJson(json); _$AudioInfoFromJson(json);
} }

View file

@ -1,15 +1,13 @@
import "package:freezed_annotation/freezed_annotation.dart"; import "package:freezed_annotation/freezed_annotation.dart";
part "file.freezed.dart"; part "file.freezed.dart";
part "file.g.dart"; part "file.g.dart";
@freezed @freezed
abstract class FileInfo with _$FileInfo { sealed class const FileInfo({
/// Information for images, [size] is in bytes.
const factory FileInfo({
@JsonKey(name: "mimetype") String? mimeType, @JsonKey(name: "mimetype") String? mimeType,
int? size, int? size,
}) = _FileInfo; }) with _$FileInfo {
factory FileInfo.fromJson(Map<String, Object?> json) => factory FileInfo.fromJson(Map<String, Object?> json) =>
_$FileInfoFromJson(json); _$FileInfoFromJson(json);
} }

View file

@ -1,18 +1,16 @@
import "package:freezed_annotation/freezed_annotation.dart"; import "package:freezed_annotation/freezed_annotation.dart";
part "image.freezed.dart"; part "image.freezed.dart";
part "image.g.dart"; part "image.g.dart";
@freezed @freezed
abstract class ImageInfo with _$ImageInfo { sealed class const ImageInfo({
/// Information for images, [size] is in bytes.
const factory ImageInfo({
@JsonKey(name: "h") double? height, @JsonKey(name: "h") double? height,
@JsonKey(name: "w") double? width, @JsonKey(name: "w") double? width,
@JsonKey(name: "mimetype") String? mimeType, @JsonKey(name: "mimetype") String? mimeType,
@JsonKey(name: "xyz.amorgan.blurhash") String? blurHash, @JsonKey(name: "xyz.amorgan.blurhash") String? blurHash,
int? size, int? size,
}) = _ImageInfo; }) with _$ImageInfo {
factory ImageInfo.fromJson(Map<String, Object?> json) => factory ImageInfo.fromJson(Map<String, Object?> json) =>
_$ImageInfoFromJson(json); _$ImageInfoFromJson(json);
} }

View file

@ -1,19 +1,17 @@
import "package:freezed_annotation/freezed_annotation.dart"; import "package:freezed_annotation/freezed_annotation.dart";
import "package:nexus/models/ms_duration.dart"; import "package:nexus/models/ms_duration.dart";
part "video.freezed.dart"; part "video.freezed.dart";
part "video.g.dart"; part "video.g.dart";
@freezed @freezed
abstract class VideoInfo with _$VideoInfo { sealed class const VideoInfo({
/// Information for images, [size] is in bytes.
const factory VideoInfo({
@JsonKey(name: "h") int? height, @JsonKey(name: "h") int? height,
@JsonKey(name: "w") int? width, @JsonKey(name: "w") int? width,
@JsonKey(name: "mimetype") String? mimeType, @JsonKey(name: "mimetype") String? mimeType,
@MSDuration() Duration? duration, @MSDuration() Duration? duration,
int? size, int? size,
}) = _VideoInfo; }) with _$VideoInfo {
factory VideoInfo.fromJson(Map<String, Object?> json) => factory VideoInfo.fromJson(Map<String, Object?> json) =>
_$VideoInfoFromJson(json); _$VideoInfoFromJson(json);
} }

View file

@ -1,16 +1,15 @@
import "package:fast_immutable_collections/fast_immutable_collections.dart"; import "package:fast_immutable_collections/fast_immutable_collections.dart";
import "package:freezed_annotation/freezed_annotation.dart"; import "package:freezed_annotation/freezed_annotation.dart";
part "lazy_load_summary.freezed.dart"; part "lazy_load_summary.freezed.dart";
part "lazy_load_summary.g.dart"; part "lazy_load_summary.g.dart";
@freezed @freezed
abstract class LazyLoadSummary with _$LazyLoadSummary { sealed class const LazyLoadSummary({
const factory LazyLoadSummary({
required IList<String>? heroes, required IList<String>? heroes,
required int? joinedMemberCount, required int? joinedMemberCount,
required int? invitedMemberCount, required int? invitedMemberCount,
}) = _LazyLoadSummary; }) with _$LazyLoadSummary {
factory LazyLoadSummary.fromJson(Map<String, Object?> json) => factory LazyLoadSummary.fromJson(Map<String, Object?> json) =>
_$LazyLoadSummaryFromJson(json); _$LazyLoadSummaryFromJson(json);
} }

View file

@ -1,15 +1,14 @@
import "package:freezed_annotation/freezed_annotation.dart"; import "package:freezed_annotation/freezed_annotation.dart";
part "oauth_auth_code_response.freezed.dart"; part "oauth_auth_code_response.freezed.dart";
part "oauth_auth_code_response.g.dart"; part "oauth_auth_code_response.g.dart";
@freezed @freezed
abstract class OAuthAuthCodeResponse with _$OAuthAuthCodeResponse { sealed class const OAuthAuthCodeResponse({
const factory OAuthAuthCodeResponse({
required String state, required String state,
required String codeVerifier, required String codeVerifier,
required Uri url, required Uri url,
}) = _OAuthAuthCodeResponse; }) with _$OAuthAuthCodeResponse {
factory OAuthAuthCodeResponse.fromJson(Map<String, Object?> json) => factory OAuthAuthCodeResponse.fromJson(Map<String, Object?> json) =>
_$OAuthAuthCodeResponseFromJson(json); _$OAuthAuthCodeResponseFromJson(json);
} }

View file

@ -1,17 +1,16 @@
import "package:freezed_annotation/freezed_annotation.dart"; import "package:freezed_annotation/freezed_annotation.dart";
part "open_graph_data.freezed.dart"; part "open_graph_data.freezed.dart";
part "open_graph_data.g.dart"; part "open_graph_data.g.dart";
@freezed @freezed
abstract class OpenGraphData with _$OpenGraphData { sealed class const OpenGraphData({
const factory OpenGraphData({
@JsonKey(name: "og:title") required String? title, @JsonKey(name: "og:title") required String? title,
@JsonKey(name: "og:description") required String? description, @JsonKey(name: "og:description") required String? description,
@JsonKey(name: "og:image") required Uri? imageUrl, @JsonKey(name: "og:image") required Uri? imageUrl,
@JsonKey(name: "og:image:width") required double? width, @JsonKey(name: "og:image:width") required double? width,
@JsonKey(name: "og:image:height") required double? height, @JsonKey(name: "og:image:height") required double? height,
}) = _OpenGraphData; }) with _$OpenGraphData {
factory OpenGraphData.fromJson(Map<String, dynamic> json) => factory OpenGraphData.fromJson(Map<String, dynamic> json) =>
_$OpenGraphDataFromJson(json); _$OpenGraphDataFromJson(json);
} }

View file

@ -1,17 +1,16 @@
import "package:fast_immutable_collections/fast_immutable_collections.dart"; import "package:fast_immutable_collections/fast_immutable_collections.dart";
import "package:freezed_annotation/freezed_annotation.dart"; import "package:freezed_annotation/freezed_annotation.dart";
import "package:nexus/models/event.dart"; import "package:nexus/models/event.dart";
part "paginate.freezed.dart"; part "paginate.freezed.dart";
part "paginate.g.dart"; part "paginate.g.dart";
@freezed @freezed
abstract class Paginate with _$Paginate { sealed class const Paginate({
const factory Paginate({
required IList<Event> events, required IList<Event> events,
required IList<Event> relatedEvents, required IList<Event> relatedEvents,
required bool hasMore, required bool hasMore,
}) = _Paginate; }) with _$Paginate {
factory Paginate.fromJson(Map<String, Object?> json) => factory Paginate.fromJson(Map<String, Object?> json) =>
_$PaginateFromJson(json); _$PaginateFromJson(json);
} }

View file

@ -1,53 +1,44 @@
import "package:fast_immutable_collections/fast_immutable_collections.dart"; import "package:fast_immutable_collections/fast_immutable_collections.dart";
import "package:freezed_annotation/freezed_annotation.dart"; import "package:freezed_annotation/freezed_annotation.dart";
import "package:nexus/models/content/membership.dart"; import "package:nexus/models/content/membership.dart";
part "profile_response.freezed.dart"; part "profile_response.freezed.dart";
part "profile_response.g.dart"; part "profile_response.g.dart";
@freezed @freezed
abstract class ProfileResponse with _$ProfileResponse { sealed class const ProfileResponse({
const factory ProfileResponse({
@JsonKey(fromJson: Profile.fromJson) required Profile profile, @JsonKey(fromJson: Profile.fromJson) required Profile profile,
required Bio? bio, required Bio? bio,
}) = _ProfileResponse; }) with _$ProfileResponse {
factory ProfileResponse.fromJson(Map<String, Object?> json) => factory ProfileResponse.fromJson(Map<String, Object?> json) =>
_$ProfileResponseFromJson(json); _$ProfileResponseFromJson(json);
} }
@freezed @freezed
abstract class Bio with _$Bio { sealed class const Bio({required String html, String? editSource}) with _$Bio {
const factory Bio({required String html, String? editSource}) = _Bio;
factory Bio.fromJson(Map<String, Object?> json) => _$BioFromJson(json); factory Bio.fromJson(Map<String, Object?> json) => _$BioFromJson(json);
} }
@freezed @freezed
abstract class Profile with _$Profile { sealed class const Profile({
String? id,
String? parseError,
Uri? avatarUrl,
@JsonKey(name: "displayname", fromJson: MembershipContent.displaynameFromJson)
String? displayName,
@JsonKey(readValue: Profile.readTimezone, name: "m.tz") String? timezone,
@JsonKey(readValue: Profile.readPronouns, name: "m.pronouns")
IList<Pronoun> pronouns = const IList.empty(),
}) with _$Profile {
static Object? readPronouns(Map<dynamic, dynamic> map, String key) => static Object? readPronouns(Map<dynamic, dynamic> map, String key) =>
map[key] ?? map["io.fsky.nyx.pronouns"]; map[key] ?? map["io.fsky.nyx.pronouns"];
static Object? readTimezone(Map<dynamic, dynamic> map, String key) => static Object? readTimezone(Map<dynamic, dynamic> map, String key) =>
map[key] ?? map["us.cloke.msc4175.tz"]; map[key] ?? map["us.cloke.msc4175.tz"];
const factory Profile({
String? id,
String? parseError,
Uri? avatarUrl,
@JsonKey(
name: "displayname",
fromJson: MembershipContent.displaynameFromJson,
)
String? displayName,
@JsonKey(readValue: Profile.readTimezone, name: "m.tz") String? timezone,
@Default(IList.empty())
@JsonKey(readValue: Profile.readPronouns, name: "m.pronouns")
IList<Pronoun> pronouns,
}) = _Profile;
factory Profile.fromJson(Map<String, dynamic> json) => factory Profile.fromJson(Map<String, dynamic> json) =>
_$ProfileFromJson(json); _$ProfileFromJson(json);
@ -55,16 +46,14 @@ abstract class Profile with _$Profile {
try { try {
return Profile.fromJson(json); return Profile.fromJson(json);
} catch (error) { } catch (error) {
return Profile(parseError: error.toString()); return _Profile(parseError: error.toString());
} }
} }
} }
@freezed @freezed
abstract class Pronoun with _$Pronoun { sealed class const Pronoun({required String language, required String summary})
const factory Pronoun({required String language, required String summary}) = with _$Pronoun {
_Pronoun;
factory Pronoun.fromJson(Map<String, Object?> json) => factory Pronoun.fromJson(Map<String, Object?> json) =>
_$PronounFromJson(json); _$PronounFromJson(json);
} }

View file

@ -1,18 +1,17 @@
import "package:freezed_annotation/freezed_annotation.dart"; import "package:freezed_annotation/freezed_annotation.dart";
import "package:nexus/models/epoch_date_time_converter.dart"; import "package:nexus/models/epoch_date_time_converter.dart";
part "read_receipt.freezed.dart"; part "read_receipt.freezed.dart";
part "read_receipt.g.dart"; part "read_receipt.g.dart";
@freezed @freezed
abstract class ReadReceipt with _$ReadReceipt { sealed class const ReadReceipt({
const factory ReadReceipt({
String? roomId, String? roomId,
required String userId, required String userId,
String? threadId, String? threadId,
required String eventId, required String eventId,
@EpochDateTimeConverter() required DateTime timestamp, @EpochDateTimeConverter() required DateTime timestamp,
}) = _ReadReceipt; }) with _$ReadReceipt {
factory ReadReceipt.fromJson(Map<String, Object?> json) => factory ReadReceipt.fromJson(Map<String, Object?> json) =>
_$ReadReceiptFromJson(json); _$ReadReceiptFromJson(json);
} }

View file

@ -1,16 +1,15 @@
import "package:freezed_annotation/freezed_annotation.dart"; import "package:freezed_annotation/freezed_annotation.dart";
part "download_media.freezed.dart"; part "download_media.freezed.dart";
part "download_media.g.dart"; part "download_media.g.dart";
@freezed @freezed
abstract class DownloadMediaRequest with _$DownloadMediaRequest { sealed class const DownloadMediaRequest({
const factory DownloadMediaRequest({
required Uri mxc, required Uri mxc,
@Default(false) bool encrypted, bool encrypted = false,
@Default(false) bool isAvatar, bool isAvatar = false,
@Default(false) bool thumbnailAvatar, bool thumbnailAvatar = false,
}) = _DownloadMediaRequest; }) with _$DownloadMediaRequest {
factory DownloadMediaRequest.fromJson(Map<String, Object?> json) => factory DownloadMediaRequest.fromJson(Map<String, Object?> json) =>
_$DownloadMediaRequestFromJson(json); _$DownloadMediaRequestFromJson(json);
} }

View file

@ -1,15 +1,14 @@
import "package:freezed_annotation/freezed_annotation.dart"; import "package:freezed_annotation/freezed_annotation.dart";
part "get_event.freezed.dart"; part "get_event.freezed.dart";
part "get_event.g.dart"; part "get_event.g.dart";
@freezed @freezed
abstract class GetEventRequest with _$GetEventRequest { sealed class const GetEventRequest({
const factory GetEventRequest({
required String roomId, required String roomId,
required String eventId, required String eventId,
@Default(false) bool unredact, bool unredact = false,
}) = _GetEventRequest; }) with _$GetEventRequest {
factory GetEventRequest.fromJson(Map<String, Object?> json) => factory GetEventRequest.fromJson(Map<String, Object?> json) =>
_$GetEventRequestFromJson(json); _$GetEventRequestFromJson(json);
} }

View file

@ -1,15 +1,14 @@
import "package:freezed_annotation/freezed_annotation.dart"; import "package:freezed_annotation/freezed_annotation.dart";
part "get_related_events.freezed.dart"; part "get_related_events.freezed.dart";
part "get_related_events.g.dart"; part "get_related_events.g.dart";
@freezed @freezed
abstract class GetRelatedEventsRequest with _$GetRelatedEventsRequest { sealed class const GetRelatedEventsRequest({
const factory GetRelatedEventsRequest({
required String roomId, required String roomId,
required String eventId, required String eventId,
required String relationType, required String relationType,
}) = _GetRelatedEventsRequest; }) with _$GetRelatedEventsRequest {
factory GetRelatedEventsRequest.fromJson(Map<String, Object?> json) => factory GetRelatedEventsRequest.fromJson(Map<String, Object?> json) =>
_$GetRelatedEventsRequestFromJson(json); _$GetRelatedEventsRequestFromJson(json);
} }

View file

@ -1,16 +1,15 @@
import "package:freezed_annotation/freezed_annotation.dart"; import "package:freezed_annotation/freezed_annotation.dart";
part "get_room_state.freezed.dart"; part "get_room_state.freezed.dart";
part "get_room_state.g.dart"; part "get_room_state.g.dart";
@freezed @freezed
abstract class GetRoomStateRequest with _$GetRoomStateRequest { sealed class const GetRoomStateRequest({
const factory GetRoomStateRequest({
required String roomId, required String roomId,
@Default(false) bool refetch, bool refetch = false,
@Default(false) bool fetchMembers, bool fetchMembers = false,
@Default(false) bool includeMembers, bool includeMembers = false,
}) = _GetRoomStateRequest; }) with _$GetRoomStateRequest {
factory GetRoomStateRequest.fromJson(Map<String, Object?> json) => factory GetRoomStateRequest.fromJson(Map<String, Object?> json) =>
_$GetRoomStateRequestFromJson(json); _$GetRoomStateRequestFromJson(json);
} }

View file

@ -1,15 +1,14 @@
import "package:fast_immutable_collections/fast_immutable_collections.dart"; import "package:fast_immutable_collections/fast_immutable_collections.dart";
import "package:freezed_annotation/freezed_annotation.dart"; import "package:freezed_annotation/freezed_annotation.dart";
part "join_room.freezed.dart"; part "join_room.freezed.dart";
part "join_room.g.dart"; part "join_room.g.dart";
@freezed @freezed
abstract class JoinRoomRequest with _$JoinRoomRequest { sealed class const JoinRoomRequest({
const factory JoinRoomRequest({
required String roomIdOrAlias, required String roomIdOrAlias,
@Default(IList.empty()) IList<String> via, IList<String> via = const IList.empty(),
}) = _JoinRoomRequest; }) with _$JoinRoomRequest {
factory JoinRoomRequest.fromJson(Map<String, Object?> json) => factory JoinRoomRequest.fromJson(Map<String, Object?> json) =>
_$JoinRoomRequestFromJson(json); _$JoinRoomRequestFromJson(json);
} }

View file

@ -1,17 +1,16 @@
import "package:freezed_annotation/freezed_annotation.dart"; import "package:freezed_annotation/freezed_annotation.dart";
part "exchange_token.freezed.dart"; part "exchange_token.freezed.dart";
part "exchange_token.g.dart"; part "exchange_token.g.dart";
@freezed @freezed
abstract class OAuthExchangeTokenRequest with _$OAuthExchangeTokenRequest { sealed class const OAuthExchangeTokenRequest({
const factory OAuthExchangeTokenRequest({
required Uri homeserverUrl, required Uri homeserverUrl,
required String codeVerifier, required String codeVerifier,
required Uri redirectUri, required Uri redirectUri,
required String code, required String code,
required String clientId, required String clientId,
}) = _OAuthExchangeTokenRequest; }) with _$OAuthExchangeTokenRequest {
factory OAuthExchangeTokenRequest.fromJson(Map<String, Object?> json) => factory OAuthExchangeTokenRequest.fromJson(Map<String, Object?> json) =>
_$OAuthExchangeTokenRequestFromJson(json); _$OAuthExchangeTokenRequestFromJson(json);
} }

View file

@ -2,25 +2,24 @@ import "dart:math";
import "package:fast_immutable_collections/fast_immutable_collections.dart"; import "package:fast_immutable_collections/fast_immutable_collections.dart";
import "package:freezed_annotation/freezed_annotation.dart"; import "package:freezed_annotation/freezed_annotation.dart";
part "get_auth_url.freezed.dart"; part "get_auth_url.freezed.dart";
part "get_auth_url.g.dart"; part "get_auth_url.g.dart";
@freezed @freezed
abstract class OAuthGetAuthUrl with _$OAuthGetAuthUrl { sealed class const OAuthGetAuthUrl({
const factory OAuthGetAuthUrl({
required ResponseMode responseMode, required ResponseMode responseMode,
required Uri homeserverUrl, required Uri homeserverUrl,
required Uri redirectUri, required Uri redirectUri,
required IList<String> scopes, required IList<String> scopes,
required String clientId, required String clientId,
String? userIdHint, String? userIdHint,
}) = _OAuthGetAuthUrl; }) with _$OAuthGetAuthUrl {
factory OAuthGetAuthUrl.fromJson(Map<String, Object?> json) => factory OAuthGetAuthUrl.fromJson(Map<String, Object?> json) =>
_$OAuthGetAuthUrlFromJson(json); _$OAuthGetAuthUrlFromJson(json);
} }
abstract class Scope { sealed class Scope {
static final openid = "openid"; static final openid = "openid";
static final email = "email"; static final email = "email";
static final clientApi = "urn:matrix:client:api:*"; static final clientApi = "urn:matrix:client:api:*";

View file

@ -1,13 +1,13 @@
import "package:fast_immutable_collections/fast_immutable_collections.dart"; import "package:fast_immutable_collections/fast_immutable_collections.dart";
import "package:freezed_annotation/freezed_annotation.dart"; import "package:freezed_annotation/freezed_annotation.dart";
part "register_client.freezed.dart"; part "register_client.freezed.dart";
part "register_client.g.dart"; part "register_client.g.dart";
@freezed @freezed
abstract class OAuthRegisterClientRequest with _$OAuthRegisterClientRequest { sealed class const OAuthRegisterClientRequest({
const factory OAuthRegisterClientRequest({
required Uri homeserverUrl, required Uri homeserverUrl,
@Default(ApplicationType.web) ApplicationType applicationType, ApplicationType applicationType = ApplicationType.web,
String? clientName, String? clientName,
required Uri clientUri, required Uri clientUri,
Uri? logoUri, Uri? logoUri,
@ -17,11 +17,9 @@ abstract class OAuthRegisterClientRequest with _$OAuthRegisterClientRequest {
IList<Uri>? redirectUris, IList<Uri>? redirectUris,
IList<ResponseType>? responseTypes, IList<ResponseType>? responseTypes,
@Default(AuthMethod.none)
@JsonKey(name: "token_endpoint_auth_method") @JsonKey(name: "token_endpoint_auth_method")
AuthMethod? authMethod, AuthMethod? authMethod = AuthMethod.none,
}) = _OAuthRegisterClientRequest; }) with _$OAuthRegisterClientRequest {
factory OAuthRegisterClientRequest.fromJson(Map<String, Object?> json) => factory OAuthRegisterClientRequest.fromJson(Map<String, Object?> json) =>
_$OAuthRegisterClientRequestFromJson(json); _$OAuthRegisterClientRequestFromJson(json);
} }

View file

@ -1,15 +1,14 @@
import "package:freezed_annotation/freezed_annotation.dart"; import "package:freezed_annotation/freezed_annotation.dart";
part "paginate.freezed.dart"; part "paginate.freezed.dart";
part "paginate.g.dart"; part "paginate.g.dart";
@freezed @freezed
abstract class PaginateRequest with _$PaginateRequest { sealed class const PaginateRequest({
const factory PaginateRequest({
required String roomId, required String roomId,
required int? maxTimelineId, required int? maxTimelineId,
@Default(20) int limit, int limit = 20,
}) = _PaginateRequest; }) with _$PaginateRequest {
factory PaginateRequest.fromJson(Map<String, Object?> json) => factory PaginateRequest.fromJson(Map<String, Object?> json) =>
_$PaginateRequestFromJson(json); _$PaginateRequestFromJson(json);
} }

View file

@ -1,15 +1,14 @@
import "package:freezed_annotation/freezed_annotation.dart"; import "package:freezed_annotation/freezed_annotation.dart";
part "report.freezed.dart"; part "report.freezed.dart";
part "report.g.dart"; part "report.g.dart";
@freezed @freezed
abstract class ReportRequest with _$ReportRequest { sealed class const ReportRequest({
const factory ReportRequest({
required String roomId, required String roomId,
required String eventId, required String eventId,
String? reason, String? reason,
}) = _ReportRequest; }) with _$ReportRequest {
factory ReportRequest.fromJson(Map<String, Object?> json) => factory ReportRequest.fromJson(Map<String, Object?> json) =>
_$ReportRequestFromJson(json); _$ReportRequestFromJson(json);
} }

View file

@ -1,20 +1,19 @@
import "package:freezed_annotation/freezed_annotation.dart"; import "package:freezed_annotation/freezed_annotation.dart";
import "package:nexus/models/content/content.dart"; import "package:nexus/models/content/content.dart";
part "send_event.freezed.dart"; part "send_event.freezed.dart";
part "send_event.g.dart"; part "send_event.g.dart";
@freezed @freezed
abstract class SendEventRequest with _$SendEventRequest { sealed class const SendEventRequest({
const factory SendEventRequest({
required String roomId, required String roomId,
required String type, required String type,
required Content content, required Content content,
String? relatesTo, String? relatesTo,
String? relationType, String? relationType,
@Default(false) bool synchronous, bool synchronous = false,
@Default(false) bool disableEncryption, bool disableEncryption = false,
}) = _SendEventRequest; }) with _$SendEventRequest {
factory SendEventRequest.fromJson(Map<String, Object?> json) => factory SendEventRequest.fromJson(Map<String, Object?> json) =>
_$SendEventRequestFromJson(json); _$SendEventRequestFromJson(json);
} }

View file

@ -2,43 +2,36 @@ import "package:fast_immutable_collections/fast_immutable_collections.dart";
import "package:freezed_annotation/freezed_annotation.dart"; import "package:freezed_annotation/freezed_annotation.dart";
import "package:nexus/models/content/content.dart"; import "package:nexus/models/content/content.dart";
import "package:nexus/models/relation_type.dart"; import "package:nexus/models/relation_type.dart";
part "send_message.freezed.dart"; part "send_message.freezed.dart";
part "send_message.g.dart"; part "send_message.g.dart";
@freezed @freezed
abstract class SendMessageRequest with _$SendMessageRequest { sealed class const SendMessageRequest({
const factory SendMessageRequest({
required String roomId, required String roomId,
required String text, required String text,
Content? baseContent, Content? baseContent,
@Default(Mentions()) @JsonKey(name: "mentions") Mentions mentions, @JsonKey(name: "mentions") Mentions mentions = const _Mentions(),
@JsonKey(name: "relates_to") Relation? relation, @JsonKey(name: "relates_to") Relation? relation,
}) = _SendMessageRequest; }) with _$SendMessageRequest {
factory SendMessageRequest.fromJson(Map<String, Object?> json) => factory SendMessageRequest.fromJson(Map<String, Object?> json) =>
_$SendMessageRequestFromJson(json); _$SendMessageRequestFromJson(json);
} }
@freezed @freezed
abstract class Mentions with _$Mentions { sealed class const Mentions({
const factory Mentions({ bool room = false,
@Default(false) bool room, IList<String> userIds = const IList.empty(),
@Default(IList.empty()) IList<String> userIds, }) with _$Mentions {
}) = _Mentions;
factory Mentions.fromJson(Map<String, Object?> json) => factory Mentions.fromJson(Map<String, Object?> json) =>
_$MentionsFromJson(json); _$MentionsFromJson(json);
} }
@Freezed(toJson: false) @Freezed(toJson: false)
abstract class Relation with _$Relation { sealed class const Relation({
const Relation._();
const factory Relation({
required String eventId, required String eventId,
required RelationType relationType, required RelationType relationType,
}) = _Relation; }) with _$Relation {
Map<String, dynamic> toJson() { Map<String, dynamic> toJson() {
switch (relationType) { switch (relationType) {
case RelationType.reply: case RelationType.reply:

View file

@ -1,15 +1,14 @@
import "package:freezed_annotation/freezed_annotation.dart"; import "package:freezed_annotation/freezed_annotation.dart";
part "set_account_data.freezed.dart"; part "set_account_data.freezed.dart";
part "set_account_data.g.dart"; part "set_account_data.g.dart";
@freezed @freezed
abstract class SetAccountDataRequest with _$SetAccountDataRequest { sealed class const SetAccountDataRequest({
const factory SetAccountDataRequest({
required String type, required String type,
required dynamic content, required dynamic content,
String? roomId, String? roomId,
}) = _SetAccountDataRequest; }) with _$SetAccountDataRequest {
factory SetAccountDataRequest.fromJson(Map<String, Object?> json) => factory SetAccountDataRequest.fromJson(Map<String, Object?> json) =>
_$SetAccountDataRequestFromJson(json); _$SetAccountDataRequestFromJson(json);
} }

View file

@ -1,19 +1,17 @@
import "package:freezed_annotation/freezed_annotation.dart"; import "package:freezed_annotation/freezed_annotation.dart";
import "package:nexus/models/membership_action.dart"; import "package:nexus/models/membership_action.dart";
part "set_membership.freezed.dart"; part "set_membership.freezed.dart";
part "set_membership.g.dart"; part "set_membership.g.dart";
@freezed @freezed
abstract class SetMembershipRequest with _$SetMembershipRequest { sealed class const SetMembershipRequest({
const factory SetMembershipRequest({
required String userId, required String userId,
required String roomId, required String roomId,
String? reason, String? reason,
@JsonKey(name: "action") required MembershipAction action, @JsonKey(name: "action") required MembershipAction action,
@Default(false) @JsonKey(name: "msc4293_redact_events") bool redact, @JsonKey(name: "msc4293_redact_events") bool redact = false,
}) = _SetMembershipRequest; }) with _$SetMembershipRequest {
factory SetMembershipRequest.fromJson(Map<String, Object?> json) => factory SetMembershipRequest.fromJson(Map<String, Object?> json) =>
_$SetMembershipRequestFromJson(json); _$SetMembershipRequestFromJson(json);
} }

View file

@ -1,12 +1,12 @@
import "package:freezed_annotation/freezed_annotation.dart"; import "package:freezed_annotation/freezed_annotation.dart";
import "package:nexus/models/content/content.dart"; import "package:nexus/models/content/content.dart";
import "package:nexus/models/ms_duration.dart"; import "package:nexus/models/ms_duration.dart";
part "set_state.freezed.dart"; part "set_state.freezed.dart";
part "set_state.g.dart"; part "set_state.g.dart";
@freezed @freezed
abstract class SetStateRequest with _$SetStateRequest { sealed class const SetStateRequest({
const factory SetStateRequest({
required String roomId, required String roomId,
required String type, required String type,
required String stateKey, required String stateKey,
@ -14,10 +14,8 @@ abstract class SetStateRequest with _$SetStateRequest {
@JsonKey(name: "delay_ms", includeIfNull: false) @JsonKey(name: "delay_ms", includeIfNull: false)
@MSDuration() @MSDuration()
@Default(null)
Duration? delay, Duration? delay,
}) = _SetStateRequest; }) with _$SetStateRequest {
factory SetStateRequest.fromJson(Map<String, Object?> json) => factory SetStateRequest.fromJson(Map<String, Object?> json) =>
_$SetStateRequestFromJson(json); _$SetStateRequestFromJson(json);
} }

View file

@ -1,24 +1,23 @@
import "package:freezed_annotation/freezed_annotation.dart"; import "package:freezed_annotation/freezed_annotation.dart";
part "upload_media.freezed.dart"; part "upload_media.freezed.dart";
part "upload_media.g.dart"; part "upload_media.g.dart";
@freezed @freezed
abstract class UploadMediaRequest with _$UploadMediaRequest { sealed class const UploadMediaRequest({
const factory UploadMediaRequest({
required String path, required String path,
required bool encrypt, required bool encrypt,
String? filename, String? filename,
@Default(false) @JsonKey(name: "voice_message") bool isVoiceMessage, @JsonKey(name: "voice_message") bool isVoiceMessage = false,
@Default(false) bool forceFile, bool forceFile = false,
// Below params only work if encodeTo is set // Below params only work if encodeTo is set
String? encodeTo, String? encodeTo,
int? resizeWidth, int? resizeWidth,
int? resizeHeight, int? resizeHeight,
int? resizePercent, int? resizePercent,
@Default(80) int quality, int quality = 80,
}) = _UploadMediaRequest; }) with _$UploadMediaRequest {
factory UploadMediaRequest.fromJson(Map<String, Object?> json) => factory UploadMediaRequest.fromJson(Map<String, Object?> json) =>
_$UploadMediaRequestFromJson(json); _$UploadMediaRequestFromJson(json);
} }

View file

@ -3,11 +3,37 @@ import "package:freezed_annotation/freezed_annotation.dart";
import "package:nexus/models/event.dart"; import "package:nexus/models/event.dart";
import "package:nexus/models/read_receipt.dart"; import "package:nexus/models/read_receipt.dart";
import "package:nexus/models/room_metadata.dart"; import "package:nexus/models/room_metadata.dart";
part "room.freezed.dart"; part "room.freezed.dart";
part "room.g.dart"; part "room.g.dart";
@freezed @freezed
abstract class Room with _$Room { sealed class const Room({
@JsonKey(name: "meta") RoomMetadata? metadata,
@JsonKey(fromJson: Room.timelineTupleJsonToIMap)
IMap<int, int?> timeline = const IMap.empty(),
ISet<int> sticky = const ISet.empty(),
@JsonKey(fromJson: Room.eventsJsonToIMap)
IMap<int, Event> events = const IMap.empty(),
bool reset = false,
bool hasFetchedState = false,
bool hasFetchedMembers = false,
IMap<String, IMap<String, int>> state = const IMap.empty(),
IMap<String, IList<ReadReceipt>> receipts = const IMap.empty(),
bool dismissNotifications = false,
bool hasMore = true,
// IMap<String, AccountData> accountData,
// IList<Notification> notifications,
}) with _$Room {
/// [timeline] is an IMap of timelineRowId to eventRowId
/// [events] is an IMap of eventRowId to event
/// [sticky] is an ISet of eventRowId
static IMap<int, int?> timelineTupleJsonToIMap(List<dynamic> json) => static IMap<int, int?> timelineTupleJsonToIMap(List<dynamic> json) =>
IMap.fromEntries( IMap.fromEntries(
json.map( json.map(
@ -26,32 +52,5 @@ abstract class Room with _$Room {
}), }),
); );
/// [timeline] is an IMap of timelineRowId to eventRowId
/// [events] is an IMap of eventRowId to event
/// [sticky] is an ISet of eventRowId
const factory Room({
@JsonKey(name: "meta") RoomMetadata? metadata,
@Default(IMap.empty())
@JsonKey(fromJson: Room.timelineTupleJsonToIMap)
IMap<int, int?> timeline,
@Default(ISet.empty()) ISet<int> sticky,
@Default(IMap.empty())
@JsonKey(fromJson: Room.eventsJsonToIMap)
IMap<int, Event> events,
@Default(false) bool reset,
@Default(false) bool hasFetchedState,
@Default(false) bool hasFetchedMembers,
@Default(IMap.empty()) IMap<String, IMap<String, int>> state,
@Default(IMap.empty()) IMap<String, IList<ReadReceipt>> receipts,
@Default(false) bool dismissNotifications,
@Default(true) bool hasMore,
// required IMap<String, AccountData> accountData,
// required IList<Notification> notifications,
}) = _Room;
factory Room.fromJson(Map<String, Object?> json) => _$RoomFromJson(json); factory Room.fromJson(Map<String, Object?> json) => _$RoomFromJson(json);
} }

View file

@ -1,16 +1,16 @@
import "package:freezed_annotation/freezed_annotation.dart"; import "package:freezed_annotation/freezed_annotation.dart";
import "package:nexus/models/epoch_date_time_converter.dart"; import "package:nexus/models/epoch_date_time_converter.dart";
import "package:nexus/models/lazy_load_summary.dart"; import "package:nexus/models/lazy_load_summary.dart";
part "room_metadata.freezed.dart"; part "room_metadata.freezed.dart";
part "room_metadata.g.dart"; part "room_metadata.g.dart";
@freezed @freezed
abstract class RoomMetadata with _$RoomMetadata { sealed class const RoomMetadata({
const factory RoomMetadata({
@JsonKey(name: "room_id") required String id, @JsonKey(name: "room_id") required String id,
// required CreateEventContent creationContent, // CreateEventContent creationContent,
// required TombstoneEventContent tombstoneEventContent, // TombstoneEventContent tombstoneEventContent,
String? name, String? name,
Uri? avatar, Uri? avatar,
String? dmUserId, String? dmUserId,
@ -23,8 +23,7 @@ abstract class RoomMetadata with _$RoomMetadata {
required int unreadHighlights, required int unreadHighlights,
required int unreadNotifications, required int unreadNotifications,
required int unreadMessages, required int unreadMessages,
}) = _RoomMetadata; }) with _$RoomMetadata {
factory RoomMetadata.fromJson(Map<String, Object?> json) => factory RoomMetadata.fromJson(Map<String, Object?> json) =>
_$RoomMetadataFromJson(json); _$RoomMetadataFromJson(json);
} }

View file

@ -1,12 +1,12 @@
import "package:freezed_annotation/freezed_annotation.dart"; import "package:freezed_annotation/freezed_annotation.dart";
import "package:nexus/models/content/create.dart"; import "package:nexus/models/content/create.dart";
import "package:nexus/models/join_rule.dart"; import "package:nexus/models/join_rule.dart";
part "room_summary.freezed.dart"; part "room_summary.freezed.dart";
part "room_summary.g.dart"; part "room_summary.g.dart";
@freezed @freezed
abstract class RoomSummary with _$RoomSummary { sealed class const RoomSummary({
const factory RoomSummary({
required String roomId, required String roomId,
@JsonKey(name: "num_joined_members") required int joinedMembers, @JsonKey(name: "num_joined_members") required int joinedMembers,
JoinRule? joinRule, JoinRule? joinRule,
@ -16,8 +16,7 @@ abstract class RoomSummary with _$RoomSummary {
String? topic, String? topic,
String? roomVersion, String? roomVersion,
@JsonKey(unknownEnumValue: RoomType.room) RoomType? roomType, @JsonKey(unknownEnumValue: RoomType.room) RoomType? roomType,
}) = _RoomSummary; }) with _$RoomSummary {
factory RoomSummary.fromJson(Map<String, Object?> json) => factory RoomSummary.fromJson(Map<String, Object?> json) =>
_$RoomSummaryFromJson(json); _$RoomSummaryFromJson(json);
} }

View file

@ -1,16 +1,13 @@
import "package:flutter/material.dart"; import "package:flutter/material.dart";
class Setting { class Setting({
final String title; required final String title,
final String description; required final String description,
final IconData icon; required final IconData icon,
final Widget Function(String title, String description, IconData icon) required final Widget Function(
builder; String title,
String description,
Setting({ IconData icon,
required this.title, )
required this.description, builder,
required this.builder,
required this.icon,
}); });
}

View file

@ -1,16 +1,15 @@
import "package:flutter/material.dart"; import "package:flutter/material.dart";
import "package:freezed_annotation/freezed_annotation.dart"; import "package:freezed_annotation/freezed_annotation.dart";
part "settings.freezed.dart"; part "settings.freezed.dart";
part "settings.g.dart"; part "settings.g.dart";
@freezed @freezed
abstract class Settings with _$Settings { sealed class const Settings({
const factory Settings({ ThemeMode theme = ThemeMode.system,
@Default(ThemeMode.system) ThemeMode theme, bool useDynamicTheming = true,
@Default(true) bool useDynamicTheming, bool linuxMobileMode = false,
@Default(false) bool linuxMobileMode, }) with _$Settings {
}) = _Settings;
factory Settings.fromJson(Map<String, Object?> json) => factory Settings.fromJson(Map<String, Object?> json) =>
_$SettingsFromJson(json); _$SettingsFromJson(json);
} }

View file

@ -2,13 +2,12 @@ import "package:fast_immutable_collections/fast_immutable_collections.dart";
import "package:flutter/material.dart"; import "package:flutter/material.dart";
import "package:freezed_annotation/freezed_annotation.dart"; import "package:freezed_annotation/freezed_annotation.dart";
import "package:nexus/models/setting.dart"; import "package:nexus/models/setting.dart";
part "settings_category.freezed.dart"; part "settings_category.freezed.dart";
@freezed @freezed
abstract class SettingsCategory with _$SettingsCategory { sealed class const SettingsCategory({
const factory SettingsCategory({
required String title, required String title,
required IconData icon, required IconData icon,
required IList<Setting> settings, required IList<Setting> settings,
}) = _SettingsCategory; }) with _$SettingsCategory;
}

View file

@ -3,16 +3,15 @@ import "package:flutter/widgets.dart";
import "package:freezed_annotation/freezed_annotation.dart"; import "package:freezed_annotation/freezed_annotation.dart";
import "package:nexus/models/room.dart"; import "package:nexus/models/room.dart";
import "package:nexus/models/subspace.dart"; import "package:nexus/models/subspace.dart";
part "space.freezed.dart"; part "space.freezed.dart";
@freezed @freezed
abstract class Space with _$Space { sealed class const Space({
const factory Space({
required String id, required String id,
required String title, required String title,
IconData? icon, IconData? icon,
Room? room, Room? room,
required IList<Room> children, required IList<Room> children,
required IList<Subspace> subSpaces, required IList<Subspace> subSpaces,
}) = _Space; }) with _$Space;
}

View file

@ -1,14 +1,11 @@
import "package:freezed_annotation/freezed_annotation.dart"; import "package:freezed_annotation/freezed_annotation.dart";
part "space_edge.freezed.dart"; part "space_edge.freezed.dart";
part "space_edge.g.dart"; part "space_edge.g.dart";
@freezed @freezed
abstract class SpaceEdge with _$SpaceEdge { sealed class const SpaceEdge({required String childId, bool suggested = false})
const factory SpaceEdge({ with _$SpaceEdge {
required String childId,
@Default(false) bool suggested,
}) = _SpaceEdge;
factory SpaceEdge.fromJson(Map<String, Object?> json) => factory SpaceEdge.fromJson(Map<String, Object?> json) =>
_$SpaceEdgeFromJson(json); _$SpaceEdgeFromJson(json);
} }

View file

@ -1,25 +1,22 @@
import "package:fast_immutable_collections/fast_immutable_collections.dart"; import "package:fast_immutable_collections/fast_immutable_collections.dart";
import "package:freezed_annotation/freezed_annotation.dart"; import "package:freezed_annotation/freezed_annotation.dart";
part "spec_versions_response.freezed.dart"; part "spec_versions_response.freezed.dart";
part "spec_versions_response.g.dart"; part "spec_versions_response.g.dart";
@freezed @freezed
abstract class SpecVersionsResponse with _$SpecVersionsResponse { sealed class const SpecVersionsResponse({
const factory SpecVersionsResponse({
required IList<String> versions, required IList<String> versions,
required UnstableFeatures unstableFeatures, required UnstableFeatures unstableFeatures,
}) = _SpecVersionsResponse; }) with _$SpecVersionsResponse {
factory SpecVersionsResponse.fromJson(Map<String, Object?> json) => factory SpecVersionsResponse.fromJson(Map<String, Object?> json) =>
_$SpecVersionsResponseFromJson(json); _$SpecVersionsResponseFromJson(json);
} }
@freezed @freezed
abstract class UnstableFeatures with _$UnstableFeatures { sealed class const UnstableFeatures({
const factory UnstableFeatures({ @JsonKey(name: "uk.timedout.msc4494") bool msc4494 = false,
@JsonKey(name: "uk.timedout.msc4494") @Default(false) bool msc4494, }) with _$UnstableFeatures {
}) = _UnstableFeatures;
factory UnstableFeatures.fromJson(Map<String, Object?> json) => factory UnstableFeatures.fromJson(Map<String, Object?> json) =>
_$UnstableFeaturesFromJson(json); _$UnstableFeaturesFromJson(json);
} }

View file

@ -1,10 +1,9 @@
import "package:fast_immutable_collections/fast_immutable_collections.dart"; import "package:fast_immutable_collections/fast_immutable_collections.dart";
import "package:freezed_annotation/freezed_annotation.dart"; import "package:freezed_annotation/freezed_annotation.dart";
import "package:nexus/models/room.dart"; import "package:nexus/models/room.dart";
part "subspace.freezed.dart"; part "subspace.freezed.dart";
@freezed @freezed
abstract class Subspace with _$Subspace { sealed class const Subspace({required Room room, required IList<Room> children})
const factory Subspace({required Room room, required IList<Room> children}) = with _$Subspace;
_Subspace;
}

View file

@ -2,21 +2,19 @@ import "package:fast_immutable_collections/fast_immutable_collections.dart";
import "package:freezed_annotation/freezed_annotation.dart"; import "package:freezed_annotation/freezed_annotation.dart";
import "package:nexus/models/room.dart"; import "package:nexus/models/room.dart";
import "package:nexus/models/space_edge.dart"; import "package:nexus/models/space_edge.dart";
part "sync_data.freezed.dart"; part "sync_data.freezed.dart";
part "sync_data.g.dart"; part "sync_data.g.dart";
@freezed @freezed
abstract class SyncData with _$SyncData { sealed class const SyncData({
const factory SyncData({ bool clearState = false,
@Default(false) bool clearState, IMap<String, IMap<String, dynamic>> accountData = const IMap.empty(),
@Default(IMap.empty()) IMap<String, IMap<String, dynamic>> accountData, IMap<String, Room> rooms = const IMap.empty(),
@Default(IMap.empty()) IMap<String, Room> rooms, ISet<String> leftRooms = const ISet.empty(),
@Default(ISet.empty()) ISet<String> leftRooms,
// required IList<InvitedRoom> invitedRooms,
IMap<String, IList<SpaceEdge>>? spaceEdges, IMap<String, IList<SpaceEdge>>? spaceEdges,
IList<String>? topLevelSpaces, IList<String>? topLevelSpaces,
}) = _SyncData; }) with _$SyncData {
factory SyncData.fromJson(Map<String, Object?> json) => factory SyncData.fromJson(Map<String, Object?> json) =>
_$SyncDataFromJson(json); _$SyncDataFromJson(json);
} }

View file

@ -1,15 +1,14 @@
import "package:freezed_annotation/freezed_annotation.dart"; import "package:freezed_annotation/freezed_annotation.dart";
part "sync_status.freezed.dart"; part "sync_status.freezed.dart";
part "sync_status.g.dart"; part "sync_status.g.dart";
@freezed @freezed
abstract class SyncStatus with _$SyncStatus { sealed class const SyncStatus({
const factory SyncStatus({
required SyncStatusType type, required SyncStatusType type,
String? error, required String? error,
required int errorCount, required int errorCount,
}) = _SyncStatus; }) with _$SyncStatus {
factory SyncStatus.fromJson(Map<String, Object?> json) => factory SyncStatus.fromJson(Map<String, Object?> json) =>
_$SyncStatusFromJson(json); _$SyncStatusFromJson(json);
} }

View file

@ -8,9 +8,7 @@ import "package:nexus/widgets/sidebar.dart";
import "package:nexus/widgets/room_chat.dart"; import "package:nexus/widgets/room_chat.dart";
import "package:nexus/widgets/loading.dart"; import "package:nexus/widgets/loading.dart";
class ChatPage extends ConsumerWidget { class const ChatPage({super.key}) extends ConsumerWidget {
const ChatPage({super.key});
@override @override
Widget build(BuildContext context, WidgetRef ref) => LayoutBuilder( Widget build(BuildContext context, WidgetRef ref) => LayoutBuilder(
builder: (context, constraints) { builder: (context, constraints) {

View file

@ -13,9 +13,7 @@ import "package:nexus/pages/settings.dart";
import "package:nexus/widgets/appbar.dart"; import "package:nexus/widgets/appbar.dart";
import "package:nexus/widgets/divider_text.dart"; import "package:nexus/widgets/divider_text.dart";
class SelectServerPage extends HookConsumerWidget { class const SelectServerPage({super.key}) extends HookConsumerWidget {
const SelectServerPage({super.key});
@override @override
Widget build(BuildContext context, WidgetRef ref) { Widget build(BuildContext context, WidgetRef ref) {
final theme = Theme.of(context); final theme = Theme.of(context);
@ -181,23 +179,20 @@ class SelectServerPage extends HookConsumerWidget {
...(<Homeserver>[ ...(<Homeserver>[
.new( .new(
name: "Matrix.org", name: "Matrix.org",
description: description: "The Matrix.org Foundation offers the matrix.org homeserver as an easy entry point for anyone wanting to try out Matrix.",
"The Matrix.org Foundation offers the matrix.org homeserver as an easy entry point for anyone wanting to try out Matrix.",
url: .https("matrix.org"), url: .https("matrix.org"),
iconUrl: iconUrl:
"https://raw.githubusercontent.com/element-hq/logos/refs/heads/master/matrix/matrix-favicon${Theme.brightnessOf(context) == Brightness.dark ? "-white" : ""}.png", "https://raw.githubusercontent.com/element-hq/logos/refs/heads/master/matrix/matrix-favicon${Theme.brightnessOf(context) == Brightness.dark ? "-white" : ""}.png",
), ),
.new( .new(
name: "Federated Nexus", name: "Federated Nexus",
description: 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.",
"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: .https("federated.nexus"), url: .https("federated.nexus"),
iconUrl: "https://federated.nexus/images/icon.png", iconUrl: "https://federated.nexus/images/icon.png",
), ),
.new( .new(
name: "Unredacted", name: "Unredacted",
description: 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.",
"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: .https("unredacted.org", "services/si/matrix"), url: .https("unredacted.org", "services/si/matrix"),
iconUrl: "https://unredacted.org/favicon.ico", iconUrl: "https://unredacted.org/favicon.ico",
), ),

View file

@ -13,9 +13,7 @@ import "package:nexus/widgets/divider_text.dart";
import "package:nexus/widgets/highlight_wrapper.dart"; import "package:nexus/widgets/highlight_wrapper.dart";
import "package:super_sliver_list/super_sliver_list.dart"; import "package:super_sliver_list/super_sliver_list.dart";
class SettingsPage extends ConsumerWidget { class const SettingsPage({super.key}) extends ConsumerWidget {
const SettingsPage({super.key});
@override @override
Widget build(BuildContext context, WidgetRef ref) => LayoutBuilder( Widget build(BuildContext context, WidgetRef ref) => LayoutBuilder(
builder: (_, constraints) => HookBuilder( builder: (_, constraints) => HookBuilder(
@ -142,12 +140,12 @@ class SettingsPage extends ConsumerWidget {
vertical: 8, vertical: 8,
), ),
margin: .symmetric(horizontal: 12), margin: .symmetric(horizontal: 12),
color: Theme.of( color: Theme.of(context)
context, .colorScheme
).colorScheme.primaryContainer, .primaryContainer,
itemCount: categories.length, itemCount: categories.length,
onTap: (index) => onTap: (index) => Navigator.of(context)
Navigator.of(context).push( .push(
MaterialPageRoute( MaterialPageRoute(
builder: (context) => builder: (context) =>
SettingsCategoryPage( SettingsCategoryPage(

View file

@ -9,11 +9,11 @@ import "package:nexus/helpers/extensions/better_when.dart";
import "package:nexus/widgets/highlight_wrapper.dart"; import "package:nexus/widgets/highlight_wrapper.dart";
import "package:super_sliver_list/super_sliver_list.dart"; import "package:super_sliver_list/super_sliver_list.dart";
class SettingsCategoryPage extends HookConsumerWidget { class const SettingsCategoryPage(
final int index; final int index, {
final int? initialHighlight; final int? initialHighlight,
const SettingsCategoryPage(this.index, {this.initialHighlight, super.key}); super.key,
}) extends HookConsumerWidget {
@override @override
Widget build(BuildContext context, WidgetRef ref) { Widget build(BuildContext context, WidgetRef ref) {
final highlight = useState<int?>(initialHighlight); final highlight = useState<int?>(initialHighlight);

View file

@ -6,9 +6,7 @@ import "package:nexus/pages/settings.dart";
import "package:nexus/widgets/appbar.dart"; import "package:nexus/widgets/appbar.dart";
import "package:nexus/helpers/required_validator_helper.dart"; import "package:nexus/helpers/required_validator_helper.dart";
class VerifyPage extends HookConsumerWidget { class const VerifyPage({super.key}) extends HookConsumerWidget {
const VerifyPage({super.key});
@override @override
Widget build(BuildContext context, WidgetRef ref) { Widget build(BuildContext context, WidgetRef ref) {
final passphraseController = useTextEditingController(); final passphraseController = useTextEditingController();

View file

@ -1,28 +1,20 @@
import "dart:io"; import "dart:io";
import "package:fast_immutable_collections/fast_immutable_collections.dart"; import "package:fast_immutable_collections/fast_immutable_collections.dart";
import "package:flutter/material.dart"; import "package:flutter/material.dart";
import "package:hooks_riverpod/hooks_riverpod.dart"; import "package:hooks_riverpod/hooks_riverpod.dart";
import "package:nexus/controllers/settings.dart"; import "package:nexus/controllers/settings.dart";
import "package:window_manager/window_manager.dart"; import "package:window_manager/window_manager.dart";
class Appbar extends ConsumerWidget implements PreferredSizeWidget { final class const Appbar({
final Widget? leading; final Widget? leading,
final Widget? title; final Widget? title,
final Color? backgroundColor; final Color? backgroundColor,
final double? scrolledUnderElevation; final double? scrolledUnderElevation,
final IList<Widget> actions; final IList<Widget> actions = const .empty(),
final VoidCallback? onTap; final VoidCallback? onTap,
const Appbar({
super.key, super.key,
this.title, }) extends ConsumerWidget implements PreferredSizeWidget {
this.onTap,
this.backgroundColor,
this.scrolledUnderElevation,
this.leading,
this.actions = const .empty(),
});
@override @override
Size get preferredSize => const .fromHeight(kToolbarHeight); Size get preferredSize => const .fromHeight(kToolbarHeight);

View file

@ -3,19 +3,13 @@ import "package:flutter/material.dart";
import "package:flutter_riverpod/flutter_riverpod.dart"; import "package:flutter_riverpod/flutter_riverpod.dart";
import "package:nexus/helpers/mxc_image.dart"; import "package:nexus/helpers/mxc_image.dart";
class AvatarOrHash extends ConsumerWidget { final class const AvatarOrHash(
final Uri? avatar; final Uri? avatar,
final String title; final String title, {
final Widget? fallback; final Widget? fallback,
final double height; final double height = 24,
const AvatarOrHash(
this.avatar,
this.title, {
this.fallback,
this.height = 24,
super.key, super.key,
}); }) extends ConsumerWidget {
@override @override
Widget build(BuildContext context, WidgetRef ref) { Widget build(BuildContext context, WidgetRef ref) {
final box = ColoredBox( final box = ColoredBox(

View file

@ -1,4 +1,5 @@
import "dart:io"; import "dart:io";
import "package:fast_immutable_collections/fast_immutable_collections.dart"; import "package:fast_immutable_collections/fast_immutable_collections.dart";
import "package:file_selector/file_selector.dart"; import "package:file_selector/file_selector.dart";
import "package:flutter/material.dart"; import "package:flutter/material.dart";
@ -17,28 +18,20 @@ import "package:nexus/widgets/composer/relation_preview.dart";
import "package:nexus/widgets/emoji_picker_button.dart"; import "package:nexus/widgets/emoji_picker_button.dart";
import "package:nexus/main.dart"; import "package:nexus/main.dart";
class Composer extends HookConsumerWidget { class const Composer(
final String roomId; final String roomId, {
final Event? relatedEvent; required final Event? relatedEvent,
final RelationType relationType; required final RelationType relationType,
final VoidCallback onDismiss; required final VoidCallback onDismiss,
final FocusNode? node; required final Future<void> Function(
final Future<void> Function(
String text, { String text, {
required bool shouldMention, required bool shouldMention,
required IList<Tag> tags, required IList<Tag> tags,
}) })
onSend; onSend,
const Composer( final FocusNode? node,
this.roomId, {
required this.relatedEvent,
required this.relationType,
required this.onDismiss,
required this.onSend,
this.node,
super.key, super.key,
}); }) extends HookConsumerWidget {
@override @override
Widget build(BuildContext context, WidgetRef ref) { Widget build(BuildContext context, WidgetRef ref) {
final theme = Theme.of(context); final theme = Theme.of(context);
@ -143,9 +136,8 @@ class Composer extends HookConsumerWidget {
), ),
onTap: () async => ref onTap: () async => ref
.watch( .watch(
AttachmentController.provider( AttachmentController.provider(roomId)
roomId, .notifier,
).notifier,
) )
.add( .add(
(await ref (await ref
@ -163,9 +155,8 @@ class Composer extends HookConsumerWidget {
), ),
onTap: () async => ref onTap: () async => ref
.watch( .watch(
AttachmentController.provider( AttachmentController.provider(roomId)
roomId, .notifier,
).notifier,
) )
.add( .add(
(await ref (await ref
@ -179,9 +170,8 @@ class Composer extends HookConsumerWidget {
PopupMenuItem( PopupMenuItem(
onTap: () async => ref onTap: () async => ref
.watch( .watch(
AttachmentController.provider( AttachmentController.provider(roomId)
roomId, .notifier,
).notifier,
) )
.add((await openFile())!) .add((await openFile())!)
.onError(showError), .onError(showError),

View file

@ -9,19 +9,14 @@ import "package:nexus/models/content/membership.dart";
import "package:nexus/widgets/avatar_or_hash.dart"; import "package:nexus/widgets/avatar_or_hash.dart";
import "package:nexus/widgets/loading.dart"; import "package:nexus/widgets/loading.dart";
class MentionOverlay extends ConsumerWidget { class const MentionOverlay(
final String? triggerCharacter; final String roomId, {
final String query; required final String query,
final String roomId; required final void Function({required String id, required String name})
final void Function({required String id, required String name}) addTag; addTag,
const MentionOverlay( required final String? triggerCharacter,
this.roomId, {
required this.query,
required this.addTag,
required this.triggerCharacter,
super.key, super.key,
}); }) extends ConsumerWidget {
@override @override
Widget build(BuildContext context, WidgetRef ref) { Widget build(BuildContext context, WidgetRef ref) {
final rooms = ref.watch(RoomsController.provider); final rooms = ref.watch(RoomsController.provider);

View file

@ -4,22 +4,14 @@ import "package:nexus/models/event.dart";
import "package:nexus/models/relation_type.dart"; import "package:nexus/models/relation_type.dart";
import "package:nexus/widgets/event_preview.dart"; import "package:nexus/widgets/event_preview.dart";
class RelationPreview extends ConsumerWidget { class const RelationPreview(
final Event? relatedEvent; final Event? relatedEvent, {
final RelationType relationType; required final RelationType relationType,
final VoidCallback onDismiss; required final VoidCallback onDismiss,
final bool shouldMention; required final bool shouldMention,
final VoidCallback toggleShouldMention; required final VoidCallback toggleShouldMention,
const RelationPreview(
this.relatedEvent, {
required this.relationType,
required this.onDismiss,
required this.shouldMention,
required this.toggleShouldMention,
super.key, super.key,
}); }) extends ConsumerWidget {
@override @override
Widget build(BuildContext context, WidgetRef ref) { Widget build(BuildContext context, WidgetRef ref) {
if (relatedEvent == null) return SizedBox.shrink(); if (relatedEvent == null) return SizedBox.shrink();

View file

@ -1,11 +1,8 @@
import "package:flutter/material.dart"; import "package:flutter/material.dart";
import "package:nexus/widgets/divider_widget.dart"; import "package:nexus/widgets/divider_widget.dart";
class DividerText extends StatelessWidget { final class const DividerText(final String text, {super.key})
final String text; extends StatelessWidget {
const DividerText(this.text, {super.key});
@override @override
Widget build(BuildContext context) => Widget build(BuildContext context) =>
DividerWidget(Text(text, style: Theme.of(context).textTheme.labelLarge)); DividerWidget(Text(text, style: Theme.of(context).textTheme.labelLarge));

View file

@ -1,9 +1,7 @@
import "package:flutter/material.dart"; import "package:flutter/material.dart";
class DividerWidget extends StatelessWidget { final class const DividerWidget(final Widget widget, {super.key})
final Widget widget; extends StatelessWidget {
const DividerWidget(this.widget, {super.key});
@override @override
Widget build(BuildContext context) => LayoutBuilder( Widget build(BuildContext context) => LayoutBuilder(
builder: (_, constraints) => Row( builder: (_, constraints) => Row(

Some files were not shown because too many files have changed in this diff Show more