diff --git a/app/Http/Controllers/Api/TimelineController.php b/app/Http/Controllers/Api/TimelineController.php index 35a517d..e18add7 100644 --- a/app/Http/Controllers/Api/TimelineController.php +++ b/app/Http/Controllers/Api/TimelineController.php @@ -58,6 +58,14 @@ public function getIndex(Request $request) if ($item->imgs) { $item->imgs = TimelineImg::getImgs($item->imgs); } + })->reject(function($item){ + if (Auth::user()->check()) { + $user = Auth::user()->user(); + //remove blocked + $timelines = $timelines->reject(function($item)use($user){ + return $user->isBlocked($item->author->id); + }); + } })->toArray(); return $timelines; diff --git a/app/Http/Controllers/Api/UserController.php b/app/Http/Controllers/Api/UserController.php index 7b31c22..0d0a870 100644 --- a/app/Http/Controllers/Api/UserController.php +++ b/app/Http/Controllers/Api/UserController.php @@ -290,4 +290,200 @@ public function anyGetVerificationCode(Request $request) return ['get verification code successful']; } + + /** + * Get the user following list + * + * @return array of User model or failure info + */ + public function getFollowing(Request $request) + { + $user = User::findOrFail($request->input('id')); + return $user->following; + } + + /** + * Get the user's followers list + * + * @return array of User model or failure info + */ + public function getFollowers(Request $request) + { + $user = User::findOrFail($request->input('id')); + return $user->followers; + } + + /** + * Add a following relationship + * + * @param \Illuminate\Http\Request $request + * @return array of status model or failure info + */ + public function postFollowing(Request $request) + { + if (Auth::user()->check()) { + $user = Auth::user()->user(); + + if ($user->id == $request->input('toUserId')) { + $result = ['status' => 'cannot_follow_yourself']; + } else { + $exist = $user->following() + ->where('to_user_id', $request->input('toUserId')) + ->first(); + if (!$exist) { + $toUser = User::findOrFail($request->input('toUserId')); + $user->following()->attach($toUser); + $result = ['status' => 'success']; + } else { + $result = ['status' => 'has_been_following']; + } + } + return $result; + } else { + return ['status' => 'not_login']; + } + } + + /** + * Remove a following relationship + * + * @param \Illuminate\Http\Request $request + * @return array of status model or failure info + */ + public function postUnFollowing(Request $request) + { + if (Auth::user()->check()) { + $user = Auth::user()->user(); + + $exist = $user->following() + ->where('to_user_id', $request->input('toUserId')) + ->first(); + if (!$exist) { + $result = ['status' => 'success']; + } else { + $toUser = User::findOrFail($request->input('toUserId')); + $user->following()->detach($toUser); + $result = ['status' => 'success']; + } + + return $result; + } else { + return ['status' => 'not_login']; + } + } + + /** + * Is userId followed by current user. + * + * @param \Illuminate\Http\Request $request + * @return array of status or failure info + */ + public function postIsFollowed(Request $request) + { + if (Auth::user()->check()) { + $user = Auth::user()->user(); + if ($user->isFollowed($request->input('toUserId'))) { + return ['status' => 'success']; + } else { + return ['status' => 'failed']; + } + } else { + return ['status' => 'not_login']; + } + } + + /** + * Is userId blocked by current user. + * + * @param \Illuminate\Http\Request $request + * @return array of status or failure info + */ + public function postIsBlocked(Request $request) + { + if (Auth::user()->check()) { + $user = Auth::user()->user(); + if ($user->isBlocked($request->input('toUserId'))) { + return ['status' => 'success']; + } else { + return ['status' => 'failed']; + } + } else { + return ['status' => 'not_login']; + } + } + + /** + * Add a block user + * + * @param \Illuminate\Http\Request $request + * @return object User model or failure info + */ + public function postBlock(Request $request) + { + if (Auth::user()->check()) { + $user = Auth::user()->user(); + if ($user->id == $request->input('toUserId')) { + return ['status' => 'cannot_block_yourself']; + } + if ($user->toBlock($request->input('toUserId'))) { + return ['status' => 'success']; + } else { + return ['status' => 'failed']; + } + } else { + return ['status' => 'not_login']; + } + } + + /** + * unblock a user + * + * @param \Illuminate\Http\Request $request + * @return object User model or failure info + */ + public function postUnBlock(Request $request) + { + if (Auth::user()->check()) { + $user = Auth::user()->user(); + if ($user->unBlock($request->input('toUserId'))) { + return ['status' => 'success']; + } else { + return ['status' => 'failed']; + } + } else { + return ['status' => 'not_login']; + } + } + + /** + * get block list + * + * @return array of object User model or failure info + */ + public function getBlock() + { + if (Auth::user()->check()) { + $user = Auth::user()->user(); + $blockList = $user->getBlock(); + return $blockList; + } else { + return ['status' => 'not_login']; + } + } + + /** + * get block list + * + * @return array of relationship nums or failure info + */ + public function getRelationshipNums(Request $request) + { + $user = User::findOrFail($request->input('id')); + $result = [ + 'follower' => count($user->followers), + 'following' => count($user->following), + 'block' => count($user->getBlock()) + ]; + return $result; + } } diff --git a/app/Http/Controllers/TimelineController.php b/app/Http/Controllers/TimelineController.php index 63f30bd..4b692d7 100644 --- a/app/Http/Controllers/TimelineController.php +++ b/app/Http/Controllers/TimelineController.php @@ -30,9 +30,31 @@ public function __construct() public function getIndex() { $timelines = Timeline::latest()->paginate(); - $users = User::limit(5)->orderByRaw('RAND()')->get(); + if (Auth::user()->check()) { + $user = Auth::user()->user(); + //remove blocked + $timelines = $timelines->reject(function($item)use($user){ + return $user->isBlocked($item->author->id); + }); + //remove myself + $userModel = User::where('id', '!=', $user->id); + } else { + $userModel = User; + } + + $currentUser = isset($user) ? $user : null; + + $users = $userModel->limit(5) + ->orderByRaw('RAND()') + ->get(); + //remove blocked + if (Auth::user()->check()) { + $users = $users->reject(function($item)use($user){ + return $user->isBlocked($item->id); + }); + } - return view('timeline.index', compact('timelines', 'users')); + return view('timeline.index', compact('timelines', 'users', 'currentUser')); } /** diff --git a/app/User.php b/app/User.php index 2b415bc..fc2d8f1 100644 --- a/app/User.php +++ b/app/User.php @@ -64,6 +64,32 @@ public function timelineComments() return $this->hasMany('App\TimelineComment', 'user_id')->orderBy('created_at', 'desc')->with('author'); } + /** + * The user's following list + */ + public function following() + { + return $this->belongsToMany('App\User', 'user_relationship', 'from_user_id', 'to_user_id') + ->withTimestamps(); + } + + /** + * The user's follower list + */ + public function followers() + { + return $this->belongsToMany('App\User', 'user_relationship', 'to_user_id', 'from_user_id') + ->withTimestamps(); + } + + /** + * The user's relationship + */ + public function userRelationship() + { + return $this->hasMany('App\UserRelationship', 'from_user_id'); + } + /* * */ @@ -91,4 +117,81 @@ public function getAvatarAttribute($url) { return \App\Helpers\FileSystem::getFullUrl($url); } + + /** + * Is someone followed by current user? + * @param int $toUserId + */ + public function isFollowed($toUserId) + { + $relationship = $this->userRelationship() + ->where('to_user_id', $toUserId) + ->first(); + return $relationship ? true : false; + } + + /** + * Is someone blocked by current user? + * @param int $toUserId + */ + public function isBlocked($toUserId) + { + $relationship = $this->userRelationship() + ->where('to_user_id', $toUserId) + ->where('is_block', UserRelationship::BLOCKED) + ->first(); + return $relationship ? true : false; + } + + /** + * Block someone + * @param int $toUserId + */ + public function toBlock($toUserId) + { + $relationship = UserRelationship::where([ + 'from_user_id' => $this->id, + 'to_user_id' => $toUserId, + ]) + ->first(); + if (!$relationship) { + $relationship = new UserRelationship; + $relationship->from_user_id = $this->id; + $relationship->to_user_id = $toUserId; + $relationship->is_block = UserRelationship::BLOCKED; + } else { + $relationship->is_block = UserRelationship::BLOCKED; + } + return $relationship->save(); + } + + /** + * Unblock someone + * @param int $userId + */ + public function unBlock($userId) + { + $relationship = UserRelationship::where([ + 'from_user_id' => $this->id, + 'to_user_id' => $userId, + ]) + ->firstOrFail(); + $relationship->is_block = UserRelationship::UNBLOCKED; + return $relationship->save(); + } + + /** + * Get block list + */ + public function getBlock() + { + $relationship = $this->userRelationship() + ->where('from_user_id', $this->id) + ->where('is_block', UserRelationship::BLOCKED) + ->get(); + $relationship = $relationship->map(function($item){ + return $item->toUser; + }); + return $relationship; + } } diff --git a/app/UserRelationship.php b/app/UserRelationship.php new file mode 100644 index 0000000..ff78b8c --- /dev/null +++ b/app/UserRelationship.php @@ -0,0 +1,31 @@ +belongsTo('App\User', 'from_user_id'); + } + + public function toUser() + { + return $this->belongsTo('App\User', 'to_user_id'); + } +} diff --git a/database/migrations/2017_05_25_123818_create_user_relationship_table.php b/database/migrations/2017_05_25_123818_create_user_relationship_table.php new file mode 100644 index 0000000..c218ee3 --- /dev/null +++ b/database/migrations/2017_05_25_123818_create_user_relationship_table.php @@ -0,0 +1,42 @@ +increments('id'); + $table->integer('type')->unsigned()->nullable(); + $table->integer('from_user_id')->index()->unsigned(); + $table->integer('to_user_id')->index()->unsigned(); + $table->integer('is_block')->default(0); + $table->softDeletes(); + $table->timestamps(); + + $table->foreign('from_user_id')->references('id')->on('users'); + $table->foreign('to_user_id')->references('id')->on('users'); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::table('user_relationship', function (Blueprint $table) { + $table->dropForeign('user_relationship_from_user_id_foreign'); + $table->dropForeign('user_relationship_to_user_id_foreign'); + }); + Schema::drop('user_relationship'); + } +} diff --git a/public/bootstrap-assets/js/application.js b/public/bootstrap-assets/js/application.js index 34c97b2..c86cd63 100644 --- a/public/bootstrap-assets/js/application.js +++ b/public/bootstrap-assets/js/application.js @@ -183,4 +183,29 @@ $(function () { }, 1000) } } -}) +}); + +$(function(){ + $('.tofollow').on('click', function(e){ + var that = this; + $.post('/api/user/following', {toUserId: e.target.dataset.id}, function(res){ + if (res.status == 'success') { + $(that).addClass('hidden'); + $(that).next().removeClass('hidden'); + } else { + alert(res.status); + } + }, 'json'); + }); + $('.hasfollowed').on('click', function(e){ + var that = this; + $.post('/api/user/un-following', {toUserId: e.target.dataset.id}, function(res){ + if (res.status == 'success') { + $(that).addClass('hidden'); + $(that).prev().removeClass('hidden'); + } else { + alert(res.status); + } + }, 'json'); + }); +}); diff --git a/resources/lang/en/hc.php b/resources/lang/en/hc.php index 196aa2c..506067c 100644 --- a/resources/lang/en/hc.php +++ b/resources/lang/en/hc.php @@ -52,6 +52,10 @@ 'view all' => 'View all', 'follow' => 'Follow', 'recommended_follow_text' => 'These are active users in the community, recommend you pay attention to them', + 'has_been_following' => 'Has been following', + 'cancel_following' => 'Cancel following', + 'following' => 'Following', + 'followed' => 'Followed', // right bottom diff --git a/resources/lang/zh-CN/hc.php b/resources/lang/zh-CN/hc.php index c3d5bd4..808ede7 100644 --- a/resources/lang/zh-CN/hc.php +++ b/resources/lang/zh-CN/hc.php @@ -52,6 +52,10 @@ 'view all' => '查看所有', 'follow' => '关注', 'recommended_follow_text' => '这些都是社区里活跃的用户,推荐你关注他们', + 'has_been_following' => '已关注', + 'cancel_following' => '取消关注', + 'following' => '正在关注', + 'followed' => '关注者', // right bottom diff --git a/resources/views/timeline/index.blade.php b/resources/views/timeline/index.blade.php index a87926f..c8caec0 100644 --- a/resources/views/timeline/index.blade.php +++ b/resources/views/timeline/index.blade.php @@ -116,7 +116,8 @@ @if ($timeline->comments) @endif @@ -170,8 +172,12 @@
{{ $user->nickname }}
- + +