fluffychat merge

pull/1186/head
ggurdin 1 year ago
commit 413d4adaec

@ -62,10 +62,11 @@ abstract class AppConfig {
host: 'github.com',
path: '/krille-chan/fluffychat/issues/new',
);
// #Pangea
// static bool renderHtml = true;
static const bool enableSentry = true;
static const String sentryDns =
'https://8591d0d863b646feb4f3dda7e5dcab38@o256755.ingest.sentry.io/5243143';
// #Pangea
static bool renderHtml = false;
// static bool renderHtml = true;
// Pangea#
@ -75,11 +76,12 @@ abstract class AppConfig {
static bool separateChatTypes = false;
static bool autoplayImages = true;
static bool sendTypingNotifications = true;
static bool sendPublicReadReceipts = true;
static bool swipeRightToLeftToReply = true;
//#Pangea
static bool sendOnEnter = true;
// static bool sendOnEnter = false;
//Pangea#
static bool sendPublicReadReceipts = true;
static bool showPresences = true;
static bool experimentalVoip = false;
static const bool hideTypingUsernames = false;
@ -115,7 +117,6 @@ abstract class AppConfig {
host: 'servers.joinmatrix.org',
path: 'servers.json',
);
// #Pangea
static String googlePlayMangementUrl =
"https://play.google.com/store/account/subscriptions";

@ -91,6 +91,7 @@ abstract class FluffyThemes {
),
textSelectionTheme: TextSelectionThemeData(
selectionColor: colorScheme.onBackground.withAlpha(128),
selectionHandleColor: colorScheme.secondary,
),
inputDecorationTheme: InputDecorationTheme(
border: OutlineInputBorder(

@ -7,7 +7,6 @@ import 'package:fluffychat/pangea/widgets/chat/message_toolbar.dart';
import 'package:fluffychat/utils/date_time_extension.dart';
import 'package:fluffychat/utils/string_color.dart';
import 'package:fluffychat/widgets/avatar.dart';
import 'package:fluffychat/widgets/hover_builder.dart';
import 'package:fluffychat/widgets/matrix.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
@ -108,6 +107,7 @@ class Message extends StatelessWidget {
final client = Matrix.of(context).client;
final ownMessage = event.senderId == client.userID;
final alignment = ownMessage ? Alignment.topRight : Alignment.topLeft;
// ignore: deprecated_member_use
var color = Theme.of(context).colorScheme.surfaceVariant;
final displayTime = event.type == EventTypes.RoomCreate ||
nextEvent == null ||
@ -132,7 +132,7 @@ class Message extends StatelessWidget {
final textColor = ownMessage
? Theme.of(context).colorScheme.onPrimary
: Theme.of(context).colorScheme.onBackground;
: Theme.of(context).colorScheme.onSurface;
final rowMainAxisAlignment =
ownMessage ? MainAxisAlignment.end : MainAxisAlignment.start;
@ -190,268 +190,331 @@ class Message extends StatelessWidget {
setState(resetAnimateIn);
});
}
return AnimatedSlide(
offset: Offset(0, animateIn ? 1 : 0),
return AnimatedSize(
duration: FluffyThemes.animationDuration,
curve: FluffyThemes.animationCurve,
child: Row(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: rowMainAxisAlignment,
children: [
if (longPressSelect)
SizedBox(
height: 32,
width: Avatar.defaultSize,
child: Checkbox.adaptive(
value: selected,
shape: const CircleBorder(),
onChanged: (_) => onSelect(event),
),
)
else if (nextEventSameSender || ownMessage)
SizedBox(
width: Avatar.defaultSize,
child: Center(
child: SizedBox(
width: 16,
height: 16,
child: event.status == EventStatus.error
? const Icon(Icons.error, color: Colors.red)
: event.fileSendingStatus != null
? const CircularProgressIndicator.adaptive(
strokeWidth: 1,
)
: null,
),
),
)
else
FutureBuilder<User?>(
future: event.fetchSenderUser(),
builder: (context, snapshot) {
final user =
snapshot.data ?? event.senderFromMemoryOrFallback;
return Avatar(
mxContent: user.avatarUrl,
name: user.calcDisplayname(),
presenceUserId: user.stateKey,
presenceBackgroundColor: avatarPresenceBackgroundColor,
onTap: () => onAvatarTab(event),
);
},
),
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisSize: MainAxisSize.min,
clipBehavior: Clip.none,
alignment: ownMessage ? Alignment.bottomRight : Alignment.bottomLeft,
child: animateIn
? const SizedBox(height: 0, width: double.infinity)
: Stack(
children: [
if (!nextEventSameSender)
Padding(
padding: const EdgeInsets.only(left: 8.0, bottom: 4),
child: ownMessage || event.room.isDirectChat
? const SizedBox(height: 12)
: FutureBuilder<User?>(
future: event.fetchSenderUser(),
builder: (context, snapshot) {
final displayname =
snapshot.data?.calcDisplayname() ??
event.senderFromMemoryOrFallback
.calcDisplayname();
return Text(
displayname,
style: TextStyle(
fontSize: 12,
color: (Theme.of(context).brightness ==
Brightness.light
? displayname.color
: displayname.lightColorText),
),
);
},
),
Positioned(
top: 0,
bottom: 0,
left: 0,
right: 0,
child: InkWell(
onTap: () => onSelect(event),
onLongPress: () => onSelect(event),
borderRadius:
BorderRadius.circular(AppConfig.borderRadius / 2),
child: Material(
borderRadius:
BorderRadius.circular(AppConfig.borderRadius / 2),
color: selected
? Theme.of(context)
.colorScheme
.secondaryContainer
.withAlpha(100)
: highlightMarker
? Theme.of(context)
.colorScheme
.tertiaryContainer
.withAlpha(100)
: Colors.transparent,
),
),
Container(
alignment: alignment,
padding: const EdgeInsets.only(left: 8),
child: GestureDetector(
// #Pangea
onTap: () => toolbarController?.showToolbar(context),
onDoubleTap: () =>
toolbarController?.showToolbar(context),
// Pangea#
onLongPress: longPressSelect
? null
: () {
HapticFeedback.heavyImpact();
onSelect(event);
},
child: AnimatedOpacity(
opacity: animateIn
? 0
: event.redacted ||
event.messageType ==
MessageTypes.BadEncrypted ||
event.status.isSending
? 0.5
: 1,
duration: FluffyThemes.animationDuration,
curve: FluffyThemes.animationCurve,
child: Material(
color: noBubble ? Colors.transparent : color,
clipBehavior: Clip.antiAlias,
shape: RoundedRectangleBorder(
borderRadius: borderRadius,
),
Row(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: rowMainAxisAlignment,
children: [
if (longPressSelect)
SizedBox(
height: 32,
width: Avatar.defaultSize,
child: Checkbox.adaptive(
value: selected,
shape: const CircleBorder(),
onChanged: (_) => onSelect(event),
),
)
else if (nextEventSameSender || ownMessage)
SizedBox(
width: Avatar.defaultSize,
child: Center(
child: SizedBox(
width: 16,
height: 16,
child: event.status == EventStatus.error
? const Icon(Icons.error, color: Colors.red)
: event.fileSendingStatus != null
? const CircularProgressIndicator
.adaptive(
strokeWidth: 1,
)
: null,
),
),
// #Pangea
child: CompositedTransformTarget(
link: MatrixState.pAnyState
.layerLinkAndKey(event.eventId)
.link,
child: Container(
key: MatrixState.pAnyState
.layerLinkAndKey(event.eventId)
.key,
// Pangea#
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(
AppConfig.borderRadius,
)
else
FutureBuilder<User?>(
future: event.fetchSenderUser(),
builder: (context, snapshot) {
final user = snapshot.data ??
event.senderFromMemoryOrFallback;
return Avatar(
mxContent: user.avatarUrl,
name: user.calcDisplayname(),
presenceUserId: user.stateKey,
presenceBackgroundColor:
avatarPresenceBackgroundColor,
onTap: () => onAvatarTab(event),
);
},
),
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisSize: MainAxisSize.min,
children: [
if (!nextEventSameSender)
Padding(
padding: const EdgeInsets.only(
left: 8.0,
bottom: 4,
),
),
padding: noBubble || noPadding
? EdgeInsets.zero
: const EdgeInsets.symmetric(
horizontal: 16,
vertical: 8,
),
constraints: const BoxConstraints(
maxWidth: FluffyThemes.columnWidth * 1.5,
),
child: Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
if (event.relationshipType ==
RelationshipTypes.reply)
FutureBuilder<Event?>(
future: event.getReplyEvent(timeline),
builder:
(BuildContext context, snapshot) {
final replyEvent = snapshot.hasData
? snapshot.data!
: Event(
eventId: event
.relationshipEventId!,
content: {
'msgtype': 'm.text',
'body': '...',
},
senderId: event.senderId,
type: 'm.room.message',
room: event.room,
status: EventStatus.sent,
originServerTs:
DateTime.now(),
);
return Padding(
padding: const EdgeInsets.only(
bottom: 4.0,
),
child: InkWell(
borderRadius:
ReplyContent.borderRadius,
onTap: () => scrollToEventId(
replyEvent.eventId,
),
child: AbsorbPointer(
child: ReplyContent(
replyEvent,
ownMessage: ownMessage,
timeline: timeline,
),
child: ownMessage || event.room.isDirectChat
? const SizedBox(height: 12)
: FutureBuilder<User?>(
future: event.fetchSenderUser(),
builder: (context, snapshot) {
final displayname = snapshot.data
?.calcDisplayname() ??
event.senderFromMemoryOrFallback
.calcDisplayname();
return Text(
displayname,
style: TextStyle(
fontSize: 12,
color: (Theme.of(context)
.brightness ==
Brightness.light
? displayname.color
: displayname
.lightColorText),
),
),
);
maxLines: 1,
overflow: TextOverflow.ellipsis,
);
},
),
),
Container(
alignment: alignment,
padding: const EdgeInsets.only(left: 8),
child: GestureDetector(
onLongPress: longPressSelect
? null
: () {
HapticFeedback.heavyImpact();
onSelect(event);
},
child: AnimatedOpacity(
opacity: animateIn
? 0
: event.redacted ||
event.messageType ==
MessageTypes.BadEncrypted ||
event.status.isSending
? 0.5
: 1,
duration: FluffyThemes.animationDuration,
curve: FluffyThemes.animationCurve,
child: Material(
color:
noBubble ? Colors.transparent : color,
clipBehavior: Clip.antiAlias,
shape: RoundedRectangleBorder(
borderRadius: borderRadius,
),
MessageContent(
displayEvent,
textColor: textColor,
onInfoTab: onInfoTab,
borderRadius: borderRadius,
// #Pangea
selected: selected,
pangeaMessageEvent:
toolbarController?.pangeaMessageEvent,
immersionMode: immersionMode,
toolbarController: toolbarController,
// Pangea#
),
if (event.hasAggregatedEvents(
timeline,
RelationshipTypes.edit,
) // #Pangea
||
(toolbarController
?.pangeaMessageEvent
.showUseType ??
false)
// Pangea#
)
Padding(
padding: const EdgeInsets.only(
top: 4.0,
),
child: Row(
mainAxisSize: MainAxisSize.min,
children: [
// #Pangea
if (toolbarController
?.pangeaMessageEvent
.showUseType ??
false) ...[
toolbarController!
.pangeaMessageEvent.useType
.iconView(
context,
textColor.withAlpha(164),
),
const SizedBox(width: 4),
],
if (event.hasAggregatedEvents(
timeline,
RelationshipTypes.edit,
)) ...[
// Pangea#
Icon(
Icons.edit_outlined,
color: textColor.withAlpha(164),
size: 14,
),
Text(
' - ${displayEvent.originServerTs.localizedTimeShort(context)}',
style: TextStyle(
color:
textColor.withAlpha(164),
fontSize: 12,
child: CompositedTransformTarget(
link: MatrixState.pAnyState
.layerLinkAndKey(event.eventId)
.link,
child: Container(
key: MatrixState.pAnyState
.layerLinkAndKey(event.eventId)
.key,
// Pangea#
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(
AppConfig.borderRadius,
),
),
padding: noBubble || noPadding
? EdgeInsets.zero
: const EdgeInsets.symmetric(
horizontal: 16,
vertical: 8,
),
constraints: const BoxConstraints(
maxWidth:
FluffyThemes.columnWidth * 1.5,
),
child: Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment:
CrossAxisAlignment.start,
children: <Widget>[
if (event.relationshipType ==
RelationshipTypes.reply)
FutureBuilder<Event?>(
future: event
.getReplyEvent(timeline),
builder: (
BuildContext context,
snapshot,
) {
final replyEvent = snapshot
.hasData
? snapshot.data!
: Event(
eventId: event
.relationshipEventId!,
content: {
'msgtype':
'm.text',
'body': '...',
},
senderId:
event.senderId,
type:
'm.room.message',
room: event.room,
status: EventStatus
.sent,
originServerTs:
DateTime.now(),
);
return Padding(
padding:
const EdgeInsets.only(
bottom: 4.0,
),
child: InkWell(
borderRadius:
ReplyContent
.borderRadius,
onTap: () =>
scrollToEventId(
replyEvent.eventId,
),
child: AbsorbPointer(
child: ReplyContent(
replyEvent,
ownMessage:
ownMessage,
timeline: timeline,
),
),
),
);
},
),
MessageContent(
displayEvent,
textColor: textColor,
onInfoTab: onInfoTab,
borderRadius: borderRadius,
// #Pangea
selected: selected,
pangeaMessageEvent:
toolbarController
?.pangeaMessageEvent,
immersionMode: immersionMode,
toolbarController:
toolbarController,
// Pangea#
),
if (event.hasAggregatedEvents(
timeline,
RelationshipTypes.edit,
)
// #Pangea
||
(toolbarController
?.pangeaMessageEvent
.showUseType ??
false)
// Pangea#
)
Padding(
padding:
const EdgeInsets.only(
top: 4.0,
),
child: Row(
mainAxisSize:
MainAxisSize.min,
children: [
// #Pangea
if (toolbarController
?.pangeaMessageEvent
.showUseType ??
false) ...[
toolbarController!
.pangeaMessageEvent
.useType
.iconView(
context,
textColor
.withAlpha(164),
),
const SizedBox(
width: 4),
],
if (event
.hasAggregatedEvents(
timeline,
RelationshipTypes.edit,
)) ...[
// Pangea#
Icon(
Icons.edit_outlined,
color: textColor
.withAlpha(164),
size: 14,
),
Text(
' - ${displayEvent.originServerTs.localizedTimeShort(context)}',
style: TextStyle(
color: textColor
.withAlpha(164),
fontSize: 12,
),
),
],
],
),
),
],
],
),
),
),
],
),
),
),
),
),
],
),
),
),
],
),
],
),
),
],
),
);
},
);
@ -472,11 +535,8 @@ class Message extends StatelessWidget {
child: Center(
child: Material(
color: displayTime
? Theme.of(context).colorScheme.background
: Theme.of(context)
.colorScheme
.background
.withOpacity(0.33),
? Theme.of(context).colorScheme.surface
: Theme.of(context).colorScheme.surface.withOpacity(0.33),
borderRadius:
BorderRadius.circular(AppConfig.borderRadius / 2),
clipBehavior: Clip.antiAlias,
@ -544,13 +604,7 @@ class Message extends StatelessWidget {
container = row;
}
return Container(
alignment: Alignment.center,
color: selected
? Theme.of(context).colorScheme.secondaryContainer.withAlpha(100)
: highlightMarker
? Theme.of(context).colorScheme.tertiaryContainer.withAlpha(100)
: Colors.transparent,
return Center(
child: Swipeable(
key: ValueKey(event.eventId),
background: const Padding(
@ -559,91 +613,21 @@ class Message extends StatelessWidget {
child: Icon(Icons.check_outlined),
),
),
direction: SwipeDirection.endToStart,
direction: AppConfig.swipeRightToLeftToReply
? SwipeDirection.endToStart
: SwipeDirection.startToEnd,
onSwipe: (_) => onSwipe(),
child: HoverBuilder(
builder: (context, hovered) => Stack(
children: [
Container(
constraints: const BoxConstraints(
maxWidth: FluffyThemes.columnWidth * 2.5,
),
padding: EdgeInsets.only(
left: 8.0,
right: 8.0,
top: nextEventSameSender ? 1.0 : 4.0,
bottom: previousEventSameSender ? 1.0 : 4.0,
),
child: container,
),
// #Pangea
// Positioned(
// left: ownMessage ? null : 48,
// right: ownMessage ? 4 : null,
// top: displayTime ? 38 : 0,
// child: AnimatedScale(
// duration: Duration(
// milliseconds:
// (FluffyThemes.animationDuration.inMilliseconds / 2)
// .floor(),
// ),
// curve: FluffyThemes.animationCurve,
// scale: !longPressSelect && hovered ? 1 : 0,
// alignment: Alignment.center,
// child: Material(
// color: Theme.of(context)
// .colorScheme
// .secondaryContainer
// .withOpacity(0.9),
// elevation:
// Theme.of(context).appBarTheme.scrolledUnderElevation ??
// 4,
// borderRadius: BorderRadius.circular(AppConfig.borderRadius),
// shadowColor: Theme.of(context).appBarTheme.shadowColor,
// child: Row(
// mainAxisSize: MainAxisSize.min,
// children: [
// if (event.room.canSendDefaultMessages)
// SizedBox(
// width: 32,
// height: 32,
// child: IconButton(
// icon: Icon(
// Icons.reply_outlined,
// size: 16,
// color: Theme.of(context)
// .colorScheme
// .onTertiaryContainer,
// ),
// tooltip: L10n.of(context)!.reply,
// onPressed: event.room.canSendDefaultMessages
// ? () => onSwipe()
// : null,
// ),
// ),
// SizedBox(
// width: 32,
// height: 32,
// child: IconButton(
// icon: Icon(
// Icons.more_vert,
// size: 16,
// color: Theme.of(context)
// .colorScheme
// .onTertiaryContainer,
// ),
// tooltip: L10n.of(context)!.select,
// onPressed: () => onSelect(event),
// ),
// ),
// ],
// ),
// ),
// ),
// ),
// Pangea#
],
child: Container(
constraints: const BoxConstraints(
maxWidth: FluffyThemes.columnWidth * 2.5,
),
padding: EdgeInsets.only(
left: 8.0,
right: 8.0,
top: nextEventSameSender ? 1.0 : 4.0,
bottom: previousEventSameSender ? 1.0 : 4.0,
),
child: container,
),
),
);

@ -5,6 +5,7 @@ import 'package:fluffychat/pangea/utils/get_chat_list_item_subtitle.dart';
import 'package:fluffychat/utils/matrix_sdk_extensions/matrix_locals.dart';
import 'package:fluffychat/utils/room_status_extension.dart';
import 'package:fluffychat/widgets/hover_builder.dart';
import 'package:fluffychat/widgets/matrix.dart';
import 'package:flutter/material.dart';
import 'package:flutter_gen/gen_l10n/l10n.dart';
import 'package:future_loading_dialog/future_loading_dialog.dart';
@ -13,7 +14,6 @@ import 'package:matrix/matrix.dart';
import '../../config/themes.dart';
import '../../utils/date_time_extension.dart';
import '../../widgets/avatar.dart';
import '../../widgets/matrix.dart';
enum ArchivedRoomAction { delete, rejoin }
@ -24,6 +24,7 @@ class ChatListItem extends StatelessWidget {
final void Function()? onLongPress;
final void Function()? onForget;
final void Function() onTap;
final String? filter;
const ChatListItem(
this.room, {
@ -32,6 +33,7 @@ class ChatListItem extends StatelessWidget {
required this.onTap,
this.onLongPress,
this.onForget,
this.filter,
super.key,
});
@ -69,8 +71,11 @@ class ChatListItem extends StatelessWidget {
final isMuted = room.pushRuleState != PushRuleState.notify;
final typingText = room.getLocalizedTypingText(context);
final lastEvent = room.lastEvent;
final ownMessage = lastEvent?.senderId == Matrix.of(context).client.userID;
final ownMessage = lastEvent?.senderId == room.client.userID;
final unread = room.isUnread || room.membership == Membership.invite;
final theme = Theme.of(context);
final directChatMatrixId = room.directChatMatrixID;
final isDirectChat = directChatMatrixId != null;
final unreadBubbleSize = unread || room.hasNewMessages
? room.notificationCount > 0
? 20.0
@ -78,13 +83,22 @@ class ChatListItem extends StatelessWidget {
: 0.0;
final hasNotifications = room.notificationCount > 0;
final backgroundColor = selected
? Theme.of(context).colorScheme.primaryContainer
? theme.colorScheme.primaryContainer
: activeChat
? Theme.of(context).colorScheme.secondaryContainer
? theme.colorScheme.secondaryContainer
: null;
final displayname = room.getLocalizedDisplayname(
MatrixLocals(L10n.of(context)!),
);
final filter = this.filter;
if (filter != null && !displayname.toLowerCase().contains(filter)) {
return const SizedBox.shrink();
}
final needLastEventSender = lastEvent == null
? false
: room.getState(EventTypes.RoomMember, lastEvent.senderId) == null;
return Padding(
padding: const EdgeInsets.symmetric(
horizontal: 8,
@ -101,14 +115,46 @@ class ChatListItem extends StatelessWidget {
visualDensity: const VisualDensity(vertical: -0.5),
contentPadding: const EdgeInsets.symmetric(horizontal: 8),
onLongPress: onLongPress,
leading: Avatar(
mxContent: room.avatar,
name: displayname,
//#Pangea
littleIcon: room.roomTypeIcon,
// Pangea#
presenceUserId: room.directChatMatrixID,
presenceBackgroundColor: backgroundColor,
leading: Stack(
clipBehavior: Clip.none,
children: [
HoverBuilder(
builder: (context, hovered) => AnimatedScale(
duration: FluffyThemes.animationDuration,
curve: FluffyThemes.animationCurve,
scale: hovered ? 1.1 : 1.0,
child: Avatar(
mxContent: room.avatar,
name: displayname,
//#Pangea
littleIcon: room.roomTypeIcon,
// Pangea#
presenceUserId: directChatMatrixId,
presenceBackgroundColor: backgroundColor,
onTap: onLongPress,
),
),
),
Positioned(
bottom: -2,
right: -2,
child: AnimatedScale(
duration: FluffyThemes.animationDuration,
curve: FluffyThemes.animationCurve,
scale: (hovered || selected) ? 1.0 : 0.0,
child: Material(
color: backgroundColor,
borderRadius: BorderRadius.circular(16),
child: Icon(
selected
? Icons.check_circle
: Icons.check_circle_outlined,
size: 18,
),
),
),
),
],
),
title: Row(
children: <Widget>[
@ -139,7 +185,7 @@ class ChatListItem extends StatelessWidget {
child: Icon(
Icons.push_pin,
size: 16,
color: Theme.of(context).colorScheme.primary,
color: theme.colorScheme.primary,
),
),
if (lastEvent != null && room.membership != Membership.invite)
@ -150,8 +196,8 @@ class ChatListItem extends StatelessWidget {
style: TextStyle(
fontSize: 13,
color: unread
? Theme.of(context).colorScheme.secondary
: Theme.of(context).textTheme.bodyMedium!.color,
? theme.colorScheme.secondary
: theme.textTheme.bodyMedium!.color,
),
),
),
@ -179,7 +225,7 @@ class ChatListItem extends StatelessWidget {
padding: const EdgeInsets.only(right: 4),
child: Icon(
Icons.edit_outlined,
color: Theme.of(context).colorScheme.secondary,
color: theme.colorScheme.secondary,
size: 14,
),
),
@ -188,24 +234,26 @@ class ChatListItem extends StatelessWidget {
? Text(
typingText,
style: TextStyle(
color: Theme.of(context).colorScheme.primary,
color: theme.colorScheme.primary,
),
maxLines: 1,
softWrap: false,
)
: FutureBuilder<String>(
: FutureBuilder(
key: ValueKey(lastEvent?.eventId),
// #Pangea
// future: room.lastEvent?.calcLocalizedBody(
// MatrixLocals(L10n.of(context)!),
// hideReply: true,
// hideEdit: true,
// plaintextBody: true,
// removeMarkdown: true,
// withSenderNamePrefix: !room.isDirectChat ||
// room.directChatMatrixID !=
// room.lastEvent?.senderId,
// ) ??
// Future.value(L10n.of(context)!.emptyChat),
// future: needLastEventSender
// ? lastEvent.calcLocalizedBody(
// MatrixLocals(L10n.of(context)!),
// hideReply: true,
// hideEdit: true,
// plaintextBody: true,
// removeMarkdown: true,
// withSenderNamePrefix: !isDirectChat ||
// directChatMatrixId !=
// room.lastEvent?.senderId,
// )
// : null,
future: room.lastEvent != null
? GetChatListItemSubtitle().getSubtitle(
L10n.of(context)!,
@ -214,42 +262,36 @@ class ChatListItem extends StatelessWidget {
)
: Future.value(L10n.of(context)!.emptyChat),
// Pangea#
builder: (context, snapshot) {
return Text(
room.membership == Membership.invite
? room.isDirectChat
? L10n.of(context)!.invitePrivateChat
: L10n.of(context)!.inviteGroupChat
: snapshot.data ??
room.lastEvent
?.calcLocalizedBodyFallback(
MatrixLocals(L10n.of(context)!),
hideReply: true,
hideEdit: true,
plaintextBody: true,
removeMarkdown: true,
withSenderNamePrefix:
!room.isDirectChat ||
room.directChatMatrixID !=
room.lastEvent?.senderId,
) ??
L10n.of(context)!.emptyChat,
softWrap: false,
maxLines: 1,
overflow: TextOverflow.ellipsis,
style: TextStyle(
fontWeight: unread || room.hasNewMessages
? FontWeight.bold
: null,
color: Theme.of(context)
.colorScheme
.onSurfaceVariant,
decoration: room.lastEvent?.redacted == true
? TextDecoration.lineThrough
: null,
),
);
},
initialData: lastEvent?.calcLocalizedBodyFallback(
MatrixLocals(L10n.of(context)!),
hideReply: true,
hideEdit: true,
plaintextBody: true,
removeMarkdown: true,
withSenderNamePrefix: !isDirectChat ||
directChatMatrixId !=
room.lastEvent?.senderId,
),
builder: (context, snapshot) => Text(
room.membership == Membership.invite
? isDirectChat
? L10n.of(context)!.invitePrivateChat
: L10n.of(context)!.inviteGroupChat
: snapshot.data ??
L10n.of(context)!.emptyChat,
softWrap: false,
maxLines: 1,
overflow: TextOverflow.ellipsis,
style: TextStyle(
fontWeight: unread || room.hasNewMessages
? FontWeight.bold
: null,
color: theme.colorScheme.onSurfaceVariant,
decoration: room.lastEvent?.redacted == true
? TextDecoration.lineThrough
: null,
),
),
),
),
const SizedBox(width: 8),
@ -278,8 +320,8 @@ class ChatListItem extends StatelessWidget {
room.membership == Membership.invite
? Colors.red
: hasNotifications || room.markedUnread
? Theme.of(context).colorScheme.primary
: Theme.of(context).colorScheme.primaryContainer,
? theme.colorScheme.primary
: theme.colorScheme.primaryContainer,
borderRadius:
BorderRadius.circular(AppConfig.borderRadius),
),
@ -291,12 +333,8 @@ class ChatListItem extends StatelessWidget {
color: room.highlightCount > 0
? Colors.white
: hasNotifications
? Theme.of(context)
.colorScheme
.onPrimary
: Theme.of(context)
.colorScheme
.onPrimaryContainer,
? theme.colorScheme.onPrimary
: theme.colorScheme.onPrimaryContainer,
fontSize: 13,
),
)
@ -307,19 +345,7 @@ class ChatListItem extends StatelessWidget {
),
onTap: onTap,
trailing: onForget == null
? hovered || selected
? IconButton(
color: selected
? Theme.of(context).colorScheme.primary
: null,
icon: Icon(
selected
? Icons.check_circle
: Icons.check_circle_outlined,
),
onPressed: onLongPress,
)
: null
? null
: IconButton(
icon: const Icon(Icons.delete_outlined),
onPressed: onForget,

@ -75,7 +75,7 @@ class HomeserverPickerController extends State<HomeserverPicker> {
if (homeserverController.text == _lastCheckedUrl) return;
_lastCheckedUrl = homeserverController.text;
setState(() {
error = _rawLoginTypes = loginHomeserverSummary = null;
error = _rawLoginTypes = loginFlows = null;
isLoading = true;
});
@ -85,7 +85,8 @@ class HomeserverPickerController extends State<HomeserverPicker> {
homeserver = Uri.https(homeserverController.text, '');
}
final client = Matrix.of(context).getLoginClient();
loginHomeserverSummary = await client.checkHomeserver(homeserver);
final (_, _, loginFlows) = await client.checkHomeserver(homeserver);
this.loginFlows = loginFlows;
if (supportsSso) {
_rawLoginTypes = await client.request(
RequestType.GET,
@ -101,11 +102,10 @@ class HomeserverPickerController extends State<HomeserverPicker> {
}
}
HomeserverSummary? loginHomeserverSummary;
List<LoginFlow>? loginFlows;
bool _supportsFlow(String flowType) =>
loginHomeserverSummary?.loginFlows.any((flow) => flow.type == flowType) ??
false;
loginFlows?.any((flow) => flow.type == flowType) ?? false;
bool get supportsSso => _supportsFlow('m.login.sso');

@ -299,7 +299,10 @@ class UserBottomSheetView extends StatelessWidget {
BorderRadius.circular(AppConfig.borderRadius / 2),
color: Theme.of(context).colorScheme.onInverseSurface,
child: DropdownButton<int>(
onChanged: user.canChangePowerLevel
onChanged: user.canChangePowerLevel ||
// Workaround until https://github.com/famedly/matrix-dart-sdk/pull/1765
(user.room.canChangePowerLevel &&
user.id == user.room.client.userID)
? controller.setPowerLevel
: null,
value: {0, 50, 100}.contains(user.powerLevel)

@ -123,9 +123,6 @@ class PangeaController {
homeserver = Uri.https(homeServer, '');
}
matrixState.loginHomeserverSummary =
await matrixState.getLoginClient().checkHomeserver(homeserver);
try {
await matrixState.getLoginClient().register();
matrixState.loginRegistrationSupported = true;

@ -10,6 +10,7 @@ import 'package:matrix/matrix.dart';
import 'package:path_provider/path_provider.dart';
import 'package:universal_html/html.dart' as html;
// ignore: deprecated_member_use
class FlutterHiveCollectionsDatabase extends HiveCollectionsDatabase {
FlutterHiveCollectionsDatabase(
super.name,

@ -75,11 +75,19 @@ Future<MatrixSdkDatabase> _constructDatabase(Client client) async {
final cipher = await getDatabaseCipher();
final fileStoragePath = PlatformInfos.isIOS || PlatformInfos.isMacOS
final databaseDirectory = PlatformInfos.isIOS || PlatformInfos.isMacOS
? await getLibraryDirectory()
: await getApplicationSupportDirectory();
Directory? fileStorageLocation;
try {
fileStorageLocation = await getTemporaryDirectory();
} on MissingPlatformDirectoryException catch (_) {
Logs().w(
'No temporary directory for file cache available on this platform.',
);
}
final path = join(fileStoragePath.path, '${client.clientName}.sqlite');
final path = join(databaseDirectory.path, '${client.clientName}.sqlite');
// fix dlopen for old Android
await applyWorkaroundToOpenSqlCipherOnOldAndroidVersions();
@ -119,7 +127,7 @@ Future<MatrixSdkDatabase> _constructDatabase(Client client) async {
client.clientName,
database: database,
maxFileSize: 1024 * 1024 * 10,
fileStoragePath: fileStoragePath,
fileStorageLocation: fileStorageLocation?.uri,
deleteFilesAfterDuration: const Duration(days: 30),
);
}

@ -72,7 +72,6 @@ class MatrixState extends State<Matrix> with WidgetsBindingObserver {
// Pangea#
SharedPreferences get store => widget.store;
HomeserverSummary? loginHomeserverSummary;
XFile? loginAvatar;
String? loginUsername;
bool? loginRegistrationSupported;

@ -21,7 +21,7 @@ Future<int?> showPermissionChooser(
return L10n.of(context)!.pleaseEnterANumber;
}
final level = int.tryParse(text);
if (level == null || level < 0) {
if (level == null) {
return L10n.of(context)!.pleaseEnterANumber;
}
return null;

File diff suppressed because it is too large Load Diff

@ -1409,18 +1409,10 @@ packages:
dependency: "direct main"
description:
name: matrix
sha256: f829dd542f354e5073e3b43aaed3adc2829e762a9ec50a3f186ffd7dddc36d5e
sha256: "36c7e13d5d7420898f2597d6f5f0611a9da8114a0fde11f41b9e54cd1140b05f"
url: "https://pub.dev"
source: hosted
version: "0.26.1"
matrix_api_lite:
dependency: transitive
description:
name: matrix_api_lite
sha256: "0e92d3402b4cbb8ab9283fd2fbe44147facf6f73de88f5adf0b3123bc5114bc1"
url: "https://pub.dev"
source: hosted
version: "1.7.3"
version: "0.27.0"
meta:
dependency: transitive
description:

@ -71,7 +71,7 @@ dependencies:
keyboard_shortcuts: ^0.1.4
latlong2: ^0.9.1
linkify: ^5.0.0
matrix: ^0.26.1
matrix: ^0.27.0
native_imaging: ^0.1.0
package_info_plus: ^6.0.0
pasteboard: ^0.2.0

@ -1,8 +1,8 @@
// ignore_for_file: depend_on_referenced_packages
import 'package:matrix/encryption/utils/key_verification.dart';
import 'package:matrix/fake_matrix_api.dart';
import 'package:matrix/matrix.dart';
import 'package:matrix_api_lite/fake_matrix_api.dart';
import 'package:fluffychat/utils/matrix_sdk_extensions/flutter_hive_collections_database.dart';

Loading…
Cancel
Save