1
0
Эх сурвалжийг харах

Merge pull request #186 from dansup/frontend-ui-refactor

Fix like/comment forms
daniel 7 жил өмнө
parent
commit
357382ba6c

+ 32 - 0
app/Http/Controllers/ApiController.php

@@ -0,0 +1,32 @@
+<?php
+
+namespace App\Http\Controllers;
+
+use Auth;
+use App\Like;
+use Illuminate\Http\Request;
+
+class ApiController extends Controller
+{
+    public function __construct()
+    {
+        $this->middleware('auth');
+    }
+
+    public function hydrateLikes(Request $request)
+    {
+        $this->validate($request, [
+            'min' => 'nullable|integer|min:1',
+            'max' => 'nullable|integer',
+        ]);
+
+        $profile = Auth::user()->profile;
+
+        $likes = Like::whereProfileId($profile->id)
+                 ->orderBy('id', 'desc')
+                 ->take(100)
+                 ->pluck('status_id');
+                 
+        return response()->json($likes);
+    }
+}

+ 9 - 1
app/Http/Controllers/CommentController.php

@@ -9,6 +9,14 @@ use App\{Comment, Profile, Status};
 
 class CommentController extends Controller
 {
+
+    public function show(Request $request, $username, int $id)
+    {
+      $user = Profile::whereUsername($username)->firstOrFail();
+      $status = Status::whereProfileId($user->id)->whereNotNull('in_reply_to_id')->findOrFail($id);
+      return view('status.reply', compact('user', 'status'));
+    }
+
     public function store(Request $request)
     {
       if(Auth::check() === false) { abort(403); }
@@ -34,7 +42,7 @@ class CommentController extends Controller
       NewStatusPipeline::dispatch($reply, false);
 
       if($request->ajax()) {
-        $response = ['code' => 200, 'msg' => 'Comment saved'];
+        $response = ['code' => 200, 'msg' => 'Comment saved', 'username' => $profile->username, 'url' => $reply->url(), 'profile' => $profile->url()];
       } else {
         $response = redirect($status->url());
       }

+ 3 - 1
app/Http/Controllers/StatusController.php

@@ -13,7 +13,9 @@ class StatusController extends Controller
     public function show(Request $request, $username, int $id)
     {
       $user = Profile::whereUsername($username)->firstOrFail();
-      $status = Status::whereProfileId($user->id)->findOrFail($id);
+      $status = Status::whereProfileId($user->id)
+              ->withCount('likes')
+              ->findOrFail($id);
       if(!$status->media_path && $status->in_reply_to_id) {
         return view('status.reply', compact('user', 'status'));
       }

+ 11 - 2
app/Http/Controllers/TimelineController.php

@@ -17,14 +17,23 @@ class TimelineController extends Controller
     {
       // TODO: Use redis for timelines
       $following = Follower::whereProfileId(Auth::user()->profile->id)->pluck('following_id');
-      $timeline = Status::whereHas('media')->whereNull('in_reply_to_id')->whereIn('profile_id', $following)->orderBy('id','desc')->simplePaginate(10);
+      $timeline = Status::whereHas('media')
+                  ->whereNull('in_reply_to_id')
+                  ->whereIn('profile_id', $following)
+                  ->orderBy('id','desc')
+                  ->withCount(['comments', 'likes'])
+                  ->simplePaginate(10);
       return view('timeline.personal', compact('timeline'));
     }
 
     public function local()
     {
       // TODO: Use redis for timelines
-      $timeline = Status::whereHas('media')->whereNull('in_reply_to_id')->orderBy('id','desc')->simplePaginate(10);
+      $timeline = Status::whereHas('media')
+                  ->whereNull('in_reply_to_id')
+                  ->orderBy('id','desc')
+                  ->withCount(['comments', 'likes'])
+                  ->simplePaginate(10);
       return view('timeline.public', compact('timeline'));
     }
 

BIN
public/css/app.css


BIN
public/js/app.js


BIN
public/mix-manifest.json


+ 3 - 2
resources/assets/js/bootstrap.js

@@ -16,9 +16,10 @@ try {
     window.typeahead = require('./lib/typeahead');
     window.Bloodhound = require('./lib/bloodhound');
 
+    require('./lib/fontawesome-all');
     require('./components/localstorage');
-    //require('./components/likebutton');
-    //require('./components/commentform');
+    require('./components/likebutton');
+    require('./components/commentform');
     require('./components/searchform');
     require('./components/bookmarkform');
 } catch (e) {}

+ 28 - 9
resources/assets/js/components/commentform.js

@@ -1,5 +1,10 @@
 $(document).ready(function() {
 
+  $('.status-comment-focus').on('click', function(el) {
+    var el = $(this).parents().eq(2).find('input[name="comment"]');
+    el.focus();
+  });
+
   $('.comment-form').submit(function(e, data) {
     e.preventDefault();
 
@@ -8,18 +13,32 @@ $(document).ready(function() {
     let commentform = el.find('input[name="comment"]');
     let commenttext = commentform.val();
     let item = {item: id, comment: commenttext};
-    try {
-      axios.post('/i/comment', item);
-      var comments = el.parent().parent().find('.comments');
-      var comment = '<p class="mb-0"><span class="font-weight-bold pr-1">' + pixelfed.user.username + '</span><span class="comment-text">'+ commenttext + '</span></p>';
-      comments.prepend(comment);
 
+    axios.post('/i/comment', item)
+    .then(function (res) {
+
+      var username = res.data.username;
+      var permalink = res.data.url;
+      var profile = res.data.profile;
+
+      if($('.status-container').length == 1) {
+        var comments = el.parents().eq(3).find('.comments');
+      } else {
+        var comments = el.parents().eq(2).find('.comments');
+      }
+
+      var comment = '<p class="mb-0"><span class="font-weight-bold pr-1"><bdi><a class="text-dark" href="' + profile + '">' + username + '</a></bdi></span><span class="comment-text">'+ commenttext + '</span><span class="float-right"><a href="' + permalink + '" class="text-dark small font-weight-bold">1s</a></span></p>';
+
+      comments.prepend(comment);
+      
       commentform.val('');
       commentform.blur();
-      return true;
-    } catch(e) {
-      return false;
-    }
+
+    })
+    .catch(function (res) {
+      
+    });
+ 
   });
 
 });

+ 34 - 4
resources/assets/js/components/likebutton.js

@@ -1,6 +1,29 @@
 $(document).ready(function() {
+
   if(!ls.get('likes')) {
-    ls.set('likes', []);
+    axios.get('/api/v1/likes')
+    .then(function (res) {
+      ls.set('likes', res.data);
+      console.log(res);
+    })
+    .catch(function (res) {
+      ls.set('likes', []);
+    })
+  }
+
+  hydrateLikes();
+
+  function hydrateLikes() {
+    var likes = ls.get('likes');
+    $('.like-form').each(function(i, el) {
+      var el = $(el);
+      var id = el.data('id');
+      var heart = el.find('.status-heart');
+
+      if(likes.indexOf(id) != -1) {
+        heart.addClass('fas fa-heart').removeClass('far fa-heart');
+      }
+    });
   }
 
   $('.like-form').submit(function(e) {
@@ -10,19 +33,26 @@ $(document).ready(function() {
     var res = axios.post('/i/like', {item: id});
     var likes = ls.get('likes');
     var action = false;
-    var counter = el.parent().parent().find('.like-count');
+    var counter = el.parents().eq(2).find('.like-count');
     var count = parseInt(counter.text());
+    var heart = el.find('.status-heart');
+
     if(likes.indexOf(id) > -1) {
-      likes.splice(id, 1);
-      count--;
+      heart.addClass('far fa-heart').removeClass('fas fa-heart');
+      likes = likes.filter(function(item) { 
+          return item !== id
+      });
+      count = count == 0 ? 0 : count--;
       counter.text(count);
       action = 'unlike';
     } else {
+      heart.addClass('fas fa-heart').removeClass('far fa-heart');
       likes.push(id);
       count++;
       counter.text(count);
       action = 'like';
     }
+
     ls.set('likes', likes);
     console.log(action + ' - ' + $(this).data('id') + ' like event');
   });

Файлын зөрүү хэтэрхий том тул дарагдсан байна
+ 124 - 0
resources/assets/js/lib/fontawesome-all.js


+ 1 - 0
resources/assets/sass/app.scss

@@ -1,6 +1,7 @@
 
 // Fonts
 @import "fonts";
+@import "lib/fontawesome";
 
 // Variables
 @import "variables";

+ 16 - 23
resources/assets/sass/custom.scss

@@ -56,37 +56,14 @@ body, button, input, textarea {
 }
 
 .card.status-container .status-photo {
-  display: block !important;
   margin: auto !important;
 }
 
 .card.status-container .status-comments {
-  height: 220px;
   overflow-y: scroll;
   border-bottom:1px solid rgba(0, 0, 0, 0.1);
 }
 
-.card.status-container.orientation-square .status-comments {
-  height: 360px !important;
-}
-
-
-.card.status-container.orientation-portrait .status-comments {
-  height: 528px !important;
-}
-
-.card.status-container.orientation-landscape .status-photo img {
-  max-height: 451px !important;
-}
-
-.card.status-container.orientation-square .status-photo img {
-  max-height: 601px !important;
-}
-
-.card.status-container.orientation-portrait .status-photo img {
-  max-height: 772px !important;
-}
-
 .no-caret.dropdown-toggle {
   text-decoration: none !important;
 }
@@ -173,3 +150,19 @@ body, button, input, textarea {
     background-size: cover;
     background-position: 50%;
 }
+
+.fas, .far {
+  font-size: 25px !important;
+}
+
+
+.far.fa-heart {
+  color: #343a40;
+}
+
+.svg-inline--fa.fa-heart.fa-w-16.status-heart.fa-2x {
+  color: #f70ec4;
+}
+
+.fas.fa-heart {
+}

+ 345 - 0
resources/assets/sass/lib/fontawesome.scss

@@ -0,0 +1,345 @@
+/*!
+ * Font Awesome Free 5.0.13 by @fontawesome - https://fontawesome.com
+ * License - https://fontawesome.com/license (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License)
+ */
+svg:not(:root).svg-inline--fa {
+  overflow: visible; }
+
+.svg-inline--fa {
+  display: inline-block;
+  font-size: inherit;
+  height: 1em;
+  overflow: visible;
+  vertical-align: -.125em; }
+  .svg-inline--fa.fa-lg {
+    vertical-align: -.225em; }
+  .svg-inline--fa.fa-w-1 {
+    width: 0.0625em; }
+  .svg-inline--fa.fa-w-2 {
+    width: 0.125em; }
+  .svg-inline--fa.fa-w-3 {
+    width: 0.1875em; }
+  .svg-inline--fa.fa-w-4 {
+    width: 0.25em; }
+  .svg-inline--fa.fa-w-5 {
+    width: 0.3125em; }
+  .svg-inline--fa.fa-w-6 {
+    width: 0.375em; }
+  .svg-inline--fa.fa-w-7 {
+    width: 0.4375em; }
+  .svg-inline--fa.fa-w-8 {
+    width: 0.5em; }
+  .svg-inline--fa.fa-w-9 {
+    width: 0.5625em; }
+  .svg-inline--fa.fa-w-10 {
+    width: 0.625em; }
+  .svg-inline--fa.fa-w-11 {
+    width: 0.6875em; }
+  .svg-inline--fa.fa-w-12 {
+    width: 0.75em; }
+  .svg-inline--fa.fa-w-13 {
+    width: 0.8125em; }
+  .svg-inline--fa.fa-w-14 {
+    width: 0.875em; }
+  .svg-inline--fa.fa-w-15 {
+    width: 0.9375em; }
+  .svg-inline--fa.fa-w-16 {
+    width: 1em; }
+  .svg-inline--fa.fa-w-17 {
+    width: 1.0625em; }
+  .svg-inline--fa.fa-w-18 {
+    width: 1.125em; }
+  .svg-inline--fa.fa-w-19 {
+    width: 1.1875em; }
+  .svg-inline--fa.fa-w-20 {
+    width: 1.25em; }
+  .svg-inline--fa.fa-pull-left {
+    margin-right: .3em;
+    width: auto; }
+  .svg-inline--fa.fa-pull-right {
+    margin-left: .3em;
+    width: auto; }
+  .svg-inline--fa.fa-border {
+    height: 1.5em; }
+  .svg-inline--fa.fa-li {
+    width: 2em; }
+  .svg-inline--fa.fa-fw {
+    width: 1.25em; }
+
+.fa-layers svg.svg-inline--fa {
+  bottom: 0;
+  left: 0;
+  margin: auto;
+  position: absolute;
+  right: 0;
+  top: 0; }
+
+.fa-layers {
+  display: inline-block;
+  height: 1em;
+  position: relative;
+  text-align: center;
+  vertical-align: -.125em;
+  width: 1em; }
+  .fa-layers svg.svg-inline--fa {
+    -webkit-transform-origin: center center;
+            transform-origin: center center; }
+
+.fa-layers-text, .fa-layers-counter {
+  display: inline-block;
+  position: absolute;
+  text-align: center; }
+
+.fa-layers-text {
+  left: 50%;
+  top: 50%;
+  -webkit-transform: translate(-50%, -50%);
+          transform: translate(-50%, -50%);
+  -webkit-transform-origin: center center;
+          transform-origin: center center; }
+
+.fa-layers-counter {
+  background-color: #ff253a;
+  border-radius: 1em;
+  -webkit-box-sizing: border-box;
+          box-sizing: border-box;
+  color: #fff;
+  height: 1.5em;
+  line-height: 1;
+  max-width: 5em;
+  min-width: 1.5em;
+  overflow: hidden;
+  padding: .25em;
+  right: 0;
+  text-overflow: ellipsis;
+  top: 0;
+  -webkit-transform: scale(0.25);
+          transform: scale(0.25);
+  -webkit-transform-origin: top right;
+          transform-origin: top right; }
+
+.fa-layers-bottom-right {
+  bottom: 0;
+  right: 0;
+  top: auto;
+  -webkit-transform: scale(0.25);
+          transform: scale(0.25);
+  -webkit-transform-origin: bottom right;
+          transform-origin: bottom right; }
+
+.fa-layers-bottom-left {
+  bottom: 0;
+  left: 0;
+  right: auto;
+  top: auto;
+  -webkit-transform: scale(0.25);
+          transform: scale(0.25);
+  -webkit-transform-origin: bottom left;
+          transform-origin: bottom left; }
+
+.fa-layers-top-right {
+  right: 0;
+  top: 0;
+  -webkit-transform: scale(0.25);
+          transform: scale(0.25);
+  -webkit-transform-origin: top right;
+          transform-origin: top right; }
+
+.fa-layers-top-left {
+  left: 0;
+  right: auto;
+  top: 0;
+  -webkit-transform: scale(0.25);
+          transform: scale(0.25);
+  -webkit-transform-origin: top left;
+          transform-origin: top left; }
+
+.fa-lg {
+  font-size: 1.33333em;
+  line-height: 0.75em;
+  vertical-align: -.0667em; }
+
+.fa-xs {
+  font-size: .75em; }
+
+.fa-sm {
+  font-size: .875em; }
+
+.fa-1x {
+  font-size: 1em; }
+
+.fa-2x {
+  font-size: 2em; }
+
+.fa-3x {
+  font-size: 3em; }
+
+.fa-4x {
+  font-size: 4em; }
+
+.fa-5x {
+  font-size: 5em; }
+
+.fa-6x {
+  font-size: 6em; }
+
+.fa-7x {
+  font-size: 7em; }
+
+.fa-8x {
+  font-size: 8em; }
+
+.fa-9x {
+  font-size: 9em; }
+
+.fa-10x {
+  font-size: 10em; }
+
+.fa-fw {
+  text-align: center;
+  width: 1.25em; }
+
+.fa-ul {
+  list-style-type: none;
+  margin-left: 2.5em;
+  padding-left: 0; }
+  .fa-ul > li {
+    position: relative; }
+
+.fa-li {
+  left: -2em;
+  position: absolute;
+  text-align: center;
+  width: 2em;
+  line-height: inherit; }
+
+.fa-border {
+  border: solid 0.08em #eee;
+  border-radius: .1em;
+  padding: .2em .25em .15em; }
+
+.fa-pull-left {
+  float: left; }
+
+.fa-pull-right {
+  float: right; }
+
+.fa.fa-pull-left,
+.fas.fa-pull-left,
+.far.fa-pull-left,
+.fal.fa-pull-left,
+.fab.fa-pull-left {
+  margin-right: .3em; }
+
+.fa.fa-pull-right,
+.fas.fa-pull-right,
+.far.fa-pull-right,
+.fal.fa-pull-right,
+.fab.fa-pull-right {
+  margin-left: .3em; }
+
+.fa-spin {
+  -webkit-animation: fa-spin 2s infinite linear;
+          animation: fa-spin 2s infinite linear; }
+
+.fa-pulse {
+  -webkit-animation: fa-spin 1s infinite steps(8);
+          animation: fa-spin 1s infinite steps(8); }
+
+@-webkit-keyframes fa-spin {
+  0% {
+    -webkit-transform: rotate(0deg);
+            transform: rotate(0deg); }
+  100% {
+    -webkit-transform: rotate(360deg);
+            transform: rotate(360deg); } }
+
+@keyframes fa-spin {
+  0% {
+    -webkit-transform: rotate(0deg);
+            transform: rotate(0deg); }
+  100% {
+    -webkit-transform: rotate(360deg);
+            transform: rotate(360deg); } }
+
+.fa-rotate-90 {
+  -ms-filter: "progid:DXImageTransform.Microsoft.BasicImage(rotation=1)";
+  -webkit-transform: rotate(90deg);
+          transform: rotate(90deg); }
+
+.fa-rotate-180 {
+  -ms-filter: "progid:DXImageTransform.Microsoft.BasicImage(rotation=2)";
+  -webkit-transform: rotate(180deg);
+          transform: rotate(180deg); }
+
+.fa-rotate-270 {
+  -ms-filter: "progid:DXImageTransform.Microsoft.BasicImage(rotation=3)";
+  -webkit-transform: rotate(270deg);
+          transform: rotate(270deg); }
+
+.fa-flip-horizontal {
+  -ms-filter: "progid:DXImageTransform.Microsoft.BasicImage(rotation=0, mirror=1)";
+  -webkit-transform: scale(-1, 1);
+          transform: scale(-1, 1); }
+
+.fa-flip-vertical {
+  -ms-filter: "progid:DXImageTransform.Microsoft.BasicImage(rotation=2, mirror=1)";
+  -webkit-transform: scale(1, -1);
+          transform: scale(1, -1); }
+
+.fa-flip-horizontal.fa-flip-vertical {
+  -ms-filter: "progid:DXImageTransform.Microsoft.BasicImage(rotation=2, mirror=1)";
+  -webkit-transform: scale(-1, -1);
+          transform: scale(-1, -1); }
+
+:root .fa-rotate-90,
+:root .fa-rotate-180,
+:root .fa-rotate-270,
+:root .fa-flip-horizontal,
+:root .fa-flip-vertical {
+  -webkit-filter: none;
+          filter: none; }
+
+.fa-stack {
+  display: inline-block;
+  height: 2em;
+  position: relative;
+  width: 2em; }
+
+.fa-stack-1x,
+.fa-stack-2x {
+  bottom: 0;
+  left: 0;
+  margin: auto;
+  position: absolute;
+  right: 0;
+  top: 0; }
+
+.svg-inline--fa.fa-stack-1x {
+  height: 1em;
+  width: 1em; }
+
+.svg-inline--fa.fa-stack-2x {
+  height: 2em;
+  width: 2em; }
+
+.fa-inverse {
+  color: #fff; }
+
+.sr-only {
+  border: 0;
+  clip: rect(0, 0, 0, 0);
+  height: 1px;
+  margin: -1px;
+  overflow: hidden;
+  padding: 0;
+  position: absolute;
+  width: 1px; }
+
+.sr-only-focusable:active, .sr-only-focusable:focus {
+  clip: auto;
+  height: auto;
+  margin: 0;
+  overflow: visible;
+  position: static;
+  width: auto; }

+ 4 - 4
resources/views/layouts/partial/footer.blade.php

@@ -1,6 +1,6 @@
-  <footer class="pt-5 mt-5">
-    <div class="container mt-5 pt-5">
-        <p class="mt-5 text-uppercase font-weight-bold small">
+  <footer>
+    <div class="container mt-5">
+        <p class="text-uppercase font-weight-bold small">
           <a href="{{route('site.about')}}" class="text-primary pr-2">About Us</a>
           <a href="{{route('site.help')}}" class="text-primary pr-2">Support</a>
           <a href="" class="text-primary pr-2">API</a>
@@ -14,4 +14,4 @@
           <a href="#" class="text-dark float-right">© {{date('Y')}} PixelFed.org</a>
         </p>
     </div>
-  </footer>
+  </footer>

+ 1 - 1
resources/views/profile/followers.blade.php

@@ -42,7 +42,7 @@
     </div>
   </div>
 
-  <div class="col-12 col-md-8 offset-2">
+  <div class="col-12 col-md-8 offset-md-2">
     @if($followers->count() !== 0)
     <ul class="list-group mt-4">
       @foreach($followers as $user)

+ 1 - 1
resources/views/profile/following.blade.php

@@ -42,7 +42,7 @@
     </div>
   </div>
 
-  <div class="col-12 col-md-8 offset-2">
+  <div class="col-12 col-md-8 offset-md-2">
     @if($following->count() !== 0)
     <ul class="list-group mt-4">
       @foreach($following as $user)

+ 12 - 6
resources/views/status/show.blade.php

@@ -19,7 +19,7 @@
             </div>
           </div>
           <div class="timestamp mb-0">
-            <p class="small text-uppercase mb-0"><a href="{{$status->url()}}" class="text-muted">{{$status->created_at->diffForHumans()}}</a></p>
+            <p class="small text-uppercase mb-0"><a href="{{$status->url()}}" class="text-muted">{{$status->created_at->diffForHumans(null, true, true, true)}}</a></p>
           </div>
         </div>
         <div class="card-body status-comments">
@@ -43,16 +43,20 @@
             <form class="d-inline-flex like-form pr-3" method="post" action="/i/like" style="display: inline;" data-id="{{$status->id}}" data-action="like">
               @csrf
               <input type="hidden" name="item" value="{{$status->id}}">
-              <button class="btn btn-link text-dark p-0" type="submit"><h3 class="icon-heart mb-0"></h3></button>
+              <button class="btn btn-link text-dark p-0" type="submit">
+                <span class="far fa-heart fa-lg mb-0"></span>
+              </button>
             </form>
-            <span class="icon-speech pr-3"></span>
+            <span class="far fa-comment fa-lg pt-1 pr-3"></span>
             @if(Auth::check())
             @if(Auth::user()->profile->id === $status->profile->id || Auth::user()->is_admin == true)
             <form method="post" action="/i/delete" class="d-inline-flex">
               @csrf
               <input type="hidden" name="type" value="post">
               <input type="hidden" name="item" value="{{$status->id}}">
-              <button type="submit" class="btn btn-link text-dark p-0"><h3 class="icon-trash mb-0"></h3></button>
+              <button type="submit" class="btn btn-link text-dark p-0">
+                <span class="far fa-trash-alt fa-lg mb-0"></span>
+              </button>
             </form>
             @endif
             @endif
@@ -60,12 +64,14 @@
               <form class="d-inline-flex bookmark-form" method="post" action="/i/bookmark" style="display: inline;" data-id="{{$status->id}}" data-action="bookmark">
                 @csrf
                 <input type="hidden" name="item" value="{{$status->id}}">
-                <button class="btn btn-link text-dark p-0" type="submit"><h3 class="icon-notebook mb-0"></h3></button>
+                <button class="btn btn-link text-dark p-0" type="submit">
+                  <span class="far fa-bookmark fa-lg mb-0"></span>
+                </button>
               </form>
             </span>
           </div>
           <div class="likes font-weight-bold mb-0">
-            <span class="like-count">{{$status->likes()->count()}}</span> likes
+            <span class="like-count" data-count="{{$status->likes_count}}">{{$status->likes_count}}</span> likes
           </div>
         </div>
         <div class="card-footer">

+ 8 - 6
resources/views/status/template.blade.php

@@ -33,22 +33,24 @@
         </a>
         <div class="card-body">
           <div class="reactions h3">
-            <form class="like-form pr-3" method="post" action="/i/like" style="display: inline;" data-id="{{$item->id}}" data-action="like">
+            <form class="like-form pr-3" method="post" action="/i/like" style="display: inline;" data-id="{{$item->id}}" data-action="like" data-count="{{$item->likes_count}}">
               @csrf
               <input type="hidden" name="item" value="{{$item->id}}">
-              <button class="btn btn-link text-dark p-0" type="submit"><span class="icon-heart" style="font-size:25px;"></span></button>
+              <button class="btn btn-link text-dark p-0" type="submit">
+                <span class="far fa-heart status-heart fa-2x"></span>
+              </button>
             </form>
-            <span class="icon-speech"></span>
+            <span class="far fa-comment status-comment-focus"></span>
             <span class="float-right">
               <form class="bookmark-form" method="post" action="/i/bookmark" style="display: inline;" data-id="{{$item->id}}" data-action="bookmark">
                 @csrf
                 <input type="hidden" name="item" value="{{$item->id}}">
-                <button class="btn btn-link text-dark p-0" type="submit"><span class="icon-notebook" style="font-size:25px;"></span></button>
+                <button class="btn btn-link text-dark p-0" type="submit"><span class="far fa-bookmark" style="font-size:25px;"></span></button>
               </form>
             </span>
           </div>
           <div class="likes font-weight-bold">
-            <span class="like-count">{{$item->likes()->count()}}</span> likes
+            <span class="like-count">{{$item->likes_count}}</span> likes
           </div>
           <div class="caption">
             <p class="mb-1">
@@ -95,7 +97,7 @@
           <form class="comment-form" method="post" action="/i/comment" data-id="{{$item->id}}" data-truncate="true">
             @csrf
             <input type="hidden" name="item" value="{{$item->id}}">
-            <input class="form-control" name="comment" placeholder="Add a comment...">
+            <input class="form-control status-reply-input" name="comment" placeholder="Add a comment...">
           </form>
         </div>
       </div>

+ 1 - 0
routes/web.php

@@ -47,6 +47,7 @@ Route::domain(config('pixelfed.domain.app'))->group(function() {
     Route::get('search/{tag}', 'SearchController@searchAPI')
           ->where('tag', '[A-Za-z0-9]+');
     Route::get('nodeinfo/2.0.json', 'FederationController@nodeinfo');
+    Route::get('v1/likes', 'ApiController@hydrateLikes');
   });
 
   Route::get('discover/tags/{hashtag}', 'DiscoverController@showTags');

Энэ ялгаанд хэт олон файл өөрчлөгдсөн тул зарим файлыг харуулаагүй болно