-import DatePicker from './wcfsetup/install/files/ts/WoltLabSuite/Core/Date/Picker';
-import Devtools from './wcfsetup/install/files/ts/WoltLabSuite/Core/Devtools';
-import DomUtil from './wcfsetup/install/files/ts/WoltLabSuite/Core/Dom/Util';
-import * as ColorUtil from './wcfsetup/install/files/ts/WoltLabSuite/Core/ColorUtil';
-import UiDropdownSimple from './wcfsetup/install/files/ts/WoltLabSuite/Core/Ui/Dropdown/Simple';
+import DatePicker from "./wcfsetup/install/files/ts/WoltLabSuite/Core/Date/Picker";
+import Devtools from "./wcfsetup/install/files/ts/WoltLabSuite/Core/Devtools";
+import DomUtil from "./wcfsetup/install/files/ts/WoltLabSuite/Core/Dom/Util";
+import * as ColorUtil from "./wcfsetup/install/files/ts/WoltLabSuite/Core/ColorUtil";
+import UiDropdownSimple from "./wcfsetup/install/files/ts/WoltLabSuite/Core/Ui/Dropdown/Simple";
import "@woltlab/zxcvbn";
+import { Reaction } from "./wcfsetup/install/files/ts/WoltLabSuite/Core/Ui/Reaction/Data";
declare global {
interface Window {
Devtools?: typeof Devtools;
ENABLE_DEBUG_MODE: boolean;
+ REACTION_TYPES: {
+ [key: string]: Reaction;
+ };
SECURITY_TOKEN: string;
TIME_NOW: number;
WCF_PATH: string;
/**
* Provides interface elements to use reactions.
*
- * @author Joshua Ruesweg
- * @copyright 2001-2019 WoltLab GmbH
- * @license GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
- * @module WoltLabSuite/Core/Ui/Reaction/Handler
+ * @author Joshua Ruesweg
+ * @copyright 2001-2019 WoltLab GmbH
+ * @license GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
+ * @module WoltLabSuite/Core/Ui/Reaction/Handler
* @since 5.2
*/
-define([
- 'Ajax', 'Core', 'Dictionary', 'Language',
- 'ObjectMap', 'StringUtil', 'Dom/ChangeListener', 'Dom/Util',
- 'Ui/Dialog', 'EventHandler'
-], function (Ajax, Core, Dictionary, Language, ObjectMap, StringUtil, DomChangeListener, DomUtil, UiDialog, EventHandler) {
+define(["require", "exports", "tslib", "../../Ajax", "../../Core", "../../Dom/Change/Listener", "../../Dom/Util", "../../Event/Handler", "../../StringUtil", "../Dialog"], function (require, exports, tslib_1, Ajax, Core, Listener_1, Util_1, EventHandler, StringUtil, Dialog_1) {
"use strict";
- /**
- * @constructor
- */
- function CountButtons(objectType, options) { this.init(objectType, options); }
- CountButtons.prototype = {
+ Ajax = tslib_1.__importStar(Ajax);
+ Core = tslib_1.__importStar(Core);
+ Listener_1 = tslib_1.__importDefault(Listener_1);
+ Util_1 = tslib_1.__importDefault(Util_1);
+ EventHandler = tslib_1.__importStar(EventHandler);
+ StringUtil = tslib_1.__importStar(StringUtil);
+ Dialog_1 = tslib_1.__importDefault(Dialog_1);
+ class CountButtons {
/**
* Initializes the like handler.
- *
- * @param {string} objectType object type
- * @param {object} options initialization options
*/
- init: function (objectType, options) {
- if (options.containerSelector === '') {
+ constructor(objectType, opts) {
+ this._containers = new Map();
+ this._currentObjectId = 0;
+ this._objects = new Map();
+ if (!opts.containerSelector) {
throw new Error("[WoltLabSuite/Core/Ui/Reaction/CountButtons] Expected a non-empty string for option 'containerSelector'.");
}
- this._containers = new Dictionary();
- this._objects = new Dictionary();
this._objectType = objectType;
this._options = Core.extend({
// selectors
- summaryListSelector: '.reactionSummaryList',
- containerSelector: '',
+ summaryListSelector: ".reactionSummaryList",
+ containerSelector: "",
isSingleItem: false,
// optional parameters
parameters: {
- data: {}
- }
- }, options);
- this.initContainers(options, objectType);
- DomChangeListener.add('WoltLabSuite/Core/Ui/Reaction/CountButtons-' + objectType, this.initContainers.bind(this));
- },
+ data: {},
+ },
+ }, opts);
+ this.initContainers();
+ Listener_1.default.add(`WoltLabSuite/Core/Ui/Reaction/CountButtons-${objectType}`, () => this.initContainers());
+ }
/**
* Initialises the containers.
*/
- initContainers: function () {
- var element, elements = elBySelAll(this._options.containerSelector), elementData, triggerChange = false, objectId;
- for (var i = 0, length = elements.length; i < length; i++) {
- element = elements[i];
- if (this._containers.has(DomUtil.identify(element))) {
- continue;
+ initContainers() {
+ let triggerChange = false;
+ document.querySelectorAll(this._options.containerSelector).forEach((element) => {
+ const elementId = Util_1.default.identify(element);
+ if (this._containers.has(elementId)) {
+ return;
}
- objectId = ~~elData(element, 'object-id');
- elementData = {
+ const objectId = ~~element.dataset.objectId;
+ const elementData = {
reactButton: null,
summary: null,
objectId: objectId,
- element: element
+ element: element,
};
- this._containers.set(DomUtil.identify(element), elementData);
+ this._containers.set(elementId, elementData);
this._initReactionCountButtons(element, elementData);
- var objects = [];
- if (this._objects.has(objectId)) {
- objects = this._objects.get(objectId);
- }
+ const objects = this._objects.get(objectId) || [];
objects.push(elementData);
this._objects.set(objectId, objects);
triggerChange = true;
- }
+ });
if (triggerChange) {
- DomChangeListener.trigger();
+ Listener_1.default.trigger();
}
- },
+ }
/**
* Update the count buttons with the given data.
- *
- * @param {int} objectId
- * @param {object} data
*/
- updateCountButtons: function (objectId, data) {
- var triggerChange = false;
- this._objects.get(objectId).forEach(function (elementData) {
- var summaryList = elBySel(this._options.summaryListSelector, this._options.isSingleItem ? undefined : elementData.element);
+ updateCountButtons(objectId, data) {
+ let triggerChange = false;
+ this._objects.get(objectId).forEach((elementData) => {
+ let summaryList;
+ if (this._options.isSingleItem) {
+ summaryList = document.querySelector(this._options.summaryListSelector);
+ }
+ else {
+ summaryList = elementData.element.querySelector(this._options.summaryListSelector);
+ }
// summary list for the object not found; abort
- if (summaryList === null)
+ if (summaryList === null) {
return;
- var sortedElements = {}, elements = elBySelAll('.reactCountButton', summaryList);
- for (var i = 0, length = elements.length; i < length; i++) {
- var reactionTypeId = elData(elements[i], 'reaction-type-id');
- if (data.hasOwnProperty(reactionTypeId)) {
- sortedElements[reactionTypeId] = elements[i];
+ }
+ const existingReactions = new Map(Object.entries(data));
+ const sortedElements = new Map();
+ summaryList.querySelectorAll(".reactCountButton").forEach((reaction) => {
+ const reactionTypeId = reaction.dataset.reactionTypeId;
+ if (existingReactions.has(reactionTypeId)) {
+ sortedElements.set(reactionTypeId, reaction);
}
else {
// The reaction no longer has any reactions.
- elRemove(elements[i]);
+ reaction.remove();
}
- }
- Object.keys(data).forEach(function (key) {
- if (sortedElements[key] !== undefined) {
- var reactionCount = elBySel('.reactionCount', sortedElements[key]);
- reactionCount.innerHTML = StringUtil.shortUnit(data[key]);
+ });
+ const availableReactions = new Map(Object.entries(window.REACTION_TYPES));
+ existingReactions.forEach((count, reactionTypeId) => {
+ if (sortedElements.has(reactionTypeId)) {
+ const reaction = sortedElements.get(reactionTypeId);
+ const reactionCount = reaction.querySelector(".reactionCount");
+ reactionCount.innerHTML = StringUtil.shortUnit(count);
}
- else if (REACTION_TYPES[key] !== undefined) {
- var createdElement = elCreate('span');
- createdElement.className = 'reactCountButton';
- createdElement.innerHTML = REACTION_TYPES[key].renderedIcon;
- elData(createdElement, 'reaction-type-id', key);
- var countSpan = elCreate('span');
- countSpan.className = 'reactionCount';
- countSpan.innerHTML = StringUtil.shortUnit(data[key]);
+ else if (availableReactions.has(reactionTypeId)) {
+ const createdElement = document.createElement("span");
+ createdElement.className = "reactCountButton";
+ createdElement.innerHTML = availableReactions.get(reactionTypeId).renderedIcon;
+ createdElement.dataset.reactionTypeId = reactionTypeId;
+ const countSpan = document.createElement("span");
+ countSpan.className = "reactionCount";
+ countSpan.innerHTML = StringUtil.shortUnit(count);
createdElement.appendChild(countSpan);
summaryList.appendChild(createdElement);
triggerChange = true;
}
- }, this);
- window[(summaryList.childElementCount > 0 ? 'elShow' : 'elHide')](summaryList);
- }.bind(this));
+ });
+ if (summaryList.childElementCount > 0) {
+ Util_1.default.show(summaryList);
+ }
+ else {
+ Util_1.default.hide(summaryList);
+ }
+ });
if (triggerChange) {
- DomChangeListener.trigger();
+ Listener_1.default.trigger();
}
- },
+ }
/**
* Initialized the reaction count buttons.
- *
- * @param {element} element
- * @param {object} elementData
*/
- _initReactionCountButtons: function (element, elementData) {
- var summaryList = elBySel(this._options.summaryListSelector, this._options.isSingleItem ? undefined : element);
+ _initReactionCountButtons(element, elementData) {
+ let summaryList;
+ if (this._options.isSingleItem) {
+ summaryList = document.querySelector(this._options.summaryListSelector);
+ }
+ else {
+ summaryList = element.querySelector(this._options.summaryListSelector);
+ }
if (summaryList !== null) {
- summaryList.addEventListener('click', this._showReactionOverlay.bind(this, elementData.objectId));
+ summaryList.addEventListener("click", (ev) => this._showReactionOverlay(elementData.objectId, ev));
}
- },
+ }
/**
* Shows the reaction overly for a specific object.
- *
- * @param {int} objectId
- * @param {Event} event
*/
- _showReactionOverlay: function (objectId, event) {
+ _showReactionOverlay(objectId, event) {
event.preventDefault();
this._currentObjectId = objectId;
this._showOverlay();
- },
+ }
/**
* Shows a specific page of the current opened reaction overlay.
*/
- _showOverlay: function () {
- this._options.parameters.data.containerID = this._objectType + '-' + this._currentObjectId;
+ _showOverlay() {
+ this._options.parameters.data.containerID = `${this._objectType}-${this._currentObjectId}`;
this._options.parameters.data.objectID = this._currentObjectId;
this._options.parameters.data.objectType = this._objectType;
Ajax.api(this, {
- parameters: this._options.parameters
+ parameters: this._options.parameters,
});
- },
- _ajaxSuccess: function (data) {
- EventHandler.fire('com.woltlab.wcf.ReactionCountButtons', 'openDialog', data);
- UiDialog.open(this, data.returnValues.template);
- UiDialog.setTitle('userReactionOverlay-' + this._objectType, data.returnValues.title);
- },
- _ajaxSetup: function () {
+ }
+ _ajaxSuccess(data) {
+ EventHandler.fire("com.woltlab.wcf.ReactionCountButtons", "openDialog", data);
+ Dialog_1.default.open(this, data.returnValues.template);
+ Dialog_1.default.setTitle("userReactionOverlay-" + this._objectType, data.returnValues.title);
+ }
+ _ajaxSetup() {
return {
data: {
- actionName: 'getReactionDetails',
- className: '\\wcf\\data\\reaction\\ReactionAction'
- }
+ actionName: "getReactionDetails",
+ className: "\\wcf\\data\\reaction\\ReactionAction",
+ },
};
- },
- _dialogSetup: function () {
+ }
+ _dialogSetup() {
return {
- id: 'userReactionOverlay-' + this._objectType,
+ id: `userReactionOverlay-${this._objectType}`,
options: {
- title: ""
+ title: "",
},
- source: null
+ source: null,
};
}
- };
+ }
+ Core.enableLegacyInheritance(CountButtons);
return CountButtons;
});
--- /dev/null
+define(["require", "exports"], function (require, exports) {
+ "use strict";
+ Object.defineProperty(exports, "__esModule", { value: true });
+});
+++ /dev/null
-/**
- * Provides interface elements to use reactions.
- *
- * @author Joshua Ruesweg
- * @copyright 2001-2019 WoltLab GmbH
- * @license GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
- * @module WoltLabSuite/Core/Ui/Reaction/Handler
- * @since 5.2
- */
-define(
- [
- 'Ajax', 'Core', 'Dictionary', 'Language',
- 'ObjectMap', 'StringUtil', 'Dom/ChangeListener', 'Dom/Util',
- 'Ui/Dialog', 'EventHandler'
- ],
- function(
- Ajax, Core, Dictionary, Language,
- ObjectMap, StringUtil, DomChangeListener, DomUtil,
- UiDialog, EventHandler
- )
- {
- "use strict";
-
- /**
- * @constructor
- */
- function CountButtons(objectType, options) { this.init(objectType, options); }
- CountButtons.prototype = {
- /**
- * Initializes the like handler.
- *
- * @param {string} objectType object type
- * @param {object} options initialization options
- */
- init: function(objectType, options) {
- if (options.containerSelector === '') {
- throw new Error("[WoltLabSuite/Core/Ui/Reaction/CountButtons] Expected a non-empty string for option 'containerSelector'.");
- }
-
- this._containers = new Dictionary();
- this._objects = new Dictionary();
- this._objectType = objectType;
-
- this._options = Core.extend({
- // selectors
- summaryListSelector: '.reactionSummaryList',
- containerSelector: '',
- isSingleItem: false,
-
- // optional parameters
- parameters: {
- data: {}
- }
- }, options);
-
- this.initContainers(options, objectType);
-
- DomChangeListener.add('WoltLabSuite/Core/Ui/Reaction/CountButtons-' + objectType, this.initContainers.bind(this));
- },
-
- /**
- * Initialises the containers.
- */
- initContainers: function() {
- var element, elements = elBySelAll(this._options.containerSelector), elementData, triggerChange = false, objectId;
- for (var i = 0, length = elements.length; i < length; i++) {
- element = elements[i];
- if (this._containers.has(DomUtil.identify(element))) {
- continue;
- }
-
- objectId = ~~elData(element, 'object-id');
- elementData = {
- reactButton: null,
- summary: null,
-
- objectId: objectId,
- element: element
- };
-
- this._containers.set(DomUtil.identify(element), elementData);
- this._initReactionCountButtons(element, elementData);
-
- var objects = [];
- if (this._objects.has(objectId)) {
- objects = this._objects.get(objectId);
- }
-
- objects.push(elementData);
-
- this._objects.set(objectId, objects);
-
- triggerChange = true;
- }
-
- if (triggerChange) {
- DomChangeListener.trigger();
- }
- },
-
- /**
- * Update the count buttons with the given data.
- *
- * @param {int} objectId
- * @param {object} data
- */
- updateCountButtons: function(objectId, data) {
- var triggerChange = false;
- this._objects.get(objectId).forEach(function(elementData) {
- var summaryList = elBySel(this._options.summaryListSelector, this._options.isSingleItem ? undefined : elementData.element);
-
- // summary list for the object not found; abort
- if (summaryList === null) return;
-
- var sortedElements = {}, elements = elBySelAll('.reactCountButton', summaryList);
- for (var i = 0, length = elements.length; i < length; i++) {
- var reactionTypeId = elData(elements[i], 'reaction-type-id');
- if (data.hasOwnProperty(reactionTypeId)) {
- sortedElements[reactionTypeId] = elements[i];
- }
- else {
- // The reaction no longer has any reactions.
- elRemove(elements[i]);
- }
- }
-
- Object.keys(data).forEach(function(key) {
- if (sortedElements[key] !== undefined) {
- var reactionCount = elBySel('.reactionCount', sortedElements[key]);
- reactionCount.innerHTML = StringUtil.shortUnit(data[key]);
- }
- else if (REACTION_TYPES[key] !== undefined) {
- var createdElement = elCreate('span');
- createdElement.className = 'reactCountButton';
- createdElement.innerHTML = REACTION_TYPES[key].renderedIcon;
- elData(createdElement, 'reaction-type-id', key);
-
- var countSpan = elCreate('span');
- countSpan.className = 'reactionCount';
- countSpan.innerHTML = StringUtil.shortUnit(data[key]);
- createdElement.appendChild(countSpan);
-
- summaryList.appendChild(createdElement);
-
- triggerChange = true;
- }
- }, this);
-
- window[(summaryList.childElementCount > 0 ? 'elShow' : 'elHide')](summaryList);
- }.bind(this));
-
- if (triggerChange) {
- DomChangeListener.trigger();
- }
- },
-
- /**
- * Initialized the reaction count buttons.
- *
- * @param {element} element
- * @param {object} elementData
- */
- _initReactionCountButtons: function(element, elementData) {
- var summaryList = elBySel(this._options.summaryListSelector, this._options.isSingleItem ? undefined : element);
- if (summaryList !== null) {
- summaryList.addEventListener('click', this._showReactionOverlay.bind(this, elementData.objectId));
- }
- },
-
- /**
- * Shows the reaction overly for a specific object.
- *
- * @param {int} objectId
- * @param {Event} event
- */
- _showReactionOverlay: function(objectId, event) {
- event.preventDefault();
-
- this._currentObjectId = objectId;
- this._showOverlay();
- },
-
- /**
- * Shows a specific page of the current opened reaction overlay.
- */
- _showOverlay: function() {
- this._options.parameters.data.containerID = this._objectType + '-' + this._currentObjectId;
- this._options.parameters.data.objectID = this._currentObjectId;
- this._options.parameters.data.objectType = this._objectType;
-
- Ajax.api(this, {
- parameters: this._options.parameters
- });
- },
-
- _ajaxSuccess: function(data) {
- EventHandler.fire('com.woltlab.wcf.ReactionCountButtons', 'openDialog', data);
-
- UiDialog.open(this, data.returnValues.template);
- UiDialog.setTitle('userReactionOverlay-' + this._objectType, data.returnValues.title);
- },
-
- _ajaxSetup: function() {
- return {
- data: {
- actionName: 'getReactionDetails',
- className: '\\wcf\\data\\reaction\\ReactionAction'
- }
- };
- },
-
- _dialogSetup: function() {
- return {
- id: 'userReactionOverlay-' + this._objectType,
- options: {
- title: ""
- },
- source: null
- };
- }
- };
-
- return CountButtons;
- });
--- /dev/null
+/**
+ * Provides interface elements to use reactions.
+ *
+ * @author Joshua Ruesweg
+ * @copyright 2001-2019 WoltLab GmbH
+ * @license GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
+ * @module WoltLabSuite/Core/Ui/Reaction/Handler
+ * @since 5.2
+ */
+
+import * as Ajax from "../../Ajax";
+import { AjaxCallbackSetup, ResponseData } from "../../Ajax/Data";
+import * as Core from "../../Core";
+import { DialogCallbackSetup } from "../Dialog/Data";
+import DomChangeListener from "../../Dom/Change/Listener";
+import DomUtil from "../../Dom/Util";
+import * as EventHandler from "../../Event/Handler";
+import { Reaction, ReactionStats } from "./Data";
+import * as StringUtil from "../../StringUtil";
+import UiDialog from "../Dialog";
+
+interface CountButtonsOptions {
+ // selectors
+ summaryListSelector: string;
+ containerSelector: string;
+ isSingleItem: boolean;
+
+ // optional parameters
+ parameters: {
+ data: {
+ [key: string]: unknown;
+ };
+ };
+}
+
+interface ElementData {
+ element: HTMLElement;
+ objectId: number;
+ reactButton: null;
+ summary: null;
+}
+
+interface AjaxResponse extends ResponseData {
+ returnValues: {
+ template: string;
+ title: string;
+ };
+}
+
+class CountButtons {
+ protected readonly _containers = new Map<string, ElementData>();
+ protected _currentObjectId = 0;
+ protected readonly _objects = new Map<number, ElementData[]>();
+ protected readonly _objectType: string;
+ protected readonly _options: CountButtonsOptions;
+
+ /**
+ * Initializes the like handler.
+ */
+ constructor(objectType: string, opts: Partial<CountButtonsOptions>) {
+ if (!opts.containerSelector) {
+ throw new Error(
+ "[WoltLabSuite/Core/Ui/Reaction/CountButtons] Expected a non-empty string for option 'containerSelector'.",
+ );
+ }
+
+ this._objectType = objectType;
+
+ this._options = Core.extend(
+ {
+ // selectors
+ summaryListSelector: ".reactionSummaryList",
+ containerSelector: "",
+ isSingleItem: false,
+
+ // optional parameters
+ parameters: {
+ data: {},
+ },
+ },
+ opts,
+ ) as CountButtonsOptions;
+
+ this.initContainers();
+
+ DomChangeListener.add(`WoltLabSuite/Core/Ui/Reaction/CountButtons-${objectType}`, () => this.initContainers());
+ }
+
+ /**
+ * Initialises the containers.
+ */
+ initContainers(): void {
+ let triggerChange = false;
+ document.querySelectorAll(this._options.containerSelector).forEach((element: HTMLElement) => {
+ const elementId = DomUtil.identify(element);
+ if (this._containers.has(elementId)) {
+ return;
+ }
+
+ const objectId = ~~element.dataset.objectId!;
+ const elementData: ElementData = {
+ reactButton: null,
+ summary: null,
+
+ objectId: objectId,
+ element: element,
+ };
+
+ this._containers.set(elementId, elementData);
+ this._initReactionCountButtons(element, elementData);
+
+ const objects = this._objects.get(objectId) || [];
+
+ objects.push(elementData);
+
+ this._objects.set(objectId, objects);
+
+ triggerChange = true;
+ });
+
+ if (triggerChange) {
+ DomChangeListener.trigger();
+ }
+ }
+
+ /**
+ * Update the count buttons with the given data.
+ */
+ updateCountButtons(objectId: number, data: ReactionStats): void {
+ let triggerChange = false;
+ this._objects.get(objectId)!.forEach((elementData) => {
+ let summaryList: HTMLElement | null;
+ if (this._options.isSingleItem) {
+ summaryList = document.querySelector(this._options.summaryListSelector);
+ } else {
+ summaryList = elementData.element.querySelector(this._options.summaryListSelector);
+ }
+
+ // summary list for the object not found; abort
+ if (summaryList === null) {
+ return;
+ }
+
+ const existingReactions = new Map<string, number>(Object.entries(data));
+
+ const sortedElements = new Map<string, HTMLElement>();
+ summaryList.querySelectorAll(".reactCountButton").forEach((reaction: HTMLElement) => {
+ const reactionTypeId = reaction.dataset.reactionTypeId!;
+ if (existingReactions.has(reactionTypeId)) {
+ sortedElements.set(reactionTypeId, reaction);
+ } else {
+ // The reaction no longer has any reactions.
+ reaction.remove();
+ }
+ });
+
+ const availableReactions = new Map<string, Reaction>(Object.entries(window.REACTION_TYPES));
+
+ existingReactions.forEach((count, reactionTypeId) => {
+ if (sortedElements.has(reactionTypeId)) {
+ const reaction = sortedElements.get(reactionTypeId)!;
+ const reactionCount = reaction.querySelector(".reactionCount") as HTMLElement;
+ reactionCount.innerHTML = StringUtil.shortUnit(count);
+ } else if (availableReactions.has(reactionTypeId)) {
+ const createdElement = document.createElement("span");
+ createdElement.className = "reactCountButton";
+ createdElement.innerHTML = availableReactions.get(reactionTypeId)!.renderedIcon;
+ createdElement.dataset.reactionTypeId = reactionTypeId;
+
+ const countSpan = document.createElement("span");
+ countSpan.className = "reactionCount";
+ countSpan.innerHTML = StringUtil.shortUnit(count);
+ createdElement.appendChild(countSpan);
+
+ summaryList!.appendChild(createdElement);
+
+ triggerChange = true;
+ }
+ });
+
+ if (summaryList.childElementCount > 0) {
+ DomUtil.show(summaryList);
+ } else {
+ DomUtil.hide(summaryList);
+ }
+ });
+
+ if (triggerChange) {
+ DomChangeListener.trigger();
+ }
+ }
+
+ /**
+ * Initialized the reaction count buttons.
+ */
+ protected _initReactionCountButtons(element: HTMLElement, elementData: ElementData): void {
+ let summaryList: HTMLElement | null;
+ if (this._options.isSingleItem) {
+ summaryList = document.querySelector(this._options.summaryListSelector);
+ } else {
+ summaryList = element.querySelector(this._options.summaryListSelector);
+ }
+
+ if (summaryList !== null) {
+ summaryList.addEventListener("click", (ev) => this._showReactionOverlay(elementData.objectId, ev));
+ }
+ }
+
+ /**
+ * Shows the reaction overly for a specific object.
+ */
+ protected _showReactionOverlay(objectId: number, event: MouseEvent): void {
+ event.preventDefault();
+
+ this._currentObjectId = objectId;
+ this._showOverlay();
+ }
+
+ /**
+ * Shows a specific page of the current opened reaction overlay.
+ */
+ protected _showOverlay(): void {
+ this._options.parameters.data.containerID = `${this._objectType}-${this._currentObjectId}`;
+ this._options.parameters.data.objectID = this._currentObjectId;
+ this._options.parameters.data.objectType = this._objectType;
+
+ Ajax.api(this, {
+ parameters: this._options.parameters,
+ });
+ }
+
+ _ajaxSuccess(data: AjaxResponse): void {
+ EventHandler.fire("com.woltlab.wcf.ReactionCountButtons", "openDialog", data);
+
+ UiDialog.open(this, data.returnValues.template);
+ UiDialog.setTitle("userReactionOverlay-" + this._objectType, data.returnValues.title);
+ }
+
+ _ajaxSetup(): ReturnType<AjaxCallbackSetup> {
+ return {
+ data: {
+ actionName: "getReactionDetails",
+ className: "\\wcf\\data\\reaction\\ReactionAction",
+ },
+ };
+ }
+
+ _dialogSetup(): ReturnType<DialogCallbackSetup> {
+ return {
+ id: `userReactionOverlay-${this._objectType}`,
+ options: {
+ title: "",
+ },
+ source: null,
+ };
+ }
+}
+
+Core.enableLegacyInheritance(CountButtons);
+
+export = CountButtons;
--- /dev/null
+export interface Reaction {
+ title: string;
+ renderedIcon: string;
+ iconPath: string;
+ showOrder: number;
+ reactionTypeID: number;
+ isAssignable: 1 | 0;
+}
+
+export interface ReactionStats {
+ [key: string]: number;
+}