Merge pull request #1560 from pixelfed/frontend-ui-refactor

Frontend ui refactor
This commit is contained in:
daniel 2019-07-30 19:52:47 -06:00 committed by GitHub
commit 320542888b
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
14 changed files with 42 additions and 403 deletions

View file

@ -296,4 +296,11 @@ class Profile extends Model
{
return $this->hasMany(Collection::class);
}
public function hasFollowRequestById(int $id)
{
return FollowRequest::whereFollowerId($id)
->whereFollowingId($this->id)
->exists();
}
}

View file

@ -125,7 +125,7 @@ class Helpers {
{
$audience = self::normalizeAudience($data);
$url = $profile->permalink();
return in_array($url, $audience);
return in_array($url, $audience['to']) || in_array($url, $audience['cc']);
}
public static function validateUrl($url)
@ -328,7 +328,9 @@ class Helpers {
$status->scope = $scope;
$status->visibility = $scope;
$status->save();
self::importNoteAttachment($res, $status);
if($reply_to == null) {
self::importNoteAttachment($res, $status);
}
return $status;
});

View file

@ -137,15 +137,13 @@ class Inbox
public function handleNoteCreate()
{
return;
$activity = $this->payload['object'];
$actor = $this->actorFirstOrCreate($this->payload['actor']);
if(!$actor || $actor->domain == null) {
return;
}
if(Helpers::userInAudience($this->profile, $this->payload) == false) {
if($actor->followers()->count() == 0) {
return;
}

View file

@ -11,7 +11,7 @@ trait User {
public function getMaxPostsPerHourAttribute()
{
return 20;
return 50;
}
public function getMaxPostsPerDayAttribute()

View file

@ -29,5 +29,15 @@ return [
]
],
'page' => [
'404' => [
'header' => env('PAGE_404_HEADER', 'Sorry, this page isn\'t available.'),
'body' => env('PAGE_404_BODY', 'The link you followed may be broken, or the page may have been removed. <a href="/">Go back to Pixelfed.</a>')
],
'503' => [
'header' => env('PAGE_503_HEADER', 'Service Unavailable'),
'body' => env('PAGE_503_BODY', 'Our service is in maintenance mode, please try again later.')
]
],
];

View file

@ -1 +1,15 @@
require('./bootstrap');
window._ = require('lodash');
window.Popper = require('popper.js').default;
window.pixelfed = window.pixelfed || {};
window.$ = window.jQuery = require('jquery');
require('bootstrap');
window.axios = require('axios');
window.axios.defaults.headers.common['X-Requested-With'] = 'XMLHttpRequest';
require('readmore-js');
let token = document.head.querySelector('meta[name="csrf-token"]');
if (token) {
window.axios.defaults.headers.common['X-CSRF-TOKEN'] = token.content;
} else {
console.error('CSRF token not found: https://laravel.com/docs/csrf#csrf-x-csrf-token');
}

View file

@ -1,15 +0,0 @@
window._ = require('lodash');
window.Popper = require('popper.js').default;
window.pixelfed = window.pixelfed || {};
window.$ = window.jQuery = require('jquery');
require('bootstrap');
window.axios = require('axios');
window.axios.defaults.headers.common['X-Requested-With'] = 'XMLHttpRequest';
require('readmore-js');
let token = document.head.querySelector('meta[name="csrf-token"]');
if (token) {
window.axios.defaults.headers.common['X-CSRF-TOKEN'] = token.content;
} else {
console.error('CSRF token not found: https://laravel.com/docs/csrf#csrf-x-csrf-token');
}

View file

@ -1,8 +0,0 @@
$(document).ready(function() {
$(document).on('submit', '.bookmark-form', function(e) {
e.preventDefault();
var el = $(this);
var id = el.data('id');
var res = axios.post('/i/bookmark', {item: id});
});
});

View file

@ -1,51 +0,0 @@
$(document).ready(function() {
$('.status-card > .card-footer').each(function() {
$(this).addClass('d-none');
});
$(document).on('click', '.status-comment-focus', function(el) {
var form = $(this).parents().eq(2).find('.card-footer');
form.removeClass('d-none');
var el = $(this).parents().eq(2).find('input[name="comment"]');
el.focus();
});
$(document).on('submit', '.comment-form', function(e, data) {
e.preventDefault();
let el = $(this);
let id = el.data('id');
let commentform = el.find('input[name="comment"]');
let commenttext = commentform.val();
let item = {item: id, comment: commenttext};
commentform.prop('disabled', true);
axios.post('/i/comment', item)
.then(function (res) {
var username = res.data.username;
var permalink = res.data.url;
var profile = res.data.profile;
var reply = res.data.comment;
if($('.status-container').length == 1) {
var comments = el.parents().eq(3).find('.comments');
} else {
var comments = el.parents().eq(1).find('.comments');
}
var comment = '<p class="mb-0"><span class="font-weight-bold pr-1"><bdi><a class="text-dark" href="' + profile + '">' + username + '</a></bdi></span><span class="comment-text">'+ reply + '</span></p>';
comments.prepend(comment);
commentform.val('');
commentform.blur();
commentform.prop('disabled', false);
})
.catch(function (res) {
});
});
});

View file

@ -1,33 +0,0 @@
window.ls = {};
window.ls.get = function(key) {
return JSON.parse(localStorage.getItem(key));
}
window.ls.set = function(key, val) {
try {
localStorage.setItem(key, JSON.stringify(val));
return true;
} catch(e) {
return false;
}
}
window.ls.del = function(key) {
try {
localStorage.removeItem(key);
return true;
} catch(e) {
return false;
}
}
window.ls.clear = function() {
try {
localStorage.clear();
return true;
} catch(e) {
return false;
}
}

View file

@ -1,159 +0,0 @@
$(document).ready(function() {
$('.nav-link.nav-notification').on('click', function(e) {
e.preventDefault();
let el = $(this);
if(el.attr('data-toggle') == 'tooltip') {
el.attr('data-toggle', 'dropdown');
el.tooltip('dispose');
}
let container = $('.navbar .nav-notification-dropdown');
if(pixelfed.notifications) {
return;
}
axios.get('/api/v2/notifications')
.then((res) => {
$('.nav-notification-dropdown .loader').hide();
let data = res.data;
data.forEach(function(v, k) {
let action = v.action;
let notification = $('<li>').addClass('dropdown-item py-3')
if(v.read_at == null) {
notification.attr('style', 'border: 1px solid #6cb2eb;background-color: #eff8ff;border-bottom:none;');
} else {
notification.attr('style', 'border-bottom: 1px solid #ccc;');
}
switch(action) {
case 'comment':
let avatar = $('<span>')
.attr('class', 'notification-icon pr-3');
let avatarImg = $('<img>')
.attr('width', '32px')
.attr('height', '32px')
.attr('class', 'rounded-circle')
.attr('style', 'border: 1px solid #ccc')
.attr('src', v.actor.avatar);
avatar = avatar.append(avatarImg);
let text = $('<span>')
.attr('href', v.url)
.attr('class', 'font-weight-bold')
.html(v.rendered);
notification.append(avatar);
notification.append(text);
container.append(notification);
break;
case 'follow':
avatar = $('<span>')
.attr('class', 'notification-icon pr-3');
avatarImg = $('<img>')
.attr('width', '32px')
.attr('height', '32px')
.attr('class', 'rounded-circle')
.attr('style', 'border: 1px solid #ccc')
.attr('src', v.actor.avatar);
avatar = avatar.append(avatarImg);
text = $('<span>')
.attr('href', v.url)
.attr('class', 'font-weight-bold')
.html(v.rendered);
notification.append(avatar);
notification.append(text);
container.append(notification);
break;
}
});
let all = $('<a>')
.attr('class', 'dropdown-item py-3 text-center text-primary font-weight-bold')
.attr('href', '/account/activity')
.attr('style', 'border-top:1px solid #ccc')
.text('View all notifications');
container.append(all);
pixelfed.notifications = true;
}).catch((err) => {
$('.nav-notification-dropdown .loader').addClass('font-weight-bold').text('Something went wrong. Please try again later.');
});
});
$('.notification-action[data-type="mark_read"]').on('click', function(e) {
e.preventDefault();
axios.post('/api/v2/notifications', {
'action': 'mark_read'
}).then(res => {
pixelfed.notifications = false;
ls.del('n.lastCheck');
ls.del('n.count');
swal(
'Success!',
'All of your notifications have been marked as read.',
'success'
);
}).catch(err => {
swal(
'Something went wrong!',
'An error occurred, please try again later.',
'error'
);
});
});
pixelfed.n.showCount = (count = 1) => {
let el = $('.nav-link.nav-notification');
el.tooltip('dispose');
el.attr('title', count)
el.attr('data-toggle', 'tooltip');
el.tooltip({
template: '<div class="tooltip notification-tooltip" role="tooltip"><div class="arrow"></div><div class="tooltip-inner bg-danger px-3"></div></div>'
});
setTimeout(function() {
el.fadeIn(function() {
el.tooltip('show')
});
}, 500);
}
pixelfed.n.sound = () => {
let beep = new Audio('/static/beep.mp3');
beep.play();
}
pixelfed.n.check = (count) => {
// pixelfed.n.sound();
pixelfed.n.showCount(count);
}
pixelfed.n.fetch = (force = false) => {
let now = Date.now();
let ts = ls.get('n.lastCheck');
let count = ls.get('n.count');
let offset = now - 9e5;
if(ts == null) {
ts = now;
}
if(!force && count != null || ts > offset) {
//pixelfed.n.showCount(count);
ls.set('n.lastCheck', ts);
return;
}
axios.get('/api/v2/notifications')
.then(res => {
let len = res.data.length;
if(len > 0) {
ls.set('n.count', len);
ls.set('n.lastCheck', Date.now());
pixelfed.n.check(len);
}
}).catch(err => {
})
}
});

View file

@ -1,126 +0,0 @@
$(document).ready(function() {
pixelfed.create = {};
pixelfed.filters = {};
pixelfed.create.hasGeneratedSelect = false;
pixelfed.create.selectedFilter = false;
pixelfed.create.currentFilterName = false;
pixelfed.create.currentFilterClass = false;
pixelfed.filters.list = [
['1977','filter-1977'],
['Aden','filter-aden'],
['Amaro','filter-amaro'],
['Ashby','filter-ashby'],
['Brannan','filter-brannan'],
['Brooklyn','filter-brooklyn'],
['Charmes','filter-charmes'],
['Clarendon','filter-clarendon'],
['Crema','filter-crema'],
['Dogpatch','filter-dogpatch'],
['Earlybird','filter-earlybird'],
['Gingham','filter-gingham'],
['Ginza','filter-ginza'],
['Hefe','filter-hefe'],
['Helena','filter-helena'],
['Hudson','filter-hudson'],
['Inkwell','filter-inkwell'],
['Kelvin','filter-kelvin'],
['Kuno','filter-juno'],
['Lark','filter-lark'],
['Lo-Fi','filter-lofi'],
['Ludwig','filter-ludwig'],
['Maven','filter-maven'],
['Mayfair','filter-mayfair'],
['Moon','filter-moon'],
['Nashville','filter-nashville'],
['Perpetua','filter-perpetua'],
['Poprocket','filter-poprocket'],
['Reyes','filter-reyes'],
['Rise','filter-rise'],
['Sierra','filter-sierra'],
['Skyline','filter-skyline'],
['Slumber','filter-slumber'],
['Stinson','filter-stinson'],
['Sutro','filter-sutro'],
['Toaster','filter-toaster'],
['Valencia','filter-valencia'],
['Vesper','filter-vesper'],
['Walden','filter-walden'],
['Willow','filter-willow'],
['X-Pro II','filter-xpro-ii']
];
function previewImage(input) {
if (input.files && input.files[0]) {
var reader = new FileReader();
reader.onload = function(e) {
$('.filterPreview').attr('src', e.target.result);
}
reader.readAsDataURL(input.files[0]);
}
}
function generateFilterSelect() {
let filters = pixelfed.filters.list;
for(var i = 0, len = filters.length; i < len; i++) {
let filter = filters[i];
let name = filter[0];
let className = filter[1];
let select = $('#filterSelectDropdown');
var template = '<option value="' + className + '">' + name + '</option>';
select.append(template);
}
pixelfed.create.hasGeneratedSelect = true;
}
$(document).on('change', '#fileInput', function() {
previewImage(this);
$('#statusForm .form-filters.d-none').removeClass('d-none');
$('#statusForm .form-preview.d-none').removeClass('d-none');
$('#statusForm #collapsePreview').collapse('show');
if(!pixelfed.create.hasGeneratedSelect) {
generateFilterSelect();
}
});
$(document).on('change', '#filterSelectDropdown', function() {
let el = $(this);
let filter = el.val();
let oldFilter = pixelfed.create.currentFilterClass;
if(filter == 'none') {
$('input[name=filter_class]').val('');
$('input[name=filter_name]').val('');
$('.filterContainer').removeClass(oldFilter);
pixelfed.create.currentFilterClass = false;
pixelfed.create.currentFilterName = 'None';
$('.form-group.form-preview .form-text').text('Current Filter: No filter selected');
return;
} else {
$('.filterContainer').removeClass(oldFilter).addClass(filter);
pixelfed.create.currentFilterClass = filter;
pixelfed.create.currentFilterName = el.find(':selected').text();
$('.form-group.form-preview .form-text').text('Current Filter: ' + pixelfed.create.currentFilterName);
$('input[name=filter_class]').val(pixelfed.create.currentFilterClass);
$('input[name=filter_name]').val(pixelfed.create.currentFilterName);
return;
}
});
$(document).on('keyup keydown', '#statusForm textarea[name=caption]', function() {
const el = $(this);
const len = el.val().length;
const limit = el.data('limit');
if(len > limit) {
const diff = limit - len;
$('#statusForm .caption-counter').text(diff).addClass('text-danger');
} else {
$('#statusForm .caption-counter').text(len).removeClass('text-danger');
}
});
$(document).on('focus', '#statusForm textarea[name=caption]', function() {
const el = $(this);
el.attr('rows', '3');
});
});

View file

@ -3,8 +3,8 @@
@section('content')
<div class="container">
<div class="error-page py-5 my-5 text-center">
<h3 class="font-weight-bold">Sorry, this page isn't available.</h3>
<p class="lead">The link you followed may be broken, or the page may have been removed. <a href="/">Go back to Pixelfed.</a></p>
<h3 class="font-weight-bold">{!!config('instance.page.404.header')!!}</h3>
<p class="lead">{!!config('instance.page.404.body')!!}</p>
</div>
</div>
@endsection

View file

@ -3,8 +3,8 @@
@section('content')
<div class="container">
<div class="error-page py-5 my-5 text-center">
<h3 class="font-weight-bold">Service Unavailable</h3>
<p class="lead">Our service is in maintenance mode, please try again later. <a href="/">Go back to Pixelfed.</a></p>
<h3 class="font-weight-bold">{!!config('instance.page.503.header')!!}</h3>
<p class="lead">{!!config('instance.page.503.body')!!}</p>
</div>
</div>
@endsection