This commit is contained in:
Thomas G 2022-07-24 17:32:10 +10:00
commit 93d63df2d8
15 changed files with 573 additions and 10 deletions

View File

@ -0,0 +1,175 @@
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Multicaret\Acquaintances\Traits\Friendable;
use App\Models\Message;
use App\Models\User;
class MessageController extends Controller
{
public function inbox()
{
$messages = Message::where('sendto_id', Auth::id())->where('deleted', false)->orderBy('id', 'desc')->paginate(10);
return view('messages.index')->with('messages', $messages);
}
public function inbox_sent()
{
$messages = Message::where('user_id', Auth::id())->orderBy('id', 'desc')->paginate(10);
return view('messages.sent')->with('messages', $messages);
}
public function deleted()
{
$messages = Message::where('sendto_id', Auth::id())->where('deleted', true)->orderBy('id', 'desc')->paginate(10);
return view('messages.deleted')->with('messages', $messages);
}
public function compose()
{
return view('messages.create');
}
public function delete_all()
{
$messages = Message::where('sendto_id', Auth::id())->where('deleted', false)->get();
if ($messages->isEmpty()){
return redirect()->back()->withErrors(['You have no messages!']);
}
foreach ($messages as $message) {
$message->deleted = true;
$message->save();
}
return redirect('/my/messages')->with('success', 'All your messages have been deleted.');
}
public function recover_all()
{
$messages = Message::where('sendto_id', Auth::id())->where('deleted', true)->get();
if ($messages->isEmpty()){
return redirect()->back()->withErrors(['You have no deleted messages!']);
}
foreach ($messages as $message) {
$message->deleted = false;
$message->save();
}
return redirect('/my/messages')->with('success', 'All your messages have been recovered.');
}
public function content($id)
{
$message = Message::where('id', $id)->first();
$valid = false;
if (!$message) {
abort(404);
}
if ($message->sendto_id == Auth::id() || $message->user_id == Auth::id()) {
$valid = true;
}
if ($valid) {
if (!$message->read && $message->sendto_id == Auth::id()) {
$message->read = true;
$message->save();
}
}
if ($valid) {
return view('messages.content')->with('message', $message);
} else {
abort(404);
}
}
public function send_message(Request $request)
{
$request->validate([
'name' => ['required', 'string', 'exists:users'],
'subject' => ['required', 'string', 'min:3', 'max:50'],
'message' => ['required', 'string', 'min:3', 'max:10000'],
]);
$userToFind = User::where('name', $request->name)->first();
$messageable = true;
$errorMsg = array();
if (Auth::id() == $userToFind->id) {
return redirect()->back()->withErrors(['You cannot message yourself!']);
}
switch ($userToFind->settings->message_preference) {
case 2:
$messageable = true;
break;
case 1:
if (!Auth::user()->isFriendWith($userToFind)) {
$messageable = false;
$errorMsg = ["You must be friends with " . $userToFind->name . " to message them."];
}
break;
default:
$messageable = false;
$errorMsg = ["This user has disabled messaging."];
}
if (!$messageable) {
return redirect()->back()->withErrors($errorMsg);
}
$msg = new Message;
$msg->user_id = Auth::id();
$msg->sendto_id = $userToFind->id;
$msg->subject = $request->subject;
$msg->content = $request->message;
$msg->save();
return redirect('/my/messages/sent')->with('success', 'Message sent.');
}
public function delete_message($id)
{
$message = Message::where('id', $id)->first();
$valid = false;
if (!$message) {
abort(404);
}
if (Auth::id() == $message->sendto_id) {
$valid = true;
}
if ($valid) {
$successMsg = "";
$deletedStatus = false;
if (!$message->deleted) {
$deletedStatus = true;
$successMsg = "Message deleted.";
} else {
$deletedStatus = false;
$successMsg = "Message recovered.";
}
$message->deleted = $deletedStatus;
$message->save();
return redirect('/my/messages')->with('success', $successMsg);
} else {
abort(404);
}
}
}

View File

