mirror of
https://github.com/pixelfed/pixelfed.git
synced 2024-12-23 13:33:18 +00:00
Merge pull request #1170 from pixelfed/frontend-ui-refactor
Frontend ui refactor
This commit is contained in:
commit
95685c3c23
5 changed files with 125 additions and 99 deletions
BIN
public/js/timeline.js
vendored
BIN
public/js/timeline.js
vendored
Binary file not shown.
Binary file not shown.
119
resources/assets/js/components/NotificationCard.vue
Normal file
119
resources/assets/js/components/NotificationCard.vue
Normal file
|
@ -0,0 +1,119 @@
|
||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
<div class="card notification-card">
|
||||||
|
<div class="card-header bg-white">
|
||||||
|
<p class="mb-0 d-flex align-items-center justify-content-between">
|
||||||
|
<span class="text-muted font-weight-bold">Notifications</span>
|
||||||
|
<a class="text-dark small" href="/account/activity">See All</a>
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<div class="card-body loader text-center" style="height: 270px;">
|
||||||
|
<div class="spinner-border" role="status">
|
||||||
|
<span class="sr-only">Loading...</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="card-body pt-2 contents" style="max-height: 270px; overflow-y: scroll;">
|
||||||
|
<div v-if="notifications.length > 0" class="media mb-3 align-items-center" v-for="(n, index) in notifications">
|
||||||
|
<img class="mr-2 rounded-circle" style="border:1px solid #ccc" :src="n.account.avatar" alt="" width="32px" height="32px">
|
||||||
|
<div class="media-body font-weight-light small">
|
||||||
|
<div v-if="n.type == 'favourite'">
|
||||||
|
<p class="my-0">
|
||||||
|
<a :href="n.account.url" class="font-weight-bold text-dark word-break">{{n.account.username}}</a> liked your <a class="font-weight-bold" v-bind:href="n.status.url">post</a>.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<div v-else-if="n.type == 'comment'">
|
||||||
|
<p class="my-0">
|
||||||
|
<a :href="n.account.url" class="font-weight-bold text-dark word-break">{{n.account.username}}</a> commented on your <a class="font-weight-bold" v-bind:href="n.status.url">post</a>.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<div v-else-if="n.type == 'mention'">
|
||||||
|
<p class="my-0">
|
||||||
|
<a :href="n.account.url" class="font-weight-bold text-dark word-break">{{n.account.username}}</a> <a class="font-weight-bold" v-bind:href="mentionUrl(n.status)">mentioned</a> you.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<div v-else-if="n.type == 'follow'">
|
||||||
|
<p class="my-0">
|
||||||
|
<a :href="n.account.url" class="font-weight-bold text-dark word-break">{{n.account.username}}</a> followed you.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<div v-else-if="n.type == 'share'">
|
||||||
|
<p class="my-0">
|
||||||
|
<a :href="n.account.url" class="font-weight-bold text-dark word-break">{{n.account.username}}</a> shared your <a class="font-weight-bold" v-bind:href="n.status.reblog.url">post</a>.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div v-if="notifications.length">
|
||||||
|
<infinite-loading @infinite="infiniteNotifications">
|
||||||
|
<div slot="no-results" class="font-weight-bold"></div>
|
||||||
|
<div slot="no-more" class="font-weight-bold"></div>
|
||||||
|
</infinite-loading>
|
||||||
|
</div>
|
||||||
|
<div v-if="notifications.length == 0" class="text-lighter text-center py-3">
|
||||||
|
<p class="mb-0"><i class="fas fa-inbox fa-3x"></i></p>
|
||||||
|
<p class="mb-0 small font-weight-bold">0 Notifications!</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<style type="text/css" scoped></style>
|
||||||
|
|
||||||
|
<script type="text/javascript">
|
||||||
|
export default {
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
notifications: {},
|
||||||
|
notificationCursor: 2
|
||||||
|
};
|
||||||
|
},
|
||||||
|
|
||||||
|
mounted() {
|
||||||
|
this.fetchNotifications();
|
||||||
|
},
|
||||||
|
|
||||||
|
methods: {
|
||||||
|
fetchNotifications() {
|
||||||
|
axios.get('/api/v1/notifications')
|
||||||
|
.then(res => {
|
||||||
|
let data = res.data.filter(n => {
|
||||||
|
if(n.type == 'share' && !status) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
});
|
||||||
|
this.notifications = data;
|
||||||
|
$('.notification-card .loader').addClass('d-none');
|
||||||
|
$('.notification-card .contents').removeClass('d-none');
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
infiniteNotifications($state) {
|
||||||
|
if(this.notificationCursor > 10) {
|
||||||
|
$state.complete();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
axios.get('/api/v1/notifications', {
|
||||||
|
params: {
|
||||||
|
page: this.notificationCursor
|
||||||
|
}
|
||||||
|
}).then(res => {
|
||||||
|
if(res.data.length) {
|
||||||
|
let data = res.data.filter(n => {
|
||||||
|
if(n.type == 'share' && !status) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
});
|
||||||
|
this.notifications.push(...data);
|
||||||
|
this.notificationCursor++;
|
||||||
|
$state.loaded();
|
||||||
|
} else {
|
||||||
|
$state.complete();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
|
@ -222,61 +222,7 @@
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div v-show="modes.notify == true" class="mb-4">
|
<div v-show="modes.notify == true" class="mb-4">
|
||||||
<div class="card notification-card">
|
<notification-card></notification-card>
|
||||||
<div class="card-header bg-white">
|
|
||||||
<p class="mb-0 d-flex align-items-center justify-content-between">
|
|
||||||
<span class="text-muted font-weight-bold">Notifications</span>
|
|
||||||
<a class="text-dark small" href="/account/activity">See All</a>
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
<div class="card-body loader text-center" style="height: 270px;">
|
|
||||||
<div class="spinner-border" role="status">
|
|
||||||
<span class="sr-only">Loading...</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="card-body pt-2 contents" style="max-height: 270px; overflow-y: scroll;">
|
|
||||||
<div v-if="notifications.length > 0" class="media mb-3 align-items-center" v-for="(n, index) in notifications">
|
|
||||||
<img class="mr-2 rounded-circle" style="border:1px solid #ccc" :src="n.account.avatar" alt="" width="32px" height="32px">
|
|
||||||
<div class="media-body font-weight-light small">
|
|
||||||
<div v-if="n.type == 'favourite'">
|
|
||||||
<p class="my-0">
|
|
||||||
<a :href="n.account.url" class="font-weight-bold text-dark word-break">{{n.account.username}}</a> liked your <a class="font-weight-bold" v-bind:href="n.status.url">post</a>.
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
<div v-else-if="n.type == 'comment'">
|
|
||||||
<p class="my-0">
|
|
||||||
<a :href="n.account.url" class="font-weight-bold text-dark word-break">{{n.account.username}}</a> commented on your <a class="font-weight-bold" v-bind:href="n.status.url">post</a>.
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
<div v-else-if="n.type == 'mention'">
|
|
||||||
<p class="my-0">
|
|
||||||
<a :href="n.account.url" class="font-weight-bold text-dark word-break">{{n.account.username}}</a> <a class="font-weight-bold" v-bind:href="mentionUrl(n.status)">mentioned</a> you.
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
<div v-else-if="n.type == 'follow'">
|
|
||||||
<p class="my-0">
|
|
||||||
<a :href="n.account.url" class="font-weight-bold text-dark word-break">{{n.account.username}}</a> followed you.
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
<div v-else-if="n.type == 'share'">
|
|
||||||
<p class="my-0">
|
|
||||||
<a :href="n.account.url" class="font-weight-bold text-dark word-break">{{n.account.username}}</a> shared your <a class="font-weight-bold" v-bind:href="n.status.reblog.url">post</a>.
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div v-if="notifications.length">
|
|
||||||
<infinite-loading @infinite="infiniteNotifications">
|
|
||||||
<div slot="no-results" class="font-weight-bold"></div>
|
|
||||||
<div slot="no-more" class="font-weight-bold"></div>
|
|
||||||
</infinite-loading>
|
|
||||||
</div>
|
|
||||||
<div v-if="notifications.length == 0" class="text-lighter text-center py-3">
|
|
||||||
<p class="mb-0"><i class="fas fa-inbox fa-3x"></i></p>
|
|
||||||
<p class="mb-0 small font-weight-bold">0 Notifications!</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<footer>
|
<footer>
|
||||||
|
@ -396,8 +342,6 @@
|
||||||
profile: {},
|
profile: {},
|
||||||
min_id: 0,
|
min_id: 0,
|
||||||
max_id: 0,
|
max_id: 0,
|
||||||
notifications: {},
|
|
||||||
notificationCursor: 2,
|
|
||||||
stories: {},
|
stories: {},
|
||||||
suggestions: {},
|
suggestions: {},
|
||||||
loading: true,
|
loading: true,
|
||||||
|
@ -483,7 +427,6 @@
|
||||||
this.max_id = Math.min(...ids);
|
this.max_id = Math.min(...ids);
|
||||||
$('.timeline .pagination').removeClass('d-none');
|
$('.timeline .pagination').removeClass('d-none');
|
||||||
this.loading = false;
|
this.loading = false;
|
||||||
this.fetchNotifications();
|
|
||||||
}).catch(err => {
|
}).catch(err => {
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
@ -553,47 +496,6 @@
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
fetchNotifications() {
|
|
||||||
axios.get('/api/v1/notifications')
|
|
||||||
.then(res => {
|
|
||||||
let data = res.data.filter(n => {
|
|
||||||
if(n.type == 'share' && !status) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
});
|
|
||||||
this.notifications = data;
|
|
||||||
$('.notification-card .loader').addClass('d-none');
|
|
||||||
$('.notification-card .contents').removeClass('d-none');
|
|
||||||
});
|
|
||||||
},
|
|
||||||
|
|
||||||
infiniteNotifications($state) {
|
|
||||||
if(this.notificationCursor > 10) {
|
|
||||||
$state.complete();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
axios.get('/api/v1/notifications', {
|
|
||||||
params: {
|
|
||||||
page: this.notificationCursor
|
|
||||||
}
|
|
||||||
}).then(res => {
|
|
||||||
if(res.data.length) {
|
|
||||||
let data = res.data.filter(n => {
|
|
||||||
if(n.type == 'share' && !status) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
});
|
|
||||||
this.notifications.push(...data);
|
|
||||||
this.notificationCursor++;
|
|
||||||
$state.loaded();
|
|
||||||
} else {
|
|
||||||
$state.complete();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
},
|
|
||||||
|
|
||||||
reportUrl(status) {
|
reportUrl(status) {
|
||||||
let type = status.in_reply_to ? 'comment' : 'post';
|
let type = status.in_reply_to ? 'comment' : 'post';
|
||||||
let id = status.id;
|
let id = status.id;
|
||||||
|
|
5
resources/assets/js/timeline.js
vendored
5
resources/assets/js/timeline.js
vendored
|
@ -1,3 +1,8 @@
|
||||||
|
Vue.component(
|
||||||
|
'notification-card',
|
||||||
|
require('./components/NotificationCard.vue').default
|
||||||
|
);
|
||||||
|
|
||||||
Vue.component(
|
Vue.component(
|
||||||
'photo-presenter',
|
'photo-presenter',
|
||||||
require('./components/presenter/PhotoPresenter.vue').default
|
require('./components/presenter/PhotoPresenter.vue').default
|
||||||
|
|
Loading…
Reference in a new issue