Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

New Room Preview facilities #2373

Draft
wants to merge 4 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 0 additions & 36 deletions app/lib/common/toolkit/buttons/room_chip.dart

This file was deleted.

4 changes: 4 additions & 0 deletions app/lib/common/utils/utils.dart
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,10 @@ List<String> asDartStringList(FfiListFfiString data) {
return data.toList().map((e) => e.toDartString()).toList();
}

extension FfiListFfiStringtoDart on FfiListFfiString {
List<String> toDart() => asDartStringList(this);
}

double? calcGap(BuildContext context) {
// ignore: deprecated_member_use
final double scale = MediaQuery.textScalerOf(context).textScaleFactor;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ class RoomHierarchyJoinButton extends ConsumerWidget {
final String roomId;
final String joinRule;
final String roomName;
final String? viaServerName;
final List<String>? viaServerName;

const RoomHierarchyJoinButton({
super.key,
Expand Down
2 changes: 1 addition & 1 deletion app/lib/features/chat/pages/sub_chats_page.dart
Original file line number Diff line number Diff line change
Expand Up @@ -229,7 +229,7 @@ class SubChatsPage extends ConsumerWidget {
joinRule: roomInfo.joinRuleStr().toLowerCase(),
roomId: roomId,
roomName: roomInfo.name() ?? roomId,
viaServerName: roomInfo.viaServerName(),
viaServerName: roomInfo.viaServerNames().toDart(),
forward: (spaceId) {
goToChat(context, spaceId);
ref.invalidate(spaceRelationsProvider(parentId));
Expand Down
54 changes: 2 additions & 52 deletions app/lib/features/chat/utils.dart
Original file line number Diff line number Diff line change
@@ -1,16 +1,14 @@
import 'package:acter/common/actions/open_link.dart';
import 'package:acter/common/providers/chat_providers.dart';
import 'package:acter/common/providers/room_providers.dart';
import 'package:acter/common/toolkit/buttons/primary_action_button.dart';
import 'package:acter/features/chat/models/chat_input_state/chat_input_state.dart';
import 'package:acter/features/chat/providers/chat_providers.dart';
import 'package:acter/features/room/actions/join_room.dart';
import 'package:acter/features/room/actions/show_room_preview.dart';
import 'package:acter/router/utils.dart';
import 'package:acter_flutter_sdk/acter_flutter_sdk_ffi.dart';
import 'package:acter_trigger_auto_complete/acter_trigger_autocomplete.dart';
import 'package:flutter/material.dart';
import 'package:flutter_chat_types/flutter_chat_types.dart' as types;
import 'package:flutter_gen/gen_l10n/l10n.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:html/dom.dart' as html;
import 'package:html/parser.dart';
Expand Down Expand Up @@ -177,58 +175,10 @@ Future<void> navigateToRoomOrAskToJoin(

/// Ask to join room if not yet joined
else {
askToJoinRoom(context, ref, roomId);
showRoomPreview(context: context, ref: ref, roomIdOrAlias: roomId);
}
}

Future<void> askToJoinRoom(
BuildContext context,
WidgetRef ref,
String roomId,
) async {
await showModalBottomSheet(
context: context,
isDismissible: true,
shape: const RoundedRectangleBorder(
borderRadius: BorderRadius.only(
topRight: Radius.circular(20),
topLeft: Radius.circular(20),
),
),
builder: (context) {
final lang = L10n.of(context);
return Container(
width: double.infinity,
padding: const EdgeInsets.all(20),
child: Column(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.center,
mainAxisSize: MainAxisSize.min,
children: [
Text(lang.youAreNotPartOfThisGroup),
const SizedBox(height: 20),
ActerPrimaryActionButton(
onPressed: () async {
Navigator.pop(context);
final server = roomId.split(':').last;
await joinRoom(
context,
ref,
lang.tryingToJoin(roomId),
roomId,
server,
(roomId) => navigateToRoomOrAskToJoin(context, ref, roomId),
);
},
child: Text(lang.joinRoom),
),
],
),
);
},
);
}

final matrixLinks = RegExp(
'(matrix:|https://matrix.to/#/)([\\S]*)',
caseSensitive: false,
Expand Down
4 changes: 2 additions & 2 deletions app/lib/features/chat/widgets/pill_builder.dart
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import 'package:acter/common/toolkit/buttons/room_chip.dart';
import 'package:acter/features/room/widgets/room_chip.dart';
import 'package:acter/common/toolkit/buttons/user_chip.dart';
import 'package:acter/features/chat/utils.dart';
import 'package:flutter/material.dart';
Expand All @@ -22,7 +22,7 @@ class ActerPillBuilder extends StatelessWidget {
roomId: roomId,
memberId: identifier,
),
'!' => RoomChip(roomId: identifier),
'!' => RoomChip(roomId: identifier, uri: uri),
_ => InkWell(
child: Text(identifier),
onTap: () => onMessageLinkTap(Uri.parse(uri), context),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ class SearchPublicDirectory extends ConsumerWidget {
ref,
lang.tryingToJoin(spaceSearchResult.name() ?? ''),
roomId,
searchServer,
searchServer != null ? [searchServer] : [],
(roomId) => context.pushNamed(
Routes.space.name,
pathParameters: {'spaceId': roomId},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -226,7 +226,7 @@ class MaybeDirectRoomActionWidget extends ConsumerWidget {
ref,
L10n.of(context).tryingToJoin(roomIdOrAlias),
roomIdOrAlias,
serverNames.first,
serverNames,
(roomId) => context.pushNamed(
Routes.forward.name,
pathParameters: {'roomId': roomId},
Expand Down
13 changes: 11 additions & 2 deletions app/lib/features/room/actions/join_room.dart
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
import 'package:acter/common/providers/chat_providers.dart';
import 'package:acter/common/providers/room_providers.dart';
import 'package:acter/common/providers/sdk_provider.dart';
import 'package:acter/common/providers/space_providers.dart';
import 'package:acter/features/home/providers/client_providers.dart';
import 'package:acter_flutter_sdk/acter_flutter_sdk_ffi.dart';
import 'package:flutter/material.dart';
import 'package:flutter_easyloading/flutter_easyloading.dart';
import 'package:flutter_gen/gen_l10n/l10n.dart';
Expand All @@ -15,14 +17,21 @@ Future<String?> joinRoom(
WidgetRef ref,
String displayMsg,
String roomIdOrAlias,
String? server,
List<String>? serverNames,
Function(String)? forward,
) async {
final lang = L10n.of(context);
EasyLoading.show(status: displayMsg);
final client = ref.read(alwaysClientProvider);
try {
final newRoom = await client.joinRoom(roomIdOrAlias, server);
final sdk = await ref.read(sdkProvider.future);
VecStringBuilder servers = sdk.api.newVecStringBuilder();
if (serverNames != null) {
for (final server in serverNames) {
servers.add(server);
}
}
final newRoom = await client.joinRoom(roomIdOrAlias, servers);
final roomId = newRoom.roomIdStr();
// ensure we re-evaluate the room data on our end. This is necessary
// if we knew of the room prior (e.g. we had left it), but hadn’t joined
Expand Down
82 changes: 82 additions & 0 deletions app/lib/features/room/actions/show_room_preview.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
import 'package:acter/common/toolkit/errors/error_page.dart';
import 'package:acter/features/room/providers/room_preview_provider.dart';
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:skeletonizer/skeletonizer.dart';

Future<void> showRoomPreview({
required BuildContext context,
required WidgetRef ref,
required String roomIdOrAlias,
List<String> serverNames = const [],
}) async {
await showModalBottomSheet(
context: context,
isDismissible: true,
shape: const RoundedRectangleBorder(
borderRadius: BorderRadius.only(
topRight: Radius.circular(20),
topLeft: Radius.circular(20),
),
),
builder: (context) => _ShowRoomPreview(
roomIdOrAlias: roomIdOrAlias,
serverNames: serverNames,
),
);
}

class _ShowRoomPreview extends ConsumerWidget {
final String roomIdOrAlias;
final List<String> serverNames;
const _ShowRoomPreview({
required this.roomIdOrAlias,
required this.serverNames,
});

@override
Widget build(BuildContext context, WidgetRef ref) {
final query = (
roomIdOrAlias: roomIdOrAlias,
serverNames: serverNames,
);
final roomPreview = ref.watch(roomPreviewProvider(query));

return Container(
width: double.infinity,
padding: const EdgeInsets.all(20),
child: roomPreview.when(
data: (roomPreview) => Column(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.center,
mainAxisSize: MainAxisSize.min,
children: [
roomHeader(context, ref, roomPreview),
const SizedBox(height: 20),
renderActions(context, ref),
],
),
error: (error, stack) => ErrorPage(
background: loading(),
error: error,
stack: stack,
onRetryTap: () => ref.invalidate(roomPreviewProvider(query)),
),
loading: loading,
),
);
}

Widget loading() => const Skeletonizer(
child: Column(
children: [Text('adbdc'), Text('adc')],
),
);

Widget roomHeader(BuildContext context, WidgetRef ref, preview) =>
Text(preview.name() ?? preview.roomIdStr());

Widget renderActions(BuildContext context, WidgetRef ref) {
return const SizedBox.shrink();
}
}
59 changes: 59 additions & 0 deletions app/lib/features/room/providers/room_preview_provider.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
import 'dart:typed_data';

import 'package:acter/common/providers/room_providers.dart';
import 'package:acter/common/providers/sdk_provider.dart';
import 'package:acter/features/home/providers/client_providers.dart';
import 'package:acter_avatar/acter_avatar.dart';
import 'package:acter_flutter_sdk/acter_flutter_sdk_ffi.dart';
import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:acter/common/extensions/options.dart';

typedef RoomPreviewQuery = ({String roomIdOrAlias, List<String> serverNames});

final roomPreviewProvider = FutureProvider.family
.autoDispose<RoomPreview, RoomPreviewQuery>((ref, query) async {
final sdk = await ref.read(sdkProvider.future);
VecStringBuilder servers = sdk.api.newVecStringBuilder();
for (final server in query.serverNames) {
servers.add(server);
}
final client = ref.watch(alwaysClientProvider);
return client.roomPreview(query.roomIdOrAlias, servers);
});

typedef RoomOrPreview = ({Room? room, RoomPreview? preview});

final roomOrPreviewProvider = FutureProvider.family
.autoDispose<RoomOrPreview, RoomPreviewQuery>((ref, arg) async {
final room = await ref.watch(maybeRoomProvider(arg.roomIdOrAlias).future);
if (room != null) {
return (room: room, preview: null);
}

final preview = await ref.watch(roomPreviewProvider(arg).future);
return (room: null, preview: preview);
});

final _roomPreviewAvatarProvider =
FutureProvider.family<MemoryImage?, RoomPreviewQuery>((ref, q) async {
final sdk = await ref.watch(sdkProvider.future);
final thumbsize = sdk.api.newThumbSize(48, 48);
final room = await ref.watch(roomPreviewProvider(q).future);
if (!room.hasAvatar()) return null;
final avatar = await room.avatar(thumbsize);
return avatar
.data()
.map((data) => MemoryImage(Uint8List.fromList(data.asTypedList())));
});

final roomPreviewAvatarInfo =
StateProvider.family.autoDispose<AvatarInfo, RoomPreviewQuery>((ref, q) {
final preview = ref.watch(roomPreviewProvider(q)).valueOrNull;
final avatarData = ref.watch(_roomPreviewAvatarProvider(q)).valueOrNull;
return AvatarInfo(
uniqueId: q.roomIdOrAlias,
displayName: preview?.name(),
avatar: avatarData,
);
});
Loading
Loading