diff --git a/app/Jobs/CommentPipeline/CommentPipeline.php b/app/Jobs/CommentPipeline/CommentPipeline.php index 4876138ce..db0951181 100644 --- a/app/Jobs/CommentPipeline/CommentPipeline.php +++ b/app/Jobs/CommentPipeline/CommentPipeline.php @@ -2,16 +2,18 @@ namespace App\Jobs\CommentPipeline; -use App\Notification; -use App\Status; -use Cache; +use App\{ + Notification, + Status +}; +use App\Services\NotificationService; +use DB, Cache, Log, Redis; + use Illuminate\Bus\Queueable; use Illuminate\Contracts\Queue\ShouldQueue; use Illuminate\Foundation\Bus\Dispatchable; use Illuminate\Queue\InteractsWithQueue; use Illuminate\Queue\SerializesModels; -use Log; -use Redis; class CommentPipeline implements ShouldQueue { @@ -55,7 +57,7 @@ class CommentPipeline implements ShouldQueue return true; } - try { + DB::transaction(function() use($target, $actor, $comment) { $notification = new Notification(); $notification->profile_id = $target->id; $notification->actor_id = $actor->id; @@ -66,14 +68,8 @@ class CommentPipeline implements ShouldQueue $notification->item_type = "App\Status"; $notification->save(); - Cache::forever('notification.'.$notification->id, $notification); - - $redis = Redis::connection(); - - $nkey = config('cache.prefix').':user.'.$target->id.'.notifications'; - $redis->lpush($nkey, $notification->id); - } catch (Exception $e) { - Log::error($e); - } + NotificationService::setNotification($notification); + NotificationService::set($notification->profile_id, $notification->id); + }); } } diff --git a/app/Jobs/StatusPipeline/StatusDelete.php b/app/Jobs/StatusPipeline/StatusDelete.php index 528617e96..fea254a8b 100644 --- a/app/Jobs/StatusPipeline/StatusDelete.php +++ b/app/Jobs/StatusPipeline/StatusDelete.php @@ -2,6 +2,7 @@ namespace App\Jobs\StatusPipeline; +use DB; use App\{ Notification, Report, @@ -79,24 +80,32 @@ class StatusDelete implements ShouldQueue } catch (Exception $e) { } } - $comments = Status::where('in_reply_to_id', $status->id)->get(); - foreach ($comments as $comment) { - $comment->in_reply_to_id = null; - $comment->save(); - Notification::whereItemType('App\Status') - ->whereItemId($comment->id) - ->delete(); + if($status->in_reply_to_id) { + DB::transaction(function() use($status) { + $parent = Status::findOrFail($status->in_reply_to_id); + --$parent->reply_count; + $parent->save(); + }); } - - $status->likes()->delete(); - Notification::whereItemType('App\Status') - ->whereItemId($status->id) - ->delete(); - StatusHashtag::whereStatusId($status->id)->delete(); - Report::whereObjectType('App\Status') - ->whereObjectId($status->id) - ->delete(); - $status->delete(); + DB::transaction(function() use($status) { + $comments = Status::where('in_reply_to_id', $status->id)->get(); + foreach ($comments as $comment) { + $comment->in_reply_to_id = null; + $comment->save(); + Notification::whereItemType('App\Status') + ->whereItemId($comment->id) + ->delete(); + } + $status->likes()->delete(); + Notification::whereItemType('App\Status') + ->whereItemId($status->id) + ->delete(); + StatusHashtag::whereStatusId($status->id)->delete(); + Report::whereObjectType('App\Status') + ->whereObjectId($status->id) + ->delete(); + $status->delete(); + }); return true; } diff --git a/app/Jobs/StatusPipeline/StatusEntityLexer.php b/app/Jobs/StatusPipeline/StatusEntityLexer.php index dd1c352a7..df1ed6775 100644 --- a/app/Jobs/StatusPipeline/StatusEntityLexer.php +++ b/app/Jobs/StatusPipeline/StatusEntityLexer.php @@ -112,7 +112,7 @@ class StatusEntityLexer implements ShouldQueue $status = $this->status; foreach ($mentions as $mention) { - $mentioned = Profile::whereUsername($mention)->firstOrFail(); + $mentioned = Profile::whereNull('domain')->whereUsername($mention)->firstOrFail(); if (empty($mentioned) || !isset($mentioned->id)) { continue; diff --git a/app/Services/NotificationService.php b/app/Services/NotificationService.php index 91b2d21c7..4827a6c6f 100644 --- a/app/Services/NotificationService.php +++ b/app/Services/NotificationService.php @@ -79,6 +79,16 @@ class NotificationService { $resource = new Fractal\Resource\Item($n, new NotificationTransformer()); return $fractal->createData($resource)->toArray(); }); + } + + public static function setNotification(Notification $notification) + { + return Cache::remember('service:notification:'.$notification->id, now()->addDays(7), function() use($notification) { + $fractal = new Fractal\Manager(); + $fractal->setSerializer(new ArraySerializer()); + $resource = new Fractal\Resource\Item($notification, new NotificationTransformer()); + return $fractal->createData($resource)->toArray(); + }); } public static function warmCache($id, $stop = 100, $force = false) diff --git a/app/Util/Lexer/Autolink.php b/app/Util/Lexer/Autolink.php index fdd06d9cb..285ff65da 100755 --- a/app/Util/Lexer/Autolink.php +++ b/app/Util/Lexer/Autolink.php @@ -9,6 +9,8 @@ namespace App\Util\Lexer; +use Illuminate\Support\Str; + /** * Twitter Autolink Class. * @@ -413,7 +415,11 @@ class Autolink extends Regex $beginIndex = 0; foreach ($entities as $entity) { if (isset($entity['screen_name'])) { - $text .= StringUtils::substr($tweet, $beginIndex, $entity['indices'][0] - $beginIndex + 1); + if(Str::startsWith($entity['screen_name'], '@')) { + $text .= StringUtils::substr($tweet, $beginIndex, $entity['indices'][0] - $beginIndex); + } else { + $text .= StringUtils::substr($tweet, $beginIndex, $entity['indices'][0] - $beginIndex + 1); + } } else { $text .= StringUtils::substr($tweet, $beginIndex, $entity['indices'][0] - $beginIndex); } @@ -704,7 +710,7 @@ class Autolink extends Regex if (!empty($entity['list_slug'])) { // Replace the list and username - $linkText = $entity['screen_name'].$entity['list_slug']; + $linkText = $entity['screen_name']; $class = $this->class_list; $url = $this->url_base_list.$linkText; } else { diff --git a/app/Util/Lexer/Extractor.php b/app/Util/Lexer/Extractor.php index c7b75682b..734938011 100755 --- a/app/Util/Lexer/Extractor.php +++ b/app/Util/Lexer/Extractor.php @@ -9,6 +9,8 @@ namespace App\Util\Lexer; +use Illuminate\Support\Str; + /** * Twitter Extractor Class. * @@ -452,8 +454,9 @@ class Extractor extends Regex list($all, $before, $at, $username, $list_slug, $outer) = array_pad($match, 6, ['', 0]); $start_position = $at[1] > 0 ? StringUtils::strlen(substr($tweet, 0, $at[1])) : $at[1]; $end_position = $start_position + StringUtils::strlen($at[0]) + StringUtils::strlen($username[0]); + $screenname = trim($all[0]) == '@'.$username[0] ? $username[0] : trim($all[0]); $entity = [ - 'screen_name' => $username[0], + 'screen_name' => $screenname, 'list_slug' => $list_slug[0], 'indices' => [$start_position, $end_position], ]; diff --git a/app/Util/Lexer/Regex.php b/app/Util/Lexer/Regex.php index 2b65fb326..c24e0d4b0 100755 --- a/app/Util/Lexer/Regex.php +++ b/app/Util/Lexer/Regex.php @@ -161,7 +161,9 @@ abstract class Regex // $after in the following regular expression. Note that we only use a // look-ahead capture here and don't append $after when we return. $tmp['valid_mention_preceding_chars'] = '([^a-zA-Z0-9_!#\$%&*@๏ผ \/]|^|(?:^|[^a-z0-9_+~.-])RT:?)'; - $re['valid_mentions_or_lists'] = '/'.$tmp['valid_mention_preceding_chars'].'(['.$tmp['at_signs'].'])([a-z0-9_]{1,20})(\/[a-z][a-z0-9_\-]{0,24})?(?=(.*|$))/iu'; + + $re['valid_mentions_or_lists'] = '/'.$tmp['valid_mention_preceding_chars'].'(['.$tmp['at_signs'].'])([a-z0-9_]{1,20})((\/[a-z][a-z0-9_\-]{0,24})?(?=(.*|$))(?:@[a-z0-9\.\-]+[a-z0-9]+)?)/i'; + $re['valid_reply'] = '/^(?:['.$tmp['spaces'].'])*['.$tmp['at_signs'].']([a-z0-9_]{1,20})(?=(.*|$))/iu'; $re['end_mention_match'] = '/\A(?:['.$tmp['at_signs'].']|['.$tmp['latin_accents'].']|:\/\/)/iu'; diff --git a/public/js/status.js b/public/js/status.js index 4e80f52ea..0ebabeea0 100644 Binary files a/public/js/status.js and b/public/js/status.js differ diff --git a/public/mix-manifest.json b/public/mix-manifest.json index 4ebfd970a..c25d1d605 100644 Binary files a/public/mix-manifest.json and b/public/mix-manifest.json differ diff --git a/resources/assets/js/components/PostComponent.vue b/resources/assets/js/components/PostComponent.vue index 9c9fb9a7f..f3edddbea 100644 --- a/resources/assets/js/components/PostComponent.vue +++ b/resources/assets/js/components/PostComponent.vue @@ -107,7 +107,7 @@
{{truncate(reply.account.username,15)}} @@ -133,21 +133,32 @@
- + {{reply.favourites_count == 1 ? '1 like' : reply.favourites_count + ' likes'}} - Reply + Reply
- - {{s.account.username}} - - -
++ + {{s.account.username}} + + + + +
+
+
++ + {{s.favourites_count == 1 ? '1 like' : s.favourites_count + ' likes'}} + Reply +
+