From ca79e26d3a9ed3c1c9d0e3a647113d69b39b37ec Mon Sep 17 00:00:00 2001 From: Daniel Supernault Date: Tue, 18 Jan 2022 23:03:21 -0700 Subject: [PATCH 01/11] Add custom emoji --- app/Models/CustomEmoji.php | 41 +++++++++ app/Services/CustomEmojiService.php | 91 +++++++++++++++++++ .../Api/StatusStatelessTransformer.php | 10 +- app/Util/Lexer/RestrictedNames.php | 2 + config/federation.php | 9 +- ...01_19_025041_create_custom_emoji_table.php | 47 ++++++++++ 6 files changed, 195 insertions(+), 5 deletions(-) create mode 100644 app/Models/CustomEmoji.php create mode 100644 app/Services/CustomEmojiService.php create mode 100644 database/migrations/2022_01_19_025041_create_custom_emoji_table.php diff --git a/app/Models/CustomEmoji.php b/app/Models/CustomEmoji.php new file mode 100644 index 000000000..0903d5375 --- /dev/null +++ b/app/Models/CustomEmoji.php @@ -0,0 +1,41 @@ +matchAll(self::SCAN_RE) + ->map(function($match) { + $tag = Cache::remember(self::CACHE_KEY . $match, 14400, function() use($match) { + return self::whereShortcode(':' . $match . ':')->first(); + }); + + if($tag) { + $url = url('/storage/' . $tag->media_path); + return [ + 'shortcode' => $match, + 'url' => $url, + 'static_path' => $url, + 'visible_in_picker' => $tag->disabled == false + ]; + } + }) + ->filter(function($tag) { + return $tag && isset($tag['static_path']); + }) + ->values(); + } +} diff --git a/app/Services/CustomEmojiService.php b/app/Services/CustomEmojiService.php new file mode 100644 index 000000000..1a64784bb --- /dev/null +++ b/app/Services/CustomEmojiService.php @@ -0,0 +1,91 @@ +first(); + } + + public static function getByUrl($url) + { + if(Helpers::validateUrl($url) == false) { + return; + } + + $emoji = CustomEmoji::whereUri($url)->first(); + if($emoji) { + return $emoji; + } + + $res = Http::acceptJson()->get($url); + + if($res->successful()) { + $json = $res->json(); + + if( + !$json || + !isset($json['id']) || + !isset($json['type']) || + $json['type'] !== 'Emoji' || + !isset($json['icon']) || + !isset($json['icon']['mediaType']) || + !isset($json['icon']['url']) || + !isset($json['icon']['type']) || + $json['icon']['type'] !== 'Image' || + !in_array($json['icon']['mediaType'], ['image/jpeg', 'image/png', 'image/jpg']) + ) { + return; + } + + if(!self::headCheck($json['icon']['url'])) { + return; + } + $emoji = new CustomEmoji; + $emoji->shortcode = $json['name']; + $emoji->uri = $json['id']; + $emoji->domain = parse_url($json['id'], PHP_URL_HOST); + $emoji->image_remote_url = $json['icon']['url']; + $emoji->save(); + + $ext = '.' . last(explode('/', $json['icon']['mediaType'])); + $dest = storage_path('app/public/emoji/') . $emoji->id . $ext; + copy($emoji->image_remote_url, $dest); + $emoji->media_path = 'emoji/' . $emoji->id . $ext; + $emoji->save(); + + return $emoji; + } else { + return; + } + } + + public static function headCheck($url) + { + $res = Http::head($url); + + if(!$res->successful()) { + return false; + } + + $type = $res->header('content-type'); + $length = $res->header('content-length'); + + if( + !$type || + !$length || + !in_array($type, ['image/jpeg', 'image/png', 'image/jpg']) || + $length > config('federation.custom_emoji.max_size') + ) { + return false; + } + + return true; + } +} diff --git a/app/Transformer/Api/StatusStatelessTransformer.php b/app/Transformer/Api/StatusStatelessTransformer.php index 91ed1484b..8f56bf75b 100644 --- a/app/Transformer/Api/StatusStatelessTransformer.php +++ b/app/Transformer/Api/StatusStatelessTransformer.php @@ -14,6 +14,7 @@ use App\Services\StatusLabelService; use App\Services\StatusMentionService; use App\Services\ProfileService; use App\Services\PollService; +use App\Models\CustomEmoji; class StatusStatelessTransformer extends Fractal\TransformerAbstract { @@ -25,17 +26,18 @@ class StatusStatelessTransformer extends Fractal\TransformerAbstract return [ '_v' => 1, 'id' => (string) $status->id, + //'gid' => $status->group_id ? (string) $status->group_id : null, 'shortcode' => HashidService::encode($status->id), 'uri' => $status->url(), 'url' => $status->url(), - 'in_reply_to_id' => (string) $status->in_reply_to_id, - 'in_reply_to_account_id' => (string) $status->in_reply_to_profile_id, + 'in_reply_to_id' => $status->in_reply_to_id ? (string) $status->in_reply_to_id : null, + 'in_reply_to_account_id' => $status->in_reply_to_profile_id ? (string) $status->in_reply_to_profile_id : null, 'reblog' => null, 'content' => $status->rendered ?? $status->caption, 'content_text' => $status->caption, 'created_at' => $status->created_at->format('c'), - 'emojis' => [], - 'reblogs_count' => 0, + 'emojis' => CustomEmoji::scan($status->caption), + 'reblogs_count' => $status->reblogs_count ?? 0, 'favourites_count' => $status->likes_count ?? 0, 'reblogged' => null, 'favourited' => null, diff --git a/app/Util/Lexer/RestrictedNames.php b/app/Util/Lexer/RestrictedNames.php index 059f5bf00..6795870b5 100644 --- a/app/Util/Lexer/RestrictedNames.php +++ b/app/Util/Lexer/RestrictedNames.php @@ -157,6 +157,8 @@ class RestrictedNames 'embed', 'email', 'emails', + 'emoji', + 'emojis', 'error', 'explore', 'export', diff --git a/config/federation.php b/config/federation.php index ce2a5770e..d5f6b2d26 100644 --- a/config/federation.php +++ b/config/federation.php @@ -44,6 +44,13 @@ return [ 'enabled' => env('WEBFINGER', true) ], - 'network_timeline' => env('PF_NETWORK_TIMELINE', true) + 'network_timeline' => env('PF_NETWORK_TIMELINE', true), + + 'custom_emoji' => [ + 'enabled' => env('CUSTOM_EMOJI', false), + + // max size in bytes, default is 2mb + 'max_size' => env('CUSTOM_EMOJI_MAX_SIZE', 2000000), + ] ]; diff --git a/database/migrations/2022_01_19_025041_create_custom_emoji_table.php b/database/migrations/2022_01_19_025041_create_custom_emoji_table.php new file mode 100644 index 000000000..8c05d9bbb --- /dev/null +++ b/database/migrations/2022_01_19_025041_create_custom_emoji_table.php @@ -0,0 +1,47 @@ +id(); + $table->string('shortcode')->unique()->index(); + $table->string('media_path')->nullable(); + $table->string('domain')->nullable()->index(); + $table->boolean('disabled')->default(false)->index(); + $table->string('uri')->nullable(); + $table->string('image_remote_url')->nullable(); + $table->unsignedInteger('category_id')->nullable(); + $table->unique(['shortcode', 'domain']); + $table->timestamps(); + }); + + Schema::create('custom_emoji_categories', function (Blueprint $table) { + $table->id(); + $table->string('name')->unique()->index(); + $table->boolean('disabled')->default(false)->index(); + $table->timestamps(); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::dropIfExists('custom_emoji'); + Schema::dropIfExists('custom_emoji_categories'); + } +} From 01798daf56979467b025ccabf322e80d7003e07b Mon Sep 17 00:00:00 2001 From: Daniel Supernault Date: Tue, 18 Jan 2022 23:26:44 -0700 Subject: [PATCH 02/11] Update AP helpers, import Emoji tags --- app/Services/CustomEmojiService.php | 4 ++-- app/Util/ActivityPub/Helpers.php | 16 +++++++++++++++- 2 files changed, 17 insertions(+), 3 deletions(-) diff --git a/app/Services/CustomEmojiService.php b/app/Services/CustomEmojiService.php index 1a64784bb..3311e5117 100644 --- a/app/Services/CustomEmojiService.php +++ b/app/Services/CustomEmojiService.php @@ -8,12 +8,12 @@ use App\Models\CustomEmoji; class CustomEmojiService { - public static function getByShortcode($shortcode) + public static function get($shortcode) { return CustomEmoji::whereShortcode($shortcode)->first(); } - public static function getByUrl($url) + public static function import($url) { if(Helpers::validateUrl($url) == false) { return; diff --git a/app/Util/ActivityPub/Helpers.php b/app/Util/ActivityPub/Helpers.php index c2a88ed5c..1413f5106 100644 --- a/app/Util/ActivityPub/Helpers.php +++ b/app/Util/ActivityPub/Helpers.php @@ -27,6 +27,7 @@ use App\Util\ActivityPub\HttpSignature; use Illuminate\Support\Str; use App\Services\ActivityPubFetchService; use App\Services\ActivityPubDeliveryService; +use App\Services\CustomEmojiService; use App\Services\InstanceService; use App\Services\MediaPathService; use App\Services\MediaStorageService; @@ -368,7 +369,6 @@ class Helpers { $cw = true; } - $statusLockKey = 'helpers:status-lock:' . hash('sha256', $res['id']); $status = Cache::lock($statusLockKey) ->get(function () use( @@ -381,6 +381,20 @@ class Helpers { $scope, $id ) { + if(isset($res['tag']) && is_array($res['tag']) && !empty($res['tag'])) { + collect($res['tag']) + ->filter(function($tag) { + // todo: finish hashtag + mention import + // return in_array($tag['type'], ['Emoji', 'Hashtag', 'Mention']); + return in_array($tag['type'], ['Emoji']); + }) + ->each(function($tag) { + if(isset($tag['id'])) { + CustomEmojiService::import($tag['id']); + } + }); + } + if($res['type'] === 'Question') { $status = self::storePoll( $profile, From dc17c9fc2715d14d642f9856d5f766bb0bdc00d0 Mon Sep 17 00:00:00 2001 From: Daniel Supernault Date: Wed, 19 Jan 2022 00:46:30 -0700 Subject: [PATCH 03/11] Improve emoji import --- .../StatusPipeline/StatusTagsPipeline.php | 56 +++++++++++++++++++ app/Models/CustomEmoji.php | 4 ++ app/Services/CustomEmojiService.php | 18 +++++- app/Util/ActivityPub/Helpers.php | 18 ++---- ...01_19_025041_create_custom_emoji_table.php | 2 +- 5 files changed, 81 insertions(+), 17 deletions(-) create mode 100644 app/Jobs/StatusPipeline/StatusTagsPipeline.php diff --git a/app/Jobs/StatusPipeline/StatusTagsPipeline.php b/app/Jobs/StatusPipeline/StatusTagsPipeline.php new file mode 100644 index 000000000..b09623b38 --- /dev/null +++ b/app/Jobs/StatusPipeline/StatusTagsPipeline.php @@ -0,0 +1,56 @@ +activity = $activity; + $this->status = $status; + } + + /** + * Execute the job. + * + * @return void + */ + public function handle() + { + $res = $this->activity; + + collect($res['tag']) + ->filter(function($tag) { + // todo: finish hashtag + mention import + // return in_array($tag['type'], ['Emoji', 'Hashtag', 'Mention']); + return $tag && $tag['type'] == 'Emoji'; + }) + ->values() + ->map(function($tag) { + CustomEmojiService::import($tag['id']); + }); + + // sleep(15); + + StatusService::del($this->status->id); + } +} diff --git a/app/Models/CustomEmoji.php b/app/Models/CustomEmoji.php index 0903d5375..fdd8ac196 100644 --- a/app/Models/CustomEmoji.php +++ b/app/Models/CustomEmoji.php @@ -16,6 +16,10 @@ class CustomEmoji extends Model public static function scan($text) { + if(config('federation.custom_emoji.enabled') == false) { + return []; + } + return Str::of($text) ->matchAll(self::SCAN_RE) ->map(function($match) { diff --git a/app/Services/CustomEmojiService.php b/app/Services/CustomEmojiService.php index 3311e5117..75b1fb0ce 100644 --- a/app/Services/CustomEmojiService.php +++ b/app/Services/CustomEmojiService.php @@ -2,26 +2,35 @@ namespace App\Services; +use App\Models\CustomEmoji; use App\Util\ActivityPub\Helpers; use Illuminate\Support\Facades\Http; -use App\Models\CustomEmoji; +use Illuminate\Support\Facades\Cache; class CustomEmojiService { public static function get($shortcode) { + if(config('federation.custom_emoji.enabled') == false) { + return; + } + return CustomEmoji::whereShortcode($shortcode)->first(); } public static function import($url) { + if(config('federation.custom_emoji.enabled') == false) { + return; + } + if(Helpers::validateUrl($url) == false) { return; } $emoji = CustomEmoji::whereUri($url)->first(); if($emoji) { - return $emoji; + return; } $res = Http::acceptJson()->get($url); @@ -47,6 +56,7 @@ class CustomEmojiService if(!self::headCheck($json['icon']['url'])) { return; } + $emoji = new CustomEmoji; $emoji->shortcode = $json['name']; $emoji->uri = $json['id']; @@ -60,7 +70,9 @@ class CustomEmojiService $emoji->media_path = 'emoji/' . $emoji->id . $ext; $emoji->save(); - return $emoji; + $name = str_replace(':', '', $json['name']); + Cache::forget('pf:custom_emoji:' . $name); + return; } else { return; } diff --git a/app/Util/ActivityPub/Helpers.php b/app/Util/ActivityPub/Helpers.php index 1413f5106..a18a57ff0 100644 --- a/app/Util/ActivityPub/Helpers.php +++ b/app/Util/ActivityPub/Helpers.php @@ -23,6 +23,7 @@ use App\Jobs\RemoteFollowPipeline\RemoteFollowImportRecent; use App\Jobs\ImageOptimizePipeline\{ImageOptimize,ImageThumbnail}; use App\Jobs\StatusPipeline\NewStatusPipeline; use App\Jobs\StatusPipeline\StatusReplyPipeline; +use App\Jobs\StatusPipeline\StatusTagsPipeline; use App\Util\ActivityPub\HttpSignature; use Illuminate\Support\Str; use App\Services\ActivityPubFetchService; @@ -381,19 +382,6 @@ class Helpers { $scope, $id ) { - if(isset($res['tag']) && is_array($res['tag']) && !empty($res['tag'])) { - collect($res['tag']) - ->filter(function($tag) { - // todo: finish hashtag + mention import - // return in_array($tag['type'], ['Emoji', 'Hashtag', 'Mention']); - return in_array($tag['type'], ['Emoji']); - }) - ->each(function($tag) { - if(isset($tag['id'])) { - CustomEmojiService::import($tag['id']); - } - }); - } if($res['type'] === 'Question') { $status = self::storePoll( @@ -430,6 +418,10 @@ class Helpers { } else { StatusReplyPipeline::dispatch($status); } + + if(isset($res['tag']) && is_array($res['tag']) && !empty($res['tag'])) { + StatusTagsPipeline::dispatch($res, $status); + } return $status; }); }); diff --git a/database/migrations/2022_01_19_025041_create_custom_emoji_table.php b/database/migrations/2022_01_19_025041_create_custom_emoji_table.php index 8c05d9bbb..40ff9b3e9 100644 --- a/database/migrations/2022_01_19_025041_create_custom_emoji_table.php +++ b/database/migrations/2022_01_19_025041_create_custom_emoji_table.php @@ -15,7 +15,7 @@ class CreateCustomEmojiTable extends Migration { Schema::create('custom_emoji', function (Blueprint $table) { $table->id(); - $table->string('shortcode')->unique()->index(); + $table->string('shortcode')->index(); $table->string('media_path')->nullable(); $table->string('domain')->nullable()->index(); $table->boolean('disabled')->default(false)->index(); From bf2828c2ee1894401d4cd610c1109523209b0ae6 Mon Sep 17 00:00:00 2001 From: Daniel Supernault Date: Wed, 19 Jan 2022 00:53:06 -0700 Subject: [PATCH 04/11] Add emoji directory and update .gitignore --- storage/app/public/.gitignore | 1 + storage/app/public/emoji/.gitignore | 2 ++ 2 files changed, 3 insertions(+) create mode 100644 storage/app/public/emoji/.gitignore diff --git a/storage/app/public/.gitignore b/storage/app/public/.gitignore index e368b9e0e..fefdd6c6f 100755 --- a/storage/app/public/.gitignore +++ b/storage/app/public/.gitignore @@ -2,5 +2,6 @@ !.gitignore !no-preview.png !m/ +!emoji/ !textimg/ !headers/ diff --git a/storage/app/public/emoji/.gitignore b/storage/app/public/emoji/.gitignore new file mode 100644 index 000000000..d6b7ef32c --- /dev/null +++ b/storage/app/public/emoji/.gitignore @@ -0,0 +1,2 @@ +* +!.gitignore From 489fdbb24836c9c5f61b5830c3b0ab59628d6e0e Mon Sep 17 00:00:00 2001 From: Daniel Supernault Date: Wed, 19 Jan 2022 00:58:13 -0700 Subject: [PATCH 05/11] Update StatusTagPipeline --- app/Jobs/StatusPipeline/StatusTagsPipeline.php | 1 - 1 file changed, 1 deletion(-) diff --git a/app/Jobs/StatusPipeline/StatusTagsPipeline.php b/app/Jobs/StatusPipeline/StatusTagsPipeline.php index b09623b38..a22bd11e9 100644 --- a/app/Jobs/StatusPipeline/StatusTagsPipeline.php +++ b/app/Jobs/StatusPipeline/StatusTagsPipeline.php @@ -44,7 +44,6 @@ class StatusTagsPipeline implements ShouldQueue // return in_array($tag['type'], ['Emoji', 'Hashtag', 'Mention']); return $tag && $tag['type'] == 'Emoji'; }) - ->values() ->map(function($tag) { CustomEmojiService::import($tag['id']); }); From 0d78a9aaf808926767e1119943714bff8872f943 Mon Sep 17 00:00:00 2001 From: Daniel Supernault Date: Wed, 19 Jan 2022 01:04:25 -0700 Subject: [PATCH 06/11] Update compiled assets --- public/js/spa.js | 2 +- public/mix-manifest.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/public/js/spa.js b/public/js/spa.js index 4de7e5ff2..bbb62cf5c 100644 --- a/public/js/spa.js +++ b/public/js/spa.js @@ -1 +1 @@ -(window.webpackJsonp=window.webpackJsonp||[]).push([[20],{"+/TA":function(t,e,n){"use strict";n("eKim")},"+3PN":function(t,e,n){var i=n("eWeD");"string"==typeof i&&(i=[[t.i,i,""]]);var o={hmr:!0,transform:void 0,insertInto:void 0};n("aET+")(i,o);i.locals&&(t.exports=i.locals)},"+VHp":function(t,e,n){"use strict";n("V8Te")},"+uhv":function(t,e,n){"use strict";n("M24V")},"/RaH":function(t,e,n){var i=n("iTP3");"string"==typeof i&&(i=[[t.i,i,""]]);var o={hmr:!0,transform:void 0,insertInto:void 0};n("aET+")(i,o);i.locals&&(t.exports=i.locals)},"/Y1X":function(t,e,n){"use strict";n("KOWi")},"/jad":function(t,e,n){"use strict";var i=n("1gDp"),o=n("ngXG"),a={props:{status:{type:Object},recommended:{type:Boolean,default:!1},reactionBar:{type:Boolean,default:!0},hasTopBorder:{type:Boolean,default:!1},size:{type:String,validator:function(t){return["regular","small"].includes(t)},default:"regular"}},components:{"context-menu":i.a,"poll-card":o.a},data:function(){return{config:window.App.config,profile:{},loading:!0,replies:[],replyId:null,lightboxMedia:!1,showSuggestions:!0,showReadMore:!0,replyStatus:{},replyText:"",replyNsfw:!1,emoji:window.App.util.emoji}},mounted:function(){this.profile=window._sharedData.curUser},methods:{formatCount:function(t){return App.util.format.count(t)},statusUrl:function(t){return 1==t.local?t.url:"/i/web/post/_/"+t.account.id+"/"+t.id},profileUrl:function(t){return 1==t.local?t.account.url:"/i/web/profile/_/"+t.account.id},timestampFormat:function(t){var e=new Date(t);return e.toDateString()+" "+e.toLocaleTimeString()},shortTimestamp:function(t){return window.App.util.format.timeAgo(t)},statusCardUsernameFormat:function(t){if(1==t.account.local)return t.account.username;var e=window.App.config.username.remote.format,n=window.App.config.username.remote.custom,i=t.account.username,o=document.createElement("a");switch(o.href=t.account.url,o=o.hostname,e){case"@":return i+'@'+o+"";case"from":return i+' from '+o+"";case"custom":return i+' '+n+" "+o+"";default:return i+'@'+o+""}},lightbox:function(t){window.location.href=t.media_attachments[0].url},labelRedirect:function(t){var e="/i/redirect?url="+encodeURI(this.config.features.label.covid.url);window.location.href=e},likeStatus:function(t,e){if(0!=$("body").hasClass("loggedIn")){var n=t.favourites_count;t.favourited=!t.favourited,axios.post("/i/like",{item:t.id}).then((function(e){t.favourites_count=e.data.count,t.favourited=!!t.favourited})).catch((function(e){t.favourited=!!t.favourited,t.favourites_count=n,swal("Error","Something went wrong, please try again later.","error")})),window.navigator.vibrate(200),t.favourited&&setTimeout((function(){e.target.classList.add("animate__animated","animate__bounce")}),100)}},commentFocus:function(t,e){this.$emit("comment-focus",t)},commentSubmit:function(t,e){var n=this;this.replySending=!0;var i=t.id,o=this.replyText,a=this.config.uploader.max_caption_length;if(o.length>a)return this.replySending=!1,void swal("Comment Too Long","Please make sure your comment is "+a+" characters or less.","error");axios.post("/i/comment",{item:i,comment:o,sensitive:this.replyNsfw}).then((function(t){n.replyText="",n.replies.push(t.data.entity),n.$refs.replyModal.hide()})),this.replySending=!1},owner:function(t){return this.profile.id===t.account.id},admin:function(){return 1==this.profile.is_admin},ownerOrAdmin:function(t){return this.owner(t)||this.admin()},ctxMenu:function(){this.$refs.contextMenu.open()},timeAgo:function(t){return App.util.format.timeAgo(t)},statusDeleted:function(t){this.$emit("status-delete",t)},canFollow:function(t){return!!t.hasOwnProperty("relationship")&&(!(!t.hasOwnProperty("account")||!t.account.hasOwnProperty("id"))&&(t.account.id!=this.profile.id&&!t.relationship.following))},follow:function(t){var e=this;event.currentTarget.blur(),axios.post("/i/follow",{item:t}).then((function(n){e.status.relationship.following=!0,e.$emit("followed",t)})).catch((function(t){t.response.data.message&&swal("Error",t.response.data.message,"error")}))},unfollow:function(t){var e=this;event.currentTarget.blur(),axios.post("/i/follow",{item:t}).then((function(n){e.status.relationship.following=!1,e.$emit("unfollowed",t)})).catch((function(t){t.response.data.message&&swal("Error",t.response.data.message,"error")}))}}},r=(n("RePV"),n("KHd+")),s=Object(r.a)(a,(function(){var t=this,e=t.$createElement,n=t._self._c||e;return n("div",{staticClass:"status-card-component",class:{"status-card-sm":"small"===t.size}},["text"===t.status.pf_type?n("div",{staticClass:"card shadow-none border rounded-0",class:{"border-top-0":!t.hasTopBorder}},[n("div",{staticClass:"card-body"},[n("div",{staticClass:"media"},[n("img",{staticClass:"rounded-circle box-shadow mr-2",attrs:{src:t.status.account.avatar,width:"32px",height:"32px",onerror:"this.onerror=null;this.src='/storage/avatars/default.png?v=2'",alt:"avatar"}}),t._v(" "),n("div",{staticClass:"media-body"},[n("div",{staticClass:"pl-2 d-flex align-items-top"},[n("a",{staticClass:"username font-weight-bold text-dark text-decoration-none text-break",attrs:{href:t.profileUrl(t.status)},domProps:{innerHTML:t._s(t.statusCardUsernameFormat(t.status))}},[t._v("\n\t\t\t\t\t\t\tLoading...\n\t\t\t\t\t\t")]),t._v(" "),n("span",{staticClass:"px-1 text-lighter"},[t._v("\n\t\t\t\t\t\t\t·\n\t\t\t\t\t\t")]),t._v(" "),n("a",{staticClass:"font-weight-bold text-lighter",attrs:{href:t.statusUrl(t.status)}},[t._v("\n\t\t\t\t\t\t\t"+t._s(t.shortTimestamp(t.status.created_at))+"\n\t\t\t\t\t\t")]),t._v(" "),n("span",{staticClass:"text-right",staticStyle:{"flex-grow":"1"}},[n("button",{staticClass:"btn btn-link text-dark py-0",attrs:{type:"button"},on:{click:function(e){return t.ctxMenu()}}},[n("span",{staticClass:"fas fa-ellipsis-h text-lighter"}),t._v(" "),n("span",{staticClass:"sr-only"},[t._v("Post Menu")])])])]),t._v(" "),n("div",{staticClass:"pl-2"},[t.status.sensitive?n("details",[n("summary",{staticClass:"mb-2 font-weight-bold text-muted"},[t._v("Content Warning")]),t._v(" "),n("p",{staticClass:"pt-2 text-break status-content",domProps:{innerHTML:t._s(t.status.content)}})]):n("p",{staticClass:"pt-2 text-break status-content",domProps:{innerHTML:t._s(t.status.content)}}),t._v(" "),n("p",{staticClass:"mb-0"},[n("i",{staticClass:"fa-heart fa-lg cursor-pointer mr-3",class:{"far text-muted":!t.status.favourited,"fas text-danger":t.status.favourited},on:{click:function(e){return t.likeStatus(t.status,e)}}}),t._v(" "),n("i",{staticClass:"far fa-comment cursor-pointer text-muted fa-lg mr-3",on:{click:function(e){return t.commentFocus(t.status,e)}}})])])])])])]):"poll"===t.status.pf_type?n("div",[n("poll-card",{attrs:{status:t.status,profile:t.profile},on:{"status-delete":t.statusDeleted}})],1):n("div",{staticClass:"card rounded-0 border-top-0 status-card card-md-rounded-0 shadow-none border"},[t.status?n("div",{staticClass:"card-header d-inline-flex align-items-center bg-white"},[n("div",[n("img",{staticClass:"rounded-circle box-shadow",attrs:{src:t.status.account.avatar,width:"32px",height:"32px",onerror:"this.onerror=null;this.src='/storage/avatars/default.png?v=2'",alt:"avatar"}})]),t._v(" "),n("div",{staticClass:"pl-2"},[n("a",{staticClass:"username font-weight-bold text-dark text-decoration-none text-break",attrs:{href:t.profileUrl(t.status)},domProps:{innerHTML:t._s(t.statusCardUsernameFormat(t.status))}},[t._v("\n\t\t\t\t\tLoading...\n\t\t\t\t")]),t._v(" "),t.status.account.is_admin?n("span",{staticClass:"fa-stack",staticStyle:{height:"1em","line-height":"1em","max-width":"19px"},attrs:{title:"Admin Account","data-toggle":"tooltip"}},[n("i",{staticClass:"fas fa-certificate text-danger fa-stack-1x"}),t._v(" "),n("i",{staticClass:"fas fa-crown text-white fa-sm fa-stack-1x",staticStyle:{"font-size":"7px"}})]):t._e(),t._v(" "),n("div",{staticClass:"d-flex align-items-center"},[t.status.place?n("a",{staticClass:"small text-decoration-none text-muted",attrs:{href:"/discover/places/"+t.status.place.id+"/"+t.status.place.slug,title:"Location","data-toggle":"tooltip"}},[n("i",{staticClass:"fas fa-map-marked-alt"}),t._v(" "+t._s(t.status.place.name)+", "+t._s(t.status.place.country))]):t._e()])]),t._v(" "),t.canFollow(t.status)?n("div",[n("span",{staticClass:"px-2"}),t._v(" "),n("button",{staticClass:"btn btn-primary btn-sm font-weight-bold py-1 px-3 rounded-lg",on:{click:function(e){return t.follow(t.status.account.id)}}},[n("i",{staticClass:"far fa-user-plus mr-1"}),t._v(" Follow")])]):t._e(),t._v(" "),t.status.hasOwnProperty("relationship")&&t.status.relationship.hasOwnProperty("following")&&t.status.relationship.following?n("div",[n("span",{staticClass:"px-2"}),t._v(" "),n("button",{staticClass:"btn btn-outline-primary btn-sm font-weight-bold py-1 px-3 rounded-lg",on:{click:function(e){return t.unfollow(t.status.account.id)}}},[n("i",{staticClass:"far fa-user-check mr-1"}),t._v(" Following")])]):t._e(),t._v(" "),n("div",{staticClass:"text-right",staticStyle:{"flex-grow":"1"}},[n("button",{staticClass:"btn btn-link text-dark py-0",attrs:{type:"button"},on:{click:function(e){return t.ctxMenu()}}},[n("span",{staticClass:"fas fa-ellipsis-h text-lighter"}),t._v(" "),n("span",{staticClass:"sr-only"},[t._v("Post Menu")])])])]):t._e(),t._v(" "),n("div",{staticClass:"postPresenterContainer",staticStyle:{background:"#000"}},["photo"===t.status.pf_type?n("div",{staticClass:"w-100"},[n("photo-presenter",{attrs:{status:t.status},on:{lightbox:t.lightbox,togglecw:function(e){t.status.sensitive=!1}}})],1):"video"===t.status.pf_type?n("div",{staticClass:"w-100"},[n("video-presenter",{attrs:{status:t.status},on:{togglecw:function(e){t.status.sensitive=!1}}})],1):"photo:album"===t.status.pf_type?n("div",{staticClass:"w-100"},[n("photo-album-presenter",{attrs:{status:t.status},on:{lightbox:t.lightbox,togglecw:function(e){t.status.sensitive=!1}}})],1):"video:album"===t.status.pf_type?n("div",{staticClass:"w-100"},[n("video-album-presenter",{attrs:{status:t.status},on:{togglecw:function(e){t.status.sensitive=!1}}})],1):"photo:video:album"===t.status.pf_type?n("div",{staticClass:"w-100"},[n("mixed-album-presenter",{attrs:{status:t.status},on:{lightbox:t.lightbox,togglecw:function(e){t.status.sensitive=!1}}})],1):n("div",{staticClass:"w-100"},[n("p",{staticClass:"text-center p-0 font-weight-bold text-white"},[t._v("Error: Problem rendering preview.")])])]),t._v(" "),t.config.features.label.covid.enabled&&t.status.label&&1==t.status.label.covid?n("div",{staticClass:"card-body border-top border-bottom py-2 cursor-pointer pr-2",on:{click:function(e){return t.labelRedirect()}}},[n("p",{staticClass:"font-weight-bold d-flex justify-content-between align-items-center mb-0"},[n("span",[n("i",{staticClass:"fas fa-info-circle mr-2"}),t._v("\n\t\t\t\t\tFor information about COVID-19, "+t._s(t.config.features.label.covid.org)+"\n\t\t\t\t")]),t._v(" "),t._m(0)])]):t._e(),t._v(" "),n("div",{staticClass:"card-body"},[t.reactionBar?n("div",{staticClass:"reactions my-1 pb-2"},[t.status.favourited?n("h3",{staticClass:"fas fa-heart text-danger pr-3 m-0 cursor-pointer",attrs:{title:"Like"},on:{click:function(e){return t.likeStatus(t.status,e)}}}):n("h3",{staticClass:"fal fa-heart pr-3 m-0 like-btn text-dark cursor-pointer",attrs:{title:"Like"},on:{click:function(e){return t.likeStatus(t.status,e)}}}),t._v(" "),t.status.comments_disabled?t._e():n("h3",{staticClass:"fal fa-comment text-dark pr-3 m-0 cursor-pointer",attrs:{title:"Comment"},on:{click:function(e){return t.commentFocus(t.status,e)}}}),t._v(" "),t.status.taggedPeople.length?n("span",{staticClass:"float-right"},[n("span",{staticClass:"font-weight-light small",staticStyle:{color:"#718096"}},[n("i",{staticClass:"far fa-user",attrs:{"data-toggle":"tooltip",title:"Tagged People"}}),t._v(" "),t._l(t.status.taggedPeople,(function(t,e){return n("span",{staticClass:"mr-n2"},[n("a",{attrs:{href:"/"+t.username}},[n("img",{staticClass:"border rounded-circle",attrs:{src:t.avatar,width:"20px",height:"20px","data-toggle":"tooltip",title:"@"+t.username,alt:"Avatar"}})])])}))],2)]):t._e()]):t._e(),t._v(" "),t.status.liked_by.username&&t.status.liked_by.username!==t.profile.username?n("div",{staticClass:"likes mb-1"},[n("span",{staticClass:"like-count"},[t._v("Liked by\n\t\t\t\t\t"),n("a",{staticClass:"font-weight-bold text-dark",attrs:{href:t.status.liked_by.url}},[t._v(t._s(t.status.liked_by.username))]),t._v(" "),1==t.status.liked_by.others?n("span",[t._v("\n\t\t\t\t\t\tand "),t.status.liked_by.total_count_pretty?n("span",{staticClass:"font-weight-bold"},[t._v(t._s(t.status.liked_by.total_count_pretty))]):t._e(),t._v(" "),n("span",{staticClass:"font-weight-bold"},[t._v("others")])]):t._e()])]):t._e(),t._v(" "),"text"!=t.status.pf_type?n("div",{staticClass:"caption"},[t.status.sensitive?t._e():n("p",{staticClass:"mb-2 read-more",staticStyle:{overflow:"hidden"}},[n("span",{staticClass:"username font-weight-bold"},[n("bdi",[n("a",{staticClass:"text-dark",attrs:{href:t.profileUrl(t.status)}},[t._v(t._s(t.status.account.username))])])]),t._v(" "),n("span",{staticClass:"status-content",domProps:{innerHTML:t._s(t.status.content)}})])]):t._e(),t._v(" "),n("div",{staticClass:"timestamp mt-2"},[n("p",{staticClass:"small mb-0"},["archived"!=t.status.visibility?n("a",{staticClass:"text-muted text-uppercase",attrs:{href:t.statusUrl(t.status)}},[n("timeago",{directives:[{name:"b-tooltip",rawName:"v-b-tooltip.hover.bottom",modifiers:{hover:!0,bottom:!0}}],attrs:{datetime:t.status.created_at,"auto-update":60,"converter-options":{includeSeconds:!0},title:t.timestampFormat(t.status.created_at)}})],1):n("span",{staticClass:"text-muted text-uppercase"},[t._v("\n\t\t\t\t\t\tPosted "),n("timeago",{directives:[{name:"b-tooltip",rawName:"v-b-tooltip.hover.bottom",modifiers:{hover:!0,bottom:!0}}],attrs:{datetime:t.status.created_at,"auto-update":60,"converter-options":{includeSeconds:!0},title:t.timestampFormat(t.status.created_at)}})],1),t._v(" "),t.recommended?n("span",[n("span",{staticClass:"px-1"},[t._v("·")]),t._v(" "),n("span",{staticClass:"text-muted"},[t._v("Based on popular and trending content")])]):t._e()])])])]),t._v(" "),n("context-menu",{ref:"contextMenu",attrs:{status:t.status,profile:t.profile},on:{"status-delete":t.statusDeleted}})],1)}),[function(){var t=this.$createElement,e=this._self._c||t;return e("span",[e("i",{staticClass:"fas fa-chevron-right text-lighter"})])}],!1,null,null,null);e.a=s.exports},"0SFe":function(t,e,n){"use strict";n("SZ2H")},"0Z5r":function(t,e,n){var i=n("UudS");"string"==typeof i&&(i=[[t.i,i,""]]);var o={hmr:!0,transform:void 0,insertInto:void 0};n("aET+")(i,o);i.locals&&(t.exports=i.locals)},"0dhX":function(t,e,n){(t.exports=n("I1BE")(!1)).push([t.i,".account-bookmarks-component .form-check[data-v-25a4c79a] {\n margin-left: 1rem;\n}\n.account-bookmarks-component .form-check .media-body[data-v-25a4c79a] {\n margin-left: 1rem;\n}\n.account-bookmarks-component .media-image-placeholder[data-v-25a4c79a] {\n display: flex;\n justify-content: center;\n align-items: center;\n width: 50px;\n height: 50px;\n background-color: #f8f9fa !important;\n border-radius: 5px;\n margin-right: 1rem;\n}",""])},"0ox+":function(t,e,n){(t.exports=n("I1BE")(!1)).push([t.i,'.autocomplete-input{border:1px solid #eee;border-radius:8px;width:100%;padding:12px 12px 12px 48px;box-sizing:border-box;position:relative;font-size:16px;line-height:1.5;flex:1;background-color:#eee;background-image:url("data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyNCIgaGVpZ2h0PSIyNCIgZmlsbD0ibm9uZSIgc3Ryb2tlPSIjNjY2IiBzdHJva2Utd2lkdGg9IjIiIHN0cm9rZS1saW5lY2FwPSJyb3VuZCIgc3Ryb2tlLWxpbmVqb2luPSJyb3VuZCI+PGNpcmNsZSBjeD0iMTEiIGN5PSIxMSIgcj0iOCIvPjxwYXRoIGQ9Ik0yMSAyMWwtNC00Ii8+PC9zdmc+");background-repeat:no-repeat;background-position:12px}.autocomplete-input:focus,.autocomplete-input[aria-expanded=true]{border-color:rgba(0,0,0,.12);background-color:#fff;outline:none;box-shadow:0 2px 2px rgba(0,0,0,.16)}[data-position=below] .autocomplete-input[aria-expanded=true]{border-bottom-color:transparent;border-radius:8px 8px 0 0}[data-position=above] .autocomplete-input[aria-expanded=true]{border-top-color:transparent;border-radius:0 0 8px 8px;z-index:2}.autocomplete[data-loading=true]:after{content:"";border:3px solid rgba(0,0,0,.12);border-right-color:rgba(0,0,0,.48);border-radius:100%;width:20px;height:20px;position:absolute;right:12px;top:50%;transform:translateY(-50%);-webkit-animation:rotate 1s linear infinite;animation:rotate 1s linear infinite}.autocomplete-result-list{margin:0;border:1px solid rgba(0,0,0,.12);padding:0;box-sizing:border-box;max-height:296px;overflow-y:auto;background:#fff;list-style:none;box-shadow:0 2px 2px rgba(0,0,0,.16)}[data-position=below] .autocomplete-result-list{margin-top:-1px;border-top-color:transparent;border-radius:0 0 8px 8px;padding-bottom:8px}[data-position=above] .autocomplete-result-list{margin-bottom:-1px;border-bottom-color:transparent;border-radius:8px 8px 0 0;padding-top:8px}.autocomplete-result{cursor:default;padding:12px 12px 12px 48px;background-image:url("data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIyNCIgaGVpZ2h0PSIyNCIgZmlsbD0ibm9uZSIgc3Ryb2tlPSIjY2NjIiBzdHJva2Utd2lkdGg9IjIiIHN0cm9rZS1saW5lY2FwPSJyb3VuZCIgc3Ryb2tlLWxpbmVqb2luPSJyb3VuZCI+PGNpcmNsZSBjeD0iMTEiIGN5PSIxMSIgcj0iOCIvPjxwYXRoIGQ9Ik0yMSAyMWwtNC00Ii8+PC9zdmc+");background-repeat:no-repeat;background-position:12px}.autocomplete-result:hover,.autocomplete-result[aria-selected=true]{background-color:rgba(0,0,0,.06)}@-webkit-keyframes rotate{0%{transform:translateY(-50%) rotate(0deg)}to{transform:translateY(-50%) rotate(359deg)}}@keyframes rotate{0%{transform:translateY(-50%) rotate(0deg)}to{transform:translateY(-50%) rotate(359deg)}}',""])},"1PLf":function(t,e,n){t.exports=function(t){var e={};function n(i){if(e[i])return e[i].exports;var o=e[i]={i:i,l:!1,exports:{}};return t[i].call(o.exports,o,o.exports,n),o.l=!0,o.exports}return n.m=t,n.c=e,n.d=function(t,e,i){n.o(t,e)||Object.defineProperty(t,e,{enumerable:!0,get:i})},n.r=function(t){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(t,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(t,"__esModule",{value:!0})},n.t=function(t,e){if(1&e&&(t=n(t)),8&e)return t;if(4&e&&"object"==typeof t&&t&&t.__esModule)return t;var i=Object.create(null);if(n.r(i),Object.defineProperty(i,"default",{enumerable:!0,value:t}),2&e&&"string"!=typeof t)for(var o in t)n.d(i,o,function(e){return t[e]}.bind(null,o));return i},n.n=function(t){var e=t&&t.__esModule?function(){return t.default}:function(){return t};return n.d(e,"a",e),e},n.o=function(t,e){return Object.prototype.hasOwnProperty.call(t,e)},n.p="",n(n.s="fb15")}({"00ee":function(t,e,n){var i={};i[n("b622")("toStringTag")]="z",t.exports="[object z]"===String(i)},"0366":function(t,e,n){var i=n("1c0b");t.exports=function(t,e,n){if(i(t),void 0===e)return t;switch(n){case 0:return function(){return t.call(e)};case 1:return function(n){return t.call(e,n)};case 2:return function(n,i){return t.call(e,n,i)};case 3:return function(n,i,o){return t.call(e,n,i,o)}}return function(){return t.apply(e,arguments)}}},"0538":function(t,e,n){"use strict";var i=n("1c0b"),o=n("861d"),a=[].slice,r={},s=function(t,e,n){if(!(e in r)){for(var i=[],o=0;o0;(a>>>=1)&&(e+=e))1&a&&(n+=e);return n}},"19aa":function(t,e){t.exports=function(t,e,n){if(!(t instanceof e))throw TypeError("Incorrect "+(n?n+" ":"")+"invocation");return t}},"1be4":function(t,e,n){var i=n("d066");t.exports=i("document","documentElement")},"1c0b":function(t,e){t.exports=function(t){if("function"!=typeof t)throw TypeError(String(t)+" is not a function");return t}},"1c7e":function(t,e,n){var i=n("b622")("iterator"),o=!1;try{var a=0,r={next:function(){return{done:!!a++}},return:function(){o=!0}};r[i]=function(){return this},Array.from(r,(function(){throw 2}))}catch(t){}t.exports=function(t,e){if(!e&&!o)return!1;var n=!1;try{var a={};a[i]=function(){return{next:function(){return{done:n=!0}}}},t(a)}catch(t){}return n}},"1cdc":function(t,e,n){var i=n("342f");t.exports=/(iphone|ipod|ipad).*applewebkit/i.test(i)},"1d80":function(t,e){t.exports=function(t){if(null==t)throw TypeError("Can't call method on "+t);return t}},2266:function(t,e,n){var i=n("825a"),o=n("e95a"),a=n("50c4"),r=n("0366"),s=n("35a1"),l=n("9bdd"),c=function(t,e){this.stopped=t,this.result=e};(t.exports=function(t,e,n,u,d){var p,h,f,m,v,g,b,y=r(e,n,u?2:1);if(d)p=t;else{if("function"!=typeof(h=s(t)))throw TypeError("Target is not iterable");if(o(h)){for(f=0,m=a(t.length);m>f;f++)if((v=u?y(i(b=t[f])[0],b[1]):y(t[f]))&&v instanceof c)return v;return new c(!1)}p=h.call(t)}for(g=p.next;!(b=g.call(p)).done;)if("object"==typeof(v=l(p,y,b.value,u))&&v&&v instanceof c)return v;return new c(!1)}).stop=function(t){return new c(!0,t)}},"23cb":function(t,e,n){var i=n("a691"),o=Math.max,a=Math.min;t.exports=function(t,e){var n=i(t);return n<0?o(n+e,0):a(n,e)}},"23e7":function(t,e,n){var i=n("da84"),o=n("06cf").f,a=n("9112"),r=n("6eeb"),s=n("ce4e"),l=n("e893"),c=n("94ca");t.exports=function(t,e){var n,u,d,p,h,f=t.target,m=t.global,v=t.stat;if(n=m?i:v?i[f]||s(f,{}):(i[f]||{}).prototype)for(u in e){if(p=e[u],d=t.noTargetGet?(h=o(n,u))&&h.value:n[u],!c(m?u:f+(v?".":"#")+u,t.forced)&&void 0!==d){if(typeof p==typeof d)continue;l(p,d)}(t.sham||d&&d.sham)&&a(p,"sham",!0),r(n,u,p,t)}}},"241c":function(t,e,n){var i=n("ca84"),o=n("7839").concat("length","prototype");e.f=Object.getOwnPropertyNames||function(t){return i(t,o)}},"25f0":function(t,e,n){"use strict";var i=n("6eeb"),o=n("825a"),a=n("d039"),r=n("ad6d"),s=RegExp.prototype,l=s.toString,c=a((function(){return"/a/b"!=l.call({source:"a",flags:"b"})})),u="toString"!=l.name;(c||u)&&i(RegExp.prototype,"toString",(function(){var t=o(this),e=String(t.source),n=t.flags;return"/"+e+"/"+String(void 0===n&&t instanceof RegExp&&!("flags"in s)?r.call(t):n)}),{unsafe:!0})},2626:function(t,e,n){"use strict";var i=n("d066"),o=n("9bf2"),a=n("b622"),r=n("83ab"),s=a("species");t.exports=function(t){var e=i(t),n=o.f;r&&e&&!e[s]&&n(e,s,{configurable:!0,get:function(){return this}})}},2994:function(t,e,n){"use strict";Object.defineProperty(e,"__esModule",{value:!0});var i=n("49d8"),o=n("3054"),a=n("aacc");e.default=function(t,e,n,r,s){if(r<1||r>9||s<1||s>9)throw new a.ValidationError("BlurHash must have between 1 and 9 components");if(e*n*4!==t.length)throw new a.ValidationError("Width and height must match the pixels array");for(var l=[],c=function(i){for(var a=function(a){var r=0==a&&0==i?1:2,s=function(t,e,n,i){for(var a=0,r=0,s=0,l=4*e,c=0;c0){var g=Math.max.apply(Math,f.map((function(t){return Math.max.apply(Math,t)}))),b=Math.floor(Math.max(0,Math.min(82,Math.floor(166*g-.5))));d=(b+1)/166,m+=i.encode83(b,1)}else d=1,m+=i.encode83(0,1);return m+=i.encode83((p=h,(o.linearTosRGB(p[0])<<16)+(o.linearTosRGB(p[1])<<8)+o.linearTosRGB(p[2])),4),f.forEach((function(t){m+=i.encode83(function(t,e){return 19*Math.floor(Math.max(0,Math.min(18,Math.floor(9*o.signPow(t[0]/e,.5)+9.5))))*19+19*Math.floor(Math.max(0,Math.min(18,Math.floor(9*o.signPow(t[1]/e,.5)+9.5))))+Math.floor(Math.max(0,Math.min(18,Math.floor(9*o.signPow(t[2]/e,.5)+9.5))))}(t,d),2)})),m}},"2cf4":function(t,e,n){var i,o,a,r=n("da84"),s=n("d039"),l=n("c6b6"),c=n("0366"),u=n("1be4"),d=n("cc12"),p=n("1cdc"),h=r.location,f=r.setImmediate,m=r.clearImmediate,v=r.process,g=r.MessageChannel,b=r.Dispatch,y=0,w={},_=function(t){if(w.hasOwnProperty(t)){var e=w[t];delete w[t],e()}},x=function(t){return function(){_(t)}},C=function(t){_(t.data)},k=function(t){r.postMessage(t+"",h.protocol+"//"+h.host)};f&&m||(f=function(t){for(var e=[],n=1;arguments.length>n;)e.push(arguments[n++]);return w[++y]=function(){("function"==typeof t?t:Function(t)).apply(void 0,e)},i(y),y},m=function(t){delete w[t]},"process"==l(v)?i=function(t){v.nextTick(x(t))}:b&&b.now?i=function(t){b.now(x(t))}:g&&!p?(a=(o=new g).port2,o.port1.onmessage=C,i=c(a.postMessage,a,1)):!r.addEventListener||"function"!=typeof postMessage||r.importScripts||s(k)||"file:"===h.protocol?i="onreadystatechange"in d("script")?function(t){u.appendChild(d("script")).onreadystatechange=function(){u.removeChild(this),_(t)}}:function(t){setTimeout(x(t),0)}:(i=k,r.addEventListener("message",C,!1))),t.exports={set:f,clear:m}},"2d00":function(t,e,n){var i,o,a=n("da84"),r=n("342f"),s=a.process,l=s&&s.versions,c=l&&l.v8;c?o=(i=c.split("."))[0]+i[1]:r&&(!(i=r.match(/Edge\/(\d+)/))||i[1]>=74)&&(i=r.match(/Chrome\/(\d+)/))&&(o=i[1]),t.exports=o&&+o},3054:function(t,e,n){"use strict";Object.defineProperty(e,"__esModule",{value:!0}),e.sRGBToLinear=function(t){var e=t/255;return e<=.04045?e/12.92:Math.pow((e+.055)/1.055,2.4)},e.linearTosRGB=function(t){var e=Math.max(0,Math.min(1,t));return e<=.0031308?Math.round(12.92*e*255+.5):Math.round(255*(1.055*Math.pow(e,1/2.4)-.055)+.5)},e.sign=function(t){return t<0?-1:1},e.signPow=function(t,n){return e.sign(t)*Math.pow(Math.abs(t),n)}},3410:function(t,e,n){var i=n("23e7"),o=n("d039"),a=n("7b0b"),r=n("e163"),s=n("e177");i({target:"Object",stat:!0,forced:o((function(){r(1)})),sham:!s},{getPrototypeOf:function(t){return r(a(t))}})},"342f":function(t,e,n){var i=n("d066");t.exports=i("navigator","userAgent")||""},"35a1":function(t,e,n){var i=n("f5df"),o=n("3f8c"),a=n("b622")("iterator");t.exports=function(t){if(null!=t)return t[a]||t["@@iterator"]||o[i(t)]}},"37e8":function(t,e,n){var i=n("83ab"),o=n("9bf2"),a=n("825a"),r=n("df75");t.exports=i?Object.defineProperties:function(t,e){a(t);for(var n,i=r(e),s=i.length,l=0;s>l;)o.f(t,n=i[l++],e[n]);return t}},"3bbe":function(t,e,n){var i=n("861d");t.exports=function(t){if(!i(t)&&null!==t)throw TypeError("Can't set "+String(t)+" as a prototype");return t}},"3ca3":function(t,e,n){"use strict";var i=n("6547").charAt,o=n("69f3"),a=n("7dd0"),r=o.set,s=o.getterFor("String Iterator");a(String,"String",(function(t){r(this,{type:"String Iterator",string:String(t),index:0})}),(function(){var t,e=s(this),n=e.string,o=e.index;return o>=n.length?{value:void 0,done:!0}:(t=i(n,o),e.index+=t.length,{value:t,done:!1})}))},"3f8c":function(t,e){t.exports={}},"408a":function(t,e,n){var i=n("c6b6");t.exports=function(t){if("number"!=typeof t&&"Number"!=i(t))throw TypeError("Incorrect invocation");return+t}},"428f":function(t,e,n){var i=n("da84");t.exports=i},"44ad":function(t,e,n){var i=n("d039"),o=n("c6b6"),a="".split;t.exports=i((function(){return!Object("z").propertyIsEnumerable(0)}))?function(t){return"String"==o(t)?a.call(t,""):Object(t)}:Object},"44d2":function(t,e,n){var i=n("b622"),o=n("7c73"),a=n("9bf2"),r=i("unscopables"),s=Array.prototype;null==s[r]&&a.f(s,r,{configurable:!0,value:o(null)}),t.exports=function(t){s[r][t]=!0}},"44de":function(t,e,n){var i=n("da84");t.exports=function(t,e){var n=i.console;n&&n.error&&(1===arguments.length?n.error(t):n.error(t,e))}},4840:function(t,e,n){var i=n("825a"),o=n("1c0b"),a=n("b622")("species");t.exports=function(t,e){var n,r=i(t).constructor;return void 0===r||null==(n=i(r)[a])?e:o(n)}},4930:function(t,e,n){var i=n("d039");t.exports=!!Object.getOwnPropertySymbols&&!i((function(){return!String(Symbol())}))},"49d8":function(t,e,n){"use strict";Object.defineProperty(e,"__esModule",{value:!0});var i=["0","1","2","3","4","5","6","7","8","9","A","B","C","D","E","F","G","H","I","J","K","L","M","N","O","P","Q","R","S","T","U","V","W","X","Y","Z","a","b","c","d","e","f","g","h","i","j","k","l","m","n","o","p","q","r","s","t","u","v","w","x","y","z","#","$","%","*","+",",","-",".",":",";","=","?","@","[","]","^","_","{","|","}","~"];e.decode83=function(t){for(var e=0,n=0;nu;)if((s=l[u++])!=s)return!0}else for(;c>u;u++)if((t||u in l)&&l[u]===n)return t||u||0;return!t&&-1}};t.exports={includes:r(!0),indexOf:r(!1)}},"50c4":function(t,e,n){var i=n("a691"),o=Math.min;t.exports=function(t){return t>0?o(i(t),9007199254740991):0}},5135:function(t,e){var n={}.hasOwnProperty;t.exports=function(t,e){return n.call(t,e)}},5692:function(t,e,n){var i=n("c430"),o=n("c6cd");(t.exports=function(t,e){return o[t]||(o[t]=void 0!==e?e:{})})("versions",[]).push({version:"3.6.5",mode:i?"pure":"global",copyright:"© 2020 Denis Pushkarev (zloirock.ru)"})},"56ef":function(t,e,n){var i=n("d066"),o=n("241c"),a=n("7418"),r=n("825a");t.exports=i("Reflect","ownKeys")||function(t){var e=o.f(r(t)),n=a.f;return n?e.concat(n(t)):e}},5899:function(t,e){t.exports="\t\n\v\f\r                 \u2028\u2029\ufeff"},"58a8":function(t,e,n){var i=n("1d80"),o="["+n("5899")+"]",a=RegExp("^"+o+o+"*"),r=RegExp(o+o+"*$"),s=function(t){return function(e){var n=String(i(e));return 1&t&&(n=n.replace(a,"")),2&t&&(n=n.replace(r,"")),n}};t.exports={start:s(1),end:s(2),trim:s(3)}},"5c6c":function(t,e){t.exports=function(t,e){return{enumerable:!(1&t),configurable:!(2&t),writable:!(4&t),value:e}}},"63a9":function(t,e,n){},6547:function(t,e,n){var i=n("a691"),o=n("1d80"),a=function(t){return function(e,n){var a,r,s=String(o(e)),l=i(n),c=s.length;return l<0||l>=c?t?"":void 0:(a=s.charCodeAt(l))<55296||a>56319||l+1===c||(r=s.charCodeAt(l+1))<56320||r>57343?t?s.charAt(l):a:t?s.slice(l,l+2):r-56320+(a-55296<<10)+65536}};t.exports={codeAt:a(!1),charAt:a(!0)}},"65f0":function(t,e,n){var i=n("861d"),o=n("e8b5"),a=n("b622")("species");t.exports=function(t,e){var n;return o(t)&&("function"!=typeof(n=t.constructor)||n!==Array&&!o(n.prototype)?i(n)&&null===(n=n[a])&&(n=void 0):n=void 0),new(void 0===n?Array:n)(0===e?0:e)}},"69f3":function(t,e,n){var i,o,a,r=n("7f9a"),s=n("da84"),l=n("861d"),c=n("9112"),u=n("5135"),d=n("f772"),p=n("d012"),h=s.WeakMap;if(r){var f=new h,m=f.get,v=f.has,g=f.set;i=function(t,e){return g.call(f,t,e),e},o=function(t){return m.call(f,t)||{}},a=function(t){return v.call(f,t)}}else{var b=d("state");p[b]=!0,i=function(t,e){return c(t,b,e),e},o=function(t){return u(t,b)?t[b]:{}},a=function(t){return u(t,b)}}t.exports={set:i,get:o,has:a,enforce:function(t){return a(t)?o(t):i(t,{})},getterFor:function(t){return function(e){var n;if(!l(e)||(n=o(e)).type!==t)throw TypeError("Incompatible receiver, "+t+" required");return n}}}},"6eeb":function(t,e,n){var i=n("da84"),o=n("9112"),a=n("5135"),r=n("ce4e"),s=n("8925"),l=n("69f3"),c=l.get,u=l.enforce,d=String(String).split("String");(t.exports=function(t,e,n,s){var l=!!s&&!!s.unsafe,c=!!s&&!!s.enumerable,p=!!s&&!!s.noTargetGet;"function"==typeof n&&("string"!=typeof e||a(n,"name")||o(n,"name",e),u(n).source=d.join("string"==typeof e?e:"")),t!==i?(l?!p&&t[e]&&(c=!0):delete t[e],c?t[e]=n:o(t,e,n)):c?t[e]=n:r(e,n)})(Function.prototype,"toString",(function(){return"function"==typeof this&&c(this).source||s(this)}))},7156:function(t,e,n){var i=n("861d"),o=n("d2bb");t.exports=function(t,e,n){var a,r;return o&&"function"==typeof(a=e.constructor)&&a!==n&&i(r=a.prototype)&&r!==n.prototype&&o(t,r),t}},7418:function(t,e){e.f=Object.getOwnPropertySymbols},"746f":function(t,e,n){var i=n("428f"),o=n("5135"),a=n("e538"),r=n("9bf2").f;t.exports=function(t){var e=i.Symbol||(i.Symbol={});o(e,t)||r(e,t,{value:a.f(t)})}},7839:function(t,e){t.exports=["constructor","hasOwnProperty","isPrototypeOf","propertyIsEnumerable","toLocaleString","toString","valueOf"]},"7b0b":function(t,e,n){var i=n("1d80");t.exports=function(t){return Object(i(t))}},"7c73":function(t,e,n){var i,o=n("825a"),a=n("37e8"),r=n("7839"),s=n("d012"),l=n("1be4"),c=n("cc12"),u=n("f772"),d=u("IE_PROTO"),p=function(){},h=function(t){return" +@endpush diff --git a/resources/views/admin/custom-emoji/duplicates.blade.php b/resources/views/admin/custom-emoji/duplicates.blade.php new file mode 100644 index 000000000..51ff3a714 --- /dev/null +++ b/resources/views/admin/custom-emoji/duplicates.blade.php @@ -0,0 +1,101 @@ +@extends('admin.partial.template-full') + +@section('section') + +
+
+
+
+
+

Custom Emoji

+

Showing duplicates of {{$emoji->shortcode}}

+
+
+
+
+
+
+
+
+
+

+ Duplicate emoji shortcodes can lead to unpredictible results +

+

If you change the primary/in-use emoji, you will need to clear the cache by running the php artisan cache:clear command for the changes to take effect immediately.

+
+ +

In Use

+
+
+
+ + +
+

{{ $emoji->shortcode }}

+

{{ $emoji->domain }}

+
+ +
Added {{$emoji->created_at->diffForHumans(null, true, true)}}
+ +
+ @csrf + +
+ + + +
+
+
+
+

Not used (due to conflicting shortcode)

+
+ @foreach($emojis as $emoji) +
+
+ + +
+

{{ $emoji->shortcode }}

+

{{ $emoji->domain }}

+
+ +
Added {{$emoji->created_at->diffForHumans(null, true, true)}}
+ +
+ @csrf + +
+ + + +
+
+ @endforeach +
+ +
+ {{ $emojis->links() }} +
+
+
+
+@endsection diff --git a/resources/views/admin/custom-emoji/home.blade.php b/resources/views/admin/custom-emoji/home.blade.php new file mode 100644 index 000000000..18b1933a1 --- /dev/null +++ b/resources/views/admin/custom-emoji/home.blade.php @@ -0,0 +1,155 @@ +@extends('admin.partial.template-full') + +@section('section') + +
+
+
+
+
+

Custom Emoji

+
+
+
+
+
+
Total Emoji
+ {{$stats['total']}} +
+
+
+
+
Total Active
+ {{$stats['active']}} +
+
+
+
+
Remote Emoji
+ {{$stats['remote']}} +
+
+
+
+
Duplicate Emoji
+ {{$stats['duplicate']}} +
+
+ +
+
+
+

+ Stats are cached for 12 hours and may not reflect the latest data.
To refresh the cache and view the most recent data, click here. +

+
+
+
+
+
+
+
+
+ + + + @if($sort == 'duplicates') +
+

+ Duplicate emoji shortcodes can lead to unpredictible results +

+
+ @endif + +
+ @foreach($emojis as $emoji) +
+
+ + +
+

{{ $emoji->shortcode }}

+

{{ $emoji->domain }}

+
+ + @if($sort == 'duplicates') + + View duplicates + + {{--
Updated {{$emoji->updated_at->diffForHumans(null, true, true)}}
--}} + @else +
Updated {{$emoji->updated_at->diffForHumans(null, true, true)}}
+ +
+ @csrf + +
+ + + @endif + +
+
+ @endforeach +
+ +
+ {{ $emojis->links() }} +
+
+
+
+@endsection + +@push('scripts') + +@endpush diff --git a/resources/views/admin/custom-emoji/not-enabled.blade.php b/resources/views/admin/custom-emoji/not-enabled.blade.php new file mode 100644 index 000000000..3fa928406 --- /dev/null +++ b/resources/views/admin/custom-emoji/not-enabled.blade.php @@ -0,0 +1,24 @@ +@extends('admin.partial.template-full') + +@section('section') + +
+
+
+
+
+

Custom Emoji

+
+
+
+
+
+
+
+
+

This feature is not enabled

+

To enable this feature, set CUSTOM_EMOJI=true in
your .env file and run php artisan config:cache

+
+
+
+@endsection diff --git a/resources/views/admin/partial/sidenav.blade.php b/resources/views/admin/partial/sidenav.blade.php index ff204756e..e63852e56 100644 --- a/resources/views/admin/partial/sidenav.blade.php +++ b/resources/views/admin/partial/sidenav.blade.php @@ -1,7 +1,7 @@