mirror of
https://github.com/pixelfed/pixelfed.git
synced 2024-12-22 21:13:16 +00:00
Merge pull request #363 from pixelfed/frontend-ui-refactor
Frontend ui refactor
This commit is contained in:
commit
280868a982
7 changed files with 176 additions and 23 deletions
|
@ -3,15 +3,22 @@
|
||||||
namespace App\Http\Controllers\Api;
|
namespace App\Http\Controllers\Api;
|
||||||
|
|
||||||
use Auth;
|
use Auth;
|
||||||
use App\{Like, Profile, Status};
|
use App\{
|
||||||
|
Avatar,
|
||||||
|
Like,
|
||||||
|
Profile,
|
||||||
|
Status
|
||||||
|
};
|
||||||
use League\Fractal;
|
use League\Fractal;
|
||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
use App\Http\Controllers\Controller;
|
use App\Http\Controllers\Controller;
|
||||||
|
use App\Http\Controllers\AvatarController;
|
||||||
use App\Util\Webfinger\Webfinger;
|
use App\Util\Webfinger\Webfinger;
|
||||||
use App\Transformer\Api\{
|
use App\Transformer\Api\{
|
||||||
AccountTransformer,
|
AccountTransformer,
|
||||||
StatusTransformer
|
StatusTransformer
|
||||||
};
|
};
|
||||||
|
use App\Jobs\AvatarPipeline\AvatarOptimize;
|
||||||
use League\Fractal\Serializer\ArraySerializer;
|
use League\Fractal\Serializer\ArraySerializer;
|
||||||
|
|
||||||
class BaseApiController extends Controller
|
class BaseApiController extends Controller
|
||||||
|
@ -68,4 +75,37 @@ class BaseApiController extends Controller
|
||||||
$res = $this->fractal->createData($resource)->toArray();
|
$res = $this->fractal->createData($resource)->toArray();
|
||||||
return response()->json($res);
|
return response()->json($res);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function avatarUpdate(Request $request)
|
||||||
|
{
|
||||||
|
$this->validate($request, [
|
||||||
|
'upload' => 'required|mimes:jpeg,png,gif|max:2000',
|
||||||
|
]);
|
||||||
|
try {
|
||||||
|
$user = Auth::user();
|
||||||
|
$file = $request->file('upload');
|
||||||
|
$path = (new AvatarController())->getPath($user, $file);
|
||||||
|
$dir = $path['root'];
|
||||||
|
$name = $path['name'];
|
||||||
|
$public = $path['storage'];
|
||||||
|
$currentAvatar = storage_path('app/'.$user->profile->avatar->media_path);
|
||||||
|
$loc = $request->file('upload')->storeAs($public, $name);
|
||||||
|
|
||||||
|
$avatar = Avatar::whereProfileId($user->profile->id)->firstOrFail();
|
||||||
|
$opath = $avatar->media_path;
|
||||||
|
$avatar->media_path = "$public/$name";
|
||||||
|
$avatar->thumb_path = null;
|
||||||
|
$avatar->change_count = ++$avatar->change_count;
|
||||||
|
$avatar->last_processed_at = null;
|
||||||
|
$avatar->save();
|
||||||
|
|
||||||
|
AvatarOptimize::dispatch($user->profile, $currentAvatar);
|
||||||
|
} catch (Exception $e) {
|
||||||
|
}
|
||||||
|
|
||||||
|
return response()->json([
|
||||||
|
'code' => 200,
|
||||||
|
'msg' => 'Avatar successfully updated'
|
||||||
|
]);
|
||||||
|
}
|
||||||
}
|
}
|
|
@ -17,7 +17,7 @@ class AvatarController extends Controller
|
||||||
public function store(Request $request)
|
public function store(Request $request)
|
||||||
{
|
{
|
||||||
$this->validate($request, [
|
$this->validate($request, [
|
||||||
'avatar' => 'required|mimes:jpeg,png|max:1000'
|
'avatar' => 'required|mimes:jpeg,png|max:2000'
|
||||||
]);
|
]);
|
||||||
try {
|
try {
|
||||||
$user = Auth::user();
|
$user = Auth::user();
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
namespace App\Http\Controllers;
|
namespace App\Http\Controllers;
|
||||||
|
|
||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
use App\{AccountLog, Media, Profile, User};
|
use App\{AccountLog, EmailVerification, Media, Profile, User};
|
||||||
use Auth, DB;
|
use Auth, DB;
|
||||||
use App\Util\Lexer\PrettyNumber;
|
use App\Util\Lexer\PrettyNumber;
|
||||||
|
|
||||||
|
@ -31,25 +31,46 @@ class SettingsController extends Controller
|
||||||
{
|
{
|
||||||
$this->validate($request, [
|
$this->validate($request, [
|
||||||
'name' => 'required|string|max:30',
|
'name' => 'required|string|max:30',
|
||||||
'bio' => 'nullable|string|max:125'
|
'bio' => 'nullable|string|max:125',
|
||||||
|
'website' => 'nullable|url',
|
||||||
|
'email' => 'nullable|email'
|
||||||
]);
|
]);
|
||||||
|
|
||||||
$changes = false;
|
$changes = false;
|
||||||
$name = $request->input('name');
|
$name = $request->input('name');
|
||||||
$bio = $request->input('bio');
|
$bio = $request->input('bio');
|
||||||
|
$website = $request->input('website');
|
||||||
|
$email = $request->input('email');
|
||||||
$user = Auth::user();
|
$user = Auth::user();
|
||||||
$profile = $user->profile;
|
$profile = $user->profile;
|
||||||
|
|
||||||
|
|
||||||
|
if($user->email != $email) {
|
||||||
|
$changes = true;
|
||||||
|
$user->email = $email;
|
||||||
|
$user->email_verified_at = null;
|
||||||
|
// Prevent old verifications from working
|
||||||
|
EmailVerification::whereUserId($user->id)->delete();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Only allow email to be updated if not yet verified
|
||||||
|
if(!$changes && $user->email_verified_at) {
|
||||||
if($profile->name != $name) {
|
if($profile->name != $name) {
|
||||||
$changes = true;
|
$changes = true;
|
||||||
$user->name = $name;
|
$user->name = $name;
|
||||||
$profile->name = $name;
|
$profile->name = $name;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if($profile->website != $website) {
|
||||||
|
$changes = true;
|
||||||
|
$profile->website = $website;
|
||||||
|
}
|
||||||
|
|
||||||
if($profile->bio != $bio) {
|
if($profile->bio != $bio) {
|
||||||
$changes = true;
|
$changes = true;
|
||||||
$profile->bio = $bio;
|
$profile->bio = $bio;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if($changes === true) {
|
if($changes === true) {
|
||||||
$user->save();
|
$user->save();
|
||||||
|
|
|
@ -18,8 +18,7 @@ class EmailVerificationCheck
|
||||||
if($request->user() &&
|
if($request->user() &&
|
||||||
config('pixelfed.enforce_email_verification') &&
|
config('pixelfed.enforce_email_verification') &&
|
||||||
is_null($request->user()->email_verified_at) &&
|
is_null($request->user()->email_verified_at) &&
|
||||||
!$request->is('i/verify-email') && !$request->is('log*') &&
|
!$request->is('i/verify-email', 'log*', 'i/confirm-email/*', 'settings/home')
|
||||||
!$request->is('i/confirm-email/*')
|
|
||||||
) {
|
) {
|
||||||
return redirect('/i/verify-email');
|
return redirect('/i/verify-email');
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,6 +8,15 @@
|
||||||
<hr>
|
<hr>
|
||||||
<form method="post">
|
<form method="post">
|
||||||
@csrf
|
@csrf
|
||||||
|
<div class="form-group row">
|
||||||
|
<div class="col-sm-3">
|
||||||
|
<img src="{{Auth::user()->profile->avatarUrl()}}" width="38px" class="rounded-circle img-thumbnail float-right">
|
||||||
|
</div>
|
||||||
|
<div class="col-sm-9">
|
||||||
|
<p class="lead font-weight-bold mb-0">{{Auth::user()->username}}</p>
|
||||||
|
<p><a href="#" class="font-weight-bold change-profile-photo">Change Profile Photo</a></p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
<div class="form-group row">
|
<div class="form-group row">
|
||||||
<label for="name" class="col-sm-3 col-form-label font-weight-bold text-right">Name</label>
|
<label for="name" class="col-sm-3 col-form-label font-weight-bold text-right">Name</label>
|
||||||
<div class="col-sm-9">
|
<div class="col-sm-9">
|
||||||
|
@ -15,15 +24,21 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="form-group row">
|
<div class="form-group row">
|
||||||
<label for="name" class="col-sm-3 col-form-label font-weight-bold text-right">Username</label>
|
<label for="username" class="col-sm-3 col-form-label font-weight-bold text-right">Username</label>
|
||||||
<div class="col-sm-9">
|
<div class="col-sm-9">
|
||||||
<input type="text" class="form-control" id="name" name="username" placeholder="Username" value="{{Auth::user()->profile->username}}" readonly>
|
<input type="text" class="form-control" id="username" name="username" placeholder="Username" value="{{Auth::user()->profile->username}}" readonly>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="form-group row">
|
<div class="form-group row">
|
||||||
<label class="col-sm-3 col-form-label font-weight-bold text-right">Bio</label>
|
<label for="website" class="col-sm-3 col-form-label font-weight-bold text-right">Website</label>
|
||||||
<div class="col-sm-9">
|
<div class="col-sm-9">
|
||||||
<textarea class="form-control" name="bio" placeholder="Add a bio here" rows="2">{{Auth::user()->profile->bio}}</textarea>
|
<input type="text" class="form-control" id="website" name="website" placeholder="Website" value="{{Auth::user()->profile->website}}">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="form-group row">
|
||||||
|
<label for="bio" class="col-sm-3 col-form-label font-weight-bold text-right">Bio</label>
|
||||||
|
<div class="col-sm-9">
|
||||||
|
<textarea class="form-control" id="bio" name="bio" placeholder="Add a bio here" rows="2">{{Auth::user()->profile->bio}}</textarea>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="pt-5">
|
<div class="pt-5">
|
||||||
|
@ -32,15 +47,91 @@
|
||||||
<div class="form-group row">
|
<div class="form-group row">
|
||||||
<label for="email" class="col-sm-3 col-form-label font-weight-bold text-right">Email</label>
|
<label for="email" class="col-sm-3 col-form-label font-weight-bold text-right">Email</label>
|
||||||
<div class="col-sm-9">
|
<div class="col-sm-9">
|
||||||
<input type="email" class="form-control" id="email" name="email" placeholder="Email Address" value="{{Auth::user()->email}}" readonly>
|
<input type="email" class="form-control" id="email" name="email" placeholder="Email Address" value="{{Auth::user()->email}}">
|
||||||
|
<p class="help-text small text-muted font-weight-bold">
|
||||||
|
@if(Auth::user()->email_verified_at)
|
||||||
|
<span class="text-success">Verified</span> {{Auth::user()->email_verified_at->diffForHumans()}}
|
||||||
|
@else
|
||||||
|
<span class="text-danger">Unverified</span> You need to <a href="/i/verify-email">verify your email</a>.
|
||||||
|
@endif
|
||||||
|
</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<hr>
|
<hr>
|
||||||
<div class="form-group row">
|
<div class="form-group row">
|
||||||
<div class="col-sm-9">
|
<div class="col-12 text-right">
|
||||||
<button type="submit" class="btn btn-primary">Submit</button>
|
<button type="submit" class="btn btn-primary font-weight-bold">Submit</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
|
|
||||||
@endsection
|
@endsection
|
||||||
|
|
||||||
|
@push('scripts')
|
||||||
|
<script type="text/javascript">
|
||||||
|
$(document).on('click', '.modal-update', function(e) {
|
||||||
|
swal({
|
||||||
|
title: 'Upload Photo',
|
||||||
|
content: {
|
||||||
|
element: 'input',
|
||||||
|
attributes: {
|
||||||
|
placeholder: 'Upload your photo',
|
||||||
|
type: 'file',
|
||||||
|
name: 'photoUpload',
|
||||||
|
id: 'photoUploadInput'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
buttons: {
|
||||||
|
confirm: {
|
||||||
|
text: 'Upload'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}).then((res) => {
|
||||||
|
const input = $('#photoUploadInput')[0];
|
||||||
|
const photo = input.files[0];
|
||||||
|
const form = new FormData();
|
||||||
|
form.append("upload", photo);
|
||||||
|
|
||||||
|
axios.post('/api/v1/avatar/update', form, {
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'multipart/form-data'
|
||||||
|
}
|
||||||
|
}).then((res) => {
|
||||||
|
swal('Success', 'Your photo has been successfully updated! It may take a few minutes to update across the site.', 'success');
|
||||||
|
}).catch((res) => {
|
||||||
|
let msg = res.response.data.errors.upload[0];
|
||||||
|
swal('Something went wrong', msg, 'error');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
$(document).on('click', '.modal-close', function(e) {
|
||||||
|
swal.close();
|
||||||
|
});
|
||||||
|
|
||||||
|
$(document).on('click', '.change-profile-photo', function(e) {
|
||||||
|
e.preventDefault();
|
||||||
|
var content = $('<ul>').addClass('list-group');
|
||||||
|
var upload = $('<li>').text('Upload photo').addClass('list-group-item');
|
||||||
|
content.append(upload);
|
||||||
|
const list = document.createElement('ul');
|
||||||
|
list.className = 'list-group';
|
||||||
|
|
||||||
|
const uploadPhoto = document.createElement('li');
|
||||||
|
uploadPhoto.innerHTML = 'Upload Photo';
|
||||||
|
uploadPhoto.className = 'list-group-item font-weight-bold text-primary modal-update';
|
||||||
|
list.appendChild(uploadPhoto);
|
||||||
|
|
||||||
|
const cancel = document.createElement('li');
|
||||||
|
cancel.innerHTML = 'Cancel';
|
||||||
|
cancel.className = 'list-group-item modal-close';
|
||||||
|
list.appendChild(cancel);
|
||||||
|
|
||||||
|
swal({
|
||||||
|
title: 'Change Profile Photo',
|
||||||
|
content: list,
|
||||||
|
buttons: false
|
||||||
|
});
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
@endpush
|
|
@ -3,9 +3,9 @@
|
||||||
<li class="nav-item pl-3 {{request()->is('settings/home')?'active':''}}">
|
<li class="nav-item pl-3 {{request()->is('settings/home')?'active':''}}">
|
||||||
<a class="nav-link font-weight-light text-muted" href="{{route('settings')}}">Profile</a>
|
<a class="nav-link font-weight-light text-muted" href="{{route('settings')}}">Profile</a>
|
||||||
</li>
|
</li>
|
||||||
<li class="nav-item pl-3 {{request()->is('settings/avatar')?'active':''}}">
|
{{-- <li class="nav-item pl-3 {{request()->is('settings/avatar')?'active':''}}">
|
||||||
<a class="nav-link font-weight-light text-muted" href="{{route('settings.avatar')}}">Avatar</a>
|
<a class="nav-link font-weight-light text-muted" href="{{route('settings.avatar')}}">Avatar</a>
|
||||||
</li>
|
</li> --}}
|
||||||
<li class="nav-item pl-3 {{request()->is('settings/password')?'active':''}}">
|
<li class="nav-item pl-3 {{request()->is('settings/password')?'active':''}}">
|
||||||
<a class="nav-link font-weight-light text-muted" href="{{route('settings.password')}}">Password</a>
|
<a class="nav-link font-weight-light text-muted" href="{{route('settings.password')}}">Password</a>
|
||||||
</li>
|
</li>
|
||||||
|
@ -14,7 +14,8 @@
|
||||||
</li>
|
</li>
|
||||||
<li class="nav-item pl-3 {{request()->is('settings/notifications')?'active':''}}">
|
<li class="nav-item pl-3 {{request()->is('settings/notifications')?'active':''}}">
|
||||||
<a class="nav-link font-weight-light text-muted" href="{{route('settings.notifications')}}">Notifications</a>
|
<a class="nav-link font-weight-light text-muted" href="{{route('settings.notifications')}}">Notifications</a>
|
||||||
</li> --}}
|
</li>
|
||||||
|
--}}
|
||||||
<li class="nav-item pl-3 {{request()->is('settings/privacy')?'active':''}}">
|
<li class="nav-item pl-3 {{request()->is('settings/privacy')?'active':''}}">
|
||||||
<a class="nav-link font-weight-light text-muted" href="{{route('settings.privacy')}}">Privacy</a>
|
<a class="nav-link font-weight-light text-muted" href="{{route('settings.privacy')}}">Privacy</a>
|
||||||
</li>
|
</li>
|
||||||
|
|
|
@ -38,6 +38,7 @@ Route::domain(config('pixelfed.domain.app'))->middleware('validemail')->group(fu
|
||||||
Route::get('nodeinfo/2.0.json', 'FederationController@nodeinfo');
|
Route::get('nodeinfo/2.0.json', 'FederationController@nodeinfo');
|
||||||
|
|
||||||
Route::group(['prefix' => 'v1'], function() {
|
Route::group(['prefix' => 'v1'], function() {
|
||||||
|
Route::post('avatar/update', 'ApiController@avatarUpdate');
|
||||||
Route::get('likes', 'ApiController@hydrateLikes');
|
Route::get('likes', 'ApiController@hydrateLikes');
|
||||||
});
|
});
|
||||||
Route::group(['prefix' => 'local'], function() {
|
Route::group(['prefix' => 'local'], function() {
|
||||||
|
|
Loading…
Reference in a new issue