УХХ БЛЯЯЯ РАТАТАТАТАТ ЯТАТАТАТАТ Переход к закрепленным сообщений, че там осталось...
This commit is contained in:
5
.gitignore
vendored
5
.gitignore
vendored
@@ -47,3 +47,8 @@ app.*.map.json
|
|||||||
pubspec.lock
|
pubspec.lock
|
||||||
.vscode/
|
.vscode/
|
||||||
macos/Podfile.lock
|
macos/Podfile.lock
|
||||||
|
|
||||||
|
# Android signing keys (keystore)
|
||||||
|
android/key.properties
|
||||||
|
android/app/*.jks
|
||||||
|
*.jks
|
||||||
@@ -38,6 +38,8 @@ android {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// keystore properties теперь лежат в android/key.properties
|
||||||
|
// rootProject указывает на каталог android/, поэтому путь должен быть именно "key.properties"
|
||||||
val keyPropertiesFile = rootProject.file("key.properties")
|
val keyPropertiesFile = rootProject.file("key.properties")
|
||||||
val keyProperties = Properties()
|
val keyProperties = Properties()
|
||||||
|
|
||||||
|
|||||||
@@ -869,6 +869,46 @@ class _ChatScreenState extends State<ChatScreen> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void _scrollToPinnedMessage() {
|
||||||
|
final pinned = _pinnedMessage;
|
||||||
|
if (pinned == null) return;
|
||||||
|
|
||||||
|
// Находим индекс элемента в _chatItems, который соответствует закрепленному сообщению
|
||||||
|
int? targetChatItemIndex;
|
||||||
|
for (int i = 0; i < _chatItems.length; i++) {
|
||||||
|
final item = _chatItems[i];
|
||||||
|
if (item is MessageItem) {
|
||||||
|
final msg = item.message;
|
||||||
|
if (msg.id == pinned.id ||
|
||||||
|
(msg.cid != null && pinned.cid != null && msg.cid == pinned.cid)) {
|
||||||
|
targetChatItemIndex = i;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (targetChatItemIndex == null) {
|
||||||
|
// Сообщение может быть вне загруженной истории
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!_itemScrollController.isAttached) return;
|
||||||
|
|
||||||
|
// ScrollablePositionedList используется с reverse:true,
|
||||||
|
// поэтому визуальный индекс считается от конца списка
|
||||||
|
final visualIndex = _chatItems.length - 1 - targetChatItemIndex;
|
||||||
|
|
||||||
|
WidgetsBinding.instance.addPostFrameCallback((_) {
|
||||||
|
if (_itemScrollController.isAttached) {
|
||||||
|
_itemScrollController.scrollTo(
|
||||||
|
index: visualIndex,
|
||||||
|
duration: const Duration(milliseconds: 300),
|
||||||
|
curve: Curves.easeInOutCubic,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
void _addMessage(Message message, {bool forceScroll = false}) {
|
void _addMessage(Message message, {bool forceScroll = false}) {
|
||||||
if (_messages.any((m) => m.id == message.id)) {
|
if (_messages.any((m) => m.id == message.id)) {
|
||||||
print('Сообщение ${message.id} уже существует, пропускаем добавление');
|
print('Сообщение ${message.id} уже существует, пропускаем добавление');
|
||||||
@@ -2078,18 +2118,19 @@ class _ChatScreenState extends State<ChatScreen> {
|
|||||||
child: _pinnedMessage != null
|
child: _pinnedMessage != null
|
||||||
? SafeArea(
|
? SafeArea(
|
||||||
key: ValueKey(_pinnedMessage!.id),
|
key: ValueKey(_pinnedMessage!.id),
|
||||||
child: PinnedMessageWidget(
|
child: InkWell(
|
||||||
pinnedMessage: _pinnedMessage!,
|
onTap: _scrollToPinnedMessage,
|
||||||
contacts: _contactDetailsCache,
|
child: PinnedMessageWidget(
|
||||||
myId: _actualMyId ?? 0,
|
pinnedMessage: _pinnedMessage!,
|
||||||
onTap: () {
|
contacts: _contactDetailsCache,
|
||||||
// TODO: Прокрутить к закрепленному сообщению
|
myId: _actualMyId ?? 0,
|
||||||
},
|
onTap: _scrollToPinnedMessage,
|
||||||
onClose: () {
|
onClose: () {
|
||||||
setState(() {
|
setState(() {
|
||||||
_pinnedMessage = null;
|
_pinnedMessage = null;
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
),
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
: const SizedBox.shrink(key: ValueKey('empty')),
|
: const SizedBox.shrink(key: ValueKey('empty')),
|
||||||
|
|||||||
Reference in New Issue
Block a user