chore: update Matrix SDK

Signed-off-by: TheOneWithTheBraid <the-one@with-the-braid.cf>
This commit is contained in:
TheOneWithTheBraid 2022-06-07 15:45:29 +02:00
parent 0dd7ac39c0
commit b13d1215b4
31 changed files with 235 additions and 183 deletions

View File

@ -154,8 +154,7 @@ abstract class FluffyThemes {
dividerColor: Colors.blueGrey.shade600, dividerColor: Colors.blueGrey.shade600,
elevatedButtonTheme: ElevatedButtonThemeData( elevatedButtonTheme: ElevatedButtonThemeData(
style: ElevatedButton.styleFrom( style: ElevatedButton.styleFrom(
primary: AppConfig.chatColor, foregroundColor: Colors.white, backgroundColor: AppConfig.chatColor,
onPrimary: Colors.white,
minimumSize: const Size.fromHeight(48), minimumSize: const Size.fromHeight(48),
textStyle: const TextStyle(fontSize: 16), textStyle: const TextStyle(fontSize: 16),
padding: const EdgeInsets.all(12), padding: const EdgeInsets.all(12),

View File

@ -22,7 +22,6 @@ import 'config/themes.dart';
import 'utils/background_push.dart'; import 'utils/background_push.dart';
import 'utils/custom_scroll_behaviour.dart'; import 'utils/custom_scroll_behaviour.dart';
import 'utils/localized_exception_extension.dart'; import 'utils/localized_exception_extension.dart';
import 'utils/platform_infos.dart';
import 'widgets/lock_screen.dart'; import 'widgets/lock_screen.dart';
import 'widgets/matrix.dart'; import 'widgets/matrix.dart';

View File

@ -128,8 +128,7 @@ class _BootstrapDialogState extends State<BootstrapDialog> {
const SizedBox(height: 16), const SizedBox(height: 16),
ElevatedButton.icon( ElevatedButton.icon(
style: ElevatedButton.styleFrom( style: ElevatedButton.styleFrom(
primary: Theme.of(context).secondaryHeaderColor, foregroundColor: Theme.of(context).primaryColor, backgroundColor: Theme.of(context).secondaryHeaderColor,
onPrimary: Theme.of(context).primaryColor,
), ),
icon: const Icon(Icons.check_outlined), icon: const Icon(Icons.check_outlined),
label: Text(L10n.of(context)!.next), label: Text(L10n.of(context)!.next),
@ -261,8 +260,7 @@ class _BootstrapDialogState extends State<BootstrapDialog> {
const SizedBox(height: 32), const SizedBox(height: 32),
ElevatedButton.icon( ElevatedButton.icon(
style: ElevatedButton.styleFrom( style: ElevatedButton.styleFrom(
primary: Theme.of(context).secondaryHeaderColor, foregroundColor: Theme.of(context).primaryColor, backgroundColor: Theme.of(context).secondaryHeaderColor,
onPrimary: Theme.of(context).primaryColor,
), ),
icon: const Icon(Icons.cast_connected_outlined), icon: const Icon(Icons.cast_connected_outlined),
label: Text(L10n.of(context)!.transferFromAnotherDevice), label: Text(L10n.of(context)!.transferFromAnotherDevice),
@ -284,8 +282,7 @@ class _BootstrapDialogState extends State<BootstrapDialog> {
const SizedBox(height: 16), const SizedBox(height: 16),
ElevatedButton.icon( ElevatedButton.icon(
style: ElevatedButton.styleFrom( style: ElevatedButton.styleFrom(
primary: Theme.of(context).secondaryHeaderColor, foregroundColor: Colors.red, backgroundColor: Theme.of(context).secondaryHeaderColor,
onPrimary: Colors.red,
), ),
icon: const Icon(Icons.delete_outlined), icon: const Icon(Icons.delete_outlined),
label: Text(L10n.of(context)!.securityKeyLost), label: Text(L10n.of(context)!.securityKeyLost),

View File

@ -29,10 +29,11 @@ class ChatAppBarTitle extends StatelessWidget {
? () => showModalBottomSheet( ? () => showModalBottomSheet(
context: context, context: context,
builder: (c) => UserBottomSheet( builder: (c) => UserBottomSheet(
user: room.getUserByMXIDSync(directChatMatrixID), user: room
.unsafeGetUserFromMemoryOrFallback(directChatMatrixID),
outerContext: context, outerContext: context,
onMention: () => controller.sendController.text += onMention: () => controller.sendController.text +=
'${room.getUserByMXIDSync(directChatMatrixID).mention} ', '${room.unsafeGetUserFromMemoryOrFallback(directChatMatrixID).mention} ',
), ),
) )
: () => VRouter.of(context).toSegments(['rooms', room.id, 'details']), : () => VRouter.of(context).toSegments(['rooms', room.id, 'details']),

View File

@ -348,15 +348,20 @@ class ChatView extends StatelessWidget {
context: context:
context, context,
builder: (c) => builder: (c) =>
UserBottomSheet( FutureBuilder<User?>(
user: event future: event.eventSender,
.sender, builder: (context, snapshot) {
final user = snapshot.data ?? event.senderFromMemoryOrFallback;
return UserBottomSheet(
user: user,
outerContext: outerContext:
context, context,
onMention: () => controller onMention: () => controller
.sendController .sendController
.text += '${event.sender.mention} ', .text += '${user.mention} ',
), );
}
),
), ),
unfold: controller unfold: controller
.unfold, .unfold,

View File

@ -20,6 +20,7 @@ extension EventInfoDialogExtension on Event {
class EventInfoDialog extends StatelessWidget { class EventInfoDialog extends StatelessWidget {
final Event event; final Event event;
final L10n l10n; final L10n l10n;
const EventInfoDialog({ const EventInfoDialog({
required this.event, required this.event,
required this.l10n, required this.l10n,
@ -46,14 +47,19 @@ class EventInfoDialog extends StatelessWidget {
), ),
body: ListView( body: ListView(
children: [ children: [
ListTile( FutureBuilder<User?>(
leading: Avatar( future: event.eventSender,
mxContent: event.sender.avatarUrl, builder: (context, snapshot) {
name: event.sender.calcDisplayname(), final user = snapshot.data ?? event.senderFromMemoryOrFallback;
), return ListTile(
title: Text(L10n.of(context)!.sender), leading: Avatar(
subtitle: mxContent: user.avatarUrl,
Text('${event.sender.calcDisplayname()} [${event.senderId}]'), name: user.calcDisplayname(),
),
title: Text(L10n.of(context)!.sender),
subtitle: Text('${user.calcDisplayname()} [${event.senderId}]'),
);
},
), ),
ListTile( ListTile(
title: Text(L10n.of(context)!.time), title: Text(L10n.of(context)!.time),

View File

@ -206,8 +206,7 @@ class _ImageBubbleState extends State<ImageBubble> {
children: [ children: [
OutlinedButton.icon( OutlinedButton.icon(
style: OutlinedButton.styleFrom( style: OutlinedButton.styleFrom(
backgroundColor: Theme.of(context).scaffoldBackgroundColor, foregroundColor: Theme.of(context).textTheme.bodyText1!.color, backgroundColor: Theme.of(context).scaffoldBackgroundColor,
primary: Theme.of(context).textTheme.bodyText1!.color,
), ),
icon: const Icon(Icons.download_outlined), icon: const Icon(Icons.download_outlined),
onPressed: () => widget.event.saveFile(context), onPressed: () => widget.event.saveFile(context),
@ -385,8 +384,7 @@ class _ImageBubbleState extends State<ImageBubble> {
children: [ children: [
OutlinedButton( OutlinedButton(
style: OutlinedButton.styleFrom( style: OutlinedButton.styleFrom(
backgroundColor: Theme.of(context).scaffoldBackgroundColor, foregroundColor: Theme.of(context).textTheme.bodyText1!.color, backgroundColor: Theme.of(context).scaffoldBackgroundColor,
primary: Theme.of(context).textTheme.bodyText1!.color,
), ),
onPressed: () => onTap(context), onPressed: () => onTap(context),
child: Text( child: Text(

View File

@ -75,7 +75,7 @@ class Message extends StatelessWidget {
EventTypes.Sticker, EventTypes.Sticker,
EventTypes.Encrypted, EventTypes.Encrypted,
].contains(nextEvent!.type) ].contains(nextEvent!.type)
? nextEvent!.sender.id == event.sender.id && !displayTime ? nextEvent!.senderId == event.senderId && !displayTime
: false; : false;
final textColor = ownMessage final textColor = ownMessage
? Theme.of(context).colorScheme.onPrimary ? Theme.of(context).colorScheme.onPrimary
@ -125,11 +125,17 @@ class Message extends StatelessWidget {
), ),
), ),
)) ))
: Avatar( : FutureBuilder<User?>(
mxContent: event.sender.avatarUrl, future: event.eventSender,
name: event.sender.calcDisplayname(), builder: (context, snapshot) {
onTap: () => onAvatarTab!(event), final user = snapshot.data ?? event.senderFromMemoryOrFallback;
), return Avatar(
mxContent: user.avatarUrl,
name: user.calcDisplayname(),
onTap: () => onAvatarTab!(event),
);
}
),
Expanded( Expanded(
child: Column( child: Column(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
@ -140,14 +146,20 @@ class Message extends StatelessWidget {
padding: const EdgeInsets.only(left: 8.0, bottom: 4), padding: const EdgeInsets.only(left: 8.0, bottom: 4),
child: ownMessage || event.room.isDirectChat child: ownMessage || event.room.isDirectChat
? const SizedBox(height: 12) ? const SizedBox(height: 12)
: Text( : FutureBuilder<User?>(
event.sender.calcDisplayname(), future: event.eventSender,
style: TextStyle( builder: (context, snapshot) {
fontSize: 12, final user = snapshot.data ?? event.senderFromMemoryOrFallback;
fontWeight: FontWeight.bold, return Text(
color: event.sender.calcDisplayname().color, user.calcDisplayname(),
), style: TextStyle(
), fontSize: 12,
fontWeight: FontWeight.bold,
color: user.calcDisplayname().color,
),
);
}
),
), ),
Container( Container(
alignment: alignment, alignment: alignment,

View File

@ -34,7 +34,7 @@ class MessageContent extends StatelessWidget {
content: Text( content: Text(
event.type == EventTypes.Encrypted event.type == EventTypes.Encrypted
? L10n.of(context)!.needPantalaimonWarning ? L10n.of(context)!.needPantalaimonWarning
: event.getLocalizedBody( : await event.getLocalizedBodyAsync(
MatrixLocals(L10n.of(context)!), MatrixLocals(L10n.of(context)!),
), ),
))); )));
@ -172,12 +172,19 @@ class MessageContent extends StatelessWidget {
textmessage: textmessage:
default: default:
if (event.redacted) { if (event.redacted) {
return _ButtonContent( return FutureBuilder<User?>(
label: L10n.of(context)!
.redactedAnEvent(event.sender.calcDisplayname()), future: event.eventSender,
icon: const Icon(Icons.delete_outlined), builder: (context, snapshot) {
textColor: buttonTextColor, final user = snapshot.data ?? event.senderFromMemoryOrFallback;
onPressed: () => onInfoTab!(event), return _ButtonContent(
label: L10n.of(context)!
.redactedAnEvent(user.calcDisplayname()),
icon: const Icon(Icons.delete_outlined),
textColor: buttonTextColor,
onPressed: () => onInfoTab!(event),
);
}
); );
} }
final bigEmotes = event.onlyEmotes && final bigEmotes = event.onlyEmotes &&
@ -200,19 +207,33 @@ class MessageContent extends StatelessWidget {
); );
} }
case EventTypes.CallInvite: case EventTypes.CallInvite:
return _ButtonContent( return FutureBuilder<User?>(
label: L10n.of(context)!.startedACall(event.sender.calcDisplayname()),
icon: const Icon(Icons.phone_outlined), future: event.eventSender,
textColor: buttonTextColor, builder: (context, snapshot) {
onPressed: () => onInfoTab!(event), final user = snapshot.data ?? event.senderFromMemoryOrFallback;
return _ButtonContent(
label: L10n.of(context)!.startedACall(user.calcDisplayname()),
icon: const Icon(Icons.phone_outlined),
textColor: buttonTextColor,
onPressed: () => onInfoTab!(event),
);
}
); );
default: default:
return _ButtonContent( return FutureBuilder<User?>(
label: L10n.of(context)!
.userSentUnknownEvent(event.sender.calcDisplayname(), event.type), future: event.eventSender,
icon: const Icon(Icons.info_outlined), builder: (context, snapshot) {
textColor: buttonTextColor, final user = snapshot.data ?? event.senderFromMemoryOrFallback;
onPressed: () => onInfoTab!(event), return _ButtonContent(
label: L10n.of(context)!
.userSentUnknownEvent(user.calcDisplayname(), event.type),
icon: const Icon(Icons.info_outlined),
textColor: buttonTextColor,
onPressed: () => onInfoTab!(event),
);
}
); );
} }
} }
@ -239,8 +260,7 @@ class _ButtonContent extends StatelessWidget {
icon: icon, icon: icon,
label: Text(label, overflow: TextOverflow.ellipsis), label: Text(label, overflow: TextOverflow.ellipsis),
style: OutlinedButton.styleFrom( style: OutlinedButton.styleFrom(
primary: textColor, foregroundColor: textColor, backgroundColor: Colors.white.withAlpha(64),
backgroundColor: Colors.white.withAlpha(64),
), ),
); );
} }

View File

@ -39,7 +39,7 @@ class MessageReactions extends StatelessWidget {
); );
} }
reactionMap[key]!.count++; reactionMap[key]!.count++;
reactionMap[key]!.reactors!.add(e.sender); reactionMap[key]!.reactors!.add(e.senderFromMemoryOrFallback);
reactionMap[key]!.reacted |= e.senderId == e.room.client.userID; reactionMap[key]!.reacted |= e.senderId == e.room.client.userID;
} }
} }

View File

@ -83,17 +83,23 @@ class ReplyContent extends StatelessWidget {
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.center, mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[ children: <Widget>[
Text( FutureBuilder<User?>(
displayEvent.sender.calcDisplayname() + ':',
maxLines: 1, future: displayEvent.eventSender,
overflow: TextOverflow.ellipsis, builder: (context, snapshot) {
style: TextStyle( final user = snapshot.data ?? displayEvent.senderFromMemoryOrFallback; return Text(
fontWeight: FontWeight.bold, user.calcDisplayname() + ':',
color: ownMessage maxLines: 1,
? Theme.of(context).colorScheme.onPrimary overflow: TextOverflow.ellipsis,
: Theme.of(context).colorScheme.onBackground, style: TextStyle(
fontSize: fontSize, fontWeight: FontWeight.bold,
), color: ownMessage
? Theme.of(context).colorScheme.onPrimary
: Theme.of(context).colorScheme.onBackground,
fontSize: fontSize,
),
);
}
), ),
replyBody, replyBody,
], ],

View File

@ -94,15 +94,18 @@ class ChatEncryptionSettingsView extends StatelessWidget {
child: ListTile( child: ListTile(
leading: Avatar( leading: Avatar(
mxContent: room mxContent: room
.getUserByMXIDSync(deviceKeys[i].userId) .unsafeGetUserFromMemoryOrFallback(
deviceKeys[i].userId)
.avatarUrl, .avatarUrl,
name: room name: room
.getUserByMXIDSync(deviceKeys[i].userId) .unsafeGetUserFromMemoryOrFallback(
deviceKeys[i].userId)
.calcDisplayname(), .calcDisplayname(),
), ),
title: Text( title: Text(
room room
.getUserByMXIDSync(deviceKeys[i].userId) .unsafeGetUserFromMemoryOrFallback(
deviceKeys[i].userId)
.calcDisplayname(), .calcDisplayname(),
), ),
subtitle: Text( subtitle: Text(

View File

@ -108,8 +108,7 @@ class ConnectPageView extends StatelessWidget {
child: ElevatedButton( child: ElevatedButton(
onPressed: controller.loading ? null : controller.signUp, onPressed: controller.loading ? null : controller.signUp,
style: ElevatedButton.styleFrom( style: ElevatedButton.styleFrom(
primary: Colors.white.withAlpha(200), foregroundColor: Colors.black, backgroundColor: Colors.white.withAlpha(200),
onPrimary: Colors.black,
shadowColor: Colors.white, shadowColor: Colors.white,
), ),
child: controller.loading child: controller.loading
@ -149,8 +148,7 @@ class ConnectPageView extends StatelessWidget {
onPressed: () => controller onPressed: () => controller
.ssoLoginAction(identityProviders.single.id!), .ssoLoginAction(identityProviders.single.id!),
style: ElevatedButton.styleFrom( style: ElevatedButton.styleFrom(
primary: Colors.white.withAlpha(200), foregroundColor: Colors.black, backgroundColor: Colors.white.withAlpha(200),
onPrimary: Colors.black,
shadowColor: Colors.white, shadowColor: Colors.white,
), ),
child: Text(identityProviders.single.name ?? child: Text(identityProviders.single.name ??
@ -177,8 +175,7 @@ class ConnectPageView extends StatelessWidget {
child: ElevatedButton( child: ElevatedButton(
onPressed: controller.loading ? () {} : controller.login, onPressed: controller.loading ? () {} : controller.login,
style: ElevatedButton.styleFrom( style: ElevatedButton.styleFrom(
primary: Colors.white.withAlpha(200), foregroundColor: Colors.black, backgroundColor: Colors.white.withAlpha(200),
onPrimary: Colors.black,
shadowColor: Colors.white, shadowColor: Colors.white,
), ),
child: Text(L10n.of(context)!.login), child: Text(L10n.of(context)!.login),

View File

@ -136,8 +136,7 @@ class HomeserverPickerView extends StatelessWidget {
? () {} ? () {}
: controller.checkHomeserverAction, : controller.checkHomeserverAction,
style: ElevatedButton.styleFrom( style: ElevatedButton.styleFrom(
primary: Colors.white.withAlpha(200), foregroundColor: Colors.black, backgroundColor: Colors.white.withAlpha(200),
onPrimary: Colors.black,
shadowColor: Colors.white, shadowColor: Colors.white,
), ),
child: controller.isLoading child: controller.isLoading

View File

@ -38,7 +38,7 @@ class InvitationSelectionController extends State<InvitationSelection> {
final participantsIds = participants.map((p) => p.stateKey).toList(); final participantsIds = participants.map((p) => p.stateKey).toList();
final contacts = client.rooms final contacts = client.rooms
.where((r) => r.isDirectChat) .where((r) => r.isDirectChat)
.map((r) => r.getUserByMXIDSync(r.directChatMatrixID!)) .map((r) => r.unsafeGetUserFromMemoryOrFallback(r.directChatMatrixID!))
.toList() .toList()
..removeWhere((u) => participantsIds.contains(u.stateKey)); ..removeWhere((u) => participantsIds.contains(u.stateKey));
contacts.sort( contacts.sort(

View File

@ -111,7 +111,7 @@ class _KeyVerificationPageState extends State<KeyVerificationDialog> {
if (directChatId != null) { if (directChatId != null) {
user = widget.request.client user = widget.request.client
.getRoomById(directChatId)! .getRoomById(directChatId)!
.getUserByMXIDSync(widget.request.userId); .unsafeGetUserFromMemoryOrFallback(widget.request.userId);
} }
final displayName = final displayName =
user?.calcDisplayname() ?? widget.request.userId.localpart!; user?.calcDisplayname() ?? widget.request.userId.localpart!;

View File

@ -98,8 +98,7 @@ class LoginView extends StatelessWidget {
? null ? null
: () => controller.login(context), : () => controller.login(context),
style: ElevatedButton.styleFrom( style: ElevatedButton.styleFrom(
primary: Colors.white.withAlpha(200), foregroundColor: Colors.black, backgroundColor: Colors.white.withAlpha(200),
onPrimary: Colors.black,
shadowColor: Colors.white, shadowColor: Colors.white,
), ),
child: controller.loading child: controller.loading
@ -127,8 +126,7 @@ class LoginView extends StatelessWidget {
onPressed: onPressed:
controller.loading ? () {} : controller.passwordForgotten, controller.loading ? () {} : controller.passwordForgotten,
style: ElevatedButton.styleFrom( style: ElevatedButton.styleFrom(
primary: Colors.white.withAlpha(156), foregroundColor: Colors.red, backgroundColor: Colors.white.withAlpha(156),
onPrimary: Colors.red,
shadowColor: Colors.white, shadowColor: Colors.white,
), ),
child: Text(L10n.of(context)!.passwordForgotten), child: Text(L10n.of(context)!.passwordForgotten),

View File

@ -46,13 +46,12 @@ class SearchView extends StatelessWidget {
}).then((QueryPublicRoomsResponse res) { }).then((QueryPublicRoomsResponse res) {
final genericSearchTerm = controller.genericSearchTerm; final genericSearchTerm = controller.genericSearchTerm;
if (genericSearchTerm != null && if (genericSearchTerm != null &&
!res.chunk.any((room) => !res.chunk.any(
(room.aliases?.contains(controller.genericSearchTerm) ?? false) || (room) => room.canonicalAlias == controller.genericSearchTerm)) {
room.canonicalAlias == controller.genericSearchTerm)) {
// we have to tack on the original alias // we have to tack on the original alias
res.chunk.add( res.chunk.add(
PublicRoomsChunk( PublicRoomsChunk(
aliases: [genericSearchTerm], canonicalAlias: genericSearchTerm,
name: genericSearchTerm, name: genericSearchTerm,
numJoinedMembers: 0, numJoinedMembers: 0,
roomId: '!unknown', roomId: '!unknown',

View File

@ -6,7 +6,6 @@ import 'package:vrouter/vrouter.dart';
import 'package:fluffychat/config/app_config.dart'; import 'package:fluffychat/config/app_config.dart';
import 'package:fluffychat/utils/platform_infos.dart'; import 'package:fluffychat/utils/platform_infos.dart';
import '../../config/app_config.dart';
import '../../widgets/content_banner.dart'; import '../../widgets/content_banner.dart';
import 'settings.dart'; import 'settings.dart';

View File

@ -107,8 +107,7 @@ class SignupPageView extends StatelessWidget {
child: ElevatedButton( child: ElevatedButton(
onPressed: controller.loading ? () {} : controller.signup, onPressed: controller.loading ? () {} : controller.signup,
style: ElevatedButton.styleFrom( style: ElevatedButton.styleFrom(
primary: Colors.white.withAlpha(200), foregroundColor: Colors.black, backgroundColor: Colors.white.withAlpha(200),
onPrimary: Colors.black,
shadowColor: Colors.white, shadowColor: Colors.white,
), ),
child: controller.loading child: controller.loading

View File

@ -45,6 +45,7 @@ class StoryPageController extends State<StoryPage> {
Timeline? timeline; Timeline? timeline;
Event? get currentEvent => index < events.length ? events[index] : null; Event? get currentEvent => index < events.length ? events[index] : null;
StoryThemeData get storyThemeData => StoryThemeData get storyThemeData =>
StoryThemeData.fromJson(currentEvent?.content StoryThemeData.fromJson(currentEvent?.content
.tryGetMap<String, dynamic>(StoryThemeData.contentKey) ?? .tryGetMap<String, dynamic>(StoryThemeData.contentKey) ??
@ -275,6 +276,7 @@ class StoryPageController extends State<StoryPage> {
} }
void loadingModeOn() => _setLoadingMode(true); void loadingModeOn() => _setLoadingMode(true);
void loadingModeOff() => _setLoadingMode(false); void loadingModeOff() => _setLoadingMode(false);
final Map<String, Future<MatrixFile>> _fileCache = {}; final Map<String, Future<MatrixFile>> _fileCache = {};
@ -366,21 +368,10 @@ class StoryPageController extends State<StoryPage> {
}) })
: null; : null;
Uri? get avatar => Matrix.of(context) Event? get event => Matrix.of(context)
.client .client
.getRoomById(roomId) .getRoomById(roomId)
?.getState(EventTypes.RoomCreate) ?.getState(EventTypes.RoomCreate);
?.sender
.avatarUrl;
String get title =>
Matrix.of(context)
.client
.getRoomById(roomId)
?.getState(EventTypes.RoomCreate)
?.sender
.calcDisplayname() ??
'Story not found';
Future<void>? loadStory; Future<void>? loadStory;
@ -485,7 +476,9 @@ class StoryPageController extends State<StoryPage> {
case PopupStoryAction.message: case PopupStoryAction.message:
final roomIdResult = await showFutureLoadingDialog( final roomIdResult = await showFutureLoadingDialog(
context: context, context: context,
future: () => currentEvent!.sender.startDirectChat(), future: () async => (await currentEvent!.eventSender ??
currentEvent!.senderFromMemoryOrFallback)
.startDirectChat(),
); );
if (roomIdResult.error != null) return; if (roomIdResult.error != null) return;
VRouter.of(context).toSegments(['rooms', roomIdResult.result!]); VRouter.of(context).toSegments(['rooms', roomIdResult.result!]);

View File

@ -17,6 +17,7 @@ import 'package:fluffychat/widgets/avatar.dart';
class StoryView extends StatelessWidget { class StoryView extends StatelessWidget {
final StoryPageController controller; final StoryPageController controller;
const StoryView(this.controller, {Key? key}) : super(key: key); const StoryView(this.controller, {Key? key}) : super(key: key);
static const List<Shadow> textShadows = [ static const List<Shadow> textShadows = [
@ -55,19 +56,25 @@ class StoryView extends StatelessWidget {
), ),
title: ListTile( title: ListTile(
contentPadding: EdgeInsets.zero, contentPadding: EdgeInsets.zero,
title: Text( title: FutureBuilder<User?>(
controller.title, future: controller.event?.eventSender,
style: const TextStyle( builder: (context, snapshot) {
color: Colors.white, final user = snapshot.data ??
shadows: [ controller.event?.senderFromMemoryOrFallback;
Shadow( return Text(
color: Colors.black, user?.displayName ?? 'Story not found',
offset: Offset(0, 0), style: const TextStyle(
blurRadius: 5, color: Colors.white,
), shadows: [
], Shadow(
), color: Colors.black,
), offset: Offset(0, 0),
blurRadius: 5,
),
],
),
);
}),
subtitle: currentEvent != null subtitle: currentEvent != null
? Text( ? Text(
currentEvent.originServerTs.localizedTime(context), currentEvent.originServerTs.localizedTime(context),
@ -83,10 +90,16 @@ class StoryView extends StatelessWidget {
), ),
) )
: null, : null,
leading: Avatar( leading: FutureBuilder<User?>(
mxContent: controller.avatar, future: controller.event?.eventSender,
name: controller.title, builder: (context, snapshot) {
), final user = snapshot.data ??
controller.event?.senderFromMemoryOrFallback;
return Avatar(
mxContent: user?.avatarUrl,
name: user?.displayName ?? 'Story not found',
);
}),
), ),
actions: currentEvent == null actions: currentEvent == null
? null ? null
@ -142,11 +155,18 @@ class StoryView extends StatelessWidget {
crossAxisAlignment: CrossAxisAlignment.center, crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.center, mainAxisAlignment: MainAxisAlignment.center,
children: [ children: [
Avatar( FutureBuilder<User?>(
mxContent: controller.avatar, future: controller.event?.eventSender,
name: controller.title, builder: (context, snapshot) {
size: 128, final user = snapshot.data ??
fontSize: 64, controller.event?.senderFromMemoryOrFallback;
return Avatar(
mxContent: user?.avatarUrl,
name: user?.displayName ?? 'Story not found',
size: 128,
fontSize: 64,
);
},
), ),
const SizedBox(height: 32), const SizedBox(height: 32),
Text( Text(

View File

@ -12,7 +12,8 @@ extension ClientStoriesExtension on Client {
List<User> get contacts => rooms List<User> get contacts => rooms
.where((room) => room.isDirectChat) .where((room) => room.isDirectChat)
.map((room) => room.getUserByMXIDSync(room.directChatMatrixID!)) .map((room) =>
room.unsafeGetUserFromMemoryOrFallback(room.directChatMatrixID!))
.toList(); .toList();
List<Room> get storiesRooms => rooms List<Room> get storiesRooms => rooms

View File

@ -1,6 +1,7 @@
// ignore_for_file: deprecated_member_use
import 'dart:convert'; import 'dart:convert';
import 'dart:io'; import 'dart:io';
import 'dart:typed_data';
import 'package:flutter/foundation.dart' hide Key; import 'package:flutter/foundation.dart' hide Key;
import 'package:flutter/services.dart'; import 'package:flutter/services.dart';

View File

@ -1,6 +1,7 @@
// ignore_for_file: deprecated_member_use
import 'dart:convert'; import 'dart:convert';
import 'dart:io'; import 'dart:io';
import 'dart:typed_data';
import 'package:flutter/foundation.dart'; import 'package:flutter/foundation.dart';
import 'package:flutter/services.dart'; import 'package:flutter/services.dart';

View File

@ -62,7 +62,7 @@ Future<void> pushHelper(
final matrixLocals = MatrixLocals(l10n); final matrixLocals = MatrixLocals(l10n);
// Calculate the body // Calculate the body
final body = event.getLocalizedBody( final body = await event.getLocalizedBodyAsync(
matrixLocals, matrixLocals,
plaintextBody: true, plaintextBody: true,
withSenderNamePrefix: !event.room.isDirectChat, withSenderNamePrefix: !event.room.isDirectChat,

View File

@ -31,7 +31,7 @@ extension LocalNotificationsExtension on MatrixState {
final event = Event.fromJson(eventUpdate.content, room); final event = Event.fromJson(eventUpdate.content, room);
final title = final title =
room.getLocalizedDisplayname(MatrixLocals(L10n.of(widget.context)!)); room.getLocalizedDisplayname(MatrixLocals(L10n.of(widget.context)!));
final body = event.getLocalizedBody( final body = await event.getLocalizedBodyAsync(
MatrixLocals(L10n.of(widget.context)!), MatrixLocals(L10n.of(widget.context)!),
withSenderNamePrefix: withSenderNamePrefix:
!room.isDirectChat || room.lastEvent?.senderId == client.userID, !room.isDirectChat || room.lastEvent?.senderId == client.userID,
@ -40,7 +40,8 @@ extension LocalNotificationsExtension on MatrixState {
hideEdit: true, hideEdit: true,
removeMarkdown: true, removeMarkdown: true,
); );
final icon = event.sender.avatarUrl?.getThumbnail(client, final sender = await event.eventSender??event.senderFromMemoryOrFallback;
final icon = sender.avatarUrl?.getThumbnail(client,
width: 64, height: 64, method: ThumbnailMethod.crop) ?? width: 64, height: 64, method: ThumbnailMethod.crop) ??
room.avatar?.getThumbnail(client, room.avatar?.getThumbnail(client,
width: 64, height: 64, method: ThumbnailMethod.crop); width: 64, height: 64, method: ThumbnailMethod.crop);

View File

@ -33,7 +33,6 @@ import '../pages/key_verification/key_verification_dialog.dart';
import '../utils/account_bundles.dart'; import '../utils/account_bundles.dart';
import '../utils/background_push.dart'; import '../utils/background_push.dart';
import '../utils/famedlysdk_store.dart'; import '../utils/famedlysdk_store.dart';
import '../utils/platform_infos.dart';
import 'local_notifications_extension.dart'; import 'local_notifications_extension.dart';
// import 'package:flutter_secure_storage/flutter_secure_storage.dart'; // import 'package:flutter_secure_storage/flutter_secure_storage.dart';

View File

@ -17,6 +17,7 @@ class PublicRoomBottomSheet extends StatelessWidget {
final String roomAlias; final String roomAlias;
final BuildContext outerContext; final BuildContext outerContext;
final PublicRoomsChunk? chunk; final PublicRoomsChunk? chunk;
const PublicRoomBottomSheet({ const PublicRoomBottomSheet({
required this.roomAlias, required this.roomAlias,
required this.outerContext, required this.outerContext,
@ -41,9 +42,7 @@ class PublicRoomBottomSheet extends StatelessWidget {
} }
} }
bool _testRoom(PublicRoomsChunk r) => bool _testRoom(PublicRoomsChunk r) => r.canonicalAlias == roomAlias;
r.canonicalAlias == roomAlias ||
(r.aliases?.contains(roomAlias) ?? false);
Future<PublicRoomsChunk> _search(BuildContext context) async { Future<PublicRoomsChunk> _search(BuildContext context) async {
final chunk = this.chunk; final chunk = this.chunk;

View File

@ -7,7 +7,7 @@ packages:
name: _fe_analyzer_shared name: _fe_analyzer_shared
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "31.0.0" version: "36.0.0"
adaptive_dialog: adaptive_dialog:
dependency: "direct main" dependency: "direct main"
description: description:
@ -28,14 +28,14 @@ packages:
name: analyzer name: analyzer
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "2.8.0" version: "3.3.1"
analyzer_plugin: analyzer_plugin:
dependency: transitive dependency: transitive
description: description:
name: analyzer_plugin name: analyzer_plugin
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "0.8.0" version: "0.9.0"
animations: animations:
dependency: "direct main" dependency: "direct main"
description: description:
@ -56,7 +56,7 @@ packages:
name: archive name: archive
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "3.1.11" version: "3.3.0"
args: args:
dependency: transitive dependency: transitive
description: description:
@ -77,7 +77,7 @@ packages:
name: async name: async
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "2.8.2" version: "2.9.0"
audio_session: audio_session:
dependency: transitive dependency: transitive
description: description:
@ -147,7 +147,7 @@ packages:
name: characters name: characters
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "1.2.0" version: "1.2.1"
charcode: charcode:
dependency: transitive dependency: transitive
description: description:
@ -162,20 +162,13 @@ packages:
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "1.3.1" version: "1.3.1"
cli_util:
dependency: transitive
description:
name: cli_util
url: "https://pub.dartlang.org"
source: hosted
version: "0.3.5"
clock: clock:
dependency: transitive dependency: transitive
description: description:
name: clock name: clock
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "1.1.0" version: "1.1.1"
collection: collection:
dependency: "direct main" dependency: "direct main"
description: description:
@ -240,7 +233,7 @@ packages:
name: coverage name: coverage
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "1.2.0" version: "1.5.0"
cross_file: cross_file:
dependency: transitive dependency: transitive
description: description:
@ -254,7 +247,7 @@ packages:
name: crypto name: crypto
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "3.0.1" version: "3.0.2"
csslib: csslib:
dependency: transitive dependency: transitive
description: description:
@ -395,13 +388,20 @@ packages:
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "5.0.1" version: "5.0.1"
enhanced_enum:
dependency: transitive
description:
name: enhanced_enum
url: "https://pub.dartlang.org"
source: hosted
version: "0.1.2"
fake_async: fake_async:
dependency: transitive dependency: transitive
description: description:
name: fake_async name: fake_async
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "1.3.0" version: "1.3.1"
ffi: ffi:
dependency: transitive dependency: transitive
description: description:
@ -788,7 +788,7 @@ packages:
name: hive name: hive
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "2.1.0" version: "2.2.1"
hive_flutter: hive_flutter:
dependency: "direct main" dependency: "direct main"
description: description:
@ -932,7 +932,7 @@ packages:
description: description:
path: "." path: "."
ref: null-safety ref: null-safety
resolved-ref: "2906e65ffaa96afbe6c72e8477d4dfcdfd06c2c3" resolved-ref: a3d4020911860ff091d90638ab708604b71d2c5a
url: "https://github.com/TheOneWithTheBraid/keyboard_shortcuts.git" url: "https://github.com/TheOneWithTheBraid/keyboard_shortcuts.git"
source: git source: git
version: "0.1.4" version: "0.1.4"
@ -998,35 +998,35 @@ packages:
name: matcher name: matcher
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "0.12.11" version: "0.12.12"
material_color_utilities: material_color_utilities:
dependency: transitive dependency: transitive
description: description:
name: material_color_utilities name: material_color_utilities
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "0.1.4" version: "0.1.5"
matrix: matrix:
dependency: "direct main" dependency: "direct main"
description: description:
name: matrix name: matrix
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "0.9.6" version: "0.9.10"
matrix_api_lite: matrix_api_lite:
dependency: transitive dependency: transitive
description: description:
name: matrix_api_lite name: matrix_api_lite
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "0.5.3" version: "1.0.0"
matrix_homeserver_recommendations: matrix_homeserver_recommendations:
dependency: "direct main" dependency: "direct main"
description: description:
name: matrix_homeserver_recommendations name: matrix_homeserver_recommendations
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "0.2.0" version: "0.2.1"
matrix_link_text: matrix_link_text:
dependency: "direct main" dependency: "direct main"
description: description:
@ -1040,7 +1040,7 @@ packages:
name: meta name: meta
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "1.7.0" version: "1.8.0"
mgrs_dart: mgrs_dart:
dependency: transitive dependency: transitive
description: description:
@ -1161,7 +1161,7 @@ packages:
name: path name: path
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "1.8.1" version: "1.8.2"
path_drawing: path_drawing:
dependency: transitive dependency: transitive
description: description:
@ -1618,7 +1618,7 @@ packages:
name: source_span name: source_span
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "1.8.2" version: "1.9.0"
sqflite: sqflite:
dependency: transitive dependency: transitive
description: description:
@ -1653,7 +1653,7 @@ packages:
name: string_scanner name: string_scanner
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "1.1.0" version: "1.1.1"
swipe_to_action: swipe_to_action:
dependency: "direct main" dependency: "direct main"
description: description:
@ -1667,7 +1667,7 @@ packages:
name: sync_http name: sync_http
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "0.3.0" version: "0.3.1"
synchronized: synchronized:
dependency: transitive dependency: transitive
description: description:
@ -1681,28 +1681,28 @@ packages:
name: term_glyph name: term_glyph
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "1.2.0" version: "1.2.1"
test: test:
dependency: transitive dependency: transitive
description: description:
name: test name: test
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "1.20.2" version: "1.21.4"
test_api: test_api:
dependency: transitive dependency: transitive
description: description:
name: test_api name: test_api
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "0.4.9" version: "0.4.12"
test_core: test_core:
dependency: transitive dependency: transitive
description: description:
name: test_core name: test_core
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "0.4.11" version: "0.4.16"
timezone: timezone:
dependency: transitive dependency: transitive
description: description:
@ -1737,7 +1737,7 @@ packages:
name: typed_data name: typed_data
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "1.3.0" version: "1.3.1"
uni_links: uni_links:
dependency: "direct main" dependency: "direct main"
description: description:
@ -1940,14 +1940,14 @@ packages:
name: visibility_detector name: visibility_detector
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "0.2.2" version: "0.3.3"
vm_service: vm_service:
dependency: transitive dependency: transitive
description: description:
name: vm_service name: vm_service
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "8.2.2" version: "9.0.0"
vrouter: vrouter:
dependency: "direct main" dependency: "direct main"
description: description:

View File

@ -57,7 +57,7 @@ dependencies:
keyboard_shortcuts: ^0.1.4 keyboard_shortcuts: ^0.1.4
localstorage: ^4.0.0+1 localstorage: ^4.0.0+1
lottie: ^1.2.2 lottie: ^1.2.2
matrix: ^0.9.4 matrix: ^0.9.10
matrix_homeserver_recommendations: ^0.2.0 matrix_homeserver_recommendations: ^0.2.0
matrix_link_text: ^1.0.2 matrix_link_text: ^1.0.2
native_imaging: native_imaging: