forked from DebaucheryLibrarian/traxxx
Added dedicated notifications page.
This commit is contained in:
@@ -137,7 +137,7 @@ async function fetchEntity(scroll = true) {
|
||||
|
||||
this.pageTitle = entity.name;
|
||||
|
||||
if (scroll) {
|
||||
if (scroll && this.$refs.filter?.$el) {
|
||||
this.$refs.filter.$el.scrollIntoView();
|
||||
}
|
||||
}
|
||||
@@ -146,9 +146,11 @@ async function mounted() {
|
||||
await this.fetchEntity();
|
||||
}
|
||||
|
||||
async function route() {
|
||||
await this.fetchEntity();
|
||||
this.expanded = false;
|
||||
async function route(to) {
|
||||
if (to.name === 'channel' || to.name === 'network' || to.name === 'studio') {
|
||||
await this.fetchEntity();
|
||||
this.expanded = false;
|
||||
}
|
||||
}
|
||||
|
||||
export default {
|
||||
|
||||
@@ -96,7 +96,11 @@
|
||||
</div>
|
||||
|
||||
<template v-slot:tooltip>
|
||||
<Notifications />
|
||||
<Notifications
|
||||
:notifications="notifications"
|
||||
:unseen-count="unseenNotificationsCount"
|
||||
@check="fetchNotifications"
|
||||
/>
|
||||
</template>
|
||||
</Tooltip>
|
||||
|
||||
@@ -154,8 +158,11 @@ function me() {
|
||||
return this.$store.state.auth.user;
|
||||
}
|
||||
|
||||
function unseenNotificationsCount() {
|
||||
return this.$store.state.ui.unseenNotificationsCount;
|
||||
async function fetchNotifications() {
|
||||
const { notifications, unseenCount } = await this.$store.dispatch('fetchNotifications');
|
||||
|
||||
this.notifications = notifications;
|
||||
this.unseenNotificationsCount = unseenCount;
|
||||
}
|
||||
|
||||
export default {
|
||||
@@ -170,11 +177,19 @@ export default {
|
||||
logo,
|
||||
searching: false,
|
||||
showFilters: false,
|
||||
notifications: [],
|
||||
unseenNotificationsCount: 0,
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
me,
|
||||
unseenNotificationsCount,
|
||||
},
|
||||
watch: {
|
||||
me: fetchNotifications,
|
||||
},
|
||||
mounted: fetchNotifications,
|
||||
methods: {
|
||||
fetchNotifications,
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
@@ -5,13 +5,14 @@
|
||||
|
||||
<div class="notifications-actions">
|
||||
<Icon
|
||||
v-if="unseenNotificationsCount > 0"
|
||||
v-if="unseenCount > 0"
|
||||
v-tooltip="'Mark all as seen'"
|
||||
icon="checkmark"
|
||||
@click="checkNotifications"
|
||||
/>
|
||||
|
||||
<Icon
|
||||
v-tooltip="'Add alert'"
|
||||
icon="plus3"
|
||||
@click="showAddAlert = true"
|
||||
/>
|
||||
@@ -111,28 +112,29 @@
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div @click="$emit('blur')">
|
||||
<router-link
|
||||
to="/notifications"
|
||||
class="notification-link notification-more"
|
||||
>See all</router-link>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import AddAlert from '../alerts/add.vue';
|
||||
|
||||
function notifications() {
|
||||
return this.$store.state.ui.notifications;
|
||||
}
|
||||
|
||||
function unseenNotificationsCount() {
|
||||
return this.$store.state.ui.unseenNotificationsCount;
|
||||
}
|
||||
|
||||
async function checkNotifications() {
|
||||
await this.$store.dispatch('checkNotifications');
|
||||
await this.$store.dispatch('fetchNotifications');
|
||||
|
||||
this.$emit('check');
|
||||
}
|
||||
|
||||
async function checkNotification(notificationId, blur) {
|
||||
await this.$store.dispatch('checkNotification', notificationId);
|
||||
await this.$store.dispatch('fetchNotifications');
|
||||
|
||||
this.$emit('check');
|
||||
|
||||
if (blur) {
|
||||
this.events.emit('blur');
|
||||
@@ -143,15 +145,21 @@ export default {
|
||||
components: {
|
||||
AddAlert,
|
||||
},
|
||||
props: {
|
||||
notifications: {
|
||||
type: Array,
|
||||
default: () => [],
|
||||
},
|
||||
unseenCount: {
|
||||
type: Number,
|
||||
default: 0,
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
showAddAlert: false,
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
notifications,
|
||||
unseenNotificationsCount,
|
||||
},
|
||||
methods: {
|
||||
checkNotifications,
|
||||
checkNotification,
|
||||
@@ -162,6 +170,9 @@ export default {
|
||||
<style lang="scss" scoped>
|
||||
.notifications {
|
||||
width: 30rem;
|
||||
max-height: calc(100vh - 5rem);
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.notifications-header {
|
||||
@@ -172,11 +183,15 @@ export default {
|
||||
padding: .5rem;
|
||||
fill: var(--shadow);
|
||||
|
||||
&:last-child {
|
||||
padding: .5rem 1rem .5rem .5rem;
|
||||
&:first-child {
|
||||
padding: .5rem .5rem .5rem 1.5rem;
|
||||
}
|
||||
|
||||
:hover {
|
||||
&:last-child {
|
||||
padding: .5rem 1.5rem .5rem .5rem;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
fill: var(--primary);
|
||||
cursor: pointer;
|
||||
}
|
||||
@@ -193,6 +208,8 @@ export default {
|
||||
}
|
||||
|
||||
.notifications-body {
|
||||
flex-grow: 1;
|
||||
overflow-y: auto;
|
||||
box-shadow: 0 0 3px var(--shadow-weak);
|
||||
}
|
||||
|
||||
@@ -204,7 +221,6 @@ export default {
|
||||
.notification {
|
||||
display: block;
|
||||
border-right: solid .5rem var(--shadow-touch);
|
||||
margin: 0 0 -1px 0;
|
||||
color: var(--text);
|
||||
|
||||
&.unseen {
|
||||
@@ -215,6 +231,10 @@ export default {
|
||||
padding: 1.3rem .5rem;
|
||||
fill: var(--shadow-weak);
|
||||
|
||||
&.notification-check {
|
||||
padding: 1.3rem .5rem 1.3rem 1rem;
|
||||
}
|
||||
|
||||
&:last-child {
|
||||
padding: 1.3rem 1rem 1.3rem .5rem;
|
||||
}
|
||||
@@ -226,6 +246,7 @@ export default {
|
||||
|
||||
&:not(:last-child) {
|
||||
border-bottom: solid 1px var(--shadow-hint);
|
||||
margin: 0 0 -1px 0;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
@@ -307,6 +328,19 @@ export default {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.notification-more {
|
||||
display: block;
|
||||
padding: .5rem 1rem;
|
||||
color: var(--shadow);
|
||||
text-align: center;
|
||||
font-size: .9rem;
|
||||
font-weight: bold;
|
||||
|
||||
&:hover {
|
||||
color: var(--primary);
|
||||
}
|
||||
}
|
||||
|
||||
.poster {
|
||||
width: 6rem;
|
||||
height: 3.6rem;
|
||||
|
||||
76
assets/components/notifications/notifications.vue
Normal file
76
assets/components/notifications/notifications.vue
Normal file
@@ -0,0 +1,76 @@
|
||||
<template>
|
||||
<div
|
||||
ref="page"
|
||||
class="notifications-container"
|
||||
>
|
||||
<h1 class="heading">Notifications</h1>
|
||||
|
||||
<ul class="notifications nolist">
|
||||
<li
|
||||
v-for="notification in notifications"
|
||||
:key="notification.id"
|
||||
>
|
||||
<SceneTile :release="notification.scene" />
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<Pagination
|
||||
:items-total="totalCount"
|
||||
:items-per-page="10"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import Pagination from '../pagination/pagination.vue';
|
||||
import SceneTile from '../releases/scene-tile.vue';
|
||||
|
||||
async function fetchNotifications() {
|
||||
const { notifications, totalCount, unseenCount } = await this.$store.dispatch('fetchNotifications', {
|
||||
page: this.$route.params.pageNumber,
|
||||
limit: this.limit,
|
||||
});
|
||||
|
||||
this.notifications = notifications;
|
||||
this.unseenNotificationsCount = unseenCount;
|
||||
this.totalCount = totalCount;
|
||||
|
||||
this.$emit('scroll');
|
||||
}
|
||||
|
||||
export default {
|
||||
components: {
|
||||
Pagination,
|
||||
SceneTile,
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
notifications: [],
|
||||
limit: 10,
|
||||
totalCount: 0,
|
||||
unseenNotificationsCount: 0,
|
||||
};
|
||||
},
|
||||
emits: ['scroll'],
|
||||
watch: {
|
||||
$route: fetchNotifications,
|
||||
},
|
||||
mounted: fetchNotifications,
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.notifications-container {
|
||||
padding: 1rem;
|
||||
}
|
||||
|
||||
.notifications {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fill, minmax(22rem, 1fr));
|
||||
grid-gap: .5rem;
|
||||
}
|
||||
|
||||
.pagination {
|
||||
margin: 1rem 0 0 0;
|
||||
}
|
||||
</style>
|
||||
@@ -22,6 +22,8 @@
|
||||
:src="getPath(release.poster, 'thumbnail')"
|
||||
:style="{ 'background-image': getBgPath(release.poster, 'lazy') }"
|
||||
:alt="release.title"
|
||||
:width="release.poster.thumbnailWidth"
|
||||
:height="release.poster.thumbnailHeight"
|
||||
class="thumbnail"
|
||||
loading="lazy"
|
||||
>
|
||||
@@ -31,6 +33,8 @@
|
||||
:src="getPath(release.photos[0], 'thumbnail')"
|
||||
:style="{ 'background-image': getBgPath(release.photos[0], 'lazy') } "
|
||||
:alt="release.title"
|
||||
:width="release.photos[0].thumbnailWidth"
|
||||
:height="release.photos[0].thumbnailHeight"
|
||||
class="thumbnail"
|
||||
loading="lazy"
|
||||
>
|
||||
|
||||
Reference in New Issue
Block a user