Wenn wir nun auf den Lesezeichen-Button von topic-timeline klicken, wird das Modal-Fenster zum Festlegen des Lesezeichens angezeigt. Beim Speichern des Lesezeichens werden die Lesezeichen-Buttons unter den first-post-menu-Buttons und den topic-footer-button aktualisiert, aber der Button von topic-timeline selbst wird nicht aktualisiert, bis das Widget topic-timeline neu geladen wird (d. h. bis wir scrollen), und umgekehrt.
first-post-menu
topic-footer-button
Ich habe festgestellt, dass das Widget post-stream immer dann neu geladen wird, wenn ein Lesezeichen gesetzt oder entfernt wird. Daher funktionieren die Lesezeichen-Buttons im Post-Menü und im topic-footer-button synchron.
Wie kann ich nun mein Widget „topic-timeline-bookmark" immer dann neu laden, wenn ein Lesezeichen gesetzt oder entfernt wird oder wenn das Widget post-stream neu geladen wird? Hier ist mein Code:
<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;
//Icon
if (bookmarkedPosts.some((bookmark) => bookmark.reminder_at))
icon = "discourse-bookmark-clock";
else
icon = "bookmark";
//Label
if (bookmarkCount === 0)
label = "bookmarked.title";
else if (bookmarkCount === 1)
label = "bookmarked.edit_bookmark";
else
label = "bookmarked.clear_bookmarks";
//Tooltip
if (bookmarkedPosts.length === 1)
tooltip = 'bookmarked.help.edit_bookmark';
else if (bookmarkedPosts.find((x) => x.reminder_at))
tooltip = 'bookmarked.help.unbookmark_with_reminder';
//Append CSS class if bookmark is set
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", {
// Code weggelassen
// Möglicherweise könnte man es direkt im API-Aufruf statt 'force-refresh'
// 'schedule-rerender' nennen und diese Funktion somit vermeiden
forceRefresh() {
this.scheduleRerender();
}
});
Ich denke, das sollte funktionieren. Falls nicht, lass es mich bitte wissen, dann versuche ich, lokal ein funktionierendes Beispiel zu erstellen.
Wir haben den von dir vorgeschlagenen Code ausprobiert, aber er funktioniert nicht.
Wir haben den folgenden API-Aufruf hinzugefügt: api.dispatchWidgetAppEvent('topic-timeline-bookmark', 'force-refresh', 'post-stream:refresh');
Und danach die Methode forceRefresh() im Widget „topic-timeline-bookmark" hinzugefügt.
Das funktioniert jedoch nicht.
Ich habe auch versucht, den zweiten Parameter der dispatchWidgetAppEvent-Methode in „schedule-rerender" umzubenennen und die forceRefresh-Funktion aus dem Widget zu entfernen. Auch das funktioniert nicht.
Ich habe mir die Implementierung der api.dispatchWidgetAppEvent-Methode angesehen. Sie nimmt drei Argumente entgegen, wobei das zweite der widgetKey ist. Ich denke, dies sollte der Wert sein, der von der buildKey()-Funktion des Widgets zurückgegeben wird.
Das dritte Argument ist das appEvent, das in camelCase umgewandelt und als Methodenname für uns verwendet wird.
@saurabhmasc Ich habe es lokal zum Laufen gebracht, musste jedoch einen Fehler im Core beheben und eine neue Funktion im Core hinzufügen. Ich werde das Thema aktualisieren, sobald alles zusammengeführt ist.
Wir haben festgestellt, dass früher, wenn wir über die Topic-Footer-Buttons ein Lesezeichen gesetzt haben, auch der erste Beitrag als gelistet markiert wurde. Jetzt wird der erste Beitrag jedoch nicht mehr gelistet. Ist das jetzt korrekt?
Wir haben Ihre Komponente in allen Fällen getestet und sie funktioniert einwandfrei. Lediglich die Funktion „Lesezeichen löschen“ arbeitet nicht synchron.
Um dies zu beheben, haben wir folgende Codezeilen hinzugefügt, und jetzt funktioniert die Funktion „Lesezeichen löschen“ ebenfalls einwandfrei:
Ich werde den ersten Punkt prüfen. Was den zweiten betrifft: Ja, es ist möglich, dass ich einen Fall übersehen habe. Der Hauptautor der Lesezeichen ist derzeit abwesend, und ich möchte ein paar Dinge ändern, aber dafür muss er zurück sein. Deine Korrektur sollte in Ordnung sein.
Wir werden ein neues Ticket erstellen und bitten, diese Kernänderungen in unsere Staging- und Produktionsumgebungen zu übernehmen, damit wir sie in Staging testen können.