<ul class="buttonGroup" id="reactionType">
{foreach from=$__wcf->getReactionHandler()->getReactionTypes() item=reactionType name=reactionTypeLoop}
- <li><a class="button small jsTooltip" data-reaction-type-id="{$reactionType->reactionTypeID}" title="{$reactionType->getTitle()}">{@$reactionType->renderIcon()} <span class="invisible">{$reactionType->getTitle()}</span></a></li>
+ <li><a class="button small jsTooltip" data-reaction-type-id="{$reactionType->reactionTypeID}" title="{$reactionType->getTitle()}" data-is-assignable="{if $reactionType->isAssignable}1{else}0{/if}">{@$reactionType->renderIcon()} <span class="invisible">{$reactionType->getTitle()}</span></a></li>
{/foreach}
</ul>
</li>
});
if (reactionTypeID) {
- elBySel('.reactionTypeButton[data-reaction-type-id="' + reactionTypeID + '"]', this._getPopover()).classList.add('active');
+ var reactionTypeButton = elBySel('.reactionTypeButton[data-reaction-type-id="' + reactionTypeID + '"]', this._getPopover());
+ reactionTypeButton.classList.add('active');
+
+ if (~~elData(reactionTypeButton, 'is-assignable') === 0) {
+ elShow(reactionTypeButton);
+ }
}
},
reactionTypeItem.className = 'reactionTypeButton jsTooltip';
elData(reactionTypeItem, 'reaction-type-id', reactionType.reactionTypeID);
elData(reactionTypeItem, 'title', reactionType.title);
+ elData(reactionTypeItem, 'is-assignable', ~~reactionType.isAssignable);
+
reactionTypeItem.title = reactionType.title;
var reactionTypeItemSpan = elCreate('span');
reactionTypeItem.addEventListener(WCF_CLICK_EVENT, this._react.bind(this, reactionType.reactionTypeID));
+ if (!reactionType.isAssignable) {
+ elHide(reactionTypeItem);
+ }
+
popoverContentHTML.appendChild(reactionTypeItem);
}
if (this._popoverCurrentObjectId !== 0) {
this._getPopover().classList.remove('active');
+ elBySelAll('.reactionTypeButton[data-is-assignable="0"]', this._getPopover(), elHide);
+
if (this._options.isButtonGroupNavigation) {
this._objects.get(this._popoverCurrentObjectId).forEach(function (elementData) {
elementData.reactButton.closest('nav').style.cssText = "";
use wcf\data\reaction\type\ReactionTypeList;
use wcf\form\AbstractFormBuilderForm;
use wcf\system\form\builder\container\FormContainer;
+use wcf\system\form\builder\field\BooleanFormField;
use wcf\system\form\builder\field\ShowOrderFormField;
use wcf\system\form\builder\field\TitleFormField;
use wcf\system\form\builder\field\UploadFormField;
ShowOrderFormField::create()
->description('wcf.acp.reactionType.showOrder.description')
->required()
- ->options(new ReactionTypeList())
+ ->options(new ReactionTypeList()),
+ BooleanFormField::create('isAssignable')
+ ->label('wcf.acp.reactionType.isAssignable')
+ ->description('wcf.acp.reactionType.isAssignable.description')
]);
$iconContainer = FormContainer::create('imageSection')
throw new PermissionDeniedException();
}
}
+
+ if (!$this->reactionType->isAssignable) {
+ // check, if the reaction is reverted
+ $like = Like::getLike($this->likeableObject->getObjectType()->objectTypeID, $this->likeableObject->getObjectID(), WCF::getUser()->userID);
+
+ if (!$like->likeID || $like->reactionTypeID !== $this->reactionType->reactionTypeID) {
+ throw new IllegalLinkException();
+ }
+ }
}
/**
* @copyright 2001-2019 WoltLab GmbH
* @license GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
* @package WoltLabSuite\Core\Data\Reaction\Type
- * @since 5.2
+ * @since 5.2
*
* @property-read integer $reactionTypeID unique id of the reaction type
* @property-read string $title
* @property-read integer $showOrder position of the reaction type in relation to the other reaction types
* @property-read string $iconFile the file location of the icon
+ * @property-read boolean $isAssignable `1`, if the reaction can be assigned
*/
class ReactionType extends DatabaseObject implements ITitledObject {
/**
* @copyright 2001-2019 WoltLab GmbH
* @license GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
* @package WoltLabSuite\Core\System\Reaction
- * @since 5.2
+ * @since 5.2
*/
class ReactionHandler extends SingletonFactory {
/**
'renderedIcon' => $reaction->renderIcon(),
'iconPath' => $reaction->getIconPath(),
'showOrder' => $reaction->showOrder,
- 'reactionTypeID' => $reaction->reactionTypeID
+ 'reactionTypeID' => $reaction->reactionTypeID,
+ 'isAssignable' => $reaction->isAssignable,
];
}
<item name="wcf.acp.reactionType.type"><![CDATA[Reaktions-Typ]]></item>
<item name="wcf.acp.reactionType.image"><![CDATA[Reaktions-Datei]]></item>
<item name="wcf.acp.reactionType.showOrder.description"><![CDATA[Der Reaktions-Typ wird nach dem ausgewählten Reaktions-Typ angezeigt.]]></item>
+ <item name="wcf.acp.reactionType.isAssignable"><![CDATA[Kann verwendet werden]]></item>
+ <item name="wcf.acp.reactionType.isAssignable.description"><![CDATA[Wenn eine Reaktion nicht verwendet werden kann, können Benutzer nicht mit der Reaktion reagieren. Wurde auf einen Inhalt bereits mit der Reaktion reagiert, ist sie auch weiterhin für Benutzer sichtbar.]]></item>
</category>
<category name="wcf.acp.rebuildData">
<item name="wcf.acp.rebuildData"><![CDATA[Anzeigen aktualisieren]]></item>
<item name="wcf.acp.reactionType.type"><![CDATA[Reaction Type]]></item>
<item name="wcf.acp.reactionType.image"><![CDATA[Reaction File]]></item>
<item name="wcf.acp.reactionType.showOrder.description"><![CDATA[The reaction type will be shown after the selected reaction type.]]></item>
+ <item name="wcf.acp.reactionType.isAssignable"><![CDATA[Can be assigend]]></item>
+ <item name="wcf.acp.reactionType.isAssignable.description"><![CDATA[If a reaction cannot be used, users cannot react with the reaction. If a content has already been reacted to with the reaction, it remains visible to users.]]></item>
</category>
<category name="wcf.acp.rebuildData">
<item name="wcf.acp.rebuildData"><![CDATA[Rebuild Data]]></item>
reactionTypeID INT(10) NOT NULL AUTO_INCREMENT PRIMARY KEY,
title VARCHAR(255),
showOrder INT(10) NOT NULL DEFAULT 0,
- iconFile MEDIUMTEXT
+ iconFile MEDIUMTEXT,
+ isAssignable TINYINT(1) NOT NULL DEFAULT 1
);
DROP TABLE IF EXISTS wcf1_registry;