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 )
2023-03-02 10:57:52 +01:00
. 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 ' ,
} ,
) ,
2022-01-15 13:31:10 +01:00
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 {
2023-03-02 10:57:52 +01:00
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 > (
2023-03-02 10:57:52 +01:00
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 ;
}