chore: Adjust styles and animations
This commit is contained in:
parent
5c88133691
commit
9724b852bb
5 changed files with 656 additions and 761 deletions
|
|
@ -462,21 +462,18 @@ class ChatController extends State<ChatPageWithRoom>
|
|||
scrollUpBannerEventId = eventId;
|
||||
});
|
||||
|
||||
bool firstUpdateReceived = false;
|
||||
|
||||
void updateView() {
|
||||
if (!mounted) return;
|
||||
setReadMarker();
|
||||
setState(() {});
|
||||
setState(() {
|
||||
firstUpdateReceived = true;
|
||||
});
|
||||
}
|
||||
|
||||
Future<void>? loadTimelineFuture;
|
||||
|
||||
int? animateInEventIndex;
|
||||
|
||||
void onInsert(int i) {
|
||||
// setState will be called by updateView() anyway
|
||||
if (timeline?.allowNewEvent == true) animateInEventIndex = i;
|
||||
}
|
||||
|
||||
Future<void> _getTimeline({String? eventContextId}) async {
|
||||
await Matrix.of(context).client.roomsLoading;
|
||||
await Matrix.of(context).client.accountDataLoading;
|
||||
|
|
@ -489,15 +486,11 @@ class ChatController extends State<ChatPageWithRoom>
|
|||
timeline = await room.getTimeline(
|
||||
onUpdate: updateView,
|
||||
eventContextId: eventContextId,
|
||||
onInsert: onInsert,
|
||||
);
|
||||
} catch (e, s) {
|
||||
Logs().w('Unable to load timeline on event ID $eventContextId', e, s);
|
||||
if (!mounted) return;
|
||||
timeline = await room.getTimeline(
|
||||
onUpdate: updateView,
|
||||
onInsert: onInsert,
|
||||
);
|
||||
timeline = await room.getTimeline(onUpdate: updateView);
|
||||
if (!mounted) return;
|
||||
if (e is TimeoutException || e is IOException) {
|
||||
_showScrollUpMaterialBanner(eventContextId!);
|
||||
|
|
|
|||
|
|
@ -35,7 +35,6 @@ class ChatEventList extends StatelessWidget {
|
|||
final events = timeline.events.filterByVisibleInGui(
|
||||
threadId: controller.activeThreadId,
|
||||
);
|
||||
final animateInEventIndex = controller.animateInEventIndex;
|
||||
|
||||
// create a map of eventId --> index to greatly improve performance of
|
||||
// ListView's findChildIndexCallback
|
||||
|
|
@ -120,10 +119,7 @@ class ChatEventList extends StatelessWidget {
|
|||
|
||||
// The message at this index:
|
||||
final event = events[i];
|
||||
final animateIn =
|
||||
animateInEventIndex != null &&
|
||||
timeline.events.length > animateInEventIndex &&
|
||||
event == timeline.events[animateInEventIndex];
|
||||
final animateIn = i == 0 && controller.firstUpdateReceived;
|
||||
|
||||
final nextEvent = i + 1 < events.length ? events[i + 1] : null;
|
||||
final previousEvent = i > 0 ? events[i - 1] : null;
|
||||
|
|
@ -139,16 +135,13 @@ class ChatEventList extends StatelessWidget {
|
|||
!controller.expandedEventIds.contains(event.eventId);
|
||||
|
||||
return AutoScrollTag(
|
||||
key: ValueKey(event.eventId),
|
||||
key: ValueKey(event.transactionId ?? event.eventId),
|
||||
index: i,
|
||||
controller: controller.scrollController,
|
||||
child: Message(
|
||||
event,
|
||||
bigEmojis: controller.bigEmojis,
|
||||
animateIn: animateIn,
|
||||
resetAnimateIn: () {
|
||||
controller.animateInEventIndex = null;
|
||||
},
|
||||
onSwipe: () => controller.replyAction(replyTo: event),
|
||||
onInfoTab: controller.showEventInfo,
|
||||
onMention: () => controller.sendController.text +=
|
||||
|
|
|
|||
|
|
@ -42,7 +42,6 @@ class Message extends StatelessWidget {
|
|||
final Timeline timeline;
|
||||
final bool highlightMarker;
|
||||
final bool animateIn;
|
||||
final void Function()? resetAnimateIn;
|
||||
final bool wallpaperMode;
|
||||
final ScrollController scrollController;
|
||||
final List<Color> colors;
|
||||
|
|
@ -67,7 +66,6 @@ class Message extends StatelessWidget {
|
|||
required this.timeline,
|
||||
this.highlightMarker = false,
|
||||
this.animateIn = false,
|
||||
this.resetAnimateIn,
|
||||
this.wallpaperMode = false,
|
||||
required this.onMention,
|
||||
required this.scrollController,
|
||||
|
|
@ -171,9 +169,6 @@ class Message extends StatelessWidget {
|
|||
: theme.bubbleColor;
|
||||
}
|
||||
|
||||
final resetAnimateIn = this.resetAnimateIn;
|
||||
var animateIn = this.animateIn;
|
||||
|
||||
final sentReactions = <String>{};
|
||||
if (singleSelected) {
|
||||
sentReactions.addAll(
|
||||
|
|
@ -209,7 +204,9 @@ class Message extends StatelessWidget {
|
|||
final enterThread = this.enterThread;
|
||||
final sender = event.senderFromMemoryOrFallback;
|
||||
|
||||
return Center(
|
||||
return _AnimateIn(
|
||||
animateIn: animateIn,
|
||||
child: Center(
|
||||
child: Swipeable(
|
||||
key: ValueKey(event.eventId),
|
||||
background: const Padding(
|
||||
|
|
@ -265,24 +262,7 @@ class Message extends StatelessWidget {
|
|||
),
|
||||
),
|
||||
),
|
||||
StatefulBuilder(
|
||||
builder: (context, setState) {
|
||||
if (animateIn && resetAnimateIn != null) {
|
||||
WidgetsBinding.instance.addPostFrameCallback((timeStamp) {
|
||||
animateIn = false;
|
||||
setState(resetAnimateIn);
|
||||
});
|
||||
}
|
||||
return AnimatedSize(
|
||||
duration: FluffyThemes.animationDuration,
|
||||
curve: FluffyThemes.animationCurve,
|
||||
clipBehavior: Clip.none,
|
||||
alignment: ownMessage
|
||||
? Alignment.bottomRight
|
||||
: Alignment.bottomLeft,
|
||||
child: animateIn
|
||||
? const SizedBox(height: 0, width: double.infinity)
|
||||
: Stack(
|
||||
Stack(
|
||||
clipBehavior: Clip.none,
|
||||
children: [
|
||||
Positioned(
|
||||
|
|
@ -291,13 +271,9 @@ class Message extends StatelessWidget {
|
|||
left: 0,
|
||||
right: 0,
|
||||
child: InkWell(
|
||||
hoverColor: longPressSelect
|
||||
? Colors.transparent
|
||||
: null,
|
||||
hoverColor: longPressSelect ? Colors.transparent : null,
|
||||
enableFeedback: !selected,
|
||||
onTap: longPressSelect
|
||||
? null
|
||||
: () => onSelect(event),
|
||||
onTap: longPressSelect ? null : () => onSelect(event),
|
||||
borderRadius: BorderRadius.circular(
|
||||
AppConfig.borderRadius / 2,
|
||||
),
|
||||
|
|
@ -306,8 +282,9 @@ class Message extends StatelessWidget {
|
|||
AppConfig.borderRadius / 2,
|
||||
),
|
||||
color: selected || highlightMarker
|
||||
? theme.colorScheme.secondaryContainer
|
||||
.withAlpha(128)
|
||||
? theme.colorScheme.secondaryContainer.withAlpha(
|
||||
128,
|
||||
)
|
||||
: Colors.transparent,
|
||||
),
|
||||
),
|
||||
|
|
@ -338,12 +315,8 @@ class Message extends StatelessWidget {
|
|||
child: SizedBox(
|
||||
width: 16,
|
||||
height: 16,
|
||||
child:
|
||||
event.status == EventStatus.error
|
||||
? const Icon(
|
||||
Icons.error,
|
||||
color: Colors.red,
|
||||
)
|
||||
child: event.status == EventStatus.error
|
||||
? const Icon(Icons.error, color: Colors.red)
|
||||
: event.fileSendingStatus != null
|
||||
? const CircularProgressIndicator.adaptive(
|
||||
strokeWidth: 1,
|
||||
|
|
@ -360,8 +333,7 @@ class Message extends StatelessWidget {
|
|||
return Avatar(
|
||||
mxContent: user.avatarUrl,
|
||||
name: user.calcDisplayname(),
|
||||
onTap: () =>
|
||||
showMemberActionsPopupMenu(
|
||||
onTap: () => showMemberActionsPopupMenu(
|
||||
context: context,
|
||||
user: user,
|
||||
onMention: onMention,
|
||||
|
|
@ -384,22 +356,17 @@ class Message extends StatelessWidget {
|
|||
left: 8.0,
|
||||
bottom: 4,
|
||||
),
|
||||
child:
|
||||
ownMessage ||
|
||||
event.room.isDirectChat
|
||||
child: ownMessage || event.room.isDirectChat
|
||||
? const SizedBox(height: 12)
|
||||
: Row(
|
||||
children: [
|
||||
if (sender.powerLevel >=
|
||||
50)
|
||||
if (sender.powerLevel >= 50)
|
||||
Padding(
|
||||
padding:
|
||||
const EdgeInsets.only(
|
||||
padding: const EdgeInsets.only(
|
||||
right: 2.0,
|
||||
),
|
||||
child: Icon(
|
||||
sender.powerLevel >=
|
||||
100
|
||||
sender.powerLevel >= 100
|
||||
? Icons
|
||||
.admin_panel_settings
|
||||
: Icons
|
||||
|
|
@ -412,31 +379,25 @@ class Message extends StatelessWidget {
|
|||
),
|
||||
Expanded(
|
||||
child: FutureBuilder<User?>(
|
||||
future: event
|
||||
.fetchSenderUser(),
|
||||
future: event.fetchSenderUser(),
|
||||
builder: (context, snapshot) {
|
||||
final displayname =
|
||||
snapshot.data
|
||||
?.calcDisplayname() ??
|
||||
sender
|
||||
.calcDisplayname();
|
||||
sender.calcDisplayname();
|
||||
return Text(
|
||||
displayname,
|
||||
style: TextStyle(
|
||||
fontSize: 11,
|
||||
fontWeight:
|
||||
FontWeight
|
||||
.bold,
|
||||
FontWeight.bold,
|
||||
color:
|
||||
(theme.brightness ==
|
||||
Brightness
|
||||
.light
|
||||
? displayname
|
||||
.color
|
||||
Brightness.light
|
||||
? displayname.color
|
||||
: displayname
|
||||
.lightColorText),
|
||||
shadows:
|
||||
!wallpaperMode
|
||||
shadows: !wallpaperMode
|
||||
? null
|
||||
: [
|
||||
const Shadow(
|
||||
|
|
@ -444,17 +405,15 @@ class Message extends StatelessWidget {
|
|||
0.0,
|
||||
0.0,
|
||||
),
|
||||
blurRadius:
|
||||
3,
|
||||
color:
|
||||
Colors.black,
|
||||
blurRadius: 3,
|
||||
color: Colors
|
||||
.black,
|
||||
),
|
||||
],
|
||||
),
|
||||
maxLines: 1,
|
||||
overflow:
|
||||
TextOverflow
|
||||
.ellipsis,
|
||||
TextOverflow.ellipsis,
|
||||
);
|
||||
},
|
||||
),
|
||||
|
|
@ -464,9 +423,7 @@ class Message extends StatelessWidget {
|
|||
),
|
||||
Container(
|
||||
alignment: alignment,
|
||||
padding: const EdgeInsets.only(
|
||||
left: 8,
|
||||
),
|
||||
padding: const EdgeInsets.only(left: 8),
|
||||
child: GestureDetector(
|
||||
onLongPress: longPressSelect
|
||||
? null
|
||||
|
|
@ -474,19 +431,6 @@ class Message extends StatelessWidget {
|
|||
HapticFeedback.heavyImpact();
|
||||
onSelect(event);
|
||||
},
|
||||
child: AnimatedOpacity(
|
||||
opacity: animateIn
|
||||
? 0
|
||||
: event.messageType ==
|
||||
MessageTypes
|
||||
.BadEncrypted ||
|
||||
event.status.isSending
|
||||
? 0.5
|
||||
: 1,
|
||||
duration: FluffyThemes
|
||||
.animationDuration,
|
||||
curve:
|
||||
FluffyThemes.animationCurve,
|
||||
child: Container(
|
||||
decoration: BoxDecoration(
|
||||
color: noBubble
|
||||
|
|
@ -500,69 +444,49 @@ class Message extends StatelessWidget {
|
|||
ignore:
|
||||
noBubble ||
|
||||
!ownMessage ||
|
||||
MediaQuery.highContrastOf(
|
||||
context,
|
||||
),
|
||||
scrollController:
|
||||
scrollController,
|
||||
MediaQuery.highContrastOf(context),
|
||||
scrollController: scrollController,
|
||||
child: Container(
|
||||
decoration: BoxDecoration(
|
||||
borderRadius:
|
||||
BorderRadius.circular(
|
||||
AppConfig
|
||||
.borderRadius,
|
||||
borderRadius: BorderRadius.circular(
|
||||
AppConfig.borderRadius,
|
||||
),
|
||||
),
|
||||
constraints:
|
||||
const BoxConstraints(
|
||||
constraints: const BoxConstraints(
|
||||
maxWidth:
|
||||
FluffyThemes
|
||||
.columnWidth *
|
||||
1.5,
|
||||
FluffyThemes.columnWidth * 1.5,
|
||||
),
|
||||
child: Column(
|
||||
mainAxisSize: .min,
|
||||
crossAxisAlignment:
|
||||
CrossAxisAlignment
|
||||
.start,
|
||||
CrossAxisAlignment.start,
|
||||
children: <Widget>[
|
||||
if (event.inReplyToEventId(
|
||||
includingFallback:
|
||||
false,
|
||||
includingFallback: false,
|
||||
) !=
|
||||
null)
|
||||
FutureBuilder<Event?>(
|
||||
future: event
|
||||
.getReplyEvent(
|
||||
future: event.getReplyEvent(
|
||||
timeline,
|
||||
),
|
||||
builder:
|
||||
(
|
||||
BuildContext
|
||||
context,
|
||||
snapshot,
|
||||
) {
|
||||
builder: (BuildContext context, snapshot) {
|
||||
final replyEvent =
|
||||
snapshot
|
||||
.hasData
|
||||
? snapshot
|
||||
.data!
|
||||
snapshot.hasData
|
||||
? snapshot.data!
|
||||
: Event(
|
||||
eventId:
|
||||
event.inReplyToEventId() ??
|
||||
event
|
||||
.inReplyToEventId() ??
|
||||
'\$fake_event_id',
|
||||
content: {
|
||||
'msgtype':
|
||||
'm.text',
|
||||
'body':
|
||||
'...',
|
||||
'msgtype': 'm.text',
|
||||
'body': '...',
|
||||
},
|
||||
senderId:
|
||||
event.senderId,
|
||||
type:
|
||||
'm.room.message',
|
||||
room:
|
||||
event.room,
|
||||
room: event.room,
|
||||
status:
|
||||
EventStatus.sent,
|
||||
originServerTs:
|
||||
|
|
@ -571,23 +495,20 @@ class Message extends StatelessWidget {
|
|||
return Padding(
|
||||
padding:
|
||||
const EdgeInsets.only(
|
||||
left:
|
||||
16,
|
||||
right:
|
||||
16,
|
||||
top:
|
||||
8,
|
||||
left: 16,
|
||||
right: 16,
|
||||
top: 8,
|
||||
),
|
||||
child: Material(
|
||||
color: Colors
|
||||
.transparent,
|
||||
borderRadius:
|
||||
ReplyContent
|
||||
color: Colors.transparent,
|
||||
borderRadius: ReplyContent
|
||||
.borderRadius,
|
||||
child: InkWell(
|
||||
borderRadius:
|
||||
ReplyContent.borderRadius,
|
||||
onTap: () => scrollToEventId(
|
||||
ReplyContent
|
||||
.borderRadius,
|
||||
onTap: () =>
|
||||
scrollToEventId(
|
||||
replyEvent
|
||||
.eventId,
|
||||
),
|
||||
|
|
@ -596,8 +517,7 @@ class Message extends StatelessWidget {
|
|||
replyEvent,
|
||||
ownMessage:
|
||||
ownMessage,
|
||||
timeline:
|
||||
timeline,
|
||||
timeline: timeline,
|
||||
),
|
||||
),
|
||||
),
|
||||
|
|
@ -610,38 +530,30 @@ class Message extends StatelessWidget {
|
|||
textColor: textColor,
|
||||
linkColor: linkColor,
|
||||
onInfoTab: onInfoTab,
|
||||
borderRadius:
|
||||
borderRadius,
|
||||
borderRadius: borderRadius,
|
||||
timeline: timeline,
|
||||
selected: selected,
|
||||
bigEmojis: bigEmojis,
|
||||
),
|
||||
if (event
|
||||
.hasAggregatedEvents(
|
||||
if (event.hasAggregatedEvents(
|
||||
timeline,
|
||||
RelationshipTypes
|
||||
.edit,
|
||||
RelationshipTypes.edit,
|
||||
))
|
||||
Padding(
|
||||
padding:
|
||||
const EdgeInsets.only(
|
||||
padding: const EdgeInsets.only(
|
||||
bottom: 8.0,
|
||||
left: 16.0,
|
||||
right: 16.0,
|
||||
),
|
||||
child: Row(
|
||||
mainAxisSize:
|
||||
MainAxisSize
|
||||
.min,
|
||||
MainAxisSize.min,
|
||||
spacing: 4.0,
|
||||
children: [
|
||||
Icon(
|
||||
Icons
|
||||
.edit_outlined,
|
||||
Icons.edit_outlined,
|
||||
color: textColor
|
||||
.withAlpha(
|
||||
164,
|
||||
),
|
||||
.withAlpha(164),
|
||||
size: 14,
|
||||
),
|
||||
Text(
|
||||
|
|
@ -652,11 +564,8 @@ class Message extends StatelessWidget {
|
|||
),
|
||||
style: TextStyle(
|
||||
color: textColor
|
||||
.withAlpha(
|
||||
164,
|
||||
),
|
||||
fontSize:
|
||||
11,
|
||||
.withAlpha(164),
|
||||
fontSize: 11,
|
||||
),
|
||||
),
|
||||
],
|
||||
|
|
@ -669,76 +578,61 @@ class Message extends StatelessWidget {
|
|||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
Align(
|
||||
alignment: ownMessage
|
||||
? Alignment.bottomRight
|
||||
: Alignment.bottomLeft,
|
||||
child: AnimatedSize(
|
||||
duration:
|
||||
FluffyThemes.animationDuration,
|
||||
duration: FluffyThemes.animationDuration,
|
||||
curve: FluffyThemes.animationCurve,
|
||||
child: showReactionPicker
|
||||
? Padding(
|
||||
padding:
|
||||
const EdgeInsets.all(
|
||||
4.0,
|
||||
),
|
||||
padding: const EdgeInsets.all(4.0),
|
||||
child: Material(
|
||||
elevation: 4,
|
||||
borderRadius:
|
||||
BorderRadius.circular(
|
||||
AppConfig
|
||||
.borderRadius,
|
||||
borderRadius: BorderRadius.circular(
|
||||
AppConfig.borderRadius,
|
||||
),
|
||||
shadowColor: theme
|
||||
.colorScheme
|
||||
.surface
|
||||
.withAlpha(128),
|
||||
child: SingleChildScrollView(
|
||||
scrollDirection:
|
||||
Axis.horizontal,
|
||||
scrollDirection: Axis.horizontal,
|
||||
child: Row(
|
||||
mainAxisSize: .min,
|
||||
children: [
|
||||
...AppConfig.defaultReactions.map(
|
||||
(
|
||||
emoji,
|
||||
) => IconButton(
|
||||
padding:
|
||||
EdgeInsets
|
||||
.zero,
|
||||
(emoji) => IconButton(
|
||||
padding: EdgeInsets.zero,
|
||||
icon: Center(
|
||||
child: Opacity(
|
||||
opacity:
|
||||
sentReactions.contains(
|
||||
sentReactions
|
||||
.contains(
|
||||
emoji,
|
||||
)
|
||||
? 0.33
|
||||
: 1,
|
||||
child: Text(
|
||||
emoji,
|
||||
style: const TextStyle(
|
||||
fontSize:
|
||||
20,
|
||||
style:
|
||||
const TextStyle(
|
||||
fontSize: 20,
|
||||
),
|
||||
textAlign:
|
||||
TextAlign
|
||||
textAlign: TextAlign
|
||||
.center,
|
||||
),
|
||||
),
|
||||
),
|
||||
onPressed:
|
||||
sentReactions
|
||||
.contains(
|
||||
emoji,
|
||||
)
|
||||
.contains(emoji)
|
||||
? null
|
||||
: () {
|
||||
onSelect(
|
||||
event,
|
||||
);
|
||||
event.room.sendReaction(
|
||||
onSelect(event);
|
||||
event.room
|
||||
.sendReaction(
|
||||
event
|
||||
.eventId,
|
||||
emoji,
|
||||
|
|
@ -756,8 +650,7 @@ class Message extends StatelessWidget {
|
|||
).customReaction,
|
||||
onPressed: () async {
|
||||
final emoji = await showAdaptiveBottomSheet<String>(
|
||||
context:
|
||||
context,
|
||||
context: context,
|
||||
builder: (context) => Scaffold(
|
||||
appBar: AppBar(
|
||||
title: Text(
|
||||
|
|
@ -766,82 +659,94 @@ class Message extends StatelessWidget {
|
|||
).customReaction,
|
||||
),
|
||||
leading: CloseButton(
|
||||
onPressed: () => Navigator.of(
|
||||
onPressed: () =>
|
||||
Navigator.of(
|
||||
context,
|
||||
).pop(null),
|
||||
),
|
||||
),
|
||||
body: SizedBox(
|
||||
height: double
|
||||
.infinity,
|
||||
height:
|
||||
double.infinity,
|
||||
child: EmojiPicker(
|
||||
onEmojiSelected:
|
||||
(
|
||||
_,
|
||||
emoji,
|
||||
) =>
|
||||
(_, emoji) =>
|
||||
Navigator.of(
|
||||
context,
|
||||
).pop(
|
||||
emoji.emoji,
|
||||
emoji
|
||||
.emoji,
|
||||
),
|
||||
config: Config(
|
||||
locale: Localizations.localeOf(
|
||||
locale:
|
||||
Localizations.localeOf(
|
||||
context,
|
||||
),
|
||||
emojiViewConfig: const EmojiViewConfig(
|
||||
emojiViewConfig:
|
||||
const EmojiViewConfig(
|
||||
backgroundColor:
|
||||
Colors.transparent,
|
||||
Colors
|
||||
.transparent,
|
||||
),
|
||||
bottomActionBarConfig: const BottomActionBarConfig(
|
||||
bottomActionBarConfig:
|
||||
const BottomActionBarConfig(
|
||||
enabled:
|
||||
false,
|
||||
),
|
||||
categoryViewConfig: CategoryViewConfig(
|
||||
initCategory:
|
||||
Category.SMILEYS,
|
||||
backspaceColor:
|
||||
theme.colorScheme.primary,
|
||||
iconColor: theme.colorScheme.primary.withAlpha(
|
||||
Category
|
||||
.SMILEYS,
|
||||
backspaceColor: theme
|
||||
.colorScheme
|
||||
.primary,
|
||||
iconColor: theme
|
||||
.colorScheme
|
||||
.primary
|
||||
.withAlpha(
|
||||
128,
|
||||
),
|
||||
iconColorSelected:
|
||||
theme.colorScheme.primary,
|
||||
indicatorColor:
|
||||
theme.colorScheme.primary,
|
||||
backgroundColor:
|
||||
theme.colorScheme.surface,
|
||||
iconColorSelected: theme
|
||||
.colorScheme
|
||||
.primary,
|
||||
indicatorColor: theme
|
||||
.colorScheme
|
||||
.primary,
|
||||
backgroundColor: theme
|
||||
.colorScheme
|
||||
.surface,
|
||||
),
|
||||
skinToneConfig: SkinToneConfig(
|
||||
dialogBackgroundColor: Color.lerp(
|
||||
theme.colorScheme.surface,
|
||||
theme.colorScheme.primaryContainer,
|
||||
theme
|
||||
.colorScheme
|
||||
.surface,
|
||||
theme
|
||||
.colorScheme
|
||||
.primaryContainer,
|
||||
0.75,
|
||||
)!,
|
||||
indicatorColor:
|
||||
theme.colorScheme.onSurface,
|
||||
indicatorColor: theme
|
||||
.colorScheme
|
||||
.onSurface,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
if (emoji ==
|
||||
null) {
|
||||
if (emoji == null) {
|
||||
return;
|
||||
}
|
||||
if (sentReactions
|
||||
.contains(
|
||||
emoji,
|
||||
)) {
|
||||
.contains(emoji)) {
|
||||
return;
|
||||
}
|
||||
onSelect(event);
|
||||
|
||||
await event.room
|
||||
.sendReaction(
|
||||
event
|
||||
.eventId,
|
||||
event.eventId,
|
||||
emoji,
|
||||
);
|
||||
},
|
||||
|
|
@ -861,9 +766,6 @@ class Message extends StatelessWidget {
|
|||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
|
||||
AnimatedSize(
|
||||
duration: FluffyThemes.animationDuration,
|
||||
|
|
@ -959,6 +861,7 @@ class Message extends StatelessWidget {
|
|||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
@ -1033,3 +936,37 @@ class BubblePainter extends CustomPainter {
|
|||
return scrollable.position != oldScrollable?.position;
|
||||
}
|
||||
}
|
||||
|
||||
class _AnimateIn extends StatefulWidget {
|
||||
final bool animateIn;
|
||||
final Widget child;
|
||||
const _AnimateIn({required this.animateIn, required this.child});
|
||||
|
||||
@override
|
||||
State<_AnimateIn> createState() => __AnimateInState();
|
||||
}
|
||||
|
||||
class __AnimateInState extends State<_AnimateIn> {
|
||||
bool _animationFinished = false;
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
if (!widget.animateIn) return widget.child;
|
||||
if (!_animationFinished) {
|
||||
WidgetsBinding.instance.addPostFrameCallback((_) {
|
||||
setState(() {
|
||||
_animationFinished = true;
|
||||
});
|
||||
});
|
||||
}
|
||||
return AnimatedOpacity(
|
||||
duration: FluffyThemes.animationDuration,
|
||||
curve: FluffyThemes.animationCurve,
|
||||
opacity: _animationFinished ? 1 : 0,
|
||||
child: AnimatedSize(
|
||||
duration: FluffyThemes.animationDuration,
|
||||
curve: FluffyThemes.animationCurve,
|
||||
child: _animationFinished ? widget.child : const SizedBox.shrink(),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,7 +2,6 @@ import 'package:flutter/material.dart';
|
|||
|
||||
import 'package:file_picker/file_picker.dart';
|
||||
|
||||
import 'package:fluffychat/config/app_config.dart';
|
||||
import 'package:fluffychat/config/setting_keys.dart';
|
||||
import 'package:fluffychat/utils/account_config.dart';
|
||||
import 'package:fluffychat/utils/file_selector.dart';
|
||||
|
|
@ -111,32 +110,6 @@ class SettingsStyleController extends State<SettingsStyle> {
|
|||
ThemeMode get currentTheme => ThemeController.of(context).themeMode;
|
||||
Color? get currentColor => ThemeController.of(context).primaryColor;
|
||||
|
||||
static final List<Color?> customColors = [
|
||||
null,
|
||||
AppConfig.chatColor,
|
||||
Colors.indigo,
|
||||
Colors.blue,
|
||||
Colors.blueAccent,
|
||||
Colors.teal,
|
||||
Colors.tealAccent,
|
||||
Colors.green,
|
||||
Colors.greenAccent,
|
||||
Colors.yellow,
|
||||
Colors.yellowAccent,
|
||||
Colors.orange,
|
||||
Colors.orangeAccent,
|
||||
Colors.red,
|
||||
Colors.redAccent,
|
||||
Colors.pink,
|
||||
Colors.pinkAccent,
|
||||
Colors.purple,
|
||||
Colors.purpleAccent,
|
||||
Colors.blueGrey,
|
||||
Colors.grey,
|
||||
Colors.white,
|
||||
Colors.black,
|
||||
];
|
||||
|
||||
void switchTheme(ThemeMode? newTheme) {
|
||||
if (newTheme == null) return;
|
||||
switch (newTheme) {
|
||||
|
|
|
|||
|
|
@ -82,14 +82,13 @@ class SettingsStyleView extends StatelessWidget {
|
|||
Theme.of(context).brightness == Brightness.light
|
||||
? light?.primary
|
||||
: dark?.primary;
|
||||
final colors = List<Color?>.from(
|
||||
SettingsStyleController.customColors,
|
||||
);
|
||||
final colors = [null, AppConfig.chatColor, ...Colors.primaries];
|
||||
if (systemColor == null) {
|
||||
colors.remove(null);
|
||||
}
|
||||
return GridView.builder(
|
||||
shrinkWrap: true,
|
||||
physics: NeverScrollableScrollPhysics(),
|
||||
gridDelegate: const SliverGridDelegateWithMaxCrossAxisExtent(
|
||||
maxCrossAxisExtent: 64,
|
||||
),
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue