@ -2,6 +2,7 @@ import 'package:fluffychat/config/app_config.dart';
import ' package:fluffychat/pangea/utils/bot_name.dart ' ;
import ' package:fluffychat/utils/date_time_extension.dart ' ;
import ' package:fluffychat/utils/fluffy_share.dart ' ;
import ' package:fluffychat/utils/localized_exception_extension.dart ' ;
import ' package:fluffychat/utils/url_launcher.dart ' ;
import ' package:fluffychat/widgets/avatar.dart ' ;
import ' package:fluffychat/widgets/presence_builder.dart ' ;
@ -29,6 +30,7 @@ class UserBottomSheetView extends StatelessWidget {
final client = Matrix . of ( controller . widget . outerContext ) . client ;
final profileSearchError = controller . widget . profileSearchError ;
final dmRoomId = client . getDirectChatFromUserId ( userId ) ;
return SafeArea (
child: Scaffold (
appBar: AppBar (
@ -36,78 +38,20 @@ class UserBottomSheetView extends StatelessWidget {
onPressed: Navigator . of ( context , rootNavigator: false ) . pop ,
) ,
centerTitle: false ,
title: Column (
crossAxisAlignment: CrossAxisAlignment . start ,
children: [
Text ( displayname ) ,
PresenceBuilder (
userId: userId ,
client: client ,
builder: ( context , presence ) {
if ( presence = = null | |
( presence . presence = = PresenceType . offline & &
presence . lastActiveTimestamp = = null ) ) {
return const SizedBox . shrink ( ) ;
}
final dotColor = presence . presence . isOnline
? Colors . green
: presence . presence . isUnavailable
? Colors . orange
: Colors . grey ;
final lastActiveTimestamp = presence . lastActiveTimestamp ;
return Row (
mainAxisSize: MainAxisSize . min ,
children: [
Container (
width: 8 ,
height: 8 ,
margin: const EdgeInsets . only ( right: 8 ) ,
decoration: BoxDecoration (
color: dotColor ,
borderRadius: BorderRadius . circular ( 16 ) ,
) ,
) ,
if ( presence . currentlyActive = = true )
Text (
L10n . of ( context ) ! . currentlyActive ,
overflow: TextOverflow . ellipsis ,
style: Theme . of ( context ) . textTheme . bodySmall ,
)
else if ( lastActiveTimestamp ! = null )
Text (
L10n . of ( context ) ! . lastActiveAgo (
lastActiveTimestamp . localizedTimeShort ( context ) ,
) ,
overflow: TextOverflow . ellipsis ,
style: Theme . of ( context ) . textTheme . bodySmall ,
) ,
] ,
) ;
} ,
) ,
] ,
) ,
actions: [
if ( userId ! = client . userID & &
! client . ignoredUsers . contains ( userId )
/ / # Pangea
& &
userId ! = BotName . byEnvironment
/ / Pangea #
)
Padding (
padding: const EdgeInsets . only ( right: 8.0 ) ,
child: IconButton (
icon: const Icon ( Icons . block_outlined ) ,
tooltip: L10n . of ( context ) ! . block ,
onPressed: ( ) = > controller
. participantAction ( UserBottomSheetAction . ignore ) ,
) ,
) ,
] ,
title: Text ( displayname ) ,
actions: dmRoomId = = null
? null
: [
Padding (
padding: const EdgeInsets . symmetric ( horizontal: 8 ) ,
child: FloatingActionButton . small (
elevation: 0 ,
onPressed: ( ) = > controller
. participantAction ( UserBottomSheetAction . message ) ,
child: const Icon ( Icons . chat_outlined ) ,
) ,
) ,
] ,
) ,
body: StreamBuilder < Object > (
stream: user ? . room . client . onSync . stream . where (
@ -174,25 +118,12 @@ class UserBottomSheetView extends StatelessWidget {
children: [
Padding (
padding: const EdgeInsets . all ( 16.0 ) ,
child: Material (
elevation: Theme . of ( context )
. appBarTheme
. scrolledUnderElevation ? ?
4 ,
shadowColor: Theme . of ( context ) . appBarTheme . shadowColor ,
shape: RoundedRectangleBorder (
side: BorderSide (
color: Theme . of ( context ) . dividerColor ,
) ,
borderRadius: BorderRadius . circular (
Avatar . defaultSize * 2.5 ,
) ,
) ,
child: Avatar (
mxContent: avatarUrl ,
name: displayname ,
size: Avatar . defaultSize * 2.5 ,
) ,
child: Avatar (
client:
Matrix . of ( controller . widget . outerContext ) . client ,
mxContent: avatarUrl ,
name: displayname ,
size: Avatar . defaultSize * 2.5 ,
) ,
) ,
Expanded (
@ -200,26 +131,6 @@ class UserBottomSheetView extends StatelessWidget {
mainAxisAlignment: MainAxisAlignment . center ,
crossAxisAlignment: CrossAxisAlignment . start ,
children: [
TextButton . icon (
onPressed: ( ) = > FluffyShare . share (
' https://matrix.to/#/ $ userId ' ,
context ,
) ,
icon: Icon (
Icons . adaptive . share_outlined ,
size: 16 ,
) ,
style: TextButton . styleFrom (
foregroundColor:
Theme . of ( context ) . colorScheme . onSurface ,
) ,
label: Text (
displayname ,
maxLines: 1 ,
overflow: TextOverflow . ellipsis ,
/ / style: const TextStyle ( fontSize: 18 ) ,
) ,
) ,
TextButton . icon (
onPressed: ( ) = > FluffyShare . share (
userId ,
@ -232,37 +143,72 @@ class UserBottomSheetView extends StatelessWidget {
) ,
style: TextButton . styleFrom (
foregroundColor:
Theme . of ( context ) . colorScheme . secondary ,
Theme . of ( context ) . colorScheme . onSurface ,
) ,
label: Text (
userId ,
maxLines: 1 ,
overflow: TextOverflow . ellipsis ,
/ / style: const TextStyle ( fontSize: 12 ) ,
) ,
) ,
PresenceBuilder (
userId: userId ,
client: client ,
builder: ( context , presence ) {
if ( presence = = null | |
( presence . presence = = PresenceType . offline & &
presence . lastActiveTimestamp = = null ) ) {
return const SizedBox . shrink ( ) ;
}
final dotColor = presence . presence . isOnline
? Colors . green
: presence . presence . isUnavailable
? Colors . orange
: Colors . grey ;
final lastActiveTimestamp =
presence . lastActiveTimestamp ;
return Row (
mainAxisSize: MainAxisSize . min ,
children: [
const SizedBox ( width: 16 ) ,
Container (
width: 8 ,
height: 8 ,
decoration: BoxDecoration (
color: dotColor ,
borderRadius: BorderRadius . circular ( 16 ) ,
) ,
) ,
const SizedBox ( width: 12 ) ,
if ( presence . currentlyActive = = true )
Text (
L10n . of ( context ) ! . currentlyActive ,
overflow: TextOverflow . ellipsis ,
style:
Theme . of ( context ) . textTheme . bodySmall ,
)
else if ( lastActiveTimestamp ! = null )
Text (
L10n . of ( context ) ! . lastActiveAgo (
lastActiveTimestamp
. localizedTimeShort ( context ) ,
) ,
overflow: TextOverflow . ellipsis ,
style:
Theme . of ( context ) . textTheme . bodySmall ,
) ,
] ,
) ;
} ,
) ,
] ,
) ,
) ,
] ,
) ,
if ( userId ! = client . userID )
Padding (
padding: const EdgeInsets . symmetric (
horizontal: 16.0 ,
vertical: 8.0 ,
) ,
child: ElevatedButton . icon (
onPressed: ( ) = > controller
. participantAction ( UserBottomSheetAction . message ) ,
icon: const Icon ( Icons . forum_outlined ) ,
label: Text (
controller . widget . user = = null
? L10n . of ( context ) ! . startConversation
: L10n . of ( context ) ! . sendAMessage ,
) ,
) ,
) ,
PresenceBuilder (
userId: userId ,
client: client ,
@ -286,6 +232,49 @@ class UserBottomSheetView extends StatelessWidget {
) ;
} ,
) ,
if ( userId ! = client . userID )
Padding (
padding: const EdgeInsets . symmetric (
horizontal: 16.0 ,
vertical: 8.0 ,
) ,
child: dmRoomId = = null
? ElevatedButton . icon (
onPressed: ( ) = > controller . participantAction (
UserBottomSheetAction . message ,
) ,
icon: const Icon ( Icons . chat_outlined ) ,
label: Text ( L10n . of ( context ) ! . startConversation ) ,
)
: TextField (
controller: controller . sendController ,
readOnly: controller . isSending ,
onSubmitted: controller . sendAction ,
minLines: 1 ,
maxLines: 1 ,
textInputAction: TextInputAction . send ,
decoration: InputDecoration (
errorText: controller . sendError
? . toLocalizedString ( context ) ,
hintText: L10n . of ( context ) ! . sendMessages ,
suffix: controller . isSending
? const SizedBox (
width: 16 ,
height: 16 ,
child: CircularProgressIndicator . adaptive (
strokeWidth: 2 ,
) ,
)
: null ,
suffixIcon: controller . isSending
? null
: IconButton (
icon: const Icon ( Icons . send_outlined ) ,
onPressed: controller . sendAction ,
) ,
) ,
) ,
) ,
if ( controller . widget . onMention ! = null )
ListTile (
leading: const Icon ( Icons . alternate_email_outlined ) ,
@ -339,8 +328,8 @@ class UserBottomSheetView extends StatelessWidget {
) ,
) ,
) ,
Divider ( color: Theme . of ( context ) . dividerColor ) ,
] ,
Divider ( color: Theme . of ( context ) . dividerColor ) ,
if ( user ! = null & & user . canKick )
ListTile (
textColor: Theme . of ( context ) . colorScheme . error ,
@ -376,7 +365,7 @@ class UserBottomSheetView extends StatelessWidget {
/ / textColor: Theme . of ( context ) . colorScheme . onErrorContainer ,
/ / iconColor: Theme . of ( context ) . colorScheme . onErrorContainer ,
/ / title: Text ( L10n . of ( context ) ! . reportUser ) ,
/ / leading: const Icon ( Icons . report _outlined) ,
/ / leading: const Icon ( Icons . gavel _outlined) ,
/ / onTap: ( ) = > controller
/ / . participantAction ( UserBottomSheetAction . report ) ,
/ / ) ,
@ -392,6 +381,21 @@ class UserBottomSheetView extends StatelessWidget {
style: const TextStyle ( color: Colors . orange ) ,
) ,
) ,
if ( userId ! = client . userID & &
! client . ignoredUsers . contains ( userId )
/ / # Pangea
& &
userId ! = BotName . byEnvironment
/ / Pangea #
)
ListTile (
textColor: Theme . of ( context ) . colorScheme . onErrorContainer ,
iconColor: Theme . of ( context ) . colorScheme . onErrorContainer ,
leading: const Icon ( Icons . block_outlined ) ,
title: Text ( L10n . of ( context ) ! . block ) ,
onTap: ( ) = > controller
. participantAction ( UserBottomSheetAction . ignore ) ,
) ,
] ,
) ;
} ,