Remove flutter chat #26
9 changed files with 164 additions and 158 deletions
fix power level logic
commit
22f9e61c7c
|
|
@ -24,10 +24,9 @@ class PowerLevelController extends Notifier<bool> {
|
|||
final event = room?.events.firstWhereOrNull(
|
||||
(event) => event.rowId == room.state[EventType.powerLevels.type]?[""],
|
||||
);
|
||||
final content = event?.content ?? PowerLevelsContent();
|
||||
final user = ref.watch(ClientStateController.provider)?.userId;
|
||||
if (user == null || event?.content is! PowerLevelsContent) return false;
|
||||
|
||||
final content = event?.content as PowerLevelsContent;
|
||||
if (user == null || content is! PowerLevelsContent) return false;
|
||||
|
||||
int powerLevelOf(String userId) =>
|
||||
content.users[userId] ?? content.usersDefault;
|
||||
|
|
@ -36,7 +35,8 @@ class PowerLevelController extends Notifier<bool> {
|
|||
|
||||
return switch (config) {
|
||||
EventPowerLevelConfig(:final eventType) =>
|
||||
userLevel > (content.events[eventType.type] ?? content.eventsDefault),
|
||||
userLevel >= (content.events[eventType.type] ?? content.eventsDefault),
|
||||
|
||||
MembershipActionPowerLevelConfig(:final action, :final targetUser) =>
|
||||
switch (action) {
|
||||
MembershipAction.invite => userLevel >= content.invite,
|
||||
|
|
@ -51,7 +51,8 @@ class PowerLevelController extends Notifier<bool> {
|
|||
},
|
||||
|
||||
StatePowerLevelConfig(:final eventType) =>
|
||||
userLevel > (content.events[eventType.type] ?? content.stateDefault),
|
||||
userLevel >= (content.events[eventType.type] ?? content.stateDefault),
|
||||
|
||||
RedactionPowerLevelConfig(:final targetUser) =>
|
||||
userLevel >=
|
||||
(targetUser == user
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@ part "membership.g.dart";
|
|||
@freezed
|
||||
abstract class MembershipContent extends Content with _$MembershipContent {
|
||||
MembershipContent._();
|
||||
|
||||
factory MembershipContent({
|
||||
@JsonKey(name: "displayname") required String? displayName,
|
||||
@JsonKey(name: "membership") required MembershipStatus status,
|
||||
|
|
|
|||
|
|
@ -1,7 +1,6 @@
|
|||
import "package:fast_immutable_collections/fast_immutable_collections.dart";
|
||||
import "package:freezed_annotation/freezed_annotation.dart";
|
||||
import "package:nexus/models/content/content.dart";
|
||||
|
||||
part "power_levels.freezed.dart";
|
||||
part "power_levels.g.dart";
|
||||
|
||||
|
|
|
|||
|
|
@ -54,7 +54,13 @@ class RelationPreview extends ConsumerWidget {
|
|||
),
|
||||
),
|
||||
Expanded(
|
||||
child: EventText(relatedEvent!, textOnly: true, maxLines: 1),
|
||||
child: IgnorePointer(
|
||||
child: EventText(
|
||||
relatedEvent!,
|
||||
textOnly: true,
|
||||
maxLines: 1,
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
|
|
|
|||
|
|
@ -1,11 +1,16 @@
|
|||
import "dart:convert";
|
||||
import "package:fast_immutable_collections/fast_immutable_collections.dart";
|
||||
import "package:flutter/material.dart";
|
||||
import "package:nexus/models/content/avatar.dart";
|
||||
import "package:nexus/models/content/message.dart";
|
||||
import "package:nexus/models/event.dart";
|
||||
import "package:nexus/widgets/chat_page/lazy_loading/message_avatar.dart";
|
||||
import "package:nexus/widgets/chat_page/lazy_loading/message_displayname.dart";
|
||||
import "package:timeago/timeago.dart";
|
||||
|
||||
class EventText extends StatelessWidget {
|
||||
final Event event;
|
||||
final bool textOnly;
|
||||
final bool isGrouped;
|
||||
final int? maxLines;
|
||||
final VoidCallback? onTapReply;
|
||||
final IList<PopupMenuEntry> Function(Event event)? getEventOptions;
|
||||
|
|
@ -13,6 +18,7 @@ class EventText extends StatelessWidget {
|
|||
this.event, {
|
||||
this.onTapReply,
|
||||
this.textOnly = false,
|
||||
this.isGrouped = false,
|
||||
this.maxLines,
|
||||
this.getEventOptions,
|
||||
super.key,
|
||||
|
|
@ -20,6 +26,81 @@ class EventText extends StatelessWidget {
|
|||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Text(json.encode(event.toJson())); // NEXT TODO
|
||||
final theme = Theme.of(context);
|
||||
final timestamp = Tooltip(
|
||||
message: event.timestamp.toString(),
|
||||
child: Text(
|
||||
format(event.timestamp),
|
||||
style: theme.textTheme.labelSmall?.copyWith(color: Colors.grey),
|
||||
),
|
||||
);
|
||||
|
||||
return switch (event.content) {
|
||||
MessageContent() => Row(
|
||||
spacing: 8,
|
||||
children: [
|
||||
isGrouped ? SizedBox(width: 40) : MessageAvatar(event, height: 40),
|
||||
Expanded(
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
if (!isGrouped)
|
||||
Row(
|
||||
spacing: 4,
|
||||
children: [
|
||||
MessageDisplayname(
|
||||
event,
|
||||
style: TextStyle(fontWeight: FontWeight.bold),
|
||||
),
|
||||
Expanded(child: timestamp),
|
||||
],
|
||||
),
|
||||
Text("data"),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
AvatarContent() => Row(
|
||||
spacing: 4,
|
||||
children: [
|
||||
SizedBox(width: 4),
|
||||
Icon(Icons.numbers),
|
||||
MessageDisplayname(
|
||||
event,
|
||||
style: TextStyle(
|
||||
color: theme.colorScheme.primary,
|
||||
fontWeight: FontWeight.bold,
|
||||
),
|
||||
),
|
||||
Text("changed the room avatar"),
|
||||
],
|
||||
),
|
||||
_ => Text("AAAAA"),
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
// ExpandableImage(
|
||||
// url,
|
||||
// child: ClipRRect(
|
||||
// borderRadius: BorderRadius.all(Radius.circular(8)),
|
||||
// child: Image(
|
||||
// image: CachedNetworkImage(
|
||||
// url,
|
||||
// ref.watch(CrossCacheController.provider),
|
||||
// headers: ref.headers,
|
||||
// ),
|
||||
// width: width,
|
||||
// height: height,
|
||||
// loadingBuilder: (context, child, loadingProgress) =>
|
||||
// blurHash == null ? Loading() : BlurHash(hash: blurHash!),
|
||||
// errorBuilder: (context, error, stackTrace) => Center(
|
||||
// child: Text(
|
||||
// "Image Failed to Load",
|
||||
// style: TextStyle(color: Theme.of(context).colorScheme.error),
|
||||
// ),
|
||||
// ),
|
||||
// ),
|
||||
// ),
|
||||
// )
|
||||
|
|
|
|||
|
|
@ -1,48 +0,0 @@
|
|||
import "package:cross_cache/cross_cache.dart";
|
||||
import "package:flutter/material.dart";
|
||||
import "package:flutter_blurhash/flutter_blurhash.dart";
|
||||
import "package:flutter_riverpod/flutter_riverpod.dart";
|
||||
import "package:nexus/controllers/cross_cache_controller.dart";
|
||||
import "package:nexus/helpers/extensions/get_headers.dart";
|
||||
import "package:nexus/widgets/chat_page/expandable_image.dart";
|
||||
import "package:nexus/widgets/loading.dart";
|
||||
|
||||
class ExpandableImageMessage extends ConsumerWidget {
|
||||
final String url;
|
||||
final double? width;
|
||||
final double? height;
|
||||
final String? blurHash;
|
||||
|
||||
const ExpandableImageMessage(
|
||||
this.url, {
|
||||
this.width,
|
||||
this.height,
|
||||
this.blurHash,
|
||||
super.key,
|
||||
});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context, WidgetRef ref) => ExpandableImage(
|
||||
url,
|
||||
child: ClipRRect(
|
||||
borderRadius: BorderRadius.all(Radius.circular(8)),
|
||||
child: Image(
|
||||
image: CachedNetworkImage(
|
||||
url,
|
||||
ref.watch(CrossCacheController.provider),
|
||||
headers: ref.headers,
|
||||
),
|
||||
width: width,
|
||||
height: height,
|
||||
loadingBuilder: (context, child, loadingProgress) =>
|
||||
blurHash == null ? Loading() : BlurHash(hash: blurHash!),
|
||||
errorBuilder: (context, error, stackTrace) => Center(
|
||||
child: Text(
|
||||
"Image Failed to Load",
|
||||
style: TextStyle(color: Theme.of(context).colorScheme.error),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
|
@ -21,7 +21,7 @@ import "package:nexus/widgets/chat_page/emoji_picker_button.dart";
|
|||
import "package:nexus/widgets/chat_page/event_text.dart";
|
||||
import "package:nexus/widgets/chat_page/member_list.dart";
|
||||
import "package:nexus/widgets/chat_page/room_appbar.dart";
|
||||
import "package:nexus/widgets/chat_page/wrappers/message_wrapper.dart";
|
||||
import "package:nexus/widgets/chat_page/wrappers/event_wrapper.dart";
|
||||
import "package:nexus/widgets/error_dialog.dart";
|
||||
import "package:nexus/widgets/form_text_input.dart";
|
||||
import "package:nexus/main.dart";
|
||||
|
|
@ -320,7 +320,9 @@ class RoomChat extends HookConsumerWidget {
|
|||
SuperSliverList.builder(
|
||||
listController: listController.value,
|
||||
itemCount: value.length,
|
||||
itemBuilder: (_, index) => MessageWrapper(
|
||||
itemBuilder: (_, index) => Padding(
|
||||
padding: EdgeInsets.symmetric(vertical: 8),
|
||||
child: EventWrapper(
|
||||
value[index],
|
||||
EventText(
|
||||
value[index],
|
||||
|
|
@ -334,13 +336,14 @@ class RoomChat extends HookConsumerWidget {
|
|||
curve: (_) => Curves.easeInOut,
|
||||
),
|
||||
getEventOptions: getEventOptions,
|
||||
),
|
||||
// TODO: Reimplement grouping
|
||||
isGrouped: false,
|
||||
),
|
||||
// TODO: Reimplement flashing
|
||||
isFlashing: false,
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
AsyncLoading() => Loading(),
|
||||
|
|
|
|||
46
lib/widgets/chat_page/wrappers/event_wrapper.dart
Normal file
46
lib/widgets/chat_page/wrappers/event_wrapper.dart
Normal file
|
|
@ -0,0 +1,46 @@
|
|||
import "package:flutter/material.dart";
|
||||
import "package:nexus/models/event.dart";
|
||||
import "package:nexus/widgets/chat_page/wrappers/reaction_row.dart";
|
||||
|
||||
class EventWrapper extends StatelessWidget {
|
||||
final Event event;
|
||||
final Widget child;
|
||||
final bool isFlashing;
|
||||
const EventWrapper(
|
||||
this.event,
|
||||
this.child, {
|
||||
this.isFlashing = false,
|
||||
super.key,
|
||||
});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final theme = Theme.of(context);
|
||||
|
||||
return ClipRRect(
|
||||
borderRadius: BorderRadius.all(Radius.circular(12)),
|
||||
child: AnimatedContainer(
|
||||
padding: isFlashing ? EdgeInsets.all(8) : EdgeInsets.all(0),
|
||||
color: isFlashing
|
||||
? Theme.of(context).colorScheme.onSurface.withAlpha(50)
|
||||
: Colors.transparent,
|
||||
duration: Duration(milliseconds: 250),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
spacing: 4,
|
||||
children: [
|
||||
child,
|
||||
if (event.sendError != null && event.sendError != "not sent")
|
||||
Text(
|
||||
event.sendError!,
|
||||
style: theme.textTheme.labelSmall?.copyWith(
|
||||
color: theme.colorScheme.error,
|
||||
),
|
||||
),
|
||||
ReactionRow(event),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,83 +0,0 @@
|
|||
import "package:flutter/material.dart";
|
||||
import "package:nexus/models/event.dart";
|
||||
import "package:nexus/widgets/chat_page/lazy_loading/message_avatar.dart";
|
||||
import "package:nexus/widgets/chat_page/lazy_loading/message_displayname.dart";
|
||||
import "package:nexus/widgets/chat_page/wrappers/reaction_row.dart";
|
||||
import "package:timeago/timeago.dart";
|
||||
|
||||
class MessageWrapper extends StatelessWidget {
|
||||
final Event event;
|
||||
final Widget child;
|
||||
final bool isGrouped;
|
||||
final bool isFlashing;
|
||||
const MessageWrapper(
|
||||
this.event,
|
||||
this.child, {
|
||||
this.isGrouped = false,
|
||||
this.isFlashing = false,
|
||||
super.key,
|
||||
});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final theme = Theme.of(context);
|
||||
|
||||
return ClipRRect(
|
||||
borderRadius: BorderRadius.all(Radius.circular(12)),
|
||||
child: AnimatedContainer(
|
||||
padding: isFlashing ? EdgeInsets.all(8) : EdgeInsets.all(0),
|
||||
color: isFlashing
|
||||
? Theme.of(context).colorScheme.onSurface.withAlpha(50)
|
||||
: Colors.transparent,
|
||||
duration: Duration(milliseconds: 250),
|
||||
child: Row(
|
||||
spacing: 8,
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
isGrouped ? SizedBox(width: 40) : MessageAvatar(event, height: 40),
|
||||
Expanded(
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
spacing: 4,
|
||||
children: [
|
||||
if (!isGrouped)
|
||||
Row(
|
||||
spacing: 4,
|
||||
children: [
|
||||
Flexible(
|
||||
child: MessageDisplayname(
|
||||
event,
|
||||
style: theme.textTheme.titleMedium?.copyWith(
|
||||
fontWeight: FontWeight.bold,
|
||||
),
|
||||
),
|
||||
),
|
||||
Tooltip(
|
||||
message: event.timestamp.toString(),
|
||||
child: Text(
|
||||
format(event.timestamp),
|
||||
style: theme.textTheme.labelSmall?.copyWith(
|
||||
color: Colors.grey,
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
child,
|
||||
if (event.sendError != null && event.sendError != "not sent")
|
||||
Text(
|
||||
event.sendError!,
|
||||
style: theme.textTheme.labelSmall?.copyWith(
|
||||
color: theme.colorScheme.error,
|
||||
),
|
||||
),
|
||||
ReactionRow(event),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue