mirror of
https://github.com/AyuGram/AyuGramDesktop.git
synced 2025-07-26 07:23:02 +02:00
Try scrolling to the task on jump.
This commit is contained in:
parent
bff86b90fb
commit
f2e53ea490
4 changed files with 98 additions and 10 deletions
|
@ -1498,12 +1498,21 @@ int HistoryWidget::itemTopForHighlight(
|
||||||
const auto heightLeft = (visibleAreaHeight - viewHeight);
|
const auto heightLeft = (visibleAreaHeight - viewHeight);
|
||||||
if (heightLeft >= 0) {
|
if (heightLeft >= 0) {
|
||||||
return std::max(itemTop - (heightLeft / 2), 0);
|
return std::max(itemTop - (heightLeft / 2), 0);
|
||||||
} else if (const auto sel = itemHighlight(item).range
|
} else if (const auto highlight = itemHighlight(item)
|
||||||
; !sel.empty() && !IsSubGroupSelection(sel)) {
|
; (!highlight.range.empty() || highlight.todoItemId)
|
||||||
|
&& !IsSubGroupSelection(highlight.range)) {
|
||||||
|
const auto sel = highlight.range;
|
||||||
const auto single = st::messageTextStyle.font->height;
|
const auto single = st::messageTextStyle.font->height;
|
||||||
const auto begin = HistoryView::FindViewY(view, sel.from) - single;
|
const auto todoy = sel.empty()
|
||||||
const auto end = HistoryView::FindViewY(view, sel.to, begin + single)
|
? HistoryView::FindViewTaskY(view, highlight.todoItemId)
|
||||||
+ 2 * single;
|
: 0;
|
||||||
|
const auto begin = sel.empty()
|
||||||
|
? (todoy - 4 * single)
|
||||||
|
: HistoryView::FindViewY(view, sel.from) - single;
|
||||||
|
const auto end = sel.empty()
|
||||||
|
? (todoy + 4 * single)
|
||||||
|
: (HistoryView::FindViewY(view, sel.to, begin + single)
|
||||||
|
+ 2 * single);
|
||||||
auto result = itemTop;
|
auto result = itemTop;
|
||||||
if (end > visibleAreaHeight) {
|
if (end > visibleAreaHeight) {
|
||||||
result = std::max(result, itemTop + end - visibleAreaHeight);
|
result = std::max(result, itemTop + end - visibleAreaHeight);
|
||||||
|
|
|
@ -46,6 +46,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
#include "data/data_channel.h"
|
#include "data/data_channel.h"
|
||||||
#include "data/data_saved_sublist.h"
|
#include "data/data_saved_sublist.h"
|
||||||
#include "data/data_session.h"
|
#include "data/data_session.h"
|
||||||
|
#include "data/data_todo_list.h"
|
||||||
#include "data/data_forum.h"
|
#include "data/data_forum.h"
|
||||||
#include "data/data_forum_topic.h"
|
#include "data/data_forum_topic.h"
|
||||||
#include "data/data_message_reactions.h"
|
#include "data/data_message_reactions.h"
|
||||||
|
@ -2455,6 +2456,70 @@ int FindViewY(not_null<Element*> view, uint16 symbol, int yfrom) {
|
||||||
return origin.y() + (yfrom + ytill) / 2;
|
return origin.y() + (yfrom + ytill) / 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int FindViewTaskY(not_null<Element*> view, int taskId, int yfrom) {
|
||||||
|
auto request = HistoryView::StateRequest();
|
||||||
|
request.flags = Ui::Text::StateRequest::Flag::LookupLink;
|
||||||
|
const auto single = st::messageTextStyle.font->height;
|
||||||
|
const auto inner = view->innerGeometry();
|
||||||
|
const auto origin = inner.topLeft();
|
||||||
|
const auto top = 0;
|
||||||
|
const auto bottom = view->height();
|
||||||
|
if (origin.y() < top
|
||||||
|
|| origin.y() + inner.height() > bottom
|
||||||
|
|| inner.height() <= 0) {
|
||||||
|
return yfrom;
|
||||||
|
}
|
||||||
|
const auto media = view->data()->media();
|
||||||
|
const auto todolist = media ? media->todolist() : nullptr;
|
||||||
|
if (!todolist) {
|
||||||
|
return yfrom;
|
||||||
|
}
|
||||||
|
const auto &items = todolist->items;
|
||||||
|
const auto indexOf = [&](int id) -> int {
|
||||||
|
return ranges::find(items, id, &TodoListItem::id) - begin(items);
|
||||||
|
};
|
||||||
|
const auto index = indexOf(taskId);
|
||||||
|
const auto count = int(items.size());
|
||||||
|
if (index == count) {
|
||||||
|
return yfrom;
|
||||||
|
}
|
||||||
|
yfrom = std::max(yfrom - origin.y(), 0);
|
||||||
|
auto ytill = inner.height() - 1;
|
||||||
|
const auto middle = (yfrom + ytill) / 2;
|
||||||
|
const auto fory = [&](int y) {
|
||||||
|
const auto state = view->textState(origin + QPoint(0, y), request);
|
||||||
|
const auto &link = state.link;
|
||||||
|
const auto id = link
|
||||||
|
? link->property(kTodoListItemIdProperty).toInt()
|
||||||
|
: -1;
|
||||||
|
const auto index = (id >= 0) ? indexOf(id) : int(items.size());
|
||||||
|
return (index < count) ? index : (y < middle) ? -1 : count;
|
||||||
|
};
|
||||||
|
auto indexfrom = fory(yfrom);
|
||||||
|
auto indextill = fory(ytill);
|
||||||
|
if ((yfrom >= ytill) || (indexfrom >= index)) {
|
||||||
|
return origin.y() + yfrom;
|
||||||
|
} else if (indextill <= index) {
|
||||||
|
return origin.y() + ytill;
|
||||||
|
}
|
||||||
|
while (ytill - yfrom >= 2 * single) {
|
||||||
|
const auto middle = (yfrom + ytill) / 2;
|
||||||
|
const auto found = fory(middle);
|
||||||
|
if (found == index
|
||||||
|
|| indexfrom > found
|
||||||
|
|| indextill < found) {
|
||||||
|
return origin.y() + middle;
|
||||||
|
} else if (found < index) {
|
||||||
|
yfrom = middle;
|
||||||
|
indexfrom = found;
|
||||||
|
} else {
|
||||||
|
ytill = middle;
|
||||||
|
indextill = found;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return origin.y() + (yfrom + ytill) / 2;
|
||||||
|
}
|
||||||
|
|
||||||
Window::SessionController *ExtractController(const ClickContext &context) {
|
Window::SessionController *ExtractController(const ClickContext &context) {
|
||||||
const auto my = context.other.value<ClickHandlerContext>();
|
const auto my = context.other.value<ClickHandlerContext>();
|
||||||
if (const auto controller = my.sessionWindow.get()) {
|
if (const auto controller = my.sessionWindow.get()) {
|
||||||
|
|
|
@ -747,6 +747,11 @@ private:
|
||||||
uint16 symbol,
|
uint16 symbol,
|
||||||
int yfrom = 0);
|
int yfrom = 0);
|
||||||
|
|
||||||
|
[[nodiscard]] int FindViewTaskY(
|
||||||
|
not_null<Element*> view,
|
||||||
|
int taskId,
|
||||||
|
int yfrom = 0);
|
||||||
|
|
||||||
[[nodiscard]] Window::SessionController *ExtractController(
|
[[nodiscard]] Window::SessionController *ExtractController(
|
||||||
const ClickContext &context);
|
const ClickContext &context);
|
||||||
|
|
||||||
|
|
|
@ -716,12 +716,21 @@ std::optional<int> ListWidget::scrollTopForView(
|
||||||
const auto heightLeft = (available - height);
|
const auto heightLeft = (available - height);
|
||||||
if (heightLeft >= 0) {
|
if (heightLeft >= 0) {
|
||||||
return std::max(top - (heightLeft / 2), 0);
|
return std::max(top - (heightLeft / 2), 0);
|
||||||
} else if (const auto sel = _highlighter.state(view->data()).range
|
} else if (const auto highlight = _highlighter.state(view->data())
|
||||||
; !sel.empty() && !IsSubGroupSelection(sel)) {
|
; (!highlight.range.empty() || highlight.todoItemId)
|
||||||
|
&& !IsSubGroupSelection(highlight.range)) {
|
||||||
|
const auto sel = highlight.range;
|
||||||
const auto single = st::messageTextStyle.font->height;
|
const auto single = st::messageTextStyle.font->height;
|
||||||
const auto begin = HistoryView::FindViewY(view, sel.from) - single;
|
const auto todoy = sel.empty()
|
||||||
const auto end = HistoryView::FindViewY(view, sel.to, begin + single)
|
? HistoryView::FindViewTaskY(view, highlight.todoItemId)
|
||||||
+ 2 * single;
|
: 0;
|
||||||
|
const auto begin = sel.empty()
|
||||||
|
? (todoy - 4 * single)
|
||||||
|
: HistoryView::FindViewY(view, sel.from) - single;
|
||||||
|
const auto end = sel.empty()
|
||||||
|
? (todoy + 4 * single)
|
||||||
|
: (HistoryView::FindViewY(view, sel.to, begin + single)
|
||||||
|
+ 2 * single);
|
||||||
auto result = top;
|
auto result = top;
|
||||||
if (end > available) {
|
if (end > available) {
|
||||||
result = std::max(result, top + end - available);
|
result = std::max(result, top + end - available);
|
||||||
|
|
Loading…
Add table
Reference in a new issue