🐛 Fixes the lifecycle issue of chat #211
This commit is contained in:
@@ -48,6 +48,9 @@ class MessagesNotifier extends _$MessagesNotifier {
|
|||||||
|
|
||||||
late Future<SnAccount?> Function(String) _fetchAccount;
|
late Future<SnAccount?> Function(String) _fetchAccount;
|
||||||
|
|
||||||
|
// Disposal handling
|
||||||
|
bool _disposed = false;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
FutureOr<List<LocalChatMessage>> build(String roomId) async {
|
FutureOr<List<LocalChatMessage>> build(String roomId) async {
|
||||||
_apiClient = ref.watch(apiClientProvider);
|
_apiClient = ref.watch(apiClientProvider);
|
||||||
@@ -76,10 +79,17 @@ class MessagesNotifier extends _$MessagesNotifier {
|
|||||||
|
|
||||||
talker.log('MessagesNotifier built for room $roomId');
|
talker.log('MessagesNotifier built for room $roomId');
|
||||||
|
|
||||||
|
// Set up disposal handling
|
||||||
|
ref.onDispose(() {
|
||||||
|
_disposed = true;
|
||||||
|
talker.log('MessagesNotifier disposed for room $roomId');
|
||||||
|
});
|
||||||
|
|
||||||
// Only setup sync and lifecycle listeners if user is a member
|
// Only setup sync and lifecycle listeners if user is a member
|
||||||
if (identity != null) {
|
if (identity != null) {
|
||||||
ref.listen(appLifecycleStateProvider, (_, next) {
|
ref.listen(appLifecycleStateProvider, (_, next) {
|
||||||
next.whenData((state) {
|
next.whenData((state) {
|
||||||
|
if (_disposed) return; // Check disposal before accessing ref
|
||||||
if (state == AppLifecycleState.paused) {
|
if (state == AppLifecycleState.paused) {
|
||||||
_lastPauseTime = DateTime.now();
|
_lastPauseTime = DateTime.now();
|
||||||
talker.log('App paused, recording time');
|
talker.log('App paused, recording time');
|
||||||
@@ -88,7 +98,9 @@ class MessagesNotifier extends _$MessagesNotifier {
|
|||||||
final diff = DateTime.now().difference(_lastPauseTime!);
|
final diff = DateTime.now().difference(_lastPauseTime!);
|
||||||
if (diff > const Duration(minutes: 1)) {
|
if (diff > const Duration(minutes: 1)) {
|
||||||
talker.log('App resumed after >1 min, syncing messages');
|
talker.log('App resumed after >1 min, syncing messages');
|
||||||
syncMessages();
|
if (!_disposed) {
|
||||||
|
syncMessages(); // Check disposal before calling syncMessages
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
talker.log('App resumed within 1 min, skipping sync');
|
talker.log('App resumed within 1 min, skipping sync');
|
||||||
}
|
}
|
||||||
@@ -167,15 +179,15 @@ class MessagesNotifier extends _$MessagesNotifier {
|
|||||||
List<LocalChatMessage> filteredMessages = dbMessages;
|
List<LocalChatMessage> filteredMessages = dbMessages;
|
||||||
|
|
||||||
if (withLinks == true) {
|
if (withLinks == true) {
|
||||||
filteredMessages =
|
filteredMessages = filteredMessages
|
||||||
filteredMessages.where((msg) => _hasLink(msg)).toList();
|
.where((msg) => _hasLink(msg))
|
||||||
|
.toList();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (withAttachments == true) {
|
if (withAttachments == true) {
|
||||||
filteredMessages =
|
filteredMessages = filteredMessages
|
||||||
filteredMessages
|
.where((msg) => msg.toRemoteMessage().attachments.isNotEmpty)
|
||||||
.where((msg) => msg.toRemoteMessage().attachments.isNotEmpty)
|
.toList();
|
||||||
.toList();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
final dbLocalMessages = filteredMessages;
|
final dbLocalMessages = filteredMessages;
|
||||||
@@ -190,8 +202,9 @@ class MessagesNotifier extends _$MessagesNotifier {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (offset == 0) {
|
if (offset == 0) {
|
||||||
final pendingForRoom =
|
final pendingForRoom = _pendingMessages.values
|
||||||
_pendingMessages.values.where((msg) => msg.roomId == roomId).toList();
|
.where((msg) => msg.roomId == roomId)
|
||||||
|
.toList();
|
||||||
|
|
||||||
final allMessages = [...pendingForRoom, ...uniqueMessages];
|
final allMessages = [...pendingForRoom, ...uniqueMessages];
|
||||||
_sortMessages(allMessages); // Use the helper function
|
_sortMessages(allMessages); // Use the helper function
|
||||||
@@ -239,8 +252,9 @@ class MessagesNotifier extends _$MessagesNotifier {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (offset == 0) {
|
if (offset == 0) {
|
||||||
final pendingForRoom =
|
final pendingForRoom = _pendingMessages.values
|
||||||
_pendingMessages.values.where((msg) => msg.roomId == roomId).toList();
|
.where((msg) => msg.roomId == roomId)
|
||||||
|
.toList();
|
||||||
|
|
||||||
final allMessages = [...pendingForRoom, ...uniqueMessages];
|
final allMessages = [...pendingForRoom, ...uniqueMessages];
|
||||||
_sortMessages(allMessages);
|
_sortMessages(allMessages);
|
||||||
@@ -284,14 +298,13 @@ class MessagesNotifier extends _$MessagesNotifier {
|
|||||||
final List<dynamic> data = response.data;
|
final List<dynamic> data = response.data;
|
||||||
_totalCount = int.parse(response.headers['x-total']?.firstOrNull ?? '0');
|
_totalCount = int.parse(response.headers['x-total']?.firstOrNull ?? '0');
|
||||||
|
|
||||||
final messages =
|
final messages = data.map((json) {
|
||||||
data.map((json) {
|
final remoteMessage = SnChatMessage.fromJson(json);
|
||||||
final remoteMessage = SnChatMessage.fromJson(json);
|
return LocalChatMessage.fromRemoteMessage(
|
||||||
return LocalChatMessage.fromRemoteMessage(
|
remoteMessage,
|
||||||
remoteMessage,
|
MessageStatus.sent,
|
||||||
MessageStatus.sent,
|
);
|
||||||
);
|
}).toList();
|
||||||
}).toList();
|
|
||||||
|
|
||||||
for (final message in messages) {
|
for (final message in messages) {
|
||||||
await _database.saveMessageWithSender(message);
|
await _database.saveMessageWithSender(message);
|
||||||
@@ -319,20 +332,21 @@ class MessagesNotifier extends _$MessagesNotifier {
|
|||||||
_allRemoteMessagesFetched = false;
|
_allRemoteMessagesFetched = false;
|
||||||
|
|
||||||
talker.log('Starting message sync');
|
talker.log('Starting message sync');
|
||||||
Future.microtask(() => ref.read(chatSyncingProvider.notifier).set(true));
|
if (!_disposed) {
|
||||||
|
Future.microtask(() => ref.read(chatSyncingProvider.notifier).set(true));
|
||||||
|
}
|
||||||
try {
|
try {
|
||||||
final dbMessages = await _database.getMessagesForRoom(
|
final dbMessages = await _database.getMessagesForRoom(
|
||||||
_room.id,
|
_room.id,
|
||||||
offset: 0,
|
offset: 0,
|
||||||
limit: 1,
|
limit: 1,
|
||||||
);
|
);
|
||||||
final lastMessage =
|
final lastMessage = dbMessages.isEmpty
|
||||||
dbMessages.isEmpty
|
? null
|
||||||
? null
|
: await _database.companionToMessage(
|
||||||
: await _database.companionToMessage(
|
dbMessages.first,
|
||||||
dbMessages.first,
|
fetchAccount: _fetchAccount,
|
||||||
fetchAccount: _fetchAccount,
|
);
|
||||||
);
|
|
||||||
|
|
||||||
if (lastMessage == null) {
|
if (lastMessage == null) {
|
||||||
talker.log('No local messages, fetching from network');
|
talker.log('No local messages, fetching from network');
|
||||||
@@ -347,8 +361,10 @@ class MessagesNotifier extends _$MessagesNotifier {
|
|||||||
// Sync with pagination support using timestamp-based cursor
|
// Sync with pagination support using timestamp-based cursor
|
||||||
int? totalMessages;
|
int? totalMessages;
|
||||||
int syncedCount = 0;
|
int syncedCount = 0;
|
||||||
int lastSyncTimestamp =
|
int lastSyncTimestamp = lastMessage
|
||||||
lastMessage.toRemoteMessage().updatedAt.millisecondsSinceEpoch;
|
.toRemoteMessage()
|
||||||
|
.updatedAt
|
||||||
|
.millisecondsSinceEpoch;
|
||||||
|
|
||||||
do {
|
do {
|
||||||
final resp = await _apiClient.post(
|
final resp = await _apiClient.post(
|
||||||
@@ -395,7 +411,11 @@ class MessagesNotifier extends _$MessagesNotifier {
|
|||||||
showErrorAlert(err);
|
showErrorAlert(err);
|
||||||
} finally {
|
} finally {
|
||||||
talker.log('Finished message sync');
|
talker.log('Finished message sync');
|
||||||
Future.microtask(() => ref.read(chatSyncingProvider.notifier).set(false));
|
if (!_disposed) {
|
||||||
|
Future.microtask(
|
||||||
|
() => ref.read(chatSyncingProvider.notifier).set(false),
|
||||||
|
);
|
||||||
|
}
|
||||||
_isSyncing = false;
|
_isSyncing = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -492,7 +512,9 @@ class MessagesNotifier extends _$MessagesNotifier {
|
|||||||
if (!_hasMore || state is AsyncLoading) return;
|
if (!_hasMore || state is AsyncLoading) return;
|
||||||
talker.log('Loading more messages');
|
talker.log('Loading more messages');
|
||||||
|
|
||||||
Future.microtask(() => ref.read(chatSyncingProvider.notifier).set(true));
|
if (!_disposed) {
|
||||||
|
Future.microtask(() => ref.read(chatSyncingProvider.notifier).set(true));
|
||||||
|
}
|
||||||
try {
|
try {
|
||||||
final currentMessages = state.value ?? [];
|
final currentMessages = state.value ?? [];
|
||||||
final offset = currentMessages.length;
|
final offset = currentMessages.length;
|
||||||
@@ -515,7 +537,11 @@ class MessagesNotifier extends _$MessagesNotifier {
|
|||||||
);
|
);
|
||||||
showErrorAlert(err);
|
showErrorAlert(err);
|
||||||
} finally {
|
} finally {
|
||||||
Future.microtask(() => ref.read(chatSyncingProvider.notifier).set(false));
|
if (!_disposed) {
|
||||||
|
Future.microtask(
|
||||||
|
() => ref.read(chatSyncingProvider.notifier).set(false),
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -559,18 +585,17 @@ class MessagesNotifier extends _$MessagesNotifier {
|
|||||||
try {
|
try {
|
||||||
var cloudAttachments = List.empty(growable: true);
|
var cloudAttachments = List.empty(growable: true);
|
||||||
for (var idx = 0; idx < attachments.length; idx++) {
|
for (var idx = 0; idx < attachments.length; idx++) {
|
||||||
final cloudFile =
|
final cloudFile = await FileUploader.createCloudFile(
|
||||||
await FileUploader.createCloudFile(
|
ref: ref,
|
||||||
ref: ref,
|
fileData: attachments[idx],
|
||||||
fileData: attachments[idx],
|
onProgress: (progress, _) {
|
||||||
onProgress: (progress, _) {
|
_fileUploadProgress[localMessage.id]?[idx] = progress ?? 0.0;
|
||||||
_fileUploadProgress[localMessage.id]?[idx] = progress ?? 0.0;
|
onProgress?.call(
|
||||||
onProgress?.call(
|
localMessage.id,
|
||||||
localMessage.id,
|
_fileUploadProgress[localMessage.id] ?? {},
|
||||||
_fileUploadProgress[localMessage.id] ?? {},
|
);
|
||||||
);
|
},
|
||||||
},
|
).future;
|
||||||
).future;
|
|
||||||
if (cloudFile == null) {
|
if (cloudFile == null) {
|
||||||
throw ArgumentError('Failed to upload the file...');
|
throw ArgumentError('Failed to upload the file...');
|
||||||
}
|
}
|
||||||
@@ -606,22 +631,20 @@ class MessagesNotifier extends _$MessagesNotifier {
|
|||||||
|
|
||||||
final currentMessages = state.value ?? [];
|
final currentMessages = state.value ?? [];
|
||||||
if (editingTo != null) {
|
if (editingTo != null) {
|
||||||
final newMessages =
|
final newMessages = currentMessages
|
||||||
currentMessages
|
.where((m) => m.id != localMessage.id) // remove pending message
|
||||||
.where((m) => m.id != localMessage.id) // remove pending message
|
.map(
|
||||||
.map(
|
(m) => m.id == editingTo.id ? updatedMessage : m,
|
||||||
(m) => m.id == editingTo.id ? updatedMessage : m,
|
) // update original message
|
||||||
) // update original message
|
.toList();
|
||||||
.toList();
|
|
||||||
state = AsyncValue.data(newMessages);
|
state = AsyncValue.data(newMessages);
|
||||||
} else {
|
} else {
|
||||||
final newMessages =
|
final newMessages = currentMessages.map((m) {
|
||||||
currentMessages.map((m) {
|
if (m.id == localMessage.id) {
|
||||||
if (m.id == localMessage.id) {
|
return updatedMessage;
|
||||||
return updatedMessage;
|
}
|
||||||
}
|
return m;
|
||||||
return m;
|
}).toList();
|
||||||
}).toList();
|
|
||||||
state = AsyncValue.data(newMessages);
|
state = AsyncValue.data(newMessages);
|
||||||
}
|
}
|
||||||
talker.log('Message with nonce $nonce sent successfully');
|
talker.log('Message with nonce $nonce sent successfully');
|
||||||
@@ -638,13 +661,12 @@ class MessagesNotifier extends _$MessagesNotifier {
|
|||||||
localMessage.id,
|
localMessage.id,
|
||||||
MessageStatus.failed,
|
MessageStatus.failed,
|
||||||
);
|
);
|
||||||
final newMessages =
|
final newMessages = (state.value ?? []).map((m) {
|
||||||
(state.value ?? []).map((m) {
|
if (m.id == localMessage.id) {
|
||||||
if (m.id == localMessage.id) {
|
return m..status = MessageStatus.failed;
|
||||||
return m..status = MessageStatus.failed;
|
}
|
||||||
}
|
return m;
|
||||||
return m;
|
}).toList();
|
||||||
}).toList();
|
|
||||||
state = AsyncValue.data(newMessages);
|
state = AsyncValue.data(newMessages);
|
||||||
showErrorAlert(e);
|
showErrorAlert(e);
|
||||||
}
|
}
|
||||||
@@ -686,13 +708,12 @@ class MessagesNotifier extends _$MessagesNotifier {
|
|||||||
await _database.deleteMessage(pendingMessageId);
|
await _database.deleteMessage(pendingMessageId);
|
||||||
await _database.saveMessageWithSender(updatedMessage);
|
await _database.saveMessageWithSender(updatedMessage);
|
||||||
|
|
||||||
final newMessages =
|
final newMessages = (state.value ?? []).map((m) {
|
||||||
(state.value ?? []).map((m) {
|
if (m.id == pendingMessageId) {
|
||||||
if (m.id == pendingMessageId) {
|
return updatedMessage;
|
||||||
return updatedMessage;
|
}
|
||||||
}
|
return m;
|
||||||
return m;
|
}).toList();
|
||||||
}).toList();
|
|
||||||
state = AsyncValue.data(newMessages);
|
state = AsyncValue.data(newMessages);
|
||||||
} catch (e, stackTrace) {
|
} catch (e, stackTrace) {
|
||||||
talker.log(
|
talker.log(
|
||||||
@@ -707,13 +728,12 @@ class MessagesNotifier extends _$MessagesNotifier {
|
|||||||
pendingMessageId,
|
pendingMessageId,
|
||||||
MessageStatus.failed,
|
MessageStatus.failed,
|
||||||
);
|
);
|
||||||
final newMessages =
|
final newMessages = (state.value ?? []).map((m) {
|
||||||
(state.value ?? []).map((m) {
|
if (m.id == pendingMessageId) {
|
||||||
if (m.id == pendingMessageId) {
|
return m..status = MessageStatus.failed;
|
||||||
return m..status = MessageStatus.failed;
|
}
|
||||||
}
|
return m;
|
||||||
return m;
|
}).toList();
|
||||||
}).toList();
|
|
||||||
state = AsyncValue.data(_sortMessages(newMessages));
|
state = AsyncValue.data(_sortMessages(newMessages));
|
||||||
showErrorAlert(e);
|
showErrorAlert(e);
|
||||||
}
|
}
|
||||||
@@ -865,8 +885,9 @@ class MessagesNotifier extends _$MessagesNotifier {
|
|||||||
await _database.deleteMessage(messageId);
|
await _database.deleteMessage(messageId);
|
||||||
|
|
||||||
final currentMessages = state.value ?? [];
|
final currentMessages = state.value ?? [];
|
||||||
final newMessages =
|
final newMessages = currentMessages
|
||||||
currentMessages.where((m) => m.id != messageId).toList();
|
.where((m) => m.id != messageId)
|
||||||
|
.toList();
|
||||||
state = AsyncValue.data(newMessages);
|
state = AsyncValue.data(newMessages);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -969,9 +990,9 @@ class MessagesNotifier extends _$MessagesNotifier {
|
|||||||
Future<LocalChatMessage?> fetchMessageById(String messageId) async {
|
Future<LocalChatMessage?> fetchMessageById(String messageId) async {
|
||||||
talker.log('Fetching message by id $messageId');
|
talker.log('Fetching message by id $messageId');
|
||||||
try {
|
try {
|
||||||
final localMessage =
|
final localMessage = await (_database.select(
|
||||||
await (_database.select(_database.chatMessages)
|
_database.chatMessages,
|
||||||
..where((tbl) => tbl.id.equals(messageId))).getSingleOrNull();
|
)..where((tbl) => tbl.id.equals(messageId))).getSingleOrNull();
|
||||||
if (localMessage != null) {
|
if (localMessage != null) {
|
||||||
return _database.companionToMessage(
|
return _database.companionToMessage(
|
||||||
localMessage,
|
localMessage,
|
||||||
@@ -1005,7 +1026,9 @@ class MessagesNotifier extends _$MessagesNotifier {
|
|||||||
_isJumping = true;
|
_isJumping = true;
|
||||||
|
|
||||||
// Clear flashing messages when starting a new jump
|
// Clear flashing messages when starting a new jump
|
||||||
ref.read(flashingMessagesProvider.notifier).state = {};
|
if (!_disposed) {
|
||||||
|
ref.read(flashingMessagesProvider.notifier).state = {};
|
||||||
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
talker.log('Fetching message $messageId');
|
talker.log('Fetching message $messageId');
|
||||||
@@ -1047,8 +1070,9 @@ class MessagesNotifier extends _$MessagesNotifier {
|
|||||||
|
|
||||||
// Calculate offset to position target message in the middle of the loaded chunk
|
// Calculate offset to position target message in the middle of the loaded chunk
|
||||||
const chunkSize = 100; // Load 100 messages around the target
|
const chunkSize = 100; // Load 100 messages around the target
|
||||||
final offset =
|
final offset = (newerCount - chunkSize ~/ 2)
|
||||||
(newerCount - chunkSize ~/ 2).clamp(0, double.infinity).toInt();
|
.clamp(0, double.infinity)
|
||||||
|
.toInt();
|
||||||
talker.log(
|
talker.log(
|
||||||
'Calculated offset $offset for target message (newer: $newerCount, chunk: $chunkSize)',
|
'Calculated offset $offset for target message (newer: $newerCount, chunk: $chunkSize)',
|
||||||
);
|
);
|
||||||
@@ -1060,8 +1084,9 @@ class MessagesNotifier extends _$MessagesNotifier {
|
|||||||
|
|
||||||
// Check if loaded messages are already in current state
|
// Check if loaded messages are already in current state
|
||||||
final currentIds = currentMessages.map((m) => m.id).toSet();
|
final currentIds = currentMessages.map((m) => m.id).toSet();
|
||||||
final newMessages =
|
final newMessages = loadedMessages
|
||||||
loadedMessages.where((m) => !currentIds.contains(m.id)).toList();
|
.where((m) => !currentIds.contains(m.id))
|
||||||
|
.toList();
|
||||||
talker.log(
|
talker.log(
|
||||||
'Loaded ${loadedMessages.length} messages, ${newMessages.length} are new',
|
'Loaded ${loadedMessages.length} messages, ${newMessages.length} are new',
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -26,13 +26,12 @@ class PostItemScreenshot extends ConsumerWidget {
|
|||||||
final renderingPadding =
|
final renderingPadding =
|
||||||
padding ?? const EdgeInsets.symmetric(horizontal: 8, vertical: 8);
|
padding ?? const EdgeInsets.symmetric(horizontal: 8, vertical: 8);
|
||||||
|
|
||||||
final mostReaction =
|
final mostReaction = item.reactionsCount.isEmpty
|
||||||
item.reactionsCount.isEmpty
|
? null
|
||||||
? null
|
: item.reactionsCount.entries
|
||||||
: item.reactionsCount.entries
|
.sortedBy((e) => e.value)
|
||||||
.sortedBy((e) => e.value)
|
.map((e) => e.key)
|
||||||
.map((e) => e.key)
|
.last;
|
||||||
.last;
|
|
||||||
|
|
||||||
final isDark = MediaQuery.of(context).platformBrightness == Brightness.dark;
|
final isDark = MediaQuery.of(context).platformBrightness == Brightness.dark;
|
||||||
|
|
||||||
@@ -51,27 +50,27 @@ class PostItemScreenshot extends ConsumerWidget {
|
|||||||
isInteractive: false,
|
isInteractive: false,
|
||||||
renderingPadding: renderingPadding,
|
renderingPadding: renderingPadding,
|
||||||
isRelativeTime: false,
|
isRelativeTime: false,
|
||||||
trailing:
|
trailing: mostReaction != null
|
||||||
mostReaction != null
|
? Row(
|
||||||
? Row(
|
children: [
|
||||||
children: [
|
Text(
|
||||||
Text(
|
kReactionTemplates[mostReaction]?.icon ?? '',
|
||||||
kReactionTemplates[mostReaction]?.icon ?? '',
|
style: const TextStyle(fontSize: 20),
|
||||||
style: const TextStyle(fontSize: 20),
|
),
|
||||||
),
|
const Gap(4),
|
||||||
const Gap(4),
|
Text(
|
||||||
Text(
|
'x${item.reactionsCount[mostReaction]}',
|
||||||
'x${item.reactionsCount[mostReaction]}',
|
style: const TextStyle(fontSize: 11),
|
||||||
style: const TextStyle(fontSize: 11),
|
),
|
||||||
),
|
],
|
||||||
],
|
)
|
||||||
)
|
: null,
|
||||||
: null,
|
|
||||||
),
|
),
|
||||||
PostBody(
|
PostBody(
|
||||||
item: item,
|
item: item,
|
||||||
renderingPadding: renderingPadding,
|
renderingPadding: renderingPadding,
|
||||||
isFullPost: isFullPost,
|
isFullPost: isFullPost,
|
||||||
|
isRelativeTime: false,
|
||||||
isTextSelectable: false,
|
isTextSelectable: false,
|
||||||
isInteractive: false,
|
isInteractive: false,
|
||||||
hideOverlay: true,
|
hideOverlay: true,
|
||||||
|
|||||||
@@ -816,17 +816,7 @@ class PostBody extends ConsumerWidget {
|
|||||||
Row(
|
Row(
|
||||||
spacing: 8,
|
spacing: 8,
|
||||||
crossAxisAlignment: CrossAxisAlignment.center,
|
crossAxisAlignment: CrossAxisAlignment.center,
|
||||||
children: [
|
children: [const Icon(Symbols.edit, size: 16), text],
|
||||||
const Icon(Symbols.edit, size: 16),
|
|
||||||
hideOverlay
|
|
||||||
? text
|
|
||||||
: Tooltip(
|
|
||||||
message: !isFullPost && isRelativeTime
|
|
||||||
? item.editedAt!.formatSystem()
|
|
||||||
: item.editedAt!.formatRelative(context),
|
|
||||||
child: text,
|
|
||||||
),
|
|
||||||
],
|
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -240,7 +240,7 @@ class PostSubscriptionFilterWidget extends HookConsumerWidget {
|
|||||||
horizontal: 16,
|
horizontal: 16,
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}).toList(),
|
}),
|
||||||
],
|
],
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
|
|||||||
Reference in New Issue
Block a user