diff --git a/mod/display.php b/mod/display.php index d3c0e0249..02e838f55 100644 --- a/mod/display.php +++ b/mod/display.php @@ -183,6 +183,8 @@ function display_content(App $a, $update = false, $update_uid = 0) $item = null; + $force = (bool)($_REQUEST['force'] ?? false); + if ($update) { $item_id = $_REQUEST['item_id']; $item = Item::selectFirst(['uid', 'parent', 'parent-uri'], ['id' => $item_id]); @@ -281,7 +283,7 @@ function display_content(App $a, $update = false, $update_uid = 0) } // We need the editor here to be able to reshare an item. - if ($is_owner) { + if ($is_owner && !$update) { $x = [ 'is_owner' => true, 'allow_location' => $a->user['allow_location'], @@ -304,7 +306,7 @@ function display_content(App $a, $update = false, $update_uid = 0) $unseen = false; } - if ($update && !$unseen) { + if ($update && !$unseen && !$force) { return ''; } diff --git a/src/Model/Item.php b/src/Model/Item.php index f014ed096..0fab3ba07 100644 --- a/src/Model/Item.php +++ b/src/Model/Item.php @@ -2946,39 +2946,6 @@ class Item return false; } - switch ($verb) { - case 'like': - case 'unlike': - $activity = Activity::LIKE; - break; - case 'dislike': - case 'undislike': - $activity = Activity::DISLIKE; - break; - case 'attendyes': - case 'unattendyes': - $activity = Activity::ATTEND; - break; - case 'attendno': - case 'unattendno': - $activity = Activity::ATTENDNO; - break; - case 'attendmaybe': - case 'unattendmaybe': - $activity = Activity::ATTENDMAYBE; - break; - case 'follow': - case 'unfollow': - $activity = Activity::FOLLOW; - break; - default: - Logger::log('like: unknown verb ' . $verb . ' for item ' . $item_id); - return false; - } - - // Enable activity toggling instead of on/off - $event_verb_flag = $activity === Activity::ATTEND || $activity === Activity::ATTENDNO || $activity === Activity::ATTENDMAYBE; - Logger::log('like: verb ' . $verb . ' item ' . $item_id); $item = self::selectFirst(self::ITEM_FIELDLIST, ['`id` = ? OR `uri` = ?', $item_id, $item_id]); @@ -3027,9 +2994,44 @@ class Item } } + $activity = null; + switch ($verb) { + case 'like': + case 'unlike': + $activity = Activity::LIKE; + break; + case 'dislike': + case 'undislike': + $activity = Activity::DISLIKE; + break; + case 'attendyes': + case 'unattendyes': + $activity = Activity::ATTEND; + break; + case 'attendno': + case 'unattendno': + $activity = Activity::ATTENDNO; + break; + case 'attendmaybe': + case 'unattendmaybe': + $activity = Activity::ATTENDMAYBE; + break; + case 'follow': + case 'unfollow': + $activity = Activity::FOLLOW; + break; + default: + Logger::log('like: unknown verb ' . $verb . ' for item ' . $item_id); + return false; + } + + $mode = Strings::startsWith($verb, 'un') ? 'delete' : 'create'; + + // Enable activity toggling instead of on/off + $event_verb_flag = $activity === Activity::ATTEND || $activity === Activity::ATTENDNO || $activity === Activity::ATTENDMAYBE; + // Look for an existing verb row - // event participation are essentially radio toggles. If you make a subsequent choice, - // we need to eradicate your first choice. + // Event participation activities are mutually exclusive, only one of them can exist at all times. if ($event_verb_flag) { $verbs = [Activity::ATTEND, Activity::ATTENDNO, Activity::ATTENDMAYBE]; @@ -3044,20 +3046,43 @@ class Item $condition = ['vid' => $vids, 'deleted' => false, 'gravity' => GRAVITY_ACTIVITY, 'author-id' => $author_id, 'uid' => $item['uid'], 'thr-parent' => $item_uri]; - $like_item = self::selectFirst(['id', 'guid', 'verb'], $condition); - // If it exists, mark it as deleted if (DBA::isResult($like_item)) { - self::markForDeletionById($like_item['id']); + /** + * Truth table for existing activities + * + * | Inputs || Outputs | + * |----------------------------||-------------------| + * | Mode | Event | Same verb || Delete? | Return? | + * |--------|-------|-----------||---------|---------| + * | create | Yes | Yes || No | Yes | + * | create | Yes | No || Yes | No | + * | create | No | Yes || No | Yes | + * | create | No | No || N/A† | + * | delete | Yes | Yes || Yes | N/A‡ | + * | delete | Yes | No || No | N/A‡ | + * | delete | No | Yes || Yes | N/A‡ | + * | delete | No | No || N/A† | + * |--------|-------|-----------||---------|---------| + * | A | B | C || A xor C | !B or C | + * + * † Can't happen: It's impossible to find an existing non-event activity without + * the same verb because we are only looking for this single verb. + * + * ‡ The "mode = delete" is returning early whether an existing activity was found or not. + */ + if ($mode == 'create' xor $like_item['verb'] == $activity) { + self::markForDeletionById($like_item['id']); + } if (!$event_verb_flag || $like_item['verb'] == $activity) { return true; } } - // Verb is "un-something", just trying to delete existing entries - if (strpos($verb, 'un') === 0) { + // No need to go further if we aren't creating anything + if ($mode == 'delete') { return true; } diff --git a/src/Module/Like.php b/src/Module/Like.php index c926012f1..ca3824750 100644 --- a/src/Module/Like.php +++ b/src/Module/Like.php @@ -22,6 +22,7 @@ namespace Friendica\Module; use Friendica\BaseModule; +use Friendica\Core\System; use Friendica\DI; use Friendica\Model\Item; use Friendica\Core\Session; @@ -68,5 +69,7 @@ class Like extends BaseModule DI::baseUrl()->redirect($returnPath . $rand); } + + System::jsonExit(['status' => 'OK']); } } diff --git a/src/Object/Post.php b/src/Object/Post.php index 1ca02873d..0a68bbbe2 100644 --- a/src/Object/Post.php +++ b/src/Object/Post.php @@ -380,8 +380,11 @@ class Post } // Disable features that aren't available in several networks - if ($buttons["dislike"] && !in_array($item["network"], [Protocol::ACTIVITYPUB, Protocol::DFRN, Protocol::DIASPORA])) { - $buttons["dislike"] = false; + if (!in_array($item["network"], [Protocol::ACTIVITYPUB, Protocol::DFRN, Protocol::DIASPORA])) { + if ($buttons["dislike"]) { + $buttons["dislike"] = false; + } + $isevent = false; $tagger = ''; } diff --git a/view/js/main.js b/view/js/main.js index 861315398..60337918b 100644 --- a/view/js/main.js +++ b/view/js/main.js @@ -594,15 +594,17 @@ function liveUpdate(src) { in_progress = true; - if ($(document).scrollTop() == 0) { - force_update = true; - } + let force = force_update || $(document).scrollTop() === 0; var orgHeight = $("section").height(); var udargs = ((netargs.length) ? '/' + netargs : ''); - var update_url = 'update_' + src + udargs + '&p=' + profile_uid + '&force=' + ((force_update) ? 1 : 0) + '&item=' + update_item; + var update_url = 'update_' + src + udargs + '&p=' + profile_uid + '&force=' + (force ? 1 : 0) + '&item=' + update_item; + + if (force_update) { + force_update = false; + } if (getUrlParameter('page')) { update_url += '&page=' + getUrlParameter('page'); @@ -614,9 +616,8 @@ function liveUpdate(src) { update_url += '&max_id=' + getUrlParameter('max_id'); } - $.get(update_url,function(data) { + $.get(update_url, function(data) { in_progress = false; - force_update = false; update_item = 0; $('.wall-item-body', data).imagesLoaded(function() { @@ -648,9 +649,15 @@ function imgdull(node) { // trickery. This still could cause confusion if the "like" ajax call // is delayed and NavUpdate runs before it completes. -function dolike(ident,verb) { +/** + * @param {int} ident The id of the relevant item + * @param {string} verb The verb of the action + * @param {boolean} un Whether to perform an activity removal instead of creation + */ +function dolike(ident, verb, un) { unpause(); $('#like-rotator-' + ident.toString()).show(); + verb = un ? 'un' + verb : verb; $.get('like/' + ident.toString() + '?verb=' + verb, NavUpdate); liking = 1; force_update = true; diff --git a/view/templates/wall_thread.tpl b/view/templates/wall_thread.tpl index 7b205504d..0d8c896e1 100644 --- a/view/templates/wall_thread.tpl +++ b/view/templates/wall_thread.tpl @@ -77,8 +77,8 @@
{{if $item.vote}}
- - {{if $item.vote.dislike}}{{/if}} + + {{if $item.vote.dislike}}{{/if}} {{if $item.vote.share}}{{/if}}
@@ -107,9 +107,9 @@ {{/if}} {{if $item.isevent }}
- - - + + +
{{/if}}
diff --git a/view/theme/frio/js/theme.js b/view/theme/frio/js/theme.js index ce3294141..be814f083 100644 --- a/view/theme/frio/js/theme.js +++ b/view/theme/frio/js/theme.js @@ -720,22 +720,17 @@ function htmlToText(htmlString) { * Sends a /like API call and updates the display of the relevant action button * before the update reloads the item. * - * @param {string} ident The id of the relevant item - * @param {string} verb The verb of the action - * @returns {undefined} + * @param {int} ident The id of the relevant item + * @param {string} verb The verb of the action + * @param {boolean} un Whether to perform an activity removal instead of creation */ -function doLikeAction(ident, verb) { - unpause(); - +function doLikeAction(ident, verb, un) { if (verb.indexOf('attend') === 0) { $('.item-' + ident + ' .button-event:not(#' + verb + '-' + ident + ')').removeClass('active'); } $('#' + verb + '-' + ident).toggleClass('active'); - $('#like-rotator-' + ident.toString()).show(); - $.get('like/' + ident.toString() + '?verb=' + verb, NavUpdate ); - liking = 1; - force_update = true; - update_item = ident.toString(); + + dolike(ident, verb, un); } // Decodes a hexadecimally encoded binary string diff --git a/view/theme/frio/templates/search_item.tpl b/view/theme/frio/templates/search_item.tpl index 1cbd8451d..ce5497dda 100644 --- a/view/theme/frio/templates/search_item.tpl +++ b/view/theme/frio/templates/search_item.tpl @@ -144,14 +144,14 @@ {{* Buttons for like and dislike *}} {{if $item.vote}} {{if $item.vote.like}} - + {{/if}} {{if $item.vote.like AND $item.vote.dislike}} {{/if}} {{if $item.vote.dislike}} - + {{/if}} {{if ($item.vote.like OR $item.vote.dislike) AND $item.comment}} @@ -249,9 +249,9 @@ {{* Event attendance buttons *}} {{if $item.isevent}} - - - + + + {{/if}} diff --git a/view/theme/frio/templates/wall_thread.tpl b/view/theme/frio/templates/wall_thread.tpl index a5a785af7..c15b110ec 100644 --- a/view/theme/frio/templates/wall_thread.tpl +++ b/view/theme/frio/templates/wall_thread.tpl @@ -282,13 +282,13 @@ as the value of $top_child_total (this is done at the end of this file) {{* Buttons for like and dislike *}} {{if $item.vote}} {{if $item.vote.like}} - + {{/if}} {{if $item.vote.like AND $item.vote.dislike}} {{/if}} {{if $item.vote.dislike}} - + {{/if}} {{if ($item.vote.like OR $item.vote.dislike) AND $item.comment}} @@ -390,9 +390,9 @@ as the value of $top_child_total (this is done at the end of this file) {{* Event attendance buttons *}} {{if $item.isevent}} - - - + + + {{/if}} @@ -409,10 +409,10 @@ as the value of $top_child_total (this is done at the end of this file) {{if $item.vote}}
{{if $item.vote.like}} - + {{/if}} {{if $item.vote.dislike}} - + {{/if}}
{{/if}} @@ -441,9 +441,9 @@ as the value of $top_child_total (this is done at the end of this file) {{* Event attendance buttons *}} {{if $item.isevent}}
- - - + + +
{{/if}} diff --git a/view/theme/quattro/templates/photo_item.tpl b/view/theme/quattro/templates/photo_item.tpl index b196824c0..e14caa542 100644 --- a/view/theme/quattro/templates/photo_item.tpl +++ b/view/theme/quattro/templates/photo_item.tpl @@ -39,8 +39,8 @@ {{/if}} {{if $vote}} - {{$vote.like.1}} - {{$vote.dislike.1}} + {{$vote.like.1}} + {{$vote.dislike.1}} {{/if}} {{if $vote.share}} diff --git a/view/theme/quattro/templates/search_item.tpl b/view/theme/quattro/templates/search_item.tpl index 38ac6cf63..0e4aaaf8f 100644 --- a/view/theme/quattro/templates/search_item.tpl +++ b/view/theme/quattro/templates/search_item.tpl @@ -54,10 +54,10 @@ {{/if}} {{if $item.vote.like}} - {{$item.vote.like.1}} + {{$item.vote.like.1}} {{/if}} {{if $item.vote.dislike}} - {{$item.vote.dislike.1}} + {{$item.vote.dislike.1}} {{/if}} {{if $item.vote.share}} diff --git a/view/theme/quattro/templates/wall_thread.tpl b/view/theme/quattro/templates/wall_thread.tpl index 10f8fe998..e6d8b9754 100644 --- a/view/theme/quattro/templates/wall_thread.tpl +++ b/view/theme/quattro/templates/wall_thread.tpl @@ -118,9 +118,9 @@ {{/if}} {{if $item.vote}} - {{$item.vote.like.1}} + {{$item.vote.like.1}} {{if $item.vote.dislike}} - {{$item.vote.dislike.1}} + {{$item.vote.dislike.1}} {{/if}} {{if $item.vote.share}} {{$item.vote.share.1}} @@ -129,9 +129,9 @@ {{if $item.isevent}}
{{/if}} diff --git a/view/theme/smoothly/templates/wall_thread.tpl b/view/theme/smoothly/templates/wall_thread.tpl index b372fbefb..85d480c31 100644 --- a/view/theme/smoothly/templates/wall_thread.tpl +++ b/view/theme/smoothly/templates/wall_thread.tpl @@ -91,9 +91,9 @@ {{if $item.vote}}