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

Frontend ui refactor
This commit is contained in:
daniel 2018-06-04 23:03:25 -06:00 committed by GitHub
commit 197742d0df
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
20 changed files with 312 additions and 251 deletions

View file

@ -94,7 +94,7 @@ class FederationController extends Controller
'outbound' => [] 'outbound' => []
], ],
'software' => [ 'software' => [
'name' => 'PixelFed', 'name' => 'pixelfed',
'version' => config('pixelfed.version') 'version' => config('pixelfed.version')
], ],
'usage' => [ 'usage' => [

BIN
public/css/app.css vendored

Binary file not shown.

Binary file not shown.

View file

@ -71,9 +71,12 @@ body, button, input, textarea {
margin: auto !important; margin: auto !important;
} }
.card.status-container .status-comments { @media (min-width: map-get($grid-breakpoints, "md")) {
overflow-y: scroll; .card.status-container .status-comments {
border-bottom:1px solid rgba(0, 0, 0, 0.1); overflow-y:scroll;
border-bottom:1px solid rgba(0,0,0,.1);
height: 200px;
}
} }
.no-caret.dropdown-toggle { .no-caret.dropdown-toggle {
@ -163,6 +166,12 @@ body, button, input, textarea {
background-position: 50%; background-position: 50%;
} }
@media (max-width: map-get($grid-breakpoints, "md")) {
.border-md-left-0 {
border-left:0!important
}
}
.fas, .far { .fas, .far {
font-size: 25px !important; font-size: 25px !important;
} }
@ -178,3 +187,18 @@ body, button, input, textarea {
.fas.fa-heart { .fas.fa-heart {
} }
@media (max-width: map-get($grid-breakpoints, "md")) {
.border-md-left-0 {
border-left:0!important
}
.card.status-container .status-comments {
border-top:1px solid rgba(0,0,0,.1);
}
.sticky-md-bottom {
position:-webkit-sticky;
position:sticky;
bottom:0;
z-index:1020
}
}

View file

@ -0,0 +1,19 @@
<?php
return [
/*
|--------------------------------------------------------------------------
| Authentication Language Lines
|--------------------------------------------------------------------------
|
| The following language lines are used during authentication for various
| messages that we need to display to the user. You are free to modify
| these language lines according to your application's requirements.
|
*/
'failed' => 'Nämä kirjautumistiedot eivät vastaa tallennettuja',
'throttle' => 'Liian monta kirjautumisyritystä. Yrityä uudelleen :seconds sekuntin kuluttua.',
];

View file

@ -0,0 +1,8 @@
<?php
return [
'likedPhoto' => 'tykkäsi kuvastasi.',
'startedFollowingYou' => 'alkoi seuraamaan sinua.',
];

View file

@ -0,0 +1,19 @@
<?php
return [
/*
|--------------------------------------------------------------------------
| Pagination Language Lines
|--------------------------------------------------------------------------
|
| The following language lines are used by the paginator library to build
| the simple pagination links. You are free to change them to anything
| you want to customize your views to better match your application.
|
*/
'previous' => '&laquo; Edellinen',
'next' => 'Seuraava &raquo;',
];

View file

@ -0,0 +1,22 @@
<?php
return [
/*
|--------------------------------------------------------------------------
| Password Reset Language Lines
|--------------------------------------------------------------------------
|
| The following language lines are the default lines which match reasons
| that are given by the password broker for a password update attempt
| has failed, such as for an invalid token or invalid new password.
|
*/
'password' => 'Salasanan täytyy olla vähintään kuusi merkkiä ja vastata vahvistusta.',
'reset' => 'Salasanasi on nollattu!',
'sent' => 'Olemme lähettäneet salasanan nollauslinkin sähköpostitse!',
'token' => 'Tämä salasanan nollauslinkki ei ole toimiva.',
'user' => "Emme löydä käyttäjää tuolla sähköpostiosoitteella.",
];

View file

@ -0,0 +1,9 @@
<?php
return [
'emptyTimeline' => 'Tällä käyttäjällä ei ole vielä päivityksiä!',
'emptyFollowers' => 'Tällä käyttäjällä ei ole vielä seuraajia!',
'emptyFollowing' => 'Tämä käyttäjä ei vielä seuraa ketään!',
'savedWarning' => 'Only you can see what you\'ve saved',
'savedWarning' => 'Vain sinä voit nähdä, mitä olet tallentanut',
];

View file

@ -0,0 +1,7 @@
<?php
return [
'emptyPersonalTimeline' => 'Aikajanasi on tyhjä.'
];

View file

@ -1,4 +1,5 @@
<?php <?php
return [ return [
'likedPhoto' => 'a aimé votre photo.', 'likedPhoto' => 'a aimé votre photo.',
'startedFollowingYou' => 'a commencé à vous suivre.',
]; ];

View file

@ -1,4 +1,7 @@
<?php <?php
return [ return [
'emptyTimeline' => 'Cet utilisateur n\'a pas encore de messages !', 'emptyTimeline' => 'Cet utilisateur n\'a pas encore de messages !',
'emptyFollowers' => 'Cet utilisateur n`\'a pas encore d\'abonné-e-s!',
'emptyFollowing' => 'Cet utilisateur ne suit pas encore quelqu\'un!',
'savedWarning' => 'Vous seul pouvez voir ce que vous avez enregistré',
]; ];

View file

@ -0,0 +1,4 @@
<?php
return [
'emptyPersonalTimeline' => 'Votre chronologie est vide.'
];

View file

@ -13,7 +13,7 @@ return [
| |
*/ */
'failed' => 'Dessa autentiseringsuppgifter matchar inte de i vårt register.', 'failed' => 'Dessa autentiseringsuppgifter matchar inte vårt register.',
'throttle' => 'För många inloggningsförsök. Var god försök igen om :seconds sekunder.', 'throttle' => 'För många inloggningsförsök. Var god försök igen om :seconds sekunder.',
]; ];

View file

@ -17,9 +17,9 @@ return [
'active_url' => ':attribute är inte en giltig URL.', 'active_url' => ':attribute är inte en giltig URL.',
'after' => ':attribute måste vara ett datum efter :date.', 'after' => ':attribute måste vara ett datum efter :date.',
'after_or_equal' => ':attribute måste vara ett datum efter eller samma som :date.', 'after_or_equal' => ':attribute måste vara ett datum efter eller samma som :date.',
'alpha' => ':attribute får endast intehålla bokstäver.', 'alpha' => ':attribute får endast innehålla bokstäver.',
'alpha_dash' => ':attribute får endast intehålla bokstäver, nummer, och bindestreck.', 'alpha_dash' => ':attribute får endast innehålla bokstäver, nummer, och bindestreck.',
'alpha_num' => ':attribute får endast intehålla bokstäver och nummer.', 'alpha_num' => ':attribute får endast innehålla bokstäver och nummer.',
'array' => ':attribute måste vara en array.', 'array' => ':attribute måste vara en array.',
'before' => ':attribute måste vara ett datum före :date.', 'before' => ':attribute måste vara ett datum före :date.',
'before_or_equal' => ':attribute måste vara ett datum före eller samma som :date.', 'before_or_equal' => ':attribute måste vara ett datum före eller samma som :date.',
@ -51,10 +51,10 @@ return [
'ipv6' => ':attribute måste vara en giltig IPv6 adress.', 'ipv6' => ':attribute måste vara en giltig IPv6 adress.',
'json' => ':attribute måste vara en giltig JSON string.', 'json' => ':attribute måste vara en giltig JSON string.',
'max' => [ 'max' => [
'numeric' => ':attribute får inte vara större than :max.', 'numeric' => ':attribute får inte vara större än :max.',
'file' => ':attribute får inte vara större than :max kilobyte.', 'file' => ':attribute får inte vara större än :max kilobyte.',
'string' => ':attribute får inte vara större than :max tecken.', 'string' => ':attribute får inte vara större än :max tecken.',
'array' => ':attribute får inte ha mer än :max objekt.', 'array' => ':attribute får inte ha fler än :max objekt.',
], ],
'mimes' => ':attribute måste vara en fil av typ: :values.', 'mimes' => ':attribute måste vara en fil av typ: :values.',
'mimetypes' => ':attribute måste vara en fil av typ: :values.', 'mimetypes' => ':attribute måste vara en fil av typ: :values.',
@ -62,7 +62,7 @@ return [
'numeric' => ':attribute måste vara åtminstone :min.', 'numeric' => ':attribute måste vara åtminstone :min.',
'file' => ':attribute måste vara åtminstone :min kilobyte.', 'file' => ':attribute måste vara åtminstone :min kilobyte.',
'string' => ':attribute måste vara åtminstone :min tecken.', 'string' => ':attribute måste vara åtminstone :min tecken.',
'array' => ':attribute måste have åtminstone :min objekt.', 'array' => ':attribute måste innehålla åtminstone :min objekt.',
], ],
'not_in' => 'vald :attribute är ogiltig.', 'not_in' => 'vald :attribute är ogiltig.',
'not_regex' => ':attribute formatet är ogiltigt.', 'not_regex' => ':attribute formatet är ogiltigt.',
@ -74,7 +74,7 @@ return [
'required_unless' => ':attribute fält krävs om inte :other är i :values.', 'required_unless' => ':attribute fält krävs om inte :other är i :values.',
'required_with' => ':attribute fält krävs när :values finns.', 'required_with' => ':attribute fält krävs när :values finns.',
'required_with_all' => ':attribute fält krävs när :values finns.', 'required_with_all' => ':attribute fält krävs när :values finns.',
'required_without' => ':attribute fält krvävs när :values inte finns.', 'required_without' => ':attribute fält krävs när :values inte finns.',
'required_without_all' => ':attribute fält krävs när inga av :values finns.', 'required_without_all' => ':attribute fält krävs när inga av :values finns.',
'same' => ':attribute och :other måste matcha.', 'same' => ':attribute och :other måste matcha.',
'size' => [ 'size' => [

View file

@ -2,46 +2,9 @@
@section('content') @section('content')
@include('profile.partial.user-info')
<div class="container following-page" style="min-height: 60vh;"> <div class="container following-page" style="min-height: 60vh;">
<div class="profile-header row my-5">
<div class="col-12 col-md-4 d-flex">
<div class="profile-avatar mx-auto">
<img class="img-thumbnail" src="{{$profile->avatarUrl()}}" style="border-radius:100%;" width="172px">
</div>
</div>
<div class="col-12 col-md-8 d-flex align-items-center">
<div class="profile-details">
<div class="username-bar pb-2 d-flex align-items-center">
<span class="font-weight-ultralight h1">{{$profile->username}}</span>
</div>
<div class="profile-stats pb-3 d-inline-flex lead">
<div class="font-weight-light pr-5">
<a class="text-dark" href="{{$profile->url()}}">
<span class="font-weight-bold">{{$profile->statuses()->whereNull('in_reply_to_id')->count()}}</span>
Posts
</a>
</div>
<div class="font-weight-light pr-5">
<a class="text-dark" href="{{$profile->url('/followers')}}">
<span class="font-weight-bold">{{$profile->followerCount(true)}}</span>
Followers
</a>
</div>
<div class="font-weight-light pr-5">
<a class="text-dark" href="{{$profile->url('/following')}}">
<span class="font-weight-bold">{{$profile->followingCount(true)}}</span>
Following
</a>
</div>
</div>
<p class="lead font-weight-bold">
{{$profile->name}}
</p>
</div>
</div>
</div>
<div class="col-12 col-md-8 offset-md-2"> <div class="col-12 col-md-8 offset-md-2">
@if($followers->count() !== 0) @if($followers->count() !== 0)
<ul class="list-group mt-4"> <ul class="list-group mt-4">

View file

@ -2,46 +2,9 @@
@section('content') @section('content')
@include('profile.partial.user-info')
<div class="container following-page" style="min-height: 60vh;"> <div class="container following-page" style="min-height: 60vh;">
<div class="profile-header row my-5">
<div class="col-12 col-md-4 d-flex">
<div class="profile-avatar mx-auto">
<img class="img-thumbnail" src="{{$profile->avatarUrl()}}" style="border-radius:100%;" width="172px">
</div>
</div>
<div class="col-12 col-md-8 d-flex align-items-center">
<div class="profile-details">
<div class="username-bar pb-2 d-flex align-items-center">
<span class="font-weight-ultralight h1">{{$profile->username}}</span>
</div>
<div class="profile-stats pb-3 d-inline-flex lead">
<div class="font-weight-light pr-5">
<a class="text-dark" href="{{$profile->url()}}">
<span class="font-weight-bold">{{$profile->statuses()->whereNull('in_reply_to_id')->count()}}</span>
Posts
</a>
</div>
<div class="font-weight-light pr-5">
<a class="text-dark" href="{{$profile->url('/followers')}}">
<span class="font-weight-bold">{{$profile->followerCount(true)}}</span>
Followers
</a>
</div>
<div class="font-weight-light pr-5">
<a class="text-dark" href="{{$profile->url('/following')}}">
<span class="font-weight-bold">{{$profile->followingCount(true)}}</span>
Following
</a>
</div>
</div>
<p class="lead font-weight-bold">
{{$profile->name}}
</p>
</div>
</div>
</div>
<div class="col-12 col-md-8 offset-md-2"> <div class="col-12 col-md-8 offset-md-2">
@if($following->count() !== 0) @if($following->count() !== 0)
<ul class="list-group mt-4"> <ul class="list-group mt-4">

View file

@ -0,0 +1,79 @@
<div class="bg-white py-5">
<div class="container">
<div class="row">
<div class="col-12 col-md-4 d-flex">
<div class="profile-avatar mx-auto">
<img class="img-thumbnail" src="{{$user->avatarUrl()}}" style="border-radius:100%;" width="172px">
</div>
</div>
<div class="col-12 col-md-8 d-flex align-items-center">
<div class="profile-details">
<div class="username-bar pb-2 d-flex align-items-center">
<span class="font-weight-ultralight h1">{{$user->username}}</span>
@if($owner == true)
<span class="h5 pl-2 b-0">
<a class="icon-settings text-muted" href="{{route('settings')}}"></a>
</span>
@elseif ($following == true)
<span class="pl-4">
<form class="follow-form" method="post" action="/i/follow" style="display: inline;" data-id="{{$user->id}}" data-action="unfollow">
@csrf
<input type="hidden" name="item" value="{{$user->id}}">
<button class="btn btn-outline-secondary font-weight-bold px-4 py-0" type="submit">Unfollow</button>
</form>
</span>
@elseif ($following == false)
<span class="pl-4">
<form class="follow-form" method="post" action="/i/follow" style="display: inline;" data-id="{{$user->id}}" data-action="follow">
@csrf
<input type="hidden" name="item" value="{{$user->id}}">
<button class="btn btn-primary font-weight-bold px-4 py-0" type="submit">Follow</button>
</form>
</span>
@endif
{{-- TODO: Implement action dropdown
<span class="pl-4">
<div class="dropdown">
<button class="btn btn-secondary dropdown-toggle py-0" type="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
<i class="icon-options"></i>
</button>
<div class="dropdown-menu" aria-labelledby="dropdownMenuButton">
<a class="dropdown-item" href="#">Report User</a>
<a class="dropdown-item" href="#">Block User</a>
</div>
</div>
</span>
--}}
</div>
<div class="profile-stats pb-3 d-inline-flex lead">
<div class="font-weight-light pr-5">
<a class="text-dark" href="{{$user->url()}}">
<span class="font-weight-bold">{{$user->statuses()->whereNull('in_reply_to_id')->count()}}</span>
Posts
</a>
</div>
<div class="font-weight-light pr-5">
<a class="text-dark" href="{{$user->url('/followers')}}">
<span class="font-weight-bold">{{$user->followerCount(true)}}</span>
Followers
</a>
</div>
<div class="font-weight-light pr-5">
<a class="text-dark" href="{{$user->url('/following')}}">
<span class="font-weight-bold">{{$user->followingCount(true)}}</span>
Following
</a>
</div>
</div>
<p class="lead">
<span class="font-weight-bold">{{$user->name}}</span>
@if($user->remote_url)
<span class="badge badge-info">REMOTE PROFILE</span>
@endif
{{$user->bio}}
</p>
</div>
</div>
</div>
</div>
</div>

View file

@ -2,84 +2,10 @@
@section('content') @section('content')
<div class="container"> @include('profile.partial.user-info')
<div class="profile-header row my-5"> @if($owner == true)
<div class="col-12 col-md-4 d-flex"> <div>
<div class="profile-avatar mx-auto">
<img class="img-thumbnail" src="{{$user->avatarUrl()}}" style="border-radius:100%;" width="172px">
</div>
</div>
<div class="col-12 col-md-8 d-flex align-items-center">
<div class="profile-details">
<div class="username-bar pb-2 d-flex align-items-center">
<span class="font-weight-ultralight h1">{{$user->username}}</span>
@if($owner == true)
<span class="h5 pl-2 b-0">
<a class="icon-settings text-muted" href="{{route('settings')}}"></a>
</span>
@elseif ($following == true)
<span class="pl-4">
<form class="follow-form" method="post" action="/i/follow" style="display: inline;" data-id="{{$user->id}}" data-action="unfollow">
@csrf
<input type="hidden" name="item" value="{{$user->id}}">
<button class="btn btn-outline-secondary font-weight-bold px-4 py-0" type="submit">Unfollow</button>
</form>
</span>
@elseif ($following == false)
<span class="pl-4">
<form class="follow-form" method="post" action="/i/follow" style="display: inline;" data-id="{{$user->id}}" data-action="follow">
@csrf
<input type="hidden" name="item" value="{{$user->id}}">
<button class="btn btn-primary font-weight-bold px-4 py-0" type="submit">Follow</button>
</form>
</span>
@endif
{{-- TODO: Implement action dropdown
<span class="pl-4">
<div class="dropdown">
<button class="btn btn-secondary dropdown-toggle py-0" type="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
<i class="icon-options"></i>
</button>
<div class="dropdown-menu" aria-labelledby="dropdownMenuButton">
<a class="dropdown-item" href="#">Report User</a>
<a class="dropdown-item" href="#">Block User</a>
</div>
</div>
</span>--}}
</div>
<div class="profile-stats pb-3 d-inline-flex lead">
<div class="font-weight-light pr-5">
<span class="font-weight-bold">{{$user->statuses()->whereNull('in_reply_to_id')->count()}}</span>
Posts
</div>
<div class="font-weight-light pr-5">
<a class="text-dark" href="{{$user->url('/followers')}}">
<span class="font-weight-bold">{{$user->followerCount(true)}}</span>
Followers
</a>
</div>
<div class="font-weight-light pr-5">
<a class="text-dark" href="{{$user->url('/following')}}">
<span class="font-weight-bold">{{$user->followingCount(true)}}</span>
Following
</a>
</div>
</div>
<p class="lead">
<span class="font-weight-bold">{{$user->name}}</span>
@if($user->remote_url)
<span class="badge badge-info">REMOTE PROFILE</span>
@endif
{{$user->bio}}
</p>
</div>
</div>
</div>
<div class="profile-timeline mt-5 row">
@if($owner == true)
<div class="col-12 mb-5">
<ul class="nav nav-topbar d-flex justify-content-center"> <ul class="nav nav-topbar d-flex justify-content-center">
<li class="nav-item"> <li class="nav-item">
<a class="nav-link {{request()->is('*/saved') ? '':'active'}} font-weight-bold text-uppercase" href="{{$user->url()}}">Posts</a> <a class="nav-link {{request()->is('*/saved') ? '':'active'}} font-weight-bold text-uppercase" href="{{$user->url()}}">Posts</a>
@ -88,15 +14,15 @@
<a class="nav-link {{request()->is('*/saved') ? 'active':''}} font-weight-bold text-uppercase" href="{{$user->url('/saved')}}">Saved</a> <a class="nav-link {{request()->is('*/saved') ? 'active':''}} font-weight-bold text-uppercase" href="{{$user->url('/saved')}}">Saved</a>
</li> </li>
</ul> </ul>
</div> </div>
@endif @endif
<div class="container">
<div class="profile-timeline mt-5 row">
@if($owner && request()->is('*/saved')) @if($owner && request()->is('*/saved'))
<div class="col-12"> <div class="col-12">
<p class="text-muted font-weight-bold small">{{__('profile.savedWarning')}}</p> <p class="text-muted font-weight-bold small">{{__('profile.savedWarning')}}</p>
</div> </div>
@endif @endif
@if($timeline->count() > 0) @if($timeline->count() > 0)
@foreach($timeline as $status) @foreach($timeline as $status)
<div class="col-12 col-md-4 mb-4"> <div class="col-12 col-md-4 mb-4">
@ -129,7 +55,6 @@
</div> </div>
@endif @endif
</div> </div>
</div> </div>
@endsection @endsection

View file

@ -5,11 +5,7 @@
<div class="container px-0 mt-md-4"> <div class="container px-0 mt-md-4">
<div class="card status-container orientation-{{$status->firstMedia()->orientation ?? 'unknown'}}"> <div class="card status-container orientation-{{$status->firstMedia()->orientation ?? 'unknown'}}">
<div class="row mx-0"> <div class="row mx-0">
<div class="col-12 col-md-8 status-photo px-0"> <div class="d-flex d-md-none align-items-center justify-content-between card-header w-100">
<img src="{{$status->mediaUrl()}}" width="100%">
</div>
<div class="col-12 col-md-4 px-0 d-flex flex-column">
<div class="d-flex align-items-center justify-content-between card-header">
<div class="d-flex align-items-center status-username"> <div class="d-flex align-items-center status-username">
<div class="status-avatar mr-2"> <div class="status-avatar mr-2">
<img class="img-thumbnail" src="{{$user->avatarUrl()}}" width="24px" height="24px" style="border-radius:12px;"> <img class="img-thumbnail" src="{{$user->avatarUrl()}}" width="24px" height="24px" style="border-radius:12px;">
@ -22,6 +18,24 @@
<p class="small text-uppercase mb-0"><a href="{{$status->url()}}" class="text-muted">{{$status->created_at->diffForHumans(null, true, true, true)}}</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> </div>
<div class="col-12 col-md-8 status-photo px-0">
<img src="{{$status->mediaUrl()}}" width="100%">
</div>
<div class="col-12 col-md-4 px-0 d-flex flex-column border-left border-md-left-0">
<div class="d-md-flex d-none align-items-center justify-content-between card-header">
<div class="d-flex align-items-center status-username">
<div class="status-avatar mr-2">
<img class="img-thumbnail" src="{{$user->avatarUrl()}}" width="24px" height="24px" style="border-radius:12px;">
</div>
<div class="username">
<a href="{{$user->url()}}" class="username-link font-weight-bold text-dark">{{$user->username}}</a>
</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(null, true, true, true)}}</a></p>
</div>
</div>
<div class="d-flex flex-md-column flex-column-reverse h-100">
<div class="card-body status-comments"> <div class="card-body status-comments">
<div class="status-comment"> <div class="status-comment">
<p class="mb-1"> <p class="mb-1">
@ -74,7 +88,8 @@
<span class="like-count" data-count="{{$status->likes_count}}">{{$status->likes_count}}</span> likes <span class="like-count" data-count="{{$status->likes_count}}">{{$status->likes_count}}</span> likes
</div> </div>
</div> </div>
<div class="card-footer"> </div>
<div class="card-footer bg-light sticky-md-bottom">
<form class="comment-form" method="post" action="/i/comment" data-id="{{$status->id}}" data-truncate="false"> <form class="comment-form" method="post" action="/i/comment" data-id="{{$status->id}}" data-truncate="false">
@csrf @csrf
<input type="hidden" name="item" value="{{$status->id}}"> <input type="hidden" name="item" value="{{$status->id}}">