@ -97,6 +97,16 @@ class SettingController extends Controller
$changeMsg = "Your time display preference has been changed.";
break;
case 7:
$request->validate([
'message_preference' => ['required', 'string', 'in:2,1,0'],
]);
$userSetting->message_preference = $request->message_preference;
$userSetting->save();
$changeMsg = "Your message privacy preference has been changed.";
break;
default:
abort(404);
}

33
app/Models/Message.php Normal file
View File

@ -0,0 +1,33 @@
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class Message extends Model
{
use HasFactory;
protected $table = 'messages';
public $primaryKey = 'id';
public $timestamps = true;
/**
* The attributes that are mass assignable.
*
* @var array<int, string>
*/
protected $fillable = [
'user_id',
'sendto_id',
'subject',
'content',
'read',
];
public function user()
{
return $this->belongsTo('App\Models\User');
}
}

View File

@ -66,6 +66,11 @@ class User extends Authenticatable
return $this->hasMany('App\Models\FeedPost');
}
public function messages()
{
return $this->hasMany('App\Models\Message');
}
public function settings()
{
return $this->hasOne('App\Models\UserSetting');

View File

@ -0,0 +1,37 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class CreateMessagesTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('messages', function (Blueprint $table) {
$table->id();
$table->integer('user_id');
$table->integer('sendto_id');
$table->string('subject');
$table->string('content', 10000);
$table->boolean('read')->default(false);
$table->boolean('deleted')->default(false);
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists('messages');
}
}

View File

@ -52,6 +52,14 @@ function openPopup(id) {
document.querySelector('.popup .warningtext').innerHTML = null;
document.querySelector('.popup #desc').innerHTML = "Choose whether 12 hour or 24 hour time is displayed on the site.";
break;
case 7:
active = 7;
setActiveSetting(7);
document.querySelector('.popup .message_change').removeAttribute('id');
document.querySelector('.popup #heading').innerHTML = "Change Message Privacy";
document.querySelector('.popup .warningtext').innerHTML = null;
document.querySelector('.popup #desc').innerHTML = "Choose who can send you messages on the website.";
break;
default:
console.error('Invalid setting.');
}
@ -78,6 +86,9 @@ function closePopup() {
case 6:
document.querySelector('.popup .time_change').setAttribute("id", "invisible");
break;
case 7:
document.querySelector('.popup .message_change').setAttribute("id", "invisible");
break;
default:
console.error('Invalid setting.');
}

View File

@ -59,6 +59,7 @@
<a class="smallnavbarbutton" href="{{ route('friends') }}">Friends @if (!Auth::guest() && count(Auth::user()->getFriendRequests())) <span class="warningtext">({{ count(Auth::user()->getFriendRequests()) }})</span> @endif</a>
<a class="smallnavbarbutton" href="{{ route('incomplete') }}">Avatar</a>
<a class="smallnavbarbutton" href="{{ route('users') }}">Users</a>
<a class="smallnavbarbutton" href="{{ route('inbox') }}">Messages @if (!Auth::guest() && App\Models\Message::where(['sendto_id' => Auth::id(), 'read' => false])->count()) <span class="warningtext">({{ App\Models\Message::where(['sendto_id' => Auth::id(), 'read' => false])->count() }})</span> @endif</a>
<a class="smallnavbarbutton" href="{{ route('blog') }}">Blog</a>
@if (!Auth::guest() && Auth::user()->isAdmin())
<a class="smallnavbarbutton" href="{{ route('admin_index') }}">Admin</a>

View File

@ -0,0 +1,33 @@
@extends('layouts.app')
@section('title')
<title>{{ $message->subject }} - {{ env('APP_NAME') }}</title>
@endsection
@section('content')
<button class="greybutton" onclick="window.location=document.referrer;">Back</button>
@if (Auth::id() != $message->user_id)
<form action="{{ route('delete_message', $message->id) }}" method="post" style="display:inline-block">
@csrf
@if ($message->deleted)
<button class="greenbutton" type="submit">Recover</button>
@else
<button class="redbutton" type="submit">Delete</button>
@endif
</form>
@endif
<br>
@if ($message->sendto_id != Auth::id())
<h3>To: {{ App\Models\User::where('id', $message->sendto_id)->first()->name }}</h3>
@else
<h3>From: {{ $message->user->name }}</h3>
@endif
@if (!Auth::user()->settings->time_preference_24hr)
<p>{{ $message->created_at->format('F d, Y h:i A') }}</p>
@else
<p>{{ $message->created_at->format('F d, Y H:i') }}</p>
@endif
<br>
<h4>{{ $message->subject }}</h4>
<p>{!! nl2br(e($message->content)) !!}</p>
<br>
@endsection

View File

@ -0,0 +1,26 @@
@extends('layouts.app')
@section('title')
<title>Create Message - {{ env('APP_NAME') }}</title>
@endsection
@section('alert')
@if ($errors->any())
<div id="alert">{{ $errors->first() }}</div>
@endif
@endsection
@section('content')
<h1 id="usernameframe">Create Message</h1>
<br>
<form action="{{ route('send_message') }}" method="POST">
@csrf
<p>To: <input type="text" name="name" placeholder="Username"
@if (request()->has('to')) value="{{ request()->to }}" @else value="{{ old('name') }}" @endif></p>
<p>Subject: <input type="text" name="subject" placeholder="Subject" value="{{ old('subject') }}"></p>
<textarea style="width: calc(100% - 5px); height: 170px; min-height: 170px; resize: vertical;"
placeholder="Write your message..." name="message">{{ old('message') }}</textarea>
<button class="greenbutton" type="submit">Send</button>
<button class="redbutton" type="reset"><a href="{{ route('inbox') }}"
style="color:white;font-weight:normal">Cancel</a></button>
</form>
@endsection

View File

@ -0,0 +1,67 @@
@extends('layouts.app')
@section('title')
<title>Deleted Messages - {{ env('APP_NAME') }}</title>
@endsection
@section('alert')
@if (session()->has('success'))
<div id="alert"
style="background:linear-gradient(0deg,#02b757 0%,#118237 49%,#01a64e 50%,#3fc679 95%,#a3e2bd 100%)">
{{ session()->get('success') }}
</div>
@endif
@if ($errors->any())
<div id="alert">{{ $errors->first() }}</div>
@endif
@endsection
@section('content')
<h1 id="usernameframe">My Messages</h1>
<button class="greenbutton"><a href="{{ route('compose') }}" style="color:white;font-weight:normal">New
Message</a></button>
<form action="{{ route('recover_all') }}" method="POST" style="display:inline-block">
@csrf
<button class="greenbutton" type="submit">Recover All Messages</button>
</form>
<br>
<br>
<a href="{{ route('inbox') }}" class="tab">Inbox
({{ App\Models\Message::where('sendto_id', Auth::id())->where('deleted', false)->count() }})</a>
<a href="{{ route('inbox_sent') }}" class="tab">Sent
({{ App\Models\Message::where('user_id', Auth::id())->count() }})</a>
<a href="#" class="tab_selected">Deleted
({{ App\Models\Message::where('sendto_id', Auth::id())->where('deleted', true)->count() }})</a>
<br>
<br>
@foreach ($messages as $message)
<div class="content_special" id="FriendsContainer" style="flex-wrap:wrap;cursor:pointer"
onclick="window.location='/my/messages/{{ $message->id }}';">
<div class="FriendsContainerBox" id="FriendsContainerBox1">
<div id="FriendsContainerBox1ImageContainer">
<a href="{{ route('profile', $message->user_id) }}"><img alt="Profile Image"
src="{{ asset('img/defaultrender.png') }}" width="60px" height="100%"></a>
</div>
<div id="FriendsContainerBox1TextContainer">
<a href="{{ route('profile', $message->user_id) }}"
id="FeedContainerBox1Username">{{ $message->user->name }}</a>
<p>{{ $message->subject }}</p>
@if (!Auth::user()->settings->time_preference_24hr)
<p id="FeedContainerBox1Timestamp">{{ $message->created_at->format('F d, Y h:i A') }}</p>
@else
<p id="FeedContainerBox1Timestamp">{{ $message->created_at->format('F d, Y H:i') }}</p>
@endif
@if ($message->read)
<p style="color:blue">Read</p>
@else
<p style="color:red">Unread</p>
@endif
</div>
</div>
</div>
@endforeach
{{ $messages->links() }}
@if ($messages->isEmpty())
<p>You haven't deleted any messages.</p>
@endif
<br>
@endsection

View File

@ -0,0 +1,66 @@
@extends('layouts.app')
@section('title')
<title>Messages - {{ env('APP_NAME') }}</title>
@endsection
@section('alert')
@if (session()->has('success'))
<div id="alert"
style="background:linear-gradient(0deg,#02b757 0%,#118237 49%,#01a64e 50%,#3fc679 95%,#a3e2bd 100%)">
{{ session()->get('success') }}</div>
@endif
@if ($errors->any())
<div id="alert">{{ $errors->first() }}</div>
@endif
@endsection
@section('content')
<h1 id="usernameframe">My Messages</h1>
<button class="greenbutton"><a href="{{ route('compose') }}" style="color:white;font-weight:normal">New
Message</a></button>
<form action="{{ route('delete_all') }}" method="POST" style="display:inline-block">
@csrf
<button class="redbutton" type="submit">Delete All Messages</button>
</form>
<br>
<br>
<a href="#" class="tab_selected">Inbox
({{ App\Models\Message::where('sendto_id', Auth::id())->where('deleted', false)->count() }})</a>
<a href="{{ route('inbox_sent') }}" class="tab">Sent
({{ App\Models\Message::where('user_id', Auth::id())->count() }})</a>
<a href="{{ route('deleted') }}" class="tab">Deleted
({{ App\Models\Message::where('sendto_id', Auth::id())->where('deleted', true)->count() }})</a>
<br>
<br>
@foreach ($messages as $message)
<div class="content_special" id="FriendsContainer" style="flex-wrap:wrap;cursor:pointer"
onclick="window.location='/my/messages/{{ $message->id }}';">
<div class="FriendsContainerBox" id="FriendsContainerBox1">
<div id="FriendsContainerBox1ImageContainer">
<a href="{{ route('profile', $message->user_id) }}"><img alt="Profile Image"
src="{{ asset('img/defaultrender.png') }}" width="60px" height="100%"></a>
</div>
<div id="FriendsContainerBox1TextContainer">
<a href="{{ route('profile', $message->user_id) }}"
id="FeedContainerBox1Username">{{ $message->user->name }}</a>
<p>{{ $message->subject }}</p>
@if (!Auth::user()->settings->time_preference_24hr)
<p id="FeedContainerBox1Timestamp">{{ $message->created_at->format('F d, Y h:i A') }}</p>
@else
<p id="FeedContainerBox1Timestamp">{{ $message->created_at->format('F d, Y H:i') }}</p>
@endif
@if ($message->read)
<p style="color:blue">Read</p>
@else
<p style="color:red">Unread</p>
@endif
</div>
</div>
</div>
@endforeach
{{ $messages->links() }}
@if ($messages->isEmpty())
<p>You have no messages.</p>
@endif
<br>
@endsection

View File

@ -0,0 +1,52 @@
@extends('layouts.app')
@section('title')
<title>Sent Messages - {{ env('APP_NAME') }}</title>
@endsection
@section('alert')
@if (session()->has('success'))
<div id="alert" style="background:linear-gradient(0deg,#02b757 0%,#118237 49%,#01a64e 50%,#3fc679 95%,#a3e2bd 100%)">{{ session()->get('success') }}
</div>
@endif
@endsection
@section('content')
<h1 id="usernameframe">My Messages</h1>
<button class="greenbutton"><a href="{{ route('compose') }}" style="color:white;font-weight:normal">New
Message</a></button>
<br>
<br>
<a href="{{ route('inbox') }}" class="tab">Inbox
({{ App\Models\Message::where('sendto_id', Auth::id())->where('deleted', false)->count() }})</a>
<a href="#" class="tab_selected">Sent ({{ App\Models\Message::where('user_id', Auth::id())->count() }})</a>
<a href="{{ route('deleted') }}" class="tab">Deleted
({{ App\Models\Message::where('sendto_id', Auth::id())->where('deleted', true)->count() }})</a>
<br>
<br>
@foreach ($messages as $message)
<div class="content_special" id="FriendsContainer" style="flex-wrap:wrap;cursor:pointer"
onclick="window.location='/my/messages/{{ $message->id }}';">
<div class="FriendsContainerBox" id="FriendsContainerBox1">
<div id="FriendsContainerBox1ImageContainer">
<a href="{{ route('profile', $message->sendto_id) }}"><img alt="Profile Image"
src="{{ asset('img/defaultrender.png') }}" width="60px" height="100%"></a>
</div>
<div id="FriendsContainerBox1TextContainer">
<a href="{{ route('profile', $message->sendto_id) }}"
id="FeedContainerBox1Username">{{ App\Models\User::where('id', $message->sendto_id)->first()->name }}</a>
<p>{{ $message->subject }}</p>
@if (!Auth::user()->settings->time_preference_24hr)
<p id="FeedContainerBox1Timestamp">{{ $message->created_at->format('F d, Y h:i A') }}</p>
@else
<p id="FeedContainerBox1Timestamp">{{ $message->created_at->format('F d, Y H:i') }}</p>
@endif
</div>
</div>
</div>
@endforeach
{{ $messages->links() }}
@if ($messages->isEmpty())
<p>You haven't sent any messages.</p>
@endif
<br>
@endsection

View File

@ -1,7 +1,7 @@
@extends('layouts.app')
@section('title')
<title>Settings - {{ env('APP_NAME') }}</title>
<script src="{{ asset('js/settings.js') }}"></script>
<script src="{{ asset('js/settings.js?id=h8z4lam02') }}"></script>
<style>
.bio_form {
width: 50%
@ -71,6 +71,14 @@
<option value="1">24 Hour</option>
</select>
</span>
<span class="message_change" id="invisible">
<br>
<select name="message_preference">
<option value="2">Everyone</option>
<option value="1">Friends Only</option>
<option value="0">No one</option>
</select>
</span>
<br>
<br>
<button class="bluebutton" type="submit">Confirm</button>
@ -82,10 +90,10 @@
@section('alert')
@if ($errors->any())
<div style="color:white;background-color:red;text-align:center;margin-top:72px">{{ $errors->first() }}</div>
<div id="alert">{{ $errors->first() }}</div>
@endif
@if (session()->has('change'))
<div style="color:white;background-color:green;text-align:center;margin-top:72px">{{ session()->get('change') }}
<div id="alert" style="background:linear-gradient(0deg,#02b757 0%,#118237 49%,#01a64e 50%,#3fc679 95%,#a3e2bd 100%)">{{ session()->get('change') }}
</div>
@endif
@endsection
@ -123,13 +131,26 @@
</p>
<p style="width: 100%;">Password: ******** <button class="bluebutton" onclick="openPopup(4)">Edit</button></p>
<p style="width: 100%;">Date Display Preference:
{{ Auth::user()->settings->date_preference }} <button class="bluebutton"
onclick="openPopup(5)">Edit</button>
{{ Auth::user()->settings->date_preference }} <button class="bluebutton" onclick="openPopup(5)">Edit</button>
</p>
<p style="width: 100%;">Time Display Preference:
{{ Auth::user()->settings->time_preference_24hr ? '24 Hour' : '12 Hour' }}
<button class="bluebutton" onclick="openPopup(6)">Edit</button>
</p>
<p style="width: 100%;">Message Privacy: @php
switch (Auth::user()->settings->message_preference) {
case 2:
echo 'Everyone';
break;
case 1:
echo 'Friends Only';
break;
default:
echo 'No one';
}
@endphp <button class="bluebutton"
onclick="openPopup(7)">Edit</button>
</p>
</div>
</div>
<div class="content_special" style="align-content: flex-end; align-items: flex-start;">
@ -137,7 +158,8 @@
style="flex-wrap: wrap; flex-direction: column; width: 50%; align-content: flex-start;">
<h3>Invite Keys</h3>
<p>You can only create 1 invite every week. <br>Manage your keys and key history below.</p>
<p><button class="bluebutton"><a href="{{ route('key_index') }}" style="font-weight:normal;color:#fff">Create
<p><button class="bluebutton"><a href="{{ route('key_index') }}"
style="font-weight:normal;color:#fff">Create
Invite Key</a></button></p>
</div>
<div class="content_special"

View File

@ -13,7 +13,7 @@
<div id="profiletopcontainer">
<h1 id="usernameframe">{{ $data['user']->name }}</h1>
@if ($data['user']->settings->changed_name)
<h4>Previous Username: {{ $data['user']->settings->old_name }}</h4>
<h4>Previous Username: {{ $data['user']->settings->old_name }}</h4>
@endif
@if (Cache::has('is_online_' . $data['user']->id))
<strong id="onlinestatus" class="onlinestatus_website">Website</strong>
@ -42,7 +42,20 @@
<button class="bluebutton" type="submit">Add Friend</button>
</form>
@endif
<a href="#"><button class="greybutton">Message</button></a>
@switch($data['user']->settings->message_preference)
@case(2)
<a href="/my/messages/compose?to={{ $data['user']->name }}"><button class="greybutton">Message</button></a>
@break
@case(1)
@if (Auth::user()->isFriendWith($data['user']))
<a href="/my/messages/compose?to={{ $data['user']->name }}"><button class="greybutton">Message</button></a>
@else
<a href="#"><button class="greybutton" disabled>Message (Friends Only)</button></a>
@endif
@break
@default
<a href="#"><button class="greybutton" disabled>Message (Disabled)</button></a>
@endswitch
@endif
</div>
<div class="content_special">
@ -87,7 +100,8 @@
<div id="profilerightcontainer">
<div class="content_special" style="justify-content: center;">
<h2>Games </h2>
<a href="{{ route('incomplete') }}" style="margin-left: 5px"> <button class="bluebutton" style="margin-top: 5px">View
<a href="{{ route('incomplete') }}" style="margin-left: 5px"> <button class="bluebutton"
style="margin-top: 5px">View
All</button></a>
</div>
<p>This user hasn't made any games yet!</p>

View File

@ -35,7 +35,8 @@ Route::middleware(['auth'])->group(function () {
// Rate limit + auth
Route::middleware(['throttle:feed_post'])->group(function () {
Route::post('/home', [App\Http\Controllers\HomeController::class, 'feed_post'])->name('feed_post');
Route::post('/home', [App\Http\Controllers\HomeController::class, 'feed_post'])->name('feed_post'); // Posting to the feed
Route::post('/my/messages/compose', [App\Http\Controllers\MessageController::class, 'send_message'])->name('send_message'); // Sending a message to a user
});
Route::get('/user/{id}/friends/mutual', [App\Http\Controllers\PageController::class, 'mutual_friends'])->name('mutual_friends');
@ -52,6 +53,16 @@ Route::middleware(['auth'])->group(function () {
Route::post('/my/friends/requests/{id}', [App\Http\Controllers\FriendController::class, 'handle'])->name('friend_handle');
Route::post('/friends/add/{id}', [App\Http\Controllers\FriendController::class, 'add'])->name('friend_add');
Route::post('/friends/remove/{id}', [App\Http\Controllers\FriendController::class, 'remove'])->name('friend_remove');
// Message system routes
Route::get('/my/messages', [App\Http\Controllers\MessageController::class, 'inbox'])->name('inbox');
Route::post('/my/messages', [App\Http\Controllers\MessageController::class, 'delete_all'])->name('delete_all');
Route::get('/my/messages/sent', [App\Http\Controllers\MessageController::class, 'inbox_sent'])->name('inbox_sent');
Route::get('/my/messages/compose', [App\Http\Controllers\MessageController::class, 'compose'])->name('compose');
Route::get('/my/messages/deleted', [App\Http\Controllers\MessageController::class, 'deleted'])->name('deleted');
Route::post('/my/messages/deleted', [App\Http\Controllers\MessageController::class, 'recover_all'])->name('recover_all');
Route::get('/my/messages/{id}', [App\Http\Controllers\MessageController::class, 'content'])->name('content');
Route::post('/my/messages/{id}', [App\Http\Controllers\MessageController::class, 'delete_message'])->name('delete_message');
});
// Admin only