diff --git a/CHANGELOG.md b/CHANGELOG.md index 53b6e45a2..00b045b5f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,8 @@ ### Added - Added drafts API endpoint for Camera Roll ([bad2ecde](https://github.com/pixelfed/pixelfed/commit/bad2ecde)) +- Added AccountService ([885a1258](https://github.com/pixelfed/pixelfed/commit/885a1258)) +- Added post embeds ([1fecf717](https://github.com/pixelfed/pixelfed/commit/1fecf717)) ### Fixed - Fixed like and share/reblog count on profiles ([86cb7d09](https://github.com/pixelfed/pixelfed/commit/86cb7d09)) @@ -45,6 +47,10 @@ - Updated StatusTransformer, added ```local``` attribute ([484bb509](https://github.com/pixelfed/pixelfed/commit/484bb509)) - Updated PostComponent, fix bug affecting MomentUI and non authenticated users ([7b3fe215](https://github.com/pixelfed/pixelfed/commit/7b3fe215)) - Updated FixUsernames command to allow usernames containing ```.``` ([e5d77c6d](https://github.com/pixelfed/pixelfed/commit/e5d77c6d)) +- Updated landing page, add age check ([d11e82c3](https://github.com/pixelfed/pixelfed/commit/d11e82c3)) +- Updated ApiV1Controller, add ```mobile_apis``` to /api/v1/instance endpoint ([57407463](https://github.com/pixelfed/pixelfed/commit/57407463)) +- Updated PublicTimelineService, add video media scopes ([7b00eba3](https://github.com/pixelfed/pixelfed/commit/7b00eba3)) +- Updated PublicApiController, add AccountService ([5ebd2c8a](https://github.com/pixelfed/pixelfed/commit/5ebd2c8a)) ## Deprecated diff --git a/app/Http/Controllers/Api/ApiV1Controller.php b/app/Http/Controllers/Api/ApiV1Controller.php index ad8772230..61948f945 100644 --- a/app/Http/Controllers/Api/ApiV1Controller.php +++ b/app/Http/Controllers/Api/ApiV1Controller.php @@ -906,7 +906,9 @@ class ApiV1Controller extends Controller 'max_avatar_size' => config('pixelfed.max_avatar_size'), 'max_caption_length' => config('pixelfed.max_caption_length'), 'max_bio_length' => config('pixelfed.max_bio_length'), - 'max_album_length' => config('pixelfed.max_album_length') + 'max_album_length' => config('pixelfed.max_album_length'), + 'mobile_apis' => config('pixelfed.oauth_enabled') + ] ]; return response()->json($res, 200, [], JSON_PRETTY_PRINT); diff --git a/app/Http/Controllers/Auth/RegisterController.php b/app/Http/Controllers/Auth/RegisterController.php index 713ffe63e..738171ded 100644 --- a/app/Http/Controllers/Auth/RegisterController.php +++ b/app/Http/Controllers/Auth/RegisterController.php @@ -63,7 +63,7 @@ class RegisterController extends Controller 'unique:users', function ($attribute, $value, $fail) { if (!ctype_alpha($value[0])) { - return $fail('Username is invalid. Username must be alpha-numeric and start with a letter.'); + return $fail('Username is invalid. Must start with a letter or number.'); } $val = str_replace(['_', '-', '.'], '', $value); if(!ctype_alnum($val)) { @@ -73,6 +73,7 @@ class RegisterController extends Controller ]; $rules = [ + 'agecheck' => 'required|accepted', 'name' => 'nullable|string|max:'.config('pixelfed.max_name_length'), 'username' => $usernameRules, 'email' => 'required|string|email|max:255|unique:users', diff --git a/app/Http/Controllers/DiscoverController.php b/app/Http/Controllers/DiscoverController.php index 77d54dbff..ccb042d98 100644 --- a/app/Http/Controllers/DiscoverController.php +++ b/app/Http/Controllers/DiscoverController.php @@ -14,6 +14,8 @@ use App\{ }; use Auth, DB, Cache; use Illuminate\Http\Request; +use App\Transformer\Api\AccountTransformer; +use App\Transformer\Api\AccountWithStatusesTransformer; use App\Transformer\Api\StatusStatelessTransformer; use League\Fractal; use League\Fractal\Serializer\ArraySerializer; @@ -131,7 +133,31 @@ class DiscoverController extends Controller public function profilesDirectory(Request $request) { - $profiles = Profile::whereNull('domain')->simplePaginate(48); - return view('discover.profiles.home', compact('profiles')); + return view('discover.profiles.home'); + } + + public function profilesDirectoryApi(Request $request) + { + $this->validate($request, [ + 'page' => 'integer|max:10' + ]); + + $page = $request->input('page') ?? 1; + $key = 'discover:profiles:page:' . $page; + $ttl = now()->addHours(12); + + $res = Cache::remember($key, $ttl, function() { + $profiles = Profile::whereNull('domain') + ->whereNull('status') + ->whereIsPrivate(false) + ->has('statuses') + ->whereIsSuggestable(true) + // ->inRandomOrder() + ->simplePaginate(8); + $resource = new Fractal\Resource\Collection($profiles, new AccountTransformer()); + return $this->fractal->createData($resource)->toArray(); + }); + + return $res; } } diff --git a/app/Http/Controllers/PublicApiController.php b/app/Http/Controllers/PublicApiController.php index 4003615ec..908fa06cd 100644 --- a/app/Http/Controllers/PublicApiController.php +++ b/app/Http/Controllers/PublicApiController.php @@ -22,7 +22,11 @@ use App\Transformer\Api\{ RelationshipTransformer, StatusTransformer, }; -use App\Services\UserFilterService; +use App\Services\{ + AccountService, + PublicTimelineService, + UserFilterService +}; use App\Jobs\StatusPipeline\NewStatusPipeline; use League\Fractal\Serializer\ArraySerializer; use League\Fractal\Pagination\IlluminatePaginatorAdapter; @@ -38,17 +42,12 @@ class PublicApiController extends Controller $this->fractal->setSerializer(new ArraySerializer()); } - protected function getUserData() + protected function getUserData($user) { - if(false == Auth::check()) { + if(!$user) { return []; } else { - $profile = Auth::user()->profile; - if($profile->status) { - return []; - } - $user = new Fractal\Resource\Item($profile, new AccountTransformer()); - return $this->fractal->createData($user)->toArray(); + return AccountService::get($user->profile_id); } } @@ -90,7 +89,7 @@ class PublicApiController extends Controller $item = new Fractal\Resource\Item($status, new StatusTransformer()); $res = [ 'status' => $this->fractal->createData($item)->toArray(), - 'user' => $this->getUserData(), + 'user' => $this->getUserData($request->user()), 'likes' => $this->getLikes($status), 'shares' => $this->getShares($status), 'reactions' => [ @@ -235,12 +234,13 @@ class PublicApiController extends Controller $max = $request->input('max_id'); $limit = $request->input('limit') ?? 3; - // $private = Cache::remember('profiles:private', now()->addMinutes(1440), function() { - // return Profile::whereIsPrivate(true) - // ->orWhere('unlisted', true) - // ->orWhere('status', '!=', null) - // ->pluck('id'); - // }); + $private = Cache::remember('profiles:private', now()->addMinutes(1440), function() { + return Profile::whereIsPrivate(true) + ->orWhere('unlisted', true) + ->orWhere('status', '!=', null) + ->pluck('id') + ->toArray(); + }); // if(Auth::check()) { // // $pid = Auth::user()->profile->id; @@ -255,7 +255,17 @@ class PublicApiController extends Controller // $filtered = []; // } - $filtered = Auth::check() ? UserFilterService::filters(Auth::user()->profile_id) : []; + $filtered = Auth::check() ? array_merge($private, UserFilterService::filters(Auth::user()->profile_id)) : []; + // if($max == 0) { + // $res = PublicTimelineService::count(); + // if($res == 0) { + // PublicTimelineService::warmCache(); + // $res = PublicTimelineService::get(0,4); + // } else { + // $res = PublicTimelineService::get(0,4); + // } + // return response()->json($res); + // } if($min || $max) { $dir = $min ? '>' : '<'; @@ -321,7 +331,6 @@ class PublicApiController extends Controller $fractal = new Fractal\Resource\Collection($timeline, new StatusTransformer()); $res = $this->fractal->createData($fractal)->toArray(); - // $res = $timeline; return response()->json($res); } @@ -439,98 +448,7 @@ class PublicApiController extends Controller public function networkTimelineApi(Request $request) { - if(!Auth::check()) { - return abort(403); - } - - $this->validate($request,[ - 'page' => 'nullable|integer|max:40', - 'min_id' => 'nullable|integer|min:0|max:' . PHP_INT_MAX, - 'max_id' => 'nullable|integer|min:0|max:' . PHP_INT_MAX, - 'limit' => 'nullable|integer|max:20' - ]); - - $page = $request->input('page'); - $min = $request->input('min_id'); - $max = $request->input('max_id'); - $limit = $request->input('limit') ?? 3; - - // TODO: Use redis for timelines - // $timeline = Timeline::build()->local(); - $pid = Auth::user()->profile->id; - - $private = Cache::remember('profiles:private', now()->addMinutes(1440), function() { - return Profile::whereIsPrivate(true) - ->orWhere('unlisted', true) - ->orWhere('status', '!=', null) - ->pluck('id'); - }); - $filters = UserFilter::whereUserId($pid) - ->whereFilterableType('App\Profile') - ->whereIn('filter_type', ['mute', 'block']) - ->pluck('filterable_id')->toArray(); - $filtered = array_merge($private->toArray(), $filters); - - if($min || $max) { - $dir = $min ? '>' : '<'; - $id = $min ?? $max; - $timeline = Status::select( - 'id', - 'uri', - 'caption', - 'rendered', - 'profile_id', - 'type', - 'in_reply_to_id', - 'reblog_of_id', - 'is_nsfw', - 'scope', - 'local', - 'reply_count', - 'comments_disabled', - 'created_at', - 'updated_at' - )->where('id', $dir, $id) - ->whereIn('type', ['photo', 'photo:album', 'video', 'video:album']) - ->whereNotIn('profile_id', $filtered) - ->whereNotNull('uri') - ->whereNull('in_reply_to_id') - ->whereNull('reblog_of_id') - ->whereVisibility('public') - ->latest() - ->limit($limit) - ->get(); - } else { - $timeline = Status::select( - 'id', - 'uri', - 'caption', - 'rendered', - 'profile_id', - 'type', - 'in_reply_to_id', - 'reblog_of_id', - 'is_nsfw', - 'scope', - 'local', - 'reply_count', - 'comments_disabled', - 'created_at', - 'updated_at' - )->whereIn('type', ['photo', 'photo:album', 'video', 'video:album']) - ->whereNotIn('profile_id', $filtered) - ->whereNull('in_reply_to_id') - ->whereNull('reblog_of_id') - ->whereNotNull('uri') - ->whereVisibility('public') - ->latest() - ->simplePaginate($limit); - } - - $fractal = new Fractal\Resource\Collection($timeline, new StatusTransformer()); - $res = $this->fractal->createData($fractal)->toArray(); - return response()->json($res); - + return response()->json([]); } public function relationships(Request $request) @@ -555,10 +473,7 @@ class PublicApiController extends Controller public function account(Request $request, $id) { - $profile = Profile::whereNull('status')->findOrFail($id); - $resource = new Fractal\Resource\Item($profile, new AccountTransformer()); - $res = $this->fractal->createData($resource)->toArray(); - + $res = AccountService::get($id); return response()->json($res); } diff --git a/app/Http/Controllers/SeasonalController.php b/app/Http/Controllers/SeasonalController.php new file mode 100644 index 000000000..2dbb50788 --- /dev/null +++ b/app/Http/Controllers/SeasonalController.php @@ -0,0 +1,20 @@ +middleware('auth'); + } + + public function yearInReview() + { + $profile = Auth::user()->profile; + return view('account.yir', compact('profile')); + } +} diff --git a/app/Http/Controllers/SiteController.php b/app/Http/Controllers/SiteController.php index 9d8563f25..68d92fc30 100644 --- a/app/Http/Controllers/SiteController.php +++ b/app/Http/Controllers/SiteController.php @@ -10,10 +10,10 @@ use App\Util\Localization\Localization; class SiteController extends Controller { - public function home() + public function home(Request $request) { if (Auth::check()) { - return $this->homeTimeline(); + return $this->homeTimeline($request); } else { return $this->homeGuest(); } @@ -24,9 +24,13 @@ class SiteController extends Controller return view('site.index'); } - public function homeTimeline() + public function homeTimeline(Request $request) { - return view('timeline.home'); + $this->validate($request, [ + 'layout' => 'nullable|string|in:grid,feed' + ]); + $layout = $request->input('layout', 'feed'); + return view('timeline.home', compact('layout')); } public function changeLocale(Request $request, $locale) diff --git a/app/Http/Controllers/StatusController.php b/app/Http/Controllers/StatusController.php index 364ca21a8..a5e9e09da 100644 --- a/app/Http/Controllers/StatusController.php +++ b/app/Http/Controllers/StatusController.php @@ -51,6 +51,12 @@ class StatusController extends Controller } } + if($status->type == 'archived') { + if(Auth::user()->profile_id !== $status->profile_id) { + abort(404); + } + } + if ($request->wantsJson() && config('federation.activitypub.enabled')) { return $this->showActivityPub($request, $status); } @@ -70,13 +76,29 @@ class StatusController extends Controller public function showEmbed(Request $request, $username, int $id) { - abort(404); - $profile = Profile::whereNull('status')->whereUsername($username)->first(); - $status = Status::whereScope('private')->find($id); - if(!$profile || !$status) { - return view('status.embed-removed'); + $profile = Profile::whereNull(['domain','status']) + ->whereIsPrivate(false) + ->whereUsername($username) + ->first(); + if(!$profile) { + $content = view('status.embed-removed'); + return response($content)->header('X-Frame-Options', 'ALLOWALL'); } - return view('status.embed', compact('status')); + $status = Status::whereProfileId($profile->id) + ->whereNull('uri') + ->whereScope('public') + ->whereIsNsfw(false) + ->whereIn('type', ['photo', 'video']) + ->find($id); + if(!$status) { + $content = view('status.embed-removed'); + return response($content)->header('X-Frame-Options', 'ALLOWALL'); + } + $showLikes = $request->filled('likes') && $request->likes == true; + $showCaption = $request->filled('caption') && $request->caption !== false; + $layout = $request->filled('layout') && $request->layout == 'compact' ? 'compact' : 'full'; + $content = view('status.embed', compact('status', 'showLikes', 'showCaption', 'layout')); + return response($content)->withHeaders(['X-Frame-Options' => 'ALLOWALL']); } public function showObject(Request $request, $username, int $id) diff --git a/app/Http/Kernel.php b/app/Http/Kernel.php index 7a8c91efe..33ed320a7 100644 --- a/app/Http/Kernel.php +++ b/app/Http/Kernel.php @@ -29,6 +29,7 @@ class Kernel extends HttpKernel protected $middlewareGroups = [ 'web' => [ \App\Http\Middleware\EncryptCookies::class, + \App\Http\Middleware\FrameGuard::class, \Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class, \Illuminate\Session\Middleware\StartSession::class, // \Illuminate\Session\Middleware\AuthenticateSession::class, diff --git a/app/Http/Middleware/FrameGuard.php b/app/Http/Middleware/FrameGuard.php new file mode 100644 index 000000000..9fa377e3b --- /dev/null +++ b/app/Http/Middleware/FrameGuard.php @@ -0,0 +1,26 @@ +headers->has('X-Frame-Options')) { + $response->headers->set('X-Frame-Options', 'SAMEORIGIN', false); + } + + return $response; + } +} diff --git a/app/Services/AccountService.php b/app/Services/AccountService.php new file mode 100644 index 000000000..e14aadf80 --- /dev/null +++ b/app/Services/AccountService.php @@ -0,0 +1,29 @@ +addHours(12); + + return Cache::remember($key, $ttl, function() use($id) { + $fractal = new Fractal\Manager(); + $fractal->setSerializer(new ArraySerializer()); + $profile = Profile::whereNull('status')->findOrFail($id); + $resource = new Fractal\Resource\Item($profile, new AccountTransformer()); + return $fractal->createData($resource)->toArray(); + }); + } + +} \ No newline at end of file diff --git a/app/Services/PublicTimelineService.php b/app/Services/PublicTimelineService.php index ded2fa247..49d0eb598 100644 --- a/app/Services/PublicTimelineService.php +++ b/app/Services/PublicTimelineService.php @@ -52,7 +52,7 @@ class PublicTimelineService { $ids = Status::whereNull('uri') ->whereNull('in_reply_to_id') ->whereNull('reblog_of_id') - ->whereIn('type', ['photo', 'photo:album']) + ->whereIn('type', ['photo', 'photo:album', 'video', 'video:album', 'photo:video:album']) ->whereScope('public') ->latest() ->limit($limit) diff --git a/app/Transformer/Api/AccountTransformer.php b/app/Transformer/Api/AccountTransformer.php index d2db1adc4..cdea53cb5 100644 --- a/app/Transformer/Api/AccountTransformer.php +++ b/app/Transformer/Api/AccountTransformer.php @@ -33,6 +33,7 @@ class AccountTransformer extends Fractal\TransformerAbstract 'website' => $profile->website, 'local' => (bool) $local, 'is_admin' => (bool) $is_admin, + 'created_at' => $profile->created_at->timestamp ]; } diff --git a/app/Transformer/Api/AccountWithStatusesTransformer.php b/app/Transformer/Api/AccountWithStatusesTransformer.php new file mode 100644 index 000000000..13af51fc7 --- /dev/null +++ b/app/Transformer/Api/AccountWithStatusesTransformer.php @@ -0,0 +1,56 @@ +domain == null; + $is_admin = !$local ? false : $profile->user->is_admin; + $acct = $local ? $profile->username : substr($profile->username, 1); + $username = $local ? $profile->username : explode('@', $acct)[0]; + return [ + 'id' => (string) $profile->id, + 'username' => $username, + 'acct' => $acct, + 'display_name' => $profile->name, + 'locked' => (bool) $profile->is_private, + 'followers_count' => $profile->followerCount(), + 'following_count' => $profile->followingCount(), + 'statuses_count' => (int) $profile->statusCount(), + 'note' => $profile->bio ?? '', + 'url' => $profile->url(), + 'avatar' => $profile->avatarUrl(), + 'website' => $profile->website, + 'local' => (bool) $local, + 'is_admin' => (bool) $is_admin, + 'created_at' => $profile->created_at->timestamp + ]; + } + + protected function includePosts(Profile $profile) + { + $posts = $profile + ->statuses() + ->whereIsNsfw(false) + ->whereType('photo') + ->whereScope('public') + ->whereNull('in_reply_to_id') + ->whereNull('reblog_of_id') + ->latest() + ->take(5) + ->get(); + + return $this->collection($posts, new StatusStatelessTransformer()); + } +} diff --git a/app/Transformer/Api/StatusStatelessTransformer.php b/app/Transformer/Api/StatusStatelessTransformer.php index 1b6cb4543..07eefb4a2 100644 --- a/app/Transformer/Api/StatusStatelessTransformer.php +++ b/app/Transformer/Api/StatusStatelessTransformer.php @@ -48,6 +48,7 @@ class StatusStatelessTransformer extends Fractal\TransformerAbstract 'thread' => false, 'replies' => [], 'parent' => $status->parent() ? $this->transform($status->parent()) : [], + 'local' => (bool) $status->local, ]; } diff --git a/public/css/app.css b/public/css/app.css index d8cb58e50..1b3866aca 100644 Binary files a/public/css/app.css and b/public/css/app.css differ diff --git a/public/css/appdark.css b/public/css/appdark.css index 2f5350bd5..ca0795d46 100644 Binary files a/public/css/appdark.css and b/public/css/appdark.css differ diff --git a/public/css/landing.css b/public/css/landing.css index 07dfc72ad..d7879c311 100644 Binary files a/public/css/landing.css and b/public/css/landing.css differ diff --git a/public/embed.js b/public/embed.js new file mode 100644 index 000000000..5acc20efe Binary files /dev/null and b/public/embed.js differ diff --git a/public/js/app.js b/public/js/app.js index 2b3436667..e04883334 100644 Binary files a/public/js/app.js and b/public/js/app.js differ diff --git a/public/js/compose.js b/public/js/compose.js index d35674ab8..760d06c34 100644 Binary files a/public/js/compose.js and b/public/js/compose.js differ diff --git a/public/js/discover.js b/public/js/discover.js index a483b7997..137739bf0 100644 Binary files a/public/js/discover.js and b/public/js/discover.js differ diff --git a/public/js/profile-directory.js b/public/js/profile-directory.js new file mode 100644 index 000000000..86a6766cc Binary files /dev/null and b/public/js/profile-directory.js differ diff --git a/public/js/quill.js b/public/js/quill.js index 67539e266..e926fa313 100644 Binary files a/public/js/quill.js and b/public/js/quill.js differ diff --git a/public/js/search.js b/public/js/search.js index f358e29f3..bda907926 100644 Binary files a/public/js/search.js and b/public/js/search.js differ diff --git a/public/js/status.js b/public/js/status.js index 6ebc771f4..cd4f8371d 100644 Binary files a/public/js/status.js and b/public/js/status.js differ diff --git a/public/js/theme-monokai.js b/public/js/theme-monokai.js index 9175ca7de..314581d0f 100644 Binary files a/public/js/theme-monokai.js and b/public/js/theme-monokai.js differ diff --git a/public/js/timeline.js b/public/js/timeline.js index 7f93fbc3b..f2f765a13 100644 Binary files a/public/js/timeline.js and b/public/js/timeline.js differ diff --git a/public/js/vendor.js b/public/js/vendor.js index e93e9f76d..7a39decc7 100644 Binary files a/public/js/vendor.js and b/public/js/vendor.js differ diff --git a/public/mix-manifest.json b/public/mix-manifest.json index 6d538d84b..07c138186 100644 Binary files a/public/mix-manifest.json and b/public/mix-manifest.json differ diff --git a/resources/assets/js/app.js b/resources/assets/js/app.js index d3f7d4ecc..e11123cc9 100644 --- a/resources/assets/js/app.js +++ b/resources/assets/js/app.js @@ -76,7 +76,21 @@ window.App.util = { ['Walden','filter-walden'], ['Willow','filter-willow'], ['X-Pro II','filter-xpro-ii'] - ], - emoji: ['๐Ÿ˜‚','๐Ÿ’ฏ','โค๏ธ','๐Ÿ™Œ','๐Ÿ‘','๐Ÿ‘Œ','๐Ÿ˜','๐Ÿ˜ฏ','๐Ÿ˜ข','๐Ÿ˜…','๐Ÿ˜','๐Ÿ™‚','๐Ÿ˜Ž','๐Ÿ˜€','๐Ÿคฃ','๐Ÿ˜ƒ','๐Ÿ˜„','๐Ÿ˜†','๐Ÿ˜‰','๐Ÿ˜Š','๐Ÿ˜‹','๐Ÿ˜˜','๐Ÿ˜—','๐Ÿ˜™','๐Ÿ˜š','๐Ÿค—','๐Ÿคฉ','๐Ÿค”','๐Ÿคจ','๐Ÿ˜','๐Ÿ˜‘','๐Ÿ˜ถ','๐Ÿ™„','๐Ÿ˜','๐Ÿ˜ฃ','๐Ÿ˜ฅ','๐Ÿ˜ฎ','๐Ÿค','๐Ÿ˜ช','๐Ÿ˜ซ','๐Ÿ˜ด','๐Ÿ˜Œ','๐Ÿ˜›','๐Ÿ˜œ','๐Ÿ˜','๐Ÿคค','๐Ÿ˜’','๐Ÿ˜“','๐Ÿ˜”','๐Ÿ˜•','๐Ÿ™ƒ','๐Ÿค‘','๐Ÿ˜ฒ','๐Ÿ™','๐Ÿ˜–','๐Ÿ˜ž','๐Ÿ˜Ÿ','๐Ÿ˜ค','๐Ÿ˜ญ','๐Ÿ˜ฆ','๐Ÿ˜ง','๐Ÿ˜จ','๐Ÿ˜ฉ','๐Ÿคฏ','๐Ÿ˜ฌ','๐Ÿ˜ฐ','๐Ÿ˜ฑ','๐Ÿ˜ณ','๐Ÿคช','๐Ÿ˜ต','๐Ÿ˜ก','๐Ÿ˜ ','๐Ÿคฌ','๐Ÿ˜ท','๐Ÿค’','๐Ÿค•','๐Ÿคข','๐Ÿคฎ','๐Ÿคง','๐Ÿ˜‡','๐Ÿค ','๐Ÿคก','๐Ÿคฅ','๐Ÿคซ','๐Ÿคญ','๐Ÿง','๐Ÿค“','๐Ÿ˜ˆ','๐Ÿ‘ฟ','๐Ÿ‘น','๐Ÿ‘บ','๐Ÿ’€','๐Ÿ‘ป','๐Ÿ‘ฝ','๐Ÿค–','๐Ÿ’ฉ','๐Ÿ˜บ','๐Ÿ˜ธ','๐Ÿ˜น','๐Ÿ˜ป','๐Ÿ˜ผ','๐Ÿ˜ฝ','๐Ÿ™€','๐Ÿ˜ฟ','๐Ÿ˜พ','๐Ÿคฒ','๐Ÿ‘','๐Ÿค','๐Ÿ‘','๐Ÿ‘Ž','๐Ÿ‘Š','โœŠ','๐Ÿค›','๐Ÿคœ','๐Ÿคž','โœŒ๏ธ','๐ŸคŸ','๐Ÿค˜','๐Ÿ‘ˆ','๐Ÿ‘‰','๐Ÿ‘†','๐Ÿ‘‡','โ˜๏ธ','โœ‹','๐Ÿคš','๐Ÿ–','๐Ÿ––','๐Ÿ‘‹','๐Ÿค™','๐Ÿ’ช','๐Ÿ–•','โœ๏ธ','๐Ÿ™','๐Ÿ’','๐Ÿ’„','๐Ÿ’‹','๐Ÿ‘„','๐Ÿ‘…','๐Ÿ‘‚','๐Ÿ‘ƒ','๐Ÿ‘ฃ','๐Ÿ‘','๐Ÿ‘€','๐Ÿง ','๐Ÿ—ฃ','๐Ÿ‘ค','๐Ÿ‘ฅ' - ], + ], + emoji: ['๐Ÿ˜‚','๐Ÿ’ฏ','โค๏ธ','๐Ÿ™Œ','๐Ÿ‘','๐Ÿ‘Œ','๐Ÿ˜','๐Ÿ˜ฏ','๐Ÿ˜ข','๐Ÿ˜…','๐Ÿ˜','๐Ÿ™‚','๐Ÿ˜Ž','๐Ÿ˜€','๐Ÿคฃ','๐Ÿ˜ƒ','๐Ÿ˜„','๐Ÿ˜†','๐Ÿ˜‰','๐Ÿ˜Š','๐Ÿ˜‹','๐Ÿ˜˜','๐Ÿ˜—','๐Ÿ˜™','๐Ÿ˜š','๐Ÿค—','๐Ÿคฉ','๐Ÿค”','๐Ÿคจ','๐Ÿ˜','๐Ÿ˜‘','๐Ÿ˜ถ','๐Ÿ™„','๐Ÿ˜','๐Ÿ˜ฃ','๐Ÿ˜ฅ','๐Ÿ˜ฎ','๐Ÿค','๐Ÿ˜ช','๐Ÿ˜ซ','๐Ÿ˜ด','๐Ÿ˜Œ','๐Ÿ˜›','๐Ÿ˜œ','๐Ÿ˜','๐Ÿคค','๐Ÿ˜’','๐Ÿ˜“','๐Ÿ˜”','๐Ÿ˜•','๐Ÿ™ƒ','๐Ÿค‘','๐Ÿ˜ฒ','๐Ÿ™','๐Ÿ˜–','๐Ÿ˜ž','๐Ÿ˜Ÿ','๐Ÿ˜ค','๐Ÿ˜ญ','๐Ÿ˜ฆ','๐Ÿ˜ง','๐Ÿ˜จ','๐Ÿ˜ฉ','๐Ÿคฏ','๐Ÿ˜ฌ','๐Ÿ˜ฐ','๐Ÿ˜ฑ','๐Ÿ˜ณ','๐Ÿคช','๐Ÿ˜ต','๐Ÿ˜ก','๐Ÿ˜ ','๐Ÿคฌ','๐Ÿ˜ท','๐Ÿค’','๐Ÿค•','๐Ÿคข','๐Ÿคฎ','๐Ÿคง','๐Ÿ˜‡','๐Ÿค ','๐Ÿคก','๐Ÿคฅ','๐Ÿคซ','๐Ÿคญ','๐Ÿง','๐Ÿค“','๐Ÿ˜ˆ','๐Ÿ‘ฟ','๐Ÿ‘น','๐Ÿ‘บ','๐Ÿ’€','๐Ÿ‘ป','๐Ÿ‘ฝ','๐Ÿค–','๐Ÿ’ฉ','๐Ÿ˜บ','๐Ÿ˜ธ','๐Ÿ˜น','๐Ÿ˜ป','๐Ÿ˜ผ','๐Ÿ˜ฝ','๐Ÿ™€','๐Ÿ˜ฟ','๐Ÿ˜พ','๐Ÿคฒ','๐Ÿ‘','๐Ÿค','๐Ÿ‘','๐Ÿ‘Ž','๐Ÿ‘Š','โœŠ','๐Ÿค›','๐Ÿคœ','๐Ÿคž','โœŒ๏ธ','๐ŸคŸ','๐Ÿค˜','๐Ÿ‘ˆ','๐Ÿ‘‰','๐Ÿ‘†','๐Ÿ‘‡','โ˜๏ธ','โœ‹','๐Ÿคš','๐Ÿ–','๐Ÿ––','๐Ÿ‘‹','๐Ÿค™','๐Ÿ’ช','๐Ÿ–•','โœ๏ธ','๐Ÿ™','๐Ÿ’','๐Ÿ’„','๐Ÿ’‹','๐Ÿ‘„','๐Ÿ‘…','๐Ÿ‘‚','๐Ÿ‘ƒ','๐Ÿ‘ฃ','๐Ÿ‘','๐Ÿ‘€','๐Ÿง ','๐Ÿ—ฃ','๐Ÿ‘ค','๐Ÿ‘ฅ' + ], + embed: { + post: (function(url, caption = true, likes = false, layout = 'full') { + let u = url + '/embed?'; + u += caption ? 'caption=true&' : 'caption=false&'; + u += likes ? 'likes=true&' : 'likes=false&'; + u += layout == 'compact' ? 'layout=compact' : 'layout=full'; + return ' diff --git a/resources/assets/js/components/DiscoverComponent.vue b/resources/assets/js/components/DiscoverComponent.vue index a22c3b0d3..172ee6b88 100644 --- a/resources/assets/js/components/DiscoverComponent.vue +++ b/resources/assets/js/components/DiscoverComponent.vue @@ -4,10 +4,10 @@
-
+ +
-
-
+ + @@ -351,7 +351,7 @@

@@ -547,6 +547,10 @@ .momentui .carousel-item { background: #000 !important; } + .reply-btn[disabled] { + opacity: .3; + color: #3897f0; + } \ No newline at end of file diff --git a/resources/assets/js/components/SearchResults.vue b/resources/assets/js/components/SearchResults.vue index 13b0e1421..add955a89 100644 --- a/resources/assets/js/components/SearchResults.vue +++ b/resources/assets/js/components/SearchResults.vue @@ -11,31 +11,31 @@