Теперь, при нажатии на кнопку закладки topic-timeline, открывается модальное окно для настройки закладки. После сохранения закладки обновляются кнопки закладок под кнопками first-post-menu и topic-footer-button, но сам виджет не обновляется до тех пор, пока не будет обновлён виджет topic-timeline (то есть до прокрутки), и наоборот.
first-post-menu
topic-footer-button
Я обнаружил, что при установке/снятии закладки обновляется виджет post-stream, поэтому кнопки закладок в post-menu и topic-footer-button работают синхронно.
Так как же теперь обновлять мой виджет topic-timeline-bookmark при установке/снятии закладки или при обновлении виджета post-stream? Ниже мой код:
<script type="text/discourse-plugin" version="0.8">
const { h } = require('virtual-dom');
const { getOwner } = require("discourse-common/lib/get-owner");
const topicController = getOwner(this).lookup("controller:topic");
api.createWidget("topic-timeline-bookmark", {
tagName: 'div.discourse-bookmark-button-wrapper',
buildKey: () => `topic-timeline-bookmark`,
toggleBookmark() {
topicController.send('toggleBookmark');
},
html(attrs, state) {
let contents = [];
const user = api.getCurrentUser();
if (user) {
let tooltip = 'bookmarked.help.bookmark';
let label = 'bookmarked.title';
let buttonClass = 'btn btn-default bookmark';
let icon = "bookmark";
let bookmarkedPosts = topicController.model.bookmarked_posts;
let bookmarkCount = 0;
if(bookmarkedPosts && bookmarkedPosts.length > 0){
bookmarkCount = bookmarkedPosts.length;
//Иконка
if (bookmarkedPosts.some((bookmark) => bookmark.reminder_at))
icon = "discourse-bookmark-clock";
else
icon = "bookmark";
//Метка
if (bookmarkCount === 0)
label = "bookmarked.title";
else if (bookmarkCount === 1)
label = "bookmarked.edit_bookmark";
else
label = "bookmarked.clear_bookmarks";
//Подсказка
if (bookmarkedPosts.length === 1)
tooltip = 'bookmarked.help.edit_bookmark';
else if (bookmarkedPosts.find((x) => x.reminder_at))
tooltip = 'bookmarked.help.unbookmark_with_reminder';
//Добавляем CSS-класс, если закладка установлена
if (bookmarkCount > 0) { buttonClass += ' bookmarked' }
}
contents.push(
this.attach('button', {
action: 'toggleBookmark',
title: tooltip,
label: label,
icon: icon,
className: buttonClass
})
);
}
return contents;
},
});
api.decorateWidget('topic-timeline:after', function(helper) {
return helper.attach('topic-timeline-bookmark');
});
</script>
api.createWidget("topic-timeline-bookmark", {
// код опущен
// возможно, можно назвать это schedule-rerender
// напрямую в вызове API вместо force-refresh
// и избежать необходимости в этой функции
forceRefresh() {
this.scheduleRerender();
}
});
Думаю, это должно сработать. Если нет — дайте знать, я попробую собрать рабочий пример локально.
Мы попробовали предложенный вами код, но он не работает.
Добавили следующий вызов API: api.dispatchWidgetAppEvent('topic-timeline-bookmark', 'force-refresh', 'post-stream:refresh');
А затем добавили метод forceRefresh() в виджет “topic-timeline-bookmark”.
Но это не помогло.
Я также попытался переименовать второй параметр метода dispatchWidgetAppEvent в “schedule-rerender” и удалил функцию forceRefresh из виджета. Это тоже не сработало.
Я изучил реализацию метода api.dispatchWidgetAppEvent: он принимает три аргумента, где второй — это widgetKey. Мне кажется, это должно быть значение, возвращаемое функцией buildKey() виджета.
Третий аргумент — это appEvent, который преобразуется в camelCase и используется как имя метода.
@saurabhmasc Я добился работы локально, однако пришлось исправить ошибку в ядре и добавить новую функцию в ядро. Я обновлю тему, когда всё это будет слито.
Раньше мы заметили, что при добавлении закладки из кнопок в подвале темы первый пост также помечался как закладочный, но теперь первый пост не помечается. Это правильно?
Мы протестировали ваш компонент: все случаи работают корректно, кроме функции «Очистить закладки», которая не синхронизируется.
Чтобы это исправить, мы добавили следующие строки кода, и теперь функция «Очистить закладки» также работает корректно.
Посмотрю на первый пункт. Что касается второго, да, возможно, я упустил один случай. Основной автор закладок сейчас отсутствует, и я хотел бы внести несколько изменений, но мне нужно, чтобы он вернулся. Ваше исправление должно подойти.
Мы создадим новый тикет с запросом на внедрение этих основных изменений в наши среды Staging и Production. Это позволит нам протестировать их в среде Staging.