fluffychat/lib/utils/matrix_sdk_extensions/client_stories_extension.dart

115 lines
3.7 KiB
Dart
Raw Permalink Normal View History

2021-12-24 14:18:09 +01:00
import 'package:flutter/cupertino.dart';
import 'package:adaptive_dialog/adaptive_dialog.dart';
2023-01-20 16:59:50 +01:00
import 'package:flutter_gen/gen_l10n/l10n.dart';
2021-12-24 14:18:09 +01:00
import 'package:matrix/matrix.dart';
2023-01-20 16:59:50 +01:00
import 'package:fluffychat/utils/matrix_sdk_extensions/matrix_locals.dart';
2021-12-24 14:18:09 +01:00
extension ClientStoriesExtension on Client {
2021-12-25 08:56:35 +01:00
static const String storiesRoomType = 'msc3588.stories.stories-room';
static const String storiesBlockListType = 'msc3588.stories.block-list';
2021-12-24 14:18:09 +01:00
static const int lifeTimeInHours = 24;
static const int maxPostsPerStory = 20;
List<User> get contacts => rooms
.where((room) => room.isDirectChat)
.map(
(room) =>
room.unsafeGetUserFromMemoryOrFallback(room.directChatMatrixID!),
)
2021-12-24 14:18:09 +01:00
.toList();
2022-08-30 20:24:36 +02:00
List<Room> get storiesRooms =>
rooms.where((room) => room.isStoryRoom).toList();
2021-12-24 14:18:09 +01:00
Future<List<User>> getUndecidedContactsForStories(Room? storiesRoom) async {
if (storiesRoom == null) return contacts;
final invitedContacts =
(await storiesRoom.requestParticipants()).map((user) => user.id);
final decidedContacts = storiesBlockList.toSet()..addAll(invitedContacts);
return contacts
.where((contact) => !decidedContacts.contains(contact.id))
.toList();
}
List<String> get storiesBlockList =>
2021-12-25 08:56:35 +01:00
accountData[storiesBlockListType]?.content.tryGetList<String>('users') ??
2021-12-24 14:18:09 +01:00
[];
Future<void> setStoriesBlockList(List<String> users) => setAccountData(
userID!,
2021-12-25 08:56:35 +01:00
storiesBlockListType,
2021-12-24 14:18:09 +01:00
{'users': users},
);
2021-12-27 08:48:06 +01:00
Future<Room> createStoriesRoom([List<String>? invite]) async {
2021-12-24 14:18:09 +01:00
final roomId = await createRoom(
creationContent: {"type": "msc3588.stories.stories-room"},
preset: CreateRoomPreset.privateChat,
powerLevelContentOverride: {"events_default": 100},
name: 'Stories from ${userID!.localpart}',
2022-01-02 19:08:42 +01:00
topic:
'This is a room for stories sharing, not unlike the similarly named features in other messaging networks. For best experience please use FluffyChat or minesTrix. Feature development can be followed on: https://github.com/matrix-org/matrix-doc/pull/3588',
2021-12-24 14:18:09 +01:00
initialState: [
StateEvent(
type: EventTypes.Encryption,
stateKey: '',
content: {
'algorithm': 'm.megolm.v1.aes-sha2',
},
),
StateEvent(
type: 'm.room.retention',
stateKey: '',
content: {
'min_lifetime': 86400000,
'max_lifetime': 86400000,
},
),
2021-12-24 14:18:09 +01:00
],
invite: invite,
);
if (getRoomById(roomId) == null) {
// Wait for room actually appears in sync
await onSync.stream
.firstWhere((sync) => sync.rooms?.join?.containsKey(roomId) ?? false);
}
2021-12-27 08:48:06 +01:00
return getRoomById(roomId)!;
2021-12-24 14:18:09 +01:00
}
Future<Room?> getStoriesRoom(BuildContext context) async {
final candidates = rooms.where(
(room) =>
room
.getState(EventTypes.RoomCreate)
?.content
.tryGet<String>('type') ==
storiesRoomType &&
room.ownPowerLevel >= 100,
);
2021-12-24 14:18:09 +01:00
if (candidates.isEmpty) return null;
if (candidates.length == 1) return candidates.single;
return await showModalActionSheet<Room>(
context: context,
actions: candidates
.map(
(room) => SheetAction(
label: room.getLocalizedDisplayname(
MatrixLocals(L10n.of(context)!),
),
key: room,
),
)
.toList(),
);
2021-12-24 14:18:09 +01:00
}
}
2022-08-30 20:24:36 +02:00
extension StoryRoom on Room {
bool get isStoryRoom =>
getState(EventTypes.RoomCreate)?.content.tryGet<String>('type') ==
ClientStoriesExtension.storiesRoomType;
}