remove selected room/space controllers
This commit is contained in:
parent
0653961f9c
commit
df5040e06c
19 changed files with 153 additions and 158 deletions
|
|
@ -12,14 +12,14 @@ class KeyController extends Notifier<String?> {
|
||||||
String? build() =>
|
String? build() =>
|
||||||
ref.watch(SharedPrefsController.provider).requireValue.getString(key);
|
ref.watch(SharedPrefsController.provider).requireValue.getString(key);
|
||||||
|
|
||||||
Future<void> set(String? id) async {
|
Future<void> set(String? value) async {
|
||||||
final prefs = ref.watch(SharedPrefsController.provider).requireValue;
|
final prefs = ref.watch(SharedPrefsController.provider).requireValue;
|
||||||
state = id;
|
state = value;
|
||||||
|
|
||||||
if (id == null) {
|
if (value == null) {
|
||||||
prefs.remove(key);
|
prefs.remove(key);
|
||||||
} else {
|
} else {
|
||||||
prefs.setString(key, id);
|
prefs.setString(key, value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,21 +1,21 @@
|
||||||
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";
|
||||||
import "package:nexus/controllers/members_controller.dart";
|
import "package:nexus/controllers/members_controller.dart";
|
||||||
|
import "package:nexus/models/configs/members_by_status_config.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";
|
||||||
import "package:nexus/models/membership_status.dart";
|
|
||||||
|
|
||||||
class MembersByTypeController extends AsyncNotifier<IList<Event>> {
|
class MembersByStatusController extends AsyncNotifier<IList<Event>> {
|
||||||
final MembershipStatus filterStatus;
|
final MembersByStatusConfig config;
|
||||||
MembersByTypeController(this.filterStatus);
|
MembersByStatusController(this.config);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<IList<Event>> build() => ref.watch(
|
Future<IList<Event>> build() => ref.watch(
|
||||||
MembersController.provider.selectAsync(
|
MembersController.provider(config.roomId).selectAsync(
|
||||||
(members) => members
|
(members) => members
|
||||||
.where(
|
.where(
|
||||||
(membership) => switch (membership.content) {
|
(membership) => switch (membership.content) {
|
||||||
MembershipContent(:final status) => filterStatus == status,
|
MembershipContent(:final status) => config.status == status,
|
||||||
_ => false,
|
_ => false,
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|
@ -25,8 +25,8 @@ class MembersByTypeController extends AsyncNotifier<IList<Event>> {
|
||||||
|
|
||||||
static final provider =
|
static final provider =
|
||||||
AsyncNotifierProvider.family<
|
AsyncNotifierProvider.family<
|
||||||
MembersByTypeController,
|
MembersByStatusController,
|
||||||
IList<Event>,
|
IList<Event>,
|
||||||
MembershipStatus
|
MembersByStatusConfig
|
||||||
>(MembersByTypeController.new);
|
>(MembersByStatusController.new);
|
||||||
}
|
}
|
||||||
|
|
@ -3,48 +3,39 @@ import "package:fast_immutable_collections/fast_immutable_collections.dart";
|
||||||
import "package:flutter_riverpod/flutter_riverpod.dart";
|
import "package:flutter_riverpod/flutter_riverpod.dart";
|
||||||
import "package:nexus/controllers/client_controller.dart";
|
import "package:nexus/controllers/client_controller.dart";
|
||||||
import "package:nexus/controllers/rooms_controller.dart";
|
import "package:nexus/controllers/rooms_controller.dart";
|
||||||
import "package:nexus/controllers/selected_room_controller.dart";
|
|
||||||
import "package:nexus/models/content/content.dart";
|
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_request.dart";
|
import "package:nexus/models/requests/get_room_state_request.dart";
|
||||||
|
|
||||||
class MembersController extends AsyncNotifier<IList<Event>> {
|
class MembersController extends AsyncNotifier<IList<Event>> {
|
||||||
|
final String roomId;
|
||||||
|
MembersController(this.roomId);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<IList<Event>> build() async {
|
Future<IList<Event>> build() async {
|
||||||
final data = ref.watch(
|
final room = ref.watch(
|
||||||
SelectedRoomController.provider.select(
|
RoomsController.provider.select((value) => value[roomId]),
|
||||||
(value) => value?.metadata == null
|
|
||||||
? null
|
|
||||||
: (
|
|
||||||
value!.metadata!.id,
|
|
||||||
value.metadata!.hasMemberList,
|
|
||||||
value.hasFetchedMembers,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
);
|
);
|
||||||
if (data == null) return const IList.empty();
|
|
||||||
|
|
||||||
if (!data.$3) {
|
if (room == null) return const IList.empty();
|
||||||
|
|
||||||
|
if (!room.hasFetchedMembers) {
|
||||||
final fetchedState = await ref
|
final fetchedState = await ref
|
||||||
.watch(ClientController.provider.notifier)
|
.watch(ClientController.provider.notifier)
|
||||||
.getRoomState(
|
.getRoomState(
|
||||||
GetRoomStateRequest(
|
GetRoomStateRequest(
|
||||||
roomId: data.$1,
|
roomId: roomId,
|
||||||
fetchMembers: data.$2 == false,
|
fetchMembers: room.metadata?.hasMemberList ?? true,
|
||||||
includeMembers: true,
|
includeMembers: true,
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
||||||
ref
|
ref
|
||||||
.read(RoomsController.provider.notifier)
|
.read(RoomsController.provider.notifier)
|
||||||
.addState(data.$1, fetchedState, isMembers: true);
|
.addState(roomId, fetchedState, isMembers: true);
|
||||||
}
|
}
|
||||||
|
|
||||||
final room = ref.watch(
|
return room.state[EventType.membership.type]?.values
|
||||||
RoomsController.provider.select((value) => value[data.$1]),
|
|
||||||
);
|
|
||||||
|
|
||||||
return room?.state[EventType.membership.type]?.values
|
|
||||||
.map(
|
.map(
|
||||||
(rowId) =>
|
(rowId) =>
|
||||||
room.events.firstWhereOrNull((event) => event.rowId == rowId),
|
room.events.firstWhereOrNull((event) => event.rowId == rowId),
|
||||||
|
|
@ -54,8 +45,6 @@ class MembersController extends AsyncNotifier<IList<Event>> {
|
||||||
const IList.empty();
|
const IList.empty();
|
||||||
}
|
}
|
||||||
|
|
||||||
static final provider =
|
static final provider = AsyncNotifierProvider.autoDispose
|
||||||
AsyncNotifierProvider.autoDispose<MembersController, IList<Event>>(
|
.family<MembersController, IList<Event>, String>(MembersController.new);
|
||||||
MembersController.new,
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
import "package:collection/collection.dart";
|
import "package:collection/collection.dart";
|
||||||
import "package:flutter_riverpod/flutter_riverpod.dart";
|
import "package:flutter_riverpod/flutter_riverpod.dart";
|
||||||
import "package:nexus/controllers/client_state_controller.dart";
|
import "package:nexus/controllers/client_state_controller.dart";
|
||||||
import "package:nexus/controllers/selected_room_controller.dart";
|
import "package:nexus/controllers/rooms_controller.dart";
|
||||||
import "package:nexus/models/configs/power_level_config.dart";
|
import "package:nexus/models/configs/power_level_config.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";
|
||||||
|
|
@ -20,7 +20,10 @@ class PowerLevelController extends Notifier<bool> {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
final room = ref.watch(SelectedRoomController.provider);
|
final room = ref.watch(
|
||||||
|
RoomsController.provider.select((value) => value[config.roomId]),
|
||||||
|
);
|
||||||
|
|
||||||
final event = room?.events.firstWhereOrNull(
|
final event = room?.events.firstWhereOrNull(
|
||||||
(event) => event.rowId == room.state[EventType.powerLevels.type]?[""],
|
(event) => event.rowId == room.state[EventType.powerLevels.type]?[""],
|
||||||
);
|
);
|
||||||
|
|
|
||||||
|
|
@ -12,6 +12,8 @@ class ProfileController extends AsyncNotifier<Profile> {
|
||||||
return client.getProfile(userId);
|
return client.getProfile(userId);
|
||||||
}
|
}
|
||||||
|
|
||||||
static final provider = AsyncNotifierProvider.autoDispose
|
static final provider =
|
||||||
.family<ProfileController, Profile, String>(ProfileController.new);
|
AsyncNotifierProvider.family<ProfileController, Profile, String>(
|
||||||
|
ProfileController.new,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,24 +0,0 @@
|
||||||
import "package:collection/collection.dart";
|
|
||||||
import "package:flutter_riverpod/flutter_riverpod.dart";
|
|
||||||
import "package:nexus/controllers/key_controller.dart";
|
|
||||||
import "package:nexus/controllers/selected_space_controller.dart";
|
|
||||||
import "package:nexus/models/room.dart";
|
|
||||||
|
|
||||||
class SelectedRoomController extends Notifier<Room?> {
|
|
||||||
@override
|
|
||||||
Room? build() {
|
|
||||||
final space = ref.watch(SelectedSpaceController.provider);
|
|
||||||
final selectedRoomId = ref.watch(
|
|
||||||
KeyController.provider(KeyController.roomKey),
|
|
||||||
);
|
|
||||||
|
|
||||||
return space.children.firstWhereOrNull(
|
|
||||||
(room) => room.metadata?.id == selectedRoomId,
|
|
||||||
) ??
|
|
||||||
space.children.firstOrNull;
|
|
||||||
}
|
|
||||||
|
|
||||||
static final provider = NotifierProvider<SelectedRoomController, Room?>(
|
|
||||||
SelectedRoomController.new,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
@ -1,22 +0,0 @@
|
||||||
import "package:collection/collection.dart";
|
|
||||||
import "package:flutter_riverpod/flutter_riverpod.dart";
|
|
||||||
import "package:nexus/controllers/key_controller.dart";
|
|
||||||
import "package:nexus/controllers/spaces_controller.dart";
|
|
||||||
import "package:nexus/models/space.dart";
|
|
||||||
|
|
||||||
class SelectedSpaceController extends Notifier<Space> {
|
|
||||||
@override
|
|
||||||
Space build() {
|
|
||||||
final spaces = ref.watch(SpacesController.provider);
|
|
||||||
final selectedSpaceId = ref.watch(
|
|
||||||
KeyController.provider(KeyController.spaceKey),
|
|
||||||
);
|
|
||||||
|
|
||||||
return spaces.firstWhereOrNull((space) => space.id == selectedSpaceId) ??
|
|
||||||
spaces.first;
|
|
||||||
}
|
|
||||||
|
|
||||||
static final provider = NotifierProvider<SelectedSpaceController, Space>(
|
|
||||||
SelectedSpaceController.new,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
@ -13,18 +13,6 @@ class UserController extends AsyncNotifier<MembershipContent> {
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<MembershipContent> build() async {
|
Future<MembershipContent> build() async {
|
||||||
final member = await ref.watch(
|
|
||||||
MembersController.provider.selectAsync(
|
|
||||||
(value) => value.firstWhereOrNull(
|
|
||||||
(membership) => membership.stateKey == userId,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
|
|
||||||
if (member?.content case final MembershipContent content) {
|
|
||||||
return content;
|
|
||||||
}
|
|
||||||
|
|
||||||
final profile = await ref.watch(ProfileController.provider(userId).future);
|
final profile = await ref.watch(ProfileController.provider(userId).future);
|
||||||
return MembershipContent(
|
return MembershipContent(
|
||||||
status: MembershipStatus.leave,
|
status: MembershipStatus.leave,
|
||||||
|
|
|
||||||
15
lib/models/configs/members_by_status_config.dart
Normal file
15
lib/models/configs/members_by_status_config.dart
Normal file
|
|
@ -0,0 +1,15 @@
|
||||||
|
import "package:freezed_annotation/freezed_annotation.dart";
|
||||||
|
import "package:nexus/models/membership_status.dart";
|
||||||
|
part "members_by_status_config.freezed.dart";
|
||||||
|
part "members_by_status_config.g.dart";
|
||||||
|
|
||||||
|
@freezed
|
||||||
|
abstract class MembersByStatusConfig with _$MembersByStatusConfig {
|
||||||
|
const factory MembersByStatusConfig({
|
||||||
|
required String roomId,
|
||||||
|
required MembershipStatus status,
|
||||||
|
}) = _MembersByStatusConfig;
|
||||||
|
|
||||||
|
factory MembersByStatusConfig.fromJson(Map<String, Object?> json) =>
|
||||||
|
_$MembersByStatusConfigFromJson(json);
|
||||||
|
}
|
||||||
|
|
@ -5,17 +5,24 @@ part "power_level_config.freezed.dart";
|
||||||
|
|
||||||
@freezed
|
@freezed
|
||||||
sealed class PowerLevelConfig with _$PowerLevelConfig {
|
sealed class PowerLevelConfig with _$PowerLevelConfig {
|
||||||
const factory PowerLevelConfig({required EventType eventType}) =
|
const factory PowerLevelConfig({
|
||||||
EventPowerLevelConfig;
|
required EventType eventType,
|
||||||
|
required String roomId,
|
||||||
|
}) = EventPowerLevelConfig;
|
||||||
|
|
||||||
const factory PowerLevelConfig.membershipAction({
|
const factory PowerLevelConfig.membershipAction({
|
||||||
required MembershipAction action,
|
required MembershipAction action,
|
||||||
required String targetUser,
|
required String targetUser,
|
||||||
|
required String roomId,
|
||||||
}) = MembershipActionPowerLevelConfig;
|
}) = MembershipActionPowerLevelConfig;
|
||||||
|
|
||||||
const factory PowerLevelConfig.state({required EventType eventType}) =
|
const factory PowerLevelConfig.state({
|
||||||
StatePowerLevelConfig;
|
required EventType eventType,
|
||||||
|
required String roomId,
|
||||||
|
}) = StatePowerLevelConfig;
|
||||||
|
|
||||||
const factory PowerLevelConfig.redaction({required String targetUser}) =
|
const factory PowerLevelConfig.redaction({
|
||||||
RedactionPowerLevelConfig;
|
required String targetUser,
|
||||||
|
required String roomId,
|
||||||
|
}) = RedactionPowerLevelConfig;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
import "package:flutter/material.dart";
|
import "package:flutter/material.dart";
|
||||||
import "package:flutter_riverpod/flutter_riverpod.dart";
|
import "package:hooks_riverpod/hooks_riverpod.dart";
|
||||||
import "package:nexus/controllers/init_complete_controller.dart";
|
import "package:nexus/controllers/init_complete_controller.dart";
|
||||||
|
import "package:nexus/controllers/key_controller.dart";
|
||||||
import "package:nexus/widgets/appbar.dart";
|
import "package:nexus/widgets/appbar.dart";
|
||||||
import "package:nexus/widgets/sidebar.dart";
|
import "package:nexus/widgets/sidebar.dart";
|
||||||
import "package:nexus/widgets/room_chat.dart";
|
import "package:nexus/widgets/room_chat.dart";
|
||||||
|
|
@ -15,22 +16,22 @@ class ChatPage extends ConsumerWidget {
|
||||||
final isDesktop = constraints.maxWidth > 650;
|
final isDesktop = constraints.maxWidth > 650;
|
||||||
final showMembersByDefault = constraints.maxWidth > 1000;
|
final showMembersByDefault = constraints.maxWidth > 1000;
|
||||||
final initComplete = ref.watch(InitCompleteController.provider);
|
final initComplete = ref.watch(InitCompleteController.provider);
|
||||||
|
final roomId = ref.watch(KeyController.provider(KeyController.roomKey));
|
||||||
|
|
||||||
return Scaffold(
|
return Scaffold(
|
||||||
appBar: initComplete ? null : Appbar(),
|
appBar: initComplete ? null : Appbar(),
|
||||||
body: initComplete
|
body: initComplete
|
||||||
? Builder(
|
? Row(
|
||||||
builder: (context) => Row(
|
|
||||||
children: [
|
children: [
|
||||||
if (isDesktop) Sidebar(isDesktop: isDesktop),
|
if (isDesktop) Sidebar(isDesktop: isDesktop),
|
||||||
Expanded(
|
Expanded(
|
||||||
child: RoomChat(
|
child: RoomChat(
|
||||||
|
roomId: roomId,
|
||||||
isDesktop: isDesktop,
|
isDesktop: isDesktop,
|
||||||
showMembersByDefault: showMembersByDefault,
|
showMembersByDefault: showMembersByDefault,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
|
||||||
)
|
)
|
||||||
: Center(
|
: Center(
|
||||||
child: Column(
|
child: Column(
|
||||||
|
|
|
||||||
|
|
@ -13,6 +13,7 @@ import "package:nexus/widgets/composer/relation_preview.dart";
|
||||||
import "package:nexus/widgets/emoji_picker_button.dart";
|
import "package:nexus/widgets/emoji_picker_button.dart";
|
||||||
|
|
||||||
class ChatBox extends HookConsumerWidget {
|
class ChatBox extends HookConsumerWidget {
|
||||||
|
final String roomId;
|
||||||
final Event? relatedEvent;
|
final Event? relatedEvent;
|
||||||
final RelationType relationType;
|
final RelationType relationType;
|
||||||
final VoidCallback onDismiss;
|
final VoidCallback onDismiss;
|
||||||
|
|
@ -23,7 +24,8 @@ class ChatBox extends HookConsumerWidget {
|
||||||
required IList<Tag> tags,
|
required IList<Tag> tags,
|
||||||
})
|
})
|
||||||
onSend;
|
onSend;
|
||||||
const ChatBox({
|
const ChatBox(
|
||||||
|
this.roomId, {
|
||||||
required this.relatedEvent,
|
required this.relatedEvent,
|
||||||
required this.relationType,
|
required this.relationType,
|
||||||
required this.onDismiss,
|
required this.onDismiss,
|
||||||
|
|
@ -88,7 +90,10 @@ class ChatBox extends HookConsumerWidget {
|
||||||
children:
|
children:
|
||||||
ref.watch(
|
ref.watch(
|
||||||
PowerLevelController.provider(
|
PowerLevelController.provider(
|
||||||
PowerLevelConfig(eventType: EventType.message),
|
PowerLevelConfig(
|
||||||
|
eventType: EventType.message,
|
||||||
|
roomId: roomId,
|
||||||
|
),
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
? [
|
? [
|
||||||
|
|
@ -125,6 +130,7 @@ class ChatBox extends HookConsumerWidget {
|
||||||
child: FlutterTagger(
|
child: FlutterTagger(
|
||||||
triggerStrategy: TriggerStrategy.eager,
|
triggerStrategy: TriggerStrategy.eager,
|
||||||
overlay: MentionOverlay(
|
overlay: MentionOverlay(
|
||||||
|
roomId,
|
||||||
query: query.value,
|
query: query.value,
|
||||||
triggerCharacter: triggerCharacter.value,
|
triggerCharacter: triggerCharacter.value,
|
||||||
addTag: ({required id, required name}) {
|
addTag: ({required id, required name}) {
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,11 @@
|
||||||
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/members_by_type_controller.dart";
|
import "package:nexus/controllers/members_by_status_controller.dart";
|
||||||
import "package:nexus/controllers/rooms_controller.dart";
|
import "package:nexus/controllers/rooms_controller.dart";
|
||||||
import "package:nexus/controllers/via_controller.dart";
|
import "package:nexus/controllers/via_controller.dart";
|
||||||
import "package:nexus/helpers/extensions/better_when.dart";
|
import "package:nexus/helpers/extensions/better_when.dart";
|
||||||
import "package:nexus/helpers/extensions/get_localpart.dart";
|
import "package:nexus/helpers/extensions/get_localpart.dart";
|
||||||
|
import "package:nexus/models/configs/members_by_status_config.dart";
|
||||||
import "package:nexus/models/content/membership.dart";
|
import "package:nexus/models/content/membership.dart";
|
||||||
import "package:nexus/models/membership_status.dart";
|
import "package:nexus/models/membership_status.dart";
|
||||||
import "package:nexus/widgets/avatar_or_hash.dart";
|
import "package:nexus/widgets/avatar_or_hash.dart";
|
||||||
|
|
@ -13,8 +14,10 @@ import "package:nexus/widgets/loading.dart";
|
||||||
class MentionOverlay extends ConsumerWidget {
|
class MentionOverlay extends ConsumerWidget {
|
||||||
final String? triggerCharacter;
|
final String? triggerCharacter;
|
||||||
final String query;
|
final String query;
|
||||||
|
final String roomId;
|
||||||
final void Function({required String id, required String name}) addTag;
|
final void Function({required String id, required String name}) addTag;
|
||||||
const MentionOverlay({
|
const MentionOverlay(
|
||||||
|
this.roomId, {
|
||||||
required this.query,
|
required this.query,
|
||||||
required this.addTag,
|
required this.addTag,
|
||||||
required this.triggerCharacter,
|
required this.triggerCharacter,
|
||||||
|
|
@ -36,7 +39,12 @@ class MentionOverlay extends ConsumerWidget {
|
||||||
"@" =>
|
"@" =>
|
||||||
ref
|
ref
|
||||||
.watch(
|
.watch(
|
||||||
MembersByTypeController.provider(MembershipStatus.join),
|
MembersByStatusController.provider(
|
||||||
|
MembersByStatusConfig(
|
||||||
|
roomId: roomId,
|
||||||
|
status: MembershipStatus.join,
|
||||||
|
),
|
||||||
|
),
|
||||||
)
|
)
|
||||||
.betterWhen(
|
.betterWhen(
|
||||||
data: (members) => ListView(
|
data: (members) => ListView(
|
||||||
|
|
|
||||||
|
|
@ -1,22 +1,26 @@
|
||||||
import "package:flutter/material.dart";
|
import "package:flutter/material.dart";
|
||||||
import "package:flutter_hooks/flutter_hooks.dart";
|
import "package:flutter_hooks/flutter_hooks.dart";
|
||||||
import "package:hooks_riverpod/hooks_riverpod.dart";
|
import "package:hooks_riverpod/hooks_riverpod.dart";
|
||||||
import "package:nexus/controllers/members_by_type_controller.dart";
|
import "package:nexus/controllers/members_by_status_controller.dart";
|
||||||
import "package:nexus/helpers/extensions/better_when.dart";
|
import "package:nexus/helpers/extensions/better_when.dart";
|
||||||
import "package:nexus/helpers/extensions/get_localpart.dart";
|
import "package:nexus/helpers/extensions/get_localpart.dart";
|
||||||
import "package:nexus/helpers/extensions/show_user_popover.dart";
|
import "package:nexus/helpers/extensions/show_user_popover.dart";
|
||||||
|
import "package:nexus/models/configs/members_by_status_config.dart";
|
||||||
import "package:nexus/models/content/membership.dart";
|
import "package:nexus/models/content/membership.dart";
|
||||||
import "package:nexus/models/membership_status.dart";
|
import "package:nexus/models/membership_status.dart";
|
||||||
import "package:nexus/widgets/avatar_or_hash.dart";
|
import "package:nexus/widgets/avatar_or_hash.dart";
|
||||||
|
|
||||||
class MemberList extends HookConsumerWidget {
|
class MemberList extends HookConsumerWidget {
|
||||||
const MemberList({super.key});
|
final String roomId;
|
||||||
|
const MemberList(this.roomId, {super.key});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context, WidgetRef ref) {
|
Widget build(BuildContext context, WidgetRef ref) {
|
||||||
final status = useState(MembershipStatus.join);
|
final status = useState(MembershipStatus.join);
|
||||||
final membersProvider = ref.watch(
|
final membersProvider = ref.watch(
|
||||||
MembersByTypeController.provider(status.value),
|
MembersByStatusController.provider(
|
||||||
|
MembersByStatusConfig(roomId: roomId, status: status.value),
|
||||||
|
),
|
||||||
);
|
);
|
||||||
|
|
||||||
return Drawer(
|
return Drawer(
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@ 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/client_state_controller.dart";
|
import "package:nexus/controllers/client_state_controller.dart";
|
||||||
import "package:nexus/controllers/selected_room_controller.dart";
|
import "package:nexus/controllers/rooms_controller.dart";
|
||||||
import "package:nexus/helpers/extensions/mxc_to_https.dart";
|
import "package:nexus/helpers/extensions/mxc_to_https.dart";
|
||||||
import "package:nexus/widgets/appbar.dart";
|
import "package:nexus/widgets/appbar.dart";
|
||||||
import "package:nexus/widgets/avatar_or_hash.dart";
|
import "package:nexus/widgets/avatar_or_hash.dart";
|
||||||
|
|
@ -13,7 +13,9 @@ class RoomAppbar extends ConsumerWidget implements PreferredSizeWidget {
|
||||||
final bool isDesktop;
|
final bool isDesktop;
|
||||||
final void Function(BuildContext context)? onOpenMemberList;
|
final void Function(BuildContext context)? onOpenMemberList;
|
||||||
final void Function(BuildContext context) onOpenDrawer;
|
final void Function(BuildContext context) onOpenDrawer;
|
||||||
|
final String? roomId;
|
||||||
const RoomAppbar({
|
const RoomAppbar({
|
||||||
|
required this.roomId,
|
||||||
required this.isDesktop,
|
required this.isDesktop,
|
||||||
required this.onOpenDrawer,
|
required this.onOpenDrawer,
|
||||||
this.onOpenMemberList,
|
this.onOpenMemberList,
|
||||||
|
|
@ -25,7 +27,9 @@ class RoomAppbar extends ConsumerWidget implements PreferredSizeWidget {
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context, WidgetRef ref) {
|
Widget build(BuildContext context, WidgetRef ref) {
|
||||||
final room = ref.watch(SelectedRoomController.provider);
|
final room = roomId == null
|
||||||
|
? null
|
||||||
|
: ref.watch(RoomsController.provider.select((value) => value[roomId!]));
|
||||||
return Appbar(
|
return Appbar(
|
||||||
leading: isDesktop
|
leading: isDesktop
|
||||||
? room == null
|
? room == null
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,6 @@ import "package:nexus/controllers/client_controller.dart";
|
||||||
import "package:nexus/controllers/client_state_controller.dart";
|
import "package:nexus/controllers/client_state_controller.dart";
|
||||||
import "package:nexus/controllers/power_level_controller.dart";
|
import "package:nexus/controllers/power_level_controller.dart";
|
||||||
import "package:nexus/controllers/rooms_controller.dart";
|
import "package:nexus/controllers/rooms_controller.dart";
|
||||||
import "package:nexus/controllers/selected_room_controller.dart";
|
|
||||||
import "package:nexus/controllers/room_chat_controller.dart";
|
import "package:nexus/controllers/room_chat_controller.dart";
|
||||||
import "package:nexus/controllers/via_controller.dart";
|
import "package:nexus/controllers/via_controller.dart";
|
||||||
import "package:nexus/models/configs/power_level_config.dart";
|
import "package:nexus/models/configs/power_level_config.dart";
|
||||||
|
|
@ -32,7 +31,9 @@ import "package:super_sliver_list/super_sliver_list.dart";
|
||||||
class RoomChat extends HookConsumerWidget {
|
class RoomChat extends HookConsumerWidget {
|
||||||
final bool isDesktop;
|
final bool isDesktop;
|
||||||
final bool showMembersByDefault;
|
final bool showMembersByDefault;
|
||||||
|
final String? roomId;
|
||||||
const RoomChat({
|
const RoomChat({
|
||||||
|
required this.roomId,
|
||||||
required this.isDesktop,
|
required this.isDesktop,
|
||||||
required this.showMembersByDefault,
|
required this.showMembersByDefault,
|
||||||
super.key,
|
super.key,
|
||||||
|
|
@ -47,15 +48,12 @@ class RoomChat extends HookConsumerWidget {
|
||||||
final memberListOpened = useState<bool>(showMembersByDefault);
|
final memberListOpened = useState<bool>(showMembersByDefault);
|
||||||
|
|
||||||
final userId = ref.watch(ClientStateController.provider)?.userId;
|
final userId = ref.watch(ClientStateController.provider)?.userId;
|
||||||
final roomId = ref.watch(
|
|
||||||
SelectedRoomController.provider.select((value) => value?.metadata?.id),
|
|
||||||
);
|
|
||||||
|
|
||||||
final theme = Theme.of(context);
|
final theme = Theme.of(context);
|
||||||
|
|
||||||
if (roomId == null || userId == null) {
|
if (userId == null || this.roomId == null) {
|
||||||
return Scaffold(
|
return Scaffold(
|
||||||
appBar: RoomAppbar(
|
appBar: RoomAppbar(
|
||||||
|
roomId: this.roomId,
|
||||||
isDesktop: isDesktop,
|
isDesktop: isDesktop,
|
||||||
onOpenDrawer: (_) => Scaffold.of(context).openDrawer(),
|
onOpenDrawer: (_) => Scaffold.of(context).openDrawer(),
|
||||||
onOpenMemberList: null,
|
onOpenMemberList: null,
|
||||||
|
|
@ -69,6 +67,8 @@ class RoomChat extends HookConsumerWidget {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
final roomId = this.roomId!;
|
||||||
|
|
||||||
final controllerProvider = RoomChatController.provider(roomId);
|
final controllerProvider = RoomChatController.provider(roomId);
|
||||||
final notifier = ref.watch(controllerProvider.notifier);
|
final notifier = ref.watch(controllerProvider.notifier);
|
||||||
|
|
||||||
|
|
@ -76,10 +76,13 @@ class RoomChat extends HookConsumerWidget {
|
||||||
|
|
||||||
final listController = useRef(ListController());
|
final listController = useRef(ListController());
|
||||||
final scrollController = useScrollController();
|
final scrollController = useScrollController();
|
||||||
scrollController.addListener(() async {
|
|
||||||
|
useEffect(() {
|
||||||
|
Future<void> listener() async {
|
||||||
if (!scrollController.position.atEdge) return;
|
if (!scrollController.position.atEdge) return;
|
||||||
|
|
||||||
if (scrollController.position.pixels == 0) {
|
if (scrollController.position.pixels == 0) {
|
||||||
|
context.mounted;
|
||||||
final room = ref.watch(
|
final room = ref.watch(
|
||||||
RoomsController.provider.select((value) => value[roomId]),
|
RoomsController.provider.select((value) => value[roomId]),
|
||||||
);
|
);
|
||||||
|
|
@ -87,7 +90,11 @@ class RoomChat extends HookConsumerWidget {
|
||||||
} else {
|
} else {
|
||||||
await notifier.loadOlder();
|
await notifier.loadOlder();
|
||||||
}
|
}
|
||||||
});
|
}
|
||||||
|
|
||||||
|
scrollController.addListener(listener);
|
||||||
|
return () => scrollController.removeListener(listener);
|
||||||
|
}, [roomId]);
|
||||||
|
|
||||||
final composerNode = useFocusNode(
|
final composerNode = useFocusNode(
|
||||||
onKeyEvent: (_, event) {
|
onKeyEvent: (_, event) {
|
||||||
|
|
@ -107,7 +114,7 @@ class RoomChat extends HookConsumerWidget {
|
||||||
return [
|
return [
|
||||||
if (ref.watch(
|
if (ref.watch(
|
||||||
PowerLevelController.provider(
|
PowerLevelController.provider(
|
||||||
PowerLevelConfig(eventType: EventType.reaction),
|
PowerLevelConfig(eventType: EventType.reaction, roomId: roomId),
|
||||||
),
|
),
|
||||||
))
|
))
|
||||||
PopupMenuItem(
|
PopupMenuItem(
|
||||||
|
|
@ -156,7 +163,7 @@ class RoomChat extends HookConsumerWidget {
|
||||||
),
|
),
|
||||||
if (ref.watch(
|
if (ref.watch(
|
||||||
PowerLevelController.provider(
|
PowerLevelController.provider(
|
||||||
PowerLevelConfig(eventType: EventType.message),
|
PowerLevelConfig(eventType: EventType.message, roomId: roomId),
|
||||||
),
|
),
|
||||||
))
|
))
|
||||||
PopupMenuItem(
|
PopupMenuItem(
|
||||||
|
|
@ -178,7 +185,9 @@ class RoomChat extends HookConsumerWidget {
|
||||||
),
|
),
|
||||||
PopupMenuItem(
|
PopupMenuItem(
|
||||||
onTap: () async {
|
onTap: () async {
|
||||||
final room = ref.watch(SelectedRoomController.provider);
|
final room = ref.watch(
|
||||||
|
RoomsController.provider.select((value) => value[roomId]),
|
||||||
|
);
|
||||||
if (room == null) return;
|
if (room == null) return;
|
||||||
|
|
||||||
final vias = ref.watch(ViaController.provider(room));
|
final vias = ref.watch(ViaController.provider(room));
|
||||||
|
|
@ -194,7 +203,10 @@ class RoomChat extends HookConsumerWidget {
|
||||||
),
|
),
|
||||||
if (ref.watch(
|
if (ref.watch(
|
||||||
PowerLevelController.provider(
|
PowerLevelController.provider(
|
||||||
PowerLevelConfig.redaction(targetUser: event.sender),
|
PowerLevelConfig.redaction(
|
||||||
|
targetUser: event.sender,
|
||||||
|
roomId: roomId,
|
||||||
|
),
|
||||||
),
|
),
|
||||||
))
|
))
|
||||||
PopupMenuItem(
|
PopupMenuItem(
|
||||||
|
|
@ -308,6 +320,7 @@ class RoomChat extends HookConsumerWidget {
|
||||||
|
|
||||||
return Scaffold(
|
return Scaffold(
|
||||||
appBar: RoomAppbar(
|
appBar: RoomAppbar(
|
||||||
|
roomId: roomId,
|
||||||
isDesktop: isDesktop,
|
isDesktop: isDesktop,
|
||||||
onOpenDrawer: (_) => Scaffold.of(context).openDrawer(),
|
onOpenDrawer: (_) => Scaffold.of(context).openDrawer(),
|
||||||
onOpenMemberList: (thisContext) {
|
onOpenMemberList: (thisContext) {
|
||||||
|
|
@ -387,6 +400,7 @@ class RoomChat extends HookConsumerWidget {
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
ChatBox(
|
ChatBox(
|
||||||
|
roomId,
|
||||||
node: composerNode,
|
node: composerNode,
|
||||||
onSend: (text, {required shouldMention, required tags}) =>
|
onSend: (text, {required shouldMention, required tags}) =>
|
||||||
notifier
|
notifier
|
||||||
|
|
@ -407,11 +421,11 @@ class RoomChat extends HookConsumerWidget {
|
||||||
),
|
),
|
||||||
|
|
||||||
if (memberListOpened.value == true && showMembersByDefault)
|
if (memberListOpened.value == true && showMembersByDefault)
|
||||||
MemberList(),
|
MemberList(roomId),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
|
|
||||||
endDrawer: showMembersByDefault ? null : MemberList(),
|
endDrawer: showMembersByDefault ? null : MemberList(roomId),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
|
import "package:collection/collection.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/key_controller.dart";
|
import "package:nexus/controllers/key_controller.dart";
|
||||||
import "package:nexus/controllers/selected_space_controller.dart";
|
|
||||||
import "package:nexus/controllers/spaces_controller.dart";
|
import "package:nexus/controllers/spaces_controller.dart";
|
||||||
import "package:nexus/widgets/avatar_or_hash.dart";
|
import "package:nexus/widgets/avatar_or_hash.dart";
|
||||||
import "package:nexus/widgets/join_dialog.dart";
|
import "package:nexus/widgets/join_dialog.dart";
|
||||||
|
|
@ -31,7 +31,9 @@ class Sidebar extends HookConsumerWidget {
|
||||||
);
|
);
|
||||||
final selectedIndex = indexOfSelected == -1 ? 0 : indexOfSelected;
|
final selectedIndex = indexOfSelected == -1 ? 0 : indexOfSelected;
|
||||||
|
|
||||||
final selectedSpace = ref.watch(SelectedSpaceController.provider);
|
final selectedSpace =
|
||||||
|
spaces.firstWhereOrNull((space) => space.id == selectedSpaceId) ??
|
||||||
|
spaces.first;
|
||||||
|
|
||||||
final indexOfSelectedRoom = selectedSpace.children.indexWhere(
|
final indexOfSelectedRoom = selectedSpace.children.indexWhere(
|
||||||
(room) => room.metadata?.id == selectedRoomId,
|
(room) => room.metadata?.id == selectedRoomId,
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,6 @@ import "package:nexus/controllers/client_controller.dart";
|
||||||
import "package:nexus/controllers/client_state_controller.dart";
|
import "package:nexus/controllers/client_state_controller.dart";
|
||||||
import "package:nexus/controllers/power_level_controller.dart";
|
import "package:nexus/controllers/power_level_controller.dart";
|
||||||
import "package:nexus/controllers/profile_controller.dart";
|
import "package:nexus/controllers/profile_controller.dart";
|
||||||
import "package:nexus/controllers/selected_room_controller.dart";
|
|
||||||
import "package:nexus/helpers/extensions/better_when.dart";
|
import "package:nexus/helpers/extensions/better_when.dart";
|
||||||
import "package:nexus/helpers/extensions/get_localpart.dart";
|
import "package:nexus/helpers/extensions/get_localpart.dart";
|
||||||
import "package:nexus/helpers/extensions/mxc_to_https.dart";
|
import "package:nexus/helpers/extensions/mxc_to_https.dart";
|
||||||
|
|
@ -23,16 +22,14 @@ import "package:nexus/widgets/form_text_input.dart";
|
||||||
class UserPopover extends ConsumerWidget {
|
class UserPopover extends ConsumerWidget {
|
||||||
final MembershipContent member;
|
final MembershipContent member;
|
||||||
final String userId;
|
final String userId;
|
||||||
const UserPopover(this.member, this.userId, {super.key});
|
final String? roomId;
|
||||||
|
const UserPopover(this.member, this.userId, {this.roomId, 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);
|
||||||
final textTheme = theme.textTheme;
|
final textTheme = theme.textTheme;
|
||||||
final client = ref.watch(ClientController.provider.notifier);
|
final client = ref.watch(ClientController.provider.notifier);
|
||||||
final roomId = ref.watch(
|
|
||||||
SelectedRoomController.provider.select((room) => room?.metadata?.id),
|
|
||||||
);
|
|
||||||
|
|
||||||
void showMembershipDialog(MembershipAction action) => showDialog(
|
void showMembershipDialog(MembershipAction action) => showDialog(
|
||||||
context: context,
|
context: context,
|
||||||
|
|
@ -164,6 +161,7 @@ class UserPopover extends ConsumerWidget {
|
||||||
PowerLevelController.provider(
|
PowerLevelController.provider(
|
||||||
PowerLevelConfig.membershipAction(
|
PowerLevelConfig.membershipAction(
|
||||||
action: MembershipAction.kick,
|
action: MembershipAction.kick,
|
||||||
|
roomId: roomId!,
|
||||||
targetUser: userId,
|
targetUser: userId,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|
@ -185,6 +183,7 @@ class UserPopover extends ConsumerWidget {
|
||||||
if (ref.watch(
|
if (ref.watch(
|
||||||
PowerLevelController.provider(
|
PowerLevelController.provider(
|
||||||
PowerLevelConfig.membershipAction(
|
PowerLevelConfig.membershipAction(
|
||||||
|
roomId: roomId!,
|
||||||
action: MembershipAction.ban,
|
action: MembershipAction.ban,
|
||||||
targetUser: userId,
|
targetUser: userId,
|
||||||
),
|
),
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,6 @@ import "package:flutter_riverpod/flutter_riverpod.dart";
|
||||||
import "package:nexus/controllers/client_state_controller.dart";
|
import "package:nexus/controllers/client_state_controller.dart";
|
||||||
import "package:nexus/controllers/cross_cache_controller.dart";
|
import "package:nexus/controllers/cross_cache_controller.dart";
|
||||||
import "package:nexus/controllers/room_chat_controller.dart";
|
import "package:nexus/controllers/room_chat_controller.dart";
|
||||||
import "package:nexus/controllers/selected_room_controller.dart";
|
|
||||||
import "package:nexus/helpers/extensions/get_headers.dart";
|
import "package:nexus/helpers/extensions/get_headers.dart";
|
||||||
import "package:nexus/helpers/extensions/mxc_to_https.dart";
|
import "package:nexus/helpers/extensions/mxc_to_https.dart";
|
||||||
import "package:nexus/main.dart";
|
import "package:nexus/main.dart";
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue