mirror of
https://github.com/pixelfed/pixelfed.git
synced 2025-01-09 21:50:45 +00:00
commit
55adeda9bb
20 changed files with 108 additions and 62 deletions
|
@ -69,6 +69,7 @@
|
|||
- Updated InternalApiController, add media tags. ([ee93f459](https://github.com/pixelfed/pixelfed/commit/ee93f459))
|
||||
- Updated ComposeModal.vue, add media tagging. ([421ea022](https://github.com/pixelfed/pixelfed/commit/421ea022))
|
||||
- Updated NotificationTransformer, add modlog and tagged types. ([49dab6fb](https://github.com/pixelfed/pixelfed/commit/49dab6fb))
|
||||
- Updated comments, fix remote reply bug. ([f330616](https://github.com/pixelfed/pixelfed/commit/f330616))
|
||||
|
||||
## [v0.10.9 (2020-04-17)](https://github.com/pixelfed/pixelfed/compare/v0.10.8...v0.10.9)
|
||||
### Added
|
||||
|
|
|
@ -58,9 +58,6 @@ class RegisterController extends Controller
|
|||
$data['email'] = strtolower($data['email']);
|
||||
}
|
||||
|
||||
$this->validateUsername($data['username']);
|
||||
$this->validateEmail($data['email']);
|
||||
|
||||
$usernameRules = [
|
||||
'required',
|
||||
'min:2',
|
||||
|
@ -87,6 +84,25 @@ class RegisterController extends Controller
|
|||
if(!ctype_alnum($val)) {
|
||||
return $fail('Username is invalid. Username must be alpha-numeric and may contain dashes (-), periods (.) and underscores (_).');
|
||||
}
|
||||
|
||||
$restricted = RestrictedNames::get();
|
||||
if (in_array($value, $restricted)) {
|
||||
return $fail('Username cannot be used.');
|
||||
}
|
||||
},
|
||||
];
|
||||
|
||||
$emailRules = [
|
||||
'required',
|
||||
'string',
|
||||
'email',
|
||||
'max:255',
|
||||
'unique:users',
|
||||
function ($attribute, $value, $fail) {
|
||||
$banned = EmailService::isBanned($value);
|
||||
if($banned) {
|
||||
return $fail('Email is invalid.');
|
||||
}
|
||||
},
|
||||
];
|
||||
|
||||
|
@ -94,7 +110,7 @@ class RegisterController extends Controller
|
|||
'agecheck' => 'required|accepted',
|
||||
'name' => 'nullable|string|max:'.config('pixelfed.max_name_length'),
|
||||
'username' => $usernameRules,
|
||||
'email' => 'required|string|email|max:255|unique:users',
|
||||
'email' => $emailRules,
|
||||
'password' => 'required|string|min:12|confirmed',
|
||||
];
|
||||
|
||||
|
@ -123,23 +139,6 @@ class RegisterController extends Controller
|
|||
]);
|
||||
}
|
||||
|
||||
public function validateUsername($username)
|
||||
{
|
||||
$restricted = RestrictedNames::get();
|
||||
|
||||
if (in_array($username, $restricted)) {
|
||||
return abort(403);
|
||||
}
|
||||
}
|
||||
|
||||
public function validateEmail($email)
|
||||
{
|
||||
$banned = EmailService::isBanned($email);
|
||||
if($banned) {
|
||||
return abort(403, 'Invalid email.');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Show the application registration form.
|
||||
*
|
||||
|
|
|
@ -110,7 +110,7 @@ class PublicApiController extends Controller
|
|||
]);
|
||||
|
||||
$limit = $request->limit ?? 10;
|
||||
$profile = Profile::whereUsername($username)->whereNull('status')->firstOrFail();
|
||||
$profile = Profile::whereNull('status')->findOrFail($username);
|
||||
$status = Status::whereProfileId($profile->id)->whereCommentsDisabled(false)->findOrFail($postId);
|
||||
$this->scopeCheck($profile, $status);
|
||||
|
||||
|
|
|
@ -136,6 +136,6 @@ class AuthLogin
|
|||
|
||||
protected function userLanguage($user)
|
||||
{
|
||||
session()->put('locale', $user->language ?? 'en');
|
||||
session()->put('locale', $user->language ?? config('app.locale'));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,10 +6,10 @@ chown -R www-data:www-data storage/ bootstrap/
|
|||
|
||||
# Refresh the environment
|
||||
php artisan storage:link
|
||||
php artisan horizon:assets
|
||||
php artisan horizon:publish
|
||||
php artisan route:cache
|
||||
php artisan view:cache
|
||||
php artisan config:cache
|
||||
|
||||
# Finally run Apache
|
||||
exec apache2-foreground
|
||||
apache2-foreground
|
||||
|
|
|
@ -6,10 +6,10 @@ chown -R www-data:www-data storage/ bootstrap/
|
|||
|
||||
# Refresh the environment
|
||||
php artisan storage:link
|
||||
php artisan horizon:assets
|
||||
php artisan horizon:publish
|
||||
php artisan route:cache
|
||||
php artisan view:cache
|
||||
php artisan config:cache
|
||||
|
||||
# Finally run FPM
|
||||
exec php-fpm
|
||||
php-fpm
|
||||
|
|
BIN
public/css/app.css
vendored
BIN
public/css/app.css
vendored
Binary file not shown.
BIN
public/css/landing.css
vendored
BIN
public/css/landing.css
vendored
Binary file not shown.
BIN
public/js/profile.js
vendored
BIN
public/js/profile.js
vendored
Binary file not shown.
BIN
public/js/rempos.js
vendored
BIN
public/js/rempos.js
vendored
Binary file not shown.
BIN
public/js/status.js
vendored
BIN
public/js/status.js
vendored
Binary file not shown.
BIN
public/js/timeline.js
vendored
BIN
public/js/timeline.js
vendored
Binary file not shown.
Binary file not shown.
|
@ -1120,7 +1120,7 @@ export default {
|
|||
},
|
||||
|
||||
fetchComments() {
|
||||
let url = '/api/v2/comments/'+this.statusUsername+'/status/'+this.statusId;
|
||||
let url = '/api/v2/comments/'+this.statusProfileId+'/status/'+this.statusId;
|
||||
axios.get(url)
|
||||
.then(response => {
|
||||
let self = this;
|
||||
|
@ -1306,7 +1306,7 @@ export default {
|
|||
reply.thread = true;
|
||||
return;
|
||||
}
|
||||
let url = '/api/v2/comments/'+reply.account.username+'/status/'+reply.id;
|
||||
let url = '/api/v2/comments/'+reply.account.id+'/status/'+reply.id;
|
||||
axios.get(url)
|
||||
.then(response => {
|
||||
reply.replies = _.reverse(response.data.data);
|
||||
|
|
|
@ -42,7 +42,7 @@
|
|||
<div class="card-body text-center pt-3">
|
||||
<p class="mb-0">
|
||||
<a :href="'/'+rec.username">
|
||||
<img :src="rec.avatar" class="img-fluid rounded-circle cursor-pointer" width="45px" height="45px" onerror="this.onerror=null;this.src='/storage/avatars/default.png?v=2'">
|
||||
<img :src="rec.avatar" class="img-fluid rounded-circle cursor-pointer" width="45px" height="45px" onerror="this.onerror=null;this.src='/storage/avatars/default.png?v=2'" alt="avatar">
|
||||
</a>
|
||||
</p>
|
||||
<div class="py-3">
|
||||
|
@ -97,7 +97,7 @@
|
|||
</div>
|
||||
<div v-else> -->
|
||||
<div>
|
||||
<img class="rounded-circle box-shadow" :src="status.account.avatar" width="32px" height="32px" onerror="this.onerror=null;this.src='/storage/avatars/default.png?v=2'">
|
||||
<img class="rounded-circle box-shadow" :src="status.account.avatar" width="32px" height="32px" onerror="this.onerror=null;this.src='/storage/avatars/default.png?v=2'" alt="avatar">
|
||||
</div>
|
||||
<div class="pl-2">
|
||||
<!-- <a class="d-block username font-weight-bold text-dark" v-bind:href="status.account.url" style="line-height:0.5;"> -->
|
||||
|
@ -117,12 +117,13 @@
|
|||
<span class="font-weight-bold cursor-pointer text-primary">Follow</span>
|
||||
</span> -->
|
||||
<div class="d-flex align-items-center">
|
||||
<a v-if="status.place" class="small text-decoration-none" :href="'/discover/places/'+status.place.id+'/'+status.place.slug" style="color:#718096" title="Location" data-toggle="tooltip"><i class="fas fa-map-marked-alt"></i> {{status.place.name}}, {{status.place.country}}</a>
|
||||
<a v-if="status.place" class="small text-decoration-none text-muted" :href="'/discover/places/'+status.place.id+'/'+status.place.slug" title="Location" data-toggle="tooltip"><i class="fas fa-map-marked-alt"></i> {{status.place.name}}, {{status.place.country}}</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="text-right" style="flex-grow:1;">
|
||||
<button class="btn btn-link text-dark py-0" type="button" @click="ctxMenu(status)">
|
||||
<span class="fas fa-ellipsis-h text-lighter"></span>
|
||||
<span class="sr-only">Post Menu</span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -164,7 +165,7 @@
|
|||
<i class="far fa-user" data-toggle="tooltip" title="Tagged People"></i>
|
||||
<span v-for="(tag, index) in status.taggedPeople" class="mr-n2">
|
||||
<a :href="'/'+tag.username">
|
||||
<img :src="tag.avatar" width="20px" height="20px" class="border rounded-circle" data-toggle="tooltip" :title="'@'+tag.username">
|
||||
<img :src="tag.avatar" width="20px" height="20px" class="border rounded-circle" data-toggle="tooltip" :title="'@'+tag.username" alt="Avatar">
|
||||
</a>
|
||||
</span>
|
||||
</span>
|
||||
|
@ -257,10 +258,10 @@
|
|||
<a :href="!userStory ? profile.url : '/stories/' + profile.acct" class="mr-3">
|
||||
<!-- <img class="mr-3 rounded-circle box-shadow" :src="profile.avatar || '/storage/avatars/default.png'" alt="avatar" width="64px" height="64px" onerror="this.onerror=null;this.src='/storage/avatars/default.png?v=2'"> -->
|
||||
<div v-if="userStory" class="has-story cursor-pointer shadow-sm" @click="storyRedirect()">
|
||||
<img class="rounded-circle box-shadow" :src="profile.avatar" width="64px" height="64px" onerror="this.onerror=null;this.src='/storage/avatars/default.png?v=2'">
|
||||
<img class="rounded-circle box-shadow" :src="profile.avatar" width="64px" height="64px" onerror="this.onerror=null;this.src='/storage/avatars/default.png?v=2'" alt="avatar">
|
||||
</div>
|
||||
<div v-else>
|
||||
<img class="rounded-circle box-shadow" :src="profile.avatar" width="64px" height="64px" onerror="this.onerror=null;this.src='/storage/avatars/default.png?v=2'">
|
||||
<img class="rounded-circle box-shadow" :src="profile.avatar" width="64px" height="64px" onerror="this.onerror=null;this.src='/storage/avatars/default.png?v=2'" alt="avatar">
|
||||
</div>
|
||||
</a>
|
||||
<div class="media-body d-flex justify-content-between word-break" >
|
||||
|
@ -269,7 +270,10 @@
|
|||
<p class="my-0 text-muted pb-0">{{profile.display_name || 'loading...'}}</p>
|
||||
</div>
|
||||
<div class="ml-2">
|
||||
<a class="text-muted" href="/settings/home"><i class="fas fa-cog fa-lg"></i></a>
|
||||
<a class="text-muted" href="/settings/home">
|
||||
<i class="fas fa-cog fa-lg"></i>
|
||||
<span class="sr-only">User Settings</span>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -313,7 +317,7 @@
|
|||
<div class="card-body pt-0">
|
||||
<div v-for="(rec, index) in suggestions" class="media align-items-center mt-3">
|
||||
<a :href="'/'+rec.username">
|
||||
<img :src="rec.avatar" width="32px" height="32px" class="rounded-circle mr-3" onerror="this.onerror=null;this.src='/storage/avatars/default.png?v=2'">
|
||||
<img :src="rec.avatar" width="32px" height="32px" class="rounded-circle mr-3" onerror="this.onerror=null;this.src='/storage/avatars/default.png?v=2'" alt="avatar">
|
||||
</a>
|
||||
<div class="media-body">
|
||||
<p class="mb-0 font-weight-bold small">
|
||||
|
@ -510,7 +514,7 @@
|
|||
body-class="p-0"
|
||||
>
|
||||
<div v-if="lightboxMedia" :class="lightboxMedia.filter_class" class="w-100 h-100">
|
||||
<img :src="lightboxMedia.url" style="max-height: 100%; max-width: 100%">
|
||||
<img :src="lightboxMedia.url" style="max-height: 100%; max-width: 100%" alt="lightbox media">
|
||||
</div>
|
||||
</b-modal>
|
||||
<b-modal ref="replyModal"
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
</summary>
|
||||
<carousel ref="carousel" :centerMode="true" :loop="false" :per-page="1" :paginationPosition="'bottom-overlay'" paginationActiveColor="#3897f0" paginationColor="#dbdbdb">
|
||||
<slide v-for="(img, index) in status.media_attachments" :key="'px-carousel-'+img.id + '-' + index" class="w-100 h-100 d-block mx-auto text-center" :title="img.description">
|
||||
<img :class="img.filter_class + ' img-fluid'" :src="img.url" :alt="img.description" onerror="this.onerror=null;this.src='/storage/no-preview.png'">
|
||||
<img :class="img.filter_class + ' img-fluid'" :src="img.url" :alt="altText(img)" onerror="this.onerror=null;this.src='/storage/no-preview.png'">
|
||||
</slide>
|
||||
</carousel>
|
||||
</details>
|
||||
|
@ -15,7 +15,7 @@
|
|||
<div v-else class="w-100 h-100 p-0">
|
||||
<carousel ref="carousel" :centerMode="true" :loop="false" :per-page="1" :paginationPosition="'bottom-overlay'" paginationActiveColor="#3897f0" paginationColor="#dbdbdb" class="p-0 m-0">
|
||||
<slide v-for="(img, index) in status.media_attachments" :key="'px-carousel-'+img.id + '-' + index" class="" style="background: #000; display: flex;align-items: center;" :title="img.description">
|
||||
<img :class="img.filter_class + ' img-fluid w-100 p-0'" style="" :src="img.url" :alt="img.description" onerror="this.onerror=null;this.src='/storage/no-preview.png'">
|
||||
<img :class="img.filter_class + ' img-fluid w-100 p-0'" style="" :src="img.url" :alt="altText(img)" onerror="this.onerror=null;this.src='/storage/no-preview.png'">
|
||||
</slide>
|
||||
</carousel>
|
||||
</div>
|
||||
|
@ -52,6 +52,15 @@
|
|||
this.$refs.carousel.goToPage(0);
|
||||
},
|
||||
|
||||
altText(img) {
|
||||
let desc = img.description;
|
||||
if(desc) {
|
||||
return desc;
|
||||
}
|
||||
|
||||
return 'Photo was not tagged with any alt text.';
|
||||
},
|
||||
|
||||
keypressNavigation(e) {
|
||||
let ref = this.$refs.carousel;
|
||||
if (e.keyCode == "37") {
|
||||
|
|
|
@ -6,13 +6,13 @@
|
|||
<p class="font-weight-light">(click to show)</p>
|
||||
</summary>
|
||||
<div class="max-hide-overflow" :title="status.media_attachments[0].description">
|
||||
<img :class="status.media_attachments[0].filter_class + ' card-img-top'" :src="status.media_attachments[0].url" loading="lazy" :alt="status.media_attachments[0].description" onerror="this.onerror=null;this.src='/storage/no-preview.png'">
|
||||
<img :class="status.media_attachments[0].filter_class + ' card-img-top'" :src="status.media_attachments[0].url" loading="lazy" :alt="altText(status)" onerror="this.onerror=null;this.src='/storage/no-preview.png'">
|
||||
</div>
|
||||
</details>
|
||||
</div>
|
||||
<div v-else>
|
||||
<div :title="status.media_attachments[0].description">
|
||||
<img :class="status.media_attachments[0].filter_class + ' card-img-top'" :src="status.media_attachments[0].url" loading="lazy" :alt="status.media_attachments[0].description" onerror="this.onerror=null;this.src='/storage/no-preview.png'">
|
||||
<img :class="status.media_attachments[0].filter_class + ' card-img-top'" :src="status.media_attachments[0].url" loading="lazy" :alt="altText(status)" onerror="this.onerror=null;this.src='/storage/no-preview.png'">
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
@ -26,6 +26,17 @@
|
|||
|
||||
<script type="text/javascript">
|
||||
export default {
|
||||
props: ['status']
|
||||
props: ['status'],
|
||||
|
||||
methods: {
|
||||
altText(status) {
|
||||
let desc = status.media_attachments[0].description;
|
||||
if(desc) {
|
||||
return desc;
|
||||
}
|
||||
|
||||
return 'Photo was not tagged with any alt text.';
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
5
resources/assets/sass/_variables.scss
vendored
5
resources/assets/sass/_variables.scss
vendored
|
@ -1,6 +1,6 @@
|
|||
|
||||
// Body
|
||||
$body-bg: #f5f8fa;
|
||||
$body-bg: #f7fbfd78;
|
||||
|
||||
// Typography
|
||||
$font-family-sans-serif:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,Helvetica,Arial,sans-serif;
|
||||
|
@ -19,7 +19,8 @@ $custom-control-indicator-disabled-bg: #e9ecef;
|
|||
$custom-control-description-disabled-color: #868e96;
|
||||
$white: white;
|
||||
$theme-colors: (
|
||||
'primary': #08d
|
||||
'primary': #2c78bf,
|
||||
'muted' : #697179
|
||||
);
|
||||
|
||||
$card-cap-bg: $white;
|
||||
|
|
|
@ -7,11 +7,11 @@
|
|||
|
||||
<div class="collapse navbar-collapse">
|
||||
@auth
|
||||
<ul class="navbar-nav d-none d-md-block mx-auto">
|
||||
<div class="navbar-nav d-none d-md-block mx-auto">
|
||||
<form class="form-inline search-bar" method="get" action="/i/results">
|
||||
<input class="form-control form-control-sm" name="q" placeholder="{{__('navmenu.search')}}" aria-label="search" autocomplete="off" required style="line-height: 0.6;width:200px">
|
||||
<input class="form-control form-control-sm" name="q" placeholder="{{__('navmenu.search')}}" aria-label="search" autocomplete="off" required style="line-height: 0.6;width:200px" role="search">
|
||||
</form>
|
||||
</ul>
|
||||
</div>
|
||||
@endauth
|
||||
|
||||
@guest
|
||||
|
@ -32,23 +32,22 @@
|
|||
@else
|
||||
<div class="ml-auto">
|
||||
<ul class="navbar-nav">
|
||||
<div class="d-none d-md-block">
|
||||
<li class="nav-item px-md-2">
|
||||
<li class="nav-item px-md-2 d-none d-md-block">
|
||||
<a class="nav-link font-weight-bold text-muted" href="{{route('discover')}}" title="Discover" data-toggle="tooltip" data-placement="bottom">
|
||||
<i class="far fa-compass fa-lg"></i>
|
||||
<span class="sr-only">Discover</span>
|
||||
</a>
|
||||
</li>
|
||||
</div>
|
||||
<div class="d-none d-md-block">
|
||||
<li class="nav-item px-md-2">
|
||||
<li class="nav-item px-md-2 d-none d-md-block">
|
||||
<a class="nav-link font-weight-bold text-muted" href="/account/activity" title="Notifications" data-toggle="tooltip" data-placement="bottom">
|
||||
<i class="far fa-bell fa-lg"></i>
|
||||
<span class="sr-only">Notifications</span>
|
||||
</a>
|
||||
</li>
|
||||
</div>
|
||||
<li class="nav-item dropdown ml-2">
|
||||
<a id="navbarDropdown" class="nav-link dropdown-toggle" href="#" role="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false" title="User Menu" data-toggle="tooltip" data-placement="bottom">
|
||||
<i class="far fa-user fa-lg text-muted"></i>
|
||||
<span class="sr-only">User Menu</span>
|
||||
</a>
|
||||
|
||||
<div class="dropdown-menu dropdown-menu-right" aria-labelledby="navbarDropdown">
|
||||
|
|
22
resources/views/site/redirect.blade.php
Normal file
22
resources/views/site/redirect.blade.php
Normal file
|
@ -0,0 +1,22 @@
|
|||
@extends('layouts.blank')
|
||||
|
||||
@section('content')
|
||||
<div style="width:100%;height:100vh;" class="d-flex justify-content-center align-items-center">
|
||||
<div class="text-center">
|
||||
<img src="/img/pixelfed-icon-grey.svg">
|
||||
<p class="mt-3 py-4">Redirecting to <span class="font-weight-bold">{{$url}}</span></p>
|
||||
<div class="spinner-border text-lighter" role="status">
|
||||
<span class="sr-only">Loading...</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@endsection
|
||||
|
||||
@push('scripts')
|
||||
<script type="text/javascript">
|
||||
window.history.replaceState({}, document.title, '/i/redirect');
|
||||
setTimeout(function() {
|
||||
window.location.href = '{{$url}}';
|
||||
}, 1500);
|
||||
</script>
|
||||
@endpush
|
Loading…
Reference in a new issue