mirror of https://github.com/pixelfed/pixelfed
commit
c643dc307b
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@ -1 +1 @@
|
||||
(()=>{"use strict";var e,r,a,t={},n={};function o(e){var r=n[e];if(void 0!==r)return r.exports;var a=n[e]={id:e,loaded:!1,exports:{}};return t[e].call(a.exports,a,a.exports,o),a.loaded=!0,a.exports}o.m=t,e=[],o.O=(r,a,t,n)=>{if(!a){var d=1/0;for(l=0;l<e.length;l++){for(var[a,t,n]=e[l],c=!0,i=0;i<a.length;i++)(!1&n||d>=n)&&Object.keys(o.O).every((e=>o.O[e](a[i])))?a.splice(i--,1):(c=!1,n<d&&(d=n));if(c){e.splice(l--,1);var s=t();void 0!==s&&(r=s)}}return r}n=n||0;for(var l=e.length;l>0&&e[l-1][2]>n;l--)e[l]=e[l-1];e[l]=[a,t,n]},o.n=e=>{var r=e&&e.__esModule?()=>e.default:()=>e;return o.d(r,{a:r}),r},o.d=(e,r)=>{for(var a in r)o.o(r,a)&&!o.o(e,a)&&Object.defineProperty(e,a,{enumerable:!0,get:r[a]})},o.f={},o.e=e=>Promise.all(Object.keys(o.f).reduce(((r,a)=>(o.f[a](e,r),r)),[])),o.u=e=>"js/"+{1084:"profile~followers.bundle",1983:"kb.bundle",2470:"home.chunk",2521:"about.bundle",2530:"discover~myhashtags.chunk",2586:"compose.chunk",2732:"dms~message.chunk",3351:"discover~settings.chunk",3365:"dms.chunk",3623:"discover~findfriends.chunk",4028:"error404.bundle",4509:"static~privacy.bundle",4958:"discover.chunk",4965:"discover~memories.chunk",5865:"post.chunk",6053:"notifications.chunk",6869:"profile.chunk",7004:"help.bundle",7019:"discover~hashtag.bundle",8021:"contact.bundle",8250:"i18n.bundle",8517:"daci.chunk",8600:"changelog.bundle",8625:"profile~following.bundle",8900:"discover~serverfeed.chunk",9144:"static~tos.bundle"}[e]+"."+{1084:"fe353e697fb7660b",1983:"f6ebdaac1fd552ca",2470:"25bd77760873ee83",2521:"44a18841089fdde3",2530:"089b7465b2359979",2586:"c413851da244ae3f",2732:"1cfdf19c4525eafa",3351:"5757ad3940569422",3365:"91ab72a8dcd1a8a8",3623:"1aabfedaab1849ba",4028:"5075813f1b00e10d",4509:"24c230550b6938b2",4958:"4f1b3ea93df06670",4965:"70b04c7698c2172b",5865:"881f8b0a9934e053",6053:"1a834e4a7bdbf21a",6869:"0f947cc09af5c8c3",7004:"7c1195b63e04d568",7019:"279c3460159d3af7",8021:"d6c1d467c11796b1",8250:"9b9bf1b64e2aa1c1",8517:"3f13ec9fc49e9d2b",8600:"7f58a5ccc6659eb2",8625:"c406db7b14d07d36",8900:"ff59ca12d08bb810",9144:"65caad6c0546d8c9"}[e]+".js",o.miniCssF=e=>({138:"css/spa",703:"css/admin",1242:"css/appdark",6170:"css/app",8737:"css/portfolio",9994:"css/landing"}[e]+".css"),o.g=function(){if("object"==typeof globalThis)return globalThis;try{return this||new Function("return this")()}catch(e){if("object"==typeof window)return window}}(),o.o=(e,r)=>Object.prototype.hasOwnProperty.call(e,r),r={},a="pixelfed:",o.l=(e,t,n,d)=>{if(r[e])r[e].push(t);else{var c,i;if(void 0!==n)for(var s=document.getElementsByTagName("script"),l=0;l<s.length;l++){var u=s[l];if(u.getAttribute("src")==e||u.getAttribute("data-webpack")==a+n){c=u;break}}c||(i=!0,(c=document.createElement("script")).charset="utf-8",c.timeout=120,o.nc&&c.setAttribute("nonce",o.nc),c.setAttribute("data-webpack",a+n),c.src=e),r[e]=[t];var f=(a,t)=>{c.onerror=c.onload=null,clearTimeout(b);var n=r[e];if(delete r[e],c.parentNode&&c.parentNode.removeChild(c),n&&n.forEach((e=>e(t))),a)return a(t)},b=setTimeout(f.bind(null,void 0,{type:"timeout",target:c}),12e4);c.onerror=f.bind(null,c.onerror),c.onload=f.bind(null,c.onload),i&&document.head.appendChild(c)}},o.r=e=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},o.nmd=e=>(e.paths=[],e.children||(e.children=[]),e),o.p="/",(()=>{var e={8929:0,1242:0,6170:0,8737:0,703:0,9994:0,138:0};o.f.j=(r,a)=>{var t=o.o(e,r)?e[r]:void 0;if(0!==t)if(t)a.push(t[2]);else if(/^(1242|138|6170|703|8737|8929|9994)$/.test(r))e[r]=0;else{var n=new Promise(((a,n)=>t=e[r]=[a,n]));a.push(t[2]=n);var d=o.p+o.u(r),c=new Error;o.l(d,(a=>{if(o.o(e,r)&&(0!==(t=e[r])&&(e[r]=void 0),t)){var n=a&&("load"===a.type?"missing":a.type),d=a&&a.target&&a.target.src;c.message="Loading chunk "+r+" failed.\n("+n+": "+d+")",c.name="ChunkLoadError",c.type=n,c.request=d,t[1](c)}}),"chunk-"+r,r)}},o.O.j=r=>0===e[r];var r=(r,a)=>{var t,n,[d,c,i]=a,s=0;if(d.some((r=>0!==e[r]))){for(t in c)o.o(c,t)&&(o.m[t]=c[t]);if(i)var l=i(o)}for(r&&r(a);s<d.length;s++)n=d[s],o.o(e,n)&&e[n]&&e[n][0](),e[n]=0;return o.O(l)},a=self.webpackChunkpixelfed=self.webpackChunkpixelfed||[];a.forEach(r.bind(null,0)),a.push=r.bind(null,a.push.bind(a))})(),o.nc=void 0})();
|
||||
(()=>{"use strict";var e,r,t,n={},a={};function o(e){var r=a[e];if(void 0!==r)return r.exports;var t=a[e]={id:e,loaded:!1,exports:{}};return n[e].call(t.exports,t,t.exports,o),t.loaded=!0,t.exports}o.m=n,e=[],o.O=(r,t,n,a)=>{if(!t){var d=1/0;for(l=0;l<e.length;l++){for(var[t,n,a]=e[l],c=!0,i=0;i<t.length;i++)(!1&a||d>=a)&&Object.keys(o.O).every((e=>o.O[e](t[i])))?t.splice(i--,1):(c=!1,a<d&&(d=a));if(c){e.splice(l--,1);var s=n();void 0!==s&&(r=s)}}return r}a=a||0;for(var l=e.length;l>0&&e[l-1][2]>a;l--)e[l]=e[l-1];e[l]=[t,n,a]},o.n=e=>{var r=e&&e.__esModule?()=>e.default:()=>e;return o.d(r,{a:r}),r},o.d=(e,r)=>{for(var t in r)o.o(r,t)&&!o.o(e,t)&&Object.defineProperty(e,t,{enumerable:!0,get:r[t]})},o.f={},o.e=e=>Promise.all(Object.keys(o.f).reduce(((r,t)=>(o.f[t](e,r),r)),[])),o.u=e=>"js/"+{1084:"profile~followers.bundle",1983:"kb.bundle",2470:"home.chunk",2521:"about.bundle",2530:"discover~myhashtags.chunk",2586:"compose.chunk",2732:"dms~message.chunk",3351:"discover~settings.chunk",3365:"dms.chunk",3623:"discover~findfriends.chunk",4028:"error404.bundle",4509:"static~privacy.bundle",4958:"discover.chunk",4965:"discover~memories.chunk",5865:"post.chunk",6053:"notifications.chunk",6869:"profile.chunk",7004:"help.bundle",7019:"discover~hashtag.bundle",8021:"contact.bundle",8250:"i18n.bundle",8517:"daci.chunk",8600:"changelog.bundle",8625:"profile~following.bundle",8900:"discover~serverfeed.chunk",9144:"static~tos.bundle"}[e]+"."+{1084:"fe353e697fb7660b",1983:"f6ebdaac1fd552ca",2470:"af8ef7b54f61b18d",2521:"44a18841089fdde3",2530:"089b7465b2359979",2586:"c413851da244ae3f",2732:"1cfdf19c4525eafa",3351:"5757ad3940569422",3365:"91ab72a8dcd1a8a8",3623:"1aabfedaab1849ba",4028:"5075813f1b00e10d",4509:"24c230550b6938b2",4958:"5ceb85dcb38dfbef",4965:"70b04c7698c2172b",5865:"62a9d21c9016fd95",6053:"9de71a122956c663",6869:"0f947cc09af5c8c3",7004:"7c1195b63e04d568",7019:"b8319d6999d3e2e3",8021:"d6c1d467c11796b1",8250:"9b9bf1b64e2aa1c1",8517:"3f13ec9fc49e9d2b",8600:"7f58a5ccc6659eb2",8625:"c406db7b14d07d36",8900:"ff59ca12d08bb810",9144:"65caad6c0546d8c9"}[e]+".js",o.miniCssF=e=>({138:"css/spa",703:"css/admin",1242:"css/appdark",6170:"css/app",8737:"css/portfolio",9994:"css/landing"}[e]+".css"),o.g=function(){if("object"==typeof globalThis)return globalThis;try{return this||new Function("return this")()}catch(e){if("object"==typeof window)return window}}(),o.o=(e,r)=>Object.prototype.hasOwnProperty.call(e,r),r={},t="pixelfed:",o.l=(e,n,a,d)=>{if(r[e])r[e].push(n);else{var c,i;if(void 0!==a)for(var s=document.getElementsByTagName("script"),l=0;l<s.length;l++){var u=s[l];if(u.getAttribute("src")==e||u.getAttribute("data-webpack")==t+a){c=u;break}}c||(i=!0,(c=document.createElement("script")).charset="utf-8",c.timeout=120,o.nc&&c.setAttribute("nonce",o.nc),c.setAttribute("data-webpack",t+a),c.src=e),r[e]=[n];var f=(t,n)=>{c.onerror=c.onload=null,clearTimeout(b);var a=r[e];if(delete r[e],c.parentNode&&c.parentNode.removeChild(c),a&&a.forEach((e=>e(n))),t)return t(n)},b=setTimeout(f.bind(null,void 0,{type:"timeout",target:c}),12e4);c.onerror=f.bind(null,c.onerror),c.onload=f.bind(null,c.onload),i&&document.head.appendChild(c)}},o.r=e=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},o.nmd=e=>(e.paths=[],e.children||(e.children=[]),e),o.p="/",(()=>{var e={8929:0,1242:0,6170:0,8737:0,703:0,9994:0,138:0};o.f.j=(r,t)=>{var n=o.o(e,r)?e[r]:void 0;if(0!==n)if(n)t.push(n[2]);else if(/^(1242|138|6170|703|8737|8929|9994)$/.test(r))e[r]=0;else{var a=new Promise(((t,a)=>n=e[r]=[t,a]));t.push(n[2]=a);var d=o.p+o.u(r),c=new Error;o.l(d,(t=>{if(o.o(e,r)&&(0!==(n=e[r])&&(e[r]=void 0),n)){var a=t&&("load"===t.type?"missing":t.type),d=t&&t.target&&t.target.src;c.message="Loading chunk "+r+" failed.\n("+a+": "+d+")",c.name="ChunkLoadError",c.type=a,c.request=d,n[1](c)}}),"chunk-"+r,r)}},o.O.j=r=>0===e[r];var r=(r,t)=>{var n,a,[d,c,i]=t,s=0;if(d.some((r=>0!==e[r]))){for(n in c)o.o(c,n)&&(o.m[n]=c[n]);if(i)var l=i(o)}for(r&&r(t);s<d.length;s++)a=d[s],o.o(e,a)&&e[a]&&e[a][0](),e[a]=0;return o.O(l)},t=self.webpackChunkpixelfed=self.webpackChunkpixelfed||[];t.forEach(r.bind(null,0)),t.push=r.bind(null,t.push.bind(t))})(),o.nc=void 0})();
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@ -0,0 +1,585 @@
|
||||
<template>
|
||||
<div class="web-wrapper notification-metro-component">
|
||||
<div v-if="isLoaded" class="container-fluid mt-3">
|
||||
<div class="row">
|
||||
<div class="col-md-3 d-md-block">
|
||||
<sidebar :user="profile" />
|
||||
</div>
|
||||
|
||||
<div class="col-md-9 col-lg-9 col-xl-5 offset-xl-1">
|
||||
<template v-if="tabIndex === 0">
|
||||
<h1 class="font-weight-bold">
|
||||
Notifications
|
||||
</h1>
|
||||
<p class="small mt-n2"> </p>
|
||||
</template>
|
||||
<template v-else-if="tabIndex === 10">
|
||||
<div class="d-flex align-items-center mb-3">
|
||||
<a class="text-muted" href="#" @click.prevent="tabIndex = 0" style="opacity:0.3">
|
||||
<i class="far fa-chevron-circle-left fa-2x mr-3" title="Go back to notifications"></i>
|
||||
</a>
|
||||
<h1 class="font-weight-bold">
|
||||
Follow Requests
|
||||
</h1>
|
||||
</div>
|
||||
</template>
|
||||
<template v-else>
|
||||
<h1 class="font-weight-bold">
|
||||
{{ tabs[tabIndex].name }}
|
||||
</h1>
|
||||
<p class="small text-lighter mt-n2">{{ tabs[tabIndex].description }}</p>
|
||||
</template>
|
||||
|
||||
<div v-if="!notificationsLoaded">
|
||||
<placeholder />
|
||||
</div>
|
||||
|
||||
<template v-else>
|
||||
<ul v-if="tabIndex != 10 && notificationsLoaded && notifications && notifications.length" class="notification-filters nav nav-tabs nav-fill mb-3">
|
||||
<li v-for="(item, idx) in tabs" class="nav-item">
|
||||
<a
|
||||
class="nav-link"
|
||||
:class="{ active: tabIndex === idx }"
|
||||
href="#"
|
||||
@click.prevent="toggleTab(idx)">
|
||||
<i
|
||||
class="mr-1 nav-link-icon"
|
||||
:class="[ item.icon ]"
|
||||
>
|
||||
</i>
|
||||
<span class="d-none d-xl-inline-block">
|
||||
{{ item.name }}
|
||||
</span>
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<div v-if="notificationsEmpty && followRequestsChecked && !followRequests.accounts.length && notificationRetries < 2">
|
||||
<div class="row justify-content-center">
|
||||
<div class="col-12 col-md-10 text-center">
|
||||
<img src="/img/illustrations/dk-nature-man-monochrome.svg" class="img-fluid" style="opacity: 0.6;">
|
||||
<p class="lead text-muted font-weight-bold">{{ $t('notifications.noneFound') }}</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div v-else-if="!notificationsLoaded || tabSwitching || ((notificationsEmpty && notificationRetries < 2 ) || !notifications && !followRequests && !followRequests.accounts && !followRequests.accounts.length)">
|
||||
<placeholder />
|
||||
</div>
|
||||
|
||||
<div v-else>
|
||||
<div v-if="tabIndex === 0">
|
||||
<div
|
||||
v-if="followRequests && followRequests.hasOwnProperty('accounts') && followRequests.accounts.length"
|
||||
class="card card-body shadow-none border border-warning rounded-pill mb-3 py-2">
|
||||
<div class="media align-items-center">
|
||||
<i class="far fa-exclamation-circle mr-3 text-warning"></i>
|
||||
<div class="media-body">
|
||||
<p class="mb-0">
|
||||
<strong>{{ followRequests.count }} follow {{ followRequests.count > 1 ? 'requests' : 'request' }}</strong>
|
||||
</p>
|
||||
</div>
|
||||
<a
|
||||
class="ml-2 small d-flex font-weight-bold primary text-uppercase mb-0"
|
||||
href="#"
|
||||
@click.prevent="showFollowRequests()">
|
||||
View<span class="d-none d-md-block"> Follow Requests</span>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div v-if="notificationsLoaded">
|
||||
<notification
|
||||
v-for="(n, index) in notifications"
|
||||
:key="`notification:${index}:${n.id}`"
|
||||
:n="n" />
|
||||
|
||||
<div v-if="notifications && notificationsLoaded && !notifications.length && notificationRetries <= 2">
|
||||
<div class="row justify-content-center">
|
||||
<div class="col-12 col-md-10 text-center">
|
||||
<img src="/img/illustrations/dk-nature-man-monochrome.svg" class="img-fluid" style="opacity: 0.6;">
|
||||
<p class="lead text-muted font-weight-bold">{{ $t('notifications.noneFound') }}</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div v-if="canLoadMore">
|
||||
<intersect @enter="enterIntersect">
|
||||
<placeholder />
|
||||
</intersect>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div v-else-if="tabIndex === 10">
|
||||
<div v-if="followRequests && followRequests.accounts && followRequests.accounts.length" class="list-group">
|
||||
<div v-for="(acct, index) in followRequests.accounts" class="list-group-item">
|
||||
<div class="media align-items-center">
|
||||
<router-link :to="`/i/web/profile/${acct.account.id}`" class="primary">
|
||||
<img :src="acct.avatar" width="80" height="80" class="rounded-lg shadow mr-3" onerror="this.onerror=null;this.src='/storage/avatars/default.jpg?v=0';">
|
||||
</router-link>
|
||||
<div class="media-body mr-3">
|
||||
<p class="font-weight-bold mb-0 text-break" style="font-size:17px">
|
||||
<router-link :to="`/i/web/profile/${acct.account.id}`" class="primary">
|
||||
{{ acct.username }}
|
||||
</router-link>
|
||||
</p>
|
||||
<p class="mb-1 text-muted text-break" style="font-size:11px">{{ truncate(acct.account.note_text, 100) }}</p>
|
||||
<div class="d-flex text-lighter" style="font-size:11px">
|
||||
<span class="mr-3">
|
||||
<span class="font-weight-bold">{{ acct.account.statuses_count }}</span>
|
||||
<span>Posts</span>
|
||||
</span>
|
||||
<span>
|
||||
<span class="font-weight-bold">{{ acct.account.followers_count }}</span>
|
||||
<span>Followers</span>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="d-flex flex-column d-md-block">
|
||||
<button
|
||||
class="btn btn-outline-success py-1 btn-sm font-weight-bold rounded-pill mr-2 mb-1"
|
||||
@click.prevent="handleFollowRequest('accept', index)"
|
||||
>
|
||||
Accept
|
||||
</button>
|
||||
|
||||
<button class="btn btn-outline-lighter py-1 btn-sm font-weight-bold rounded-pill mb-1"
|
||||
@click.prevent="handleFollowRequest('reject', index)"
|
||||
>
|
||||
Reject
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div v-else>
|
||||
<div v-if="filteredLoaded">
|
||||
<div class="card card-body bg-transparent shadow-none border p-2 mb-3 rounded-pill text-lighter">
|
||||
<div class="media align-items-center small">
|
||||
<i class="far fa-exclamation-triangle mx-2"></i>
|
||||
<div class="media-body">
|
||||
<p class="mb-0 font-weight-bold">Filtering results may not include older notifications</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div v-if="filteredFeed.length">
|
||||
<notification
|
||||
v-for="(n, index) in filteredFeed"
|
||||
:key="`notification:filtered:${index}:${n.id}`"
|
||||
:n="n" />
|
||||
</div>
|
||||
|
||||
<div v-else>
|
||||
<div v-if="filteredEmpty && notificationRetries <= 2">
|
||||
<div class="card card-body shadow-sm border-0 d-flex flex-row align-items-center" style="border-radius: 20px;gap:1rem;">
|
||||
<i class="far fa-inbox fa-2x text-muted"></i>
|
||||
<div class="font-weight-bold">No recent {{ tabs[tabIndex].name }}!</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<placeholder v-else />
|
||||
</div>
|
||||
|
||||
<div v-if="canLoadMoreFiltered">
|
||||
<intersect @enter="enterFilteredIntersect">
|
||||
<placeholder />
|
||||
</intersect>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div v-else>
|
||||
<placeholder />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
</div>
|
||||
</div>
|
||||
<drawer />
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script type="text/javascript">
|
||||
import Drawer from './partials/drawer.vue';
|
||||
import Sidebar from './partials/sidebar.vue';
|
||||
import Notification from './partials/timeline/Notification.vue';
|
||||
import Placeholder from './partials/placeholders/NotificationPlaceholder.vue';
|
||||
import Intersect from 'vue-intersect';
|
||||
|
||||
export default {
|
||||
components: {
|
||||
"drawer": Drawer,
|
||||
"sidebar": Sidebar,
|
||||
"intersect": Intersect,
|
||||
"notification": Notification,
|
||||
"placeholder": Placeholder,
|
||||
},
|
||||
|
||||
data() {
|
||||
return {
|
||||
isLoaded: false,
|
||||
profile: undefined,
|
||||
ids: [],
|
||||
notifications: undefined,
|
||||
notificationsLoaded: false,
|
||||
notificationRetries: 0,
|
||||
notificationsEmpty: true,
|
||||
notificationRetryTimeout: undefined,
|
||||
max_id: undefined,
|
||||
canLoadMore: false,
|
||||
isIntersecting: false,
|
||||
tabIndex: 0,
|
||||
tabs: [
|
||||
{
|
||||
id: 'all',
|
||||
name: 'All',
|
||||
icon: 'far fa-bell',
|
||||
types: []
|
||||
},
|
||||
|
||||
{
|
||||
id: 'mentions',
|
||||
name: 'Mentions',
|
||||
description: 'Replies to your posts and posts you were mentioned in',
|
||||
icon: 'far fa-at',
|
||||
types: ['comment', 'mention']
|
||||
},
|
||||
|
||||
{
|
||||
id: 'likes',
|
||||
name: 'Likes',
|
||||
description: 'Accounts that liked your posts',
|
||||
icon: 'far fa-heart',
|
||||
types: ['favourite']
|
||||
},
|
||||
|
||||
{
|
||||
id: 'followers',
|
||||
name: 'Followers',
|
||||
description: 'Accounts that followed you',
|
||||
icon: 'far fa-user-plus',
|
||||
types: ['follow']
|
||||
},
|
||||
|
||||
{
|
||||
id: 'reblogs',
|
||||
name: 'Reblogs',
|
||||
description: 'Accounts that shared or reblogged your posts',
|
||||
icon: 'far fa-retweet',
|
||||
types: ['share']
|
||||
},
|
||||
|
||||
{
|
||||
id: 'direct',
|
||||
name: 'DMs',
|
||||
description: 'Direct messages you have with other accounts',
|
||||
icon: 'far fa-envelope',
|
||||
types: ['direct']
|
||||
},
|
||||
],
|
||||
tabSwitching: false,
|
||||
filteredFeed: [],
|
||||
filteredLoaded: false,
|
||||
filteredIsIntersecting: false,
|
||||
filteredMaxId: undefined,
|
||||
canLoadMoreFiltered: true,
|
||||
filterPaginationTimeout: undefined,
|
||||
filteredIterations: 0,
|
||||
filteredEmpty: false,
|
||||
followRequests: [],
|
||||
followRequestsChecked: false,
|
||||
followRequestsPage: 1
|
||||
}
|
||||
},
|
||||
|
||||
updated() {
|
||||
},
|
||||
|
||||
mounted() {
|
||||
this.profile = window._sharedData.user;
|
||||
this.isLoaded = true;
|
||||
if(this.profile.locked) {
|
||||
this.fetchFollowRequests();
|
||||
}
|
||||
this.fetchNotifications();
|
||||
},
|
||||
|
||||
beforeDestroy() {
|
||||
clearTimeout(this.notificationRetryTimeout);
|
||||
},
|
||||
|
||||
methods: {
|
||||
fetchNotifications() {
|
||||
this.notificationRetries++;
|
||||
axios.get('/api/pixelfed/v1/notifications?pg=true')
|
||||
.then(res => {
|
||||
if(!res || !res.data || !res.data.length) {
|
||||
if(this.notificationRetries == 2) {
|
||||
clearTimeout(this.notificationRetryTimeout);
|
||||
this.canLoadMore = false;
|
||||
this.notificationsLoaded = true;
|
||||
this.notificationsEmpty = true;
|
||||
return;
|
||||
}
|
||||
this.notificationRetryTimeout = setTimeout(() => {
|
||||
this.fetchNotifications();
|
||||
}, 1000);
|
||||
return;
|
||||
}
|
||||
|
||||
let data = res.data.filter(n => {
|
||||
if(n.type == 'share' && !n.status) {
|
||||
return false;
|
||||
}
|
||||
if(n.type == 'comment' && !n.status) {
|
||||
return false;
|
||||
}
|
||||
if(n.type == 'mention' && !n.status) {
|
||||
return false;
|
||||
}
|
||||
if(n.type == 'favourite' && !n.status) {
|
||||
return false;
|
||||
}
|
||||
if(n.type == 'follow' && !n.account) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
});
|
||||
let ids = res.data.map(n => n.id);
|
||||
this.max_id = Math.min(...ids);
|
||||
this.ids.push(...ids);
|
||||
this.notifications = data;
|
||||
this.notificationsLoaded = true;
|
||||
this.notificationsEmpty = false;
|
||||
this.canLoadMore = true;
|
||||
});
|
||||
},
|
||||
|
||||
enterIntersect() {
|
||||
if(this.isIntersecting) {
|
||||
return;
|
||||
}
|
||||
|
||||
if(!isFinite(this.max_id)) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.isIntersecting = true;
|
||||
|
||||
axios.get('/api/pixelfed/v1/notifications', {
|
||||
params: {
|
||||
max_id: this.max_id
|
||||
}
|
||||
}).then(res => {
|
||||
if(!res.data.length) {
|
||||
this.canLoadMore = false;
|
||||
}
|
||||
let ids = res.data.map(n => n.id);
|
||||
this.max_id = Math.min(...ids);
|
||||
this.notifications.push(...res.data);
|
||||
this.isIntersecting = false;
|
||||
})
|
||||
},
|
||||
|
||||
toggleTab(idx) {
|
||||
this.tabSwitching = true;
|
||||
this.canLoadMoreFiltered = true;
|
||||
this.filteredEmpty = false;
|
||||
this.filteredIterations = 0;
|
||||
this.filterFeed(this.tabs[idx].id);
|
||||
},
|
||||
|
||||
filterFeed(type) {
|
||||
switch(type) {
|
||||
case 'all':
|
||||
this.tabIndex = 0;
|
||||
this.filteredFeed = [];
|
||||
this.filteredLoaded = false;
|
||||
this.filteredIsIntersecting = false;
|
||||
this.filteredMaxId = undefined;
|
||||
this.canLoadMoreFiltered = false;
|
||||
this.tabSwitching = false;
|
||||
break;
|
||||
|
||||
case 'mentions':
|
||||
this.tabIndex = 1;
|
||||
this.filteredMaxId = this.max_id;
|
||||
this.filteredFeed = this.notifications.filter(n => this.tabs[this.tabIndex].types.includes(n.type));
|
||||
this.filteredIsIntersecting = false;
|
||||
this.tabSwitching = false;
|
||||
this.filteredLoaded = true;
|
||||
break;
|
||||
|
||||
case 'likes':
|
||||
this.tabIndex = 2;
|
||||
this.filteredMaxId = this.max_id;
|
||||
this.filteredFeed = this.notifications.filter(n => n.type === 'favourite');
|
||||
this.filteredIsIntersecting = false;
|
||||
this.tabSwitching = false;
|
||||
this.filteredLoaded = true;
|
||||
break;
|
||||
|
||||
case 'followers':
|
||||
this.tabIndex = 3;
|
||||
this.filteredMaxId = this.max_id;
|
||||
this.filteredFeed = this.notifications.filter(n => n.type === 'follow');
|
||||
this.filteredIsIntersecting = false;
|
||||
this.tabSwitching = false;
|
||||
this.filteredLoaded = true;
|
||||
break;
|
||||
|
||||
case 'reblogs':
|
||||
this.tabIndex = 4;
|
||||
this.filteredMaxId = this.max_id;
|
||||
this.filteredFeed = this.notifications.filter(n => n.type === 'share');
|
||||
this.filteredIsIntersecting = false;
|
||||
this.tabSwitching = false;
|
||||
this.filteredLoaded = true;
|
||||
break;
|
||||
|
||||
case 'direct':
|
||||
this.tabIndex = 5;
|
||||
this.filteredMaxId = this.max_id;
|
||||
this.filteredFeed = this.notifications.filter(n => n.type === 'direct');
|
||||
this.filteredIsIntersecting = false;
|
||||
this.tabSwitching = false;
|
||||
this.filteredLoaded = true;
|
||||
break;
|
||||
}
|
||||
},
|
||||
|
||||
enterFilteredIntersect() {
|
||||
if( !this.canLoadMoreFiltered ||
|
||||
this.filteredIsIntersecting ||
|
||||
this.filteredIterations > 10
|
||||
) {
|
||||
if(this.filteredFeed.length == 0) {
|
||||
this.filteredEmpty = true;
|
||||
this.canLoadMoreFiltered = false;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if(!isFinite(this.max_id) || !isFinite(this.filteredMaxId)) {
|
||||
this.canLoadMoreFiltered = false;
|
||||
return;
|
||||
}
|
||||
|
||||
this.filteredIsIntersecting = true;
|
||||
|
||||
axios.get('/api/pixelfed/v1/notifications', {
|
||||
params: {
|
||||
max_id: this.filteredMaxId,
|
||||
limit: 40
|
||||
}
|
||||
})
|
||||
.then(res => {
|
||||
let mids = res.data.map(n => n.id);
|
||||
let max_id = Math.min(...mids);
|
||||
if(max_id < this.max_id) {
|
||||
this.max_id = max_id;
|
||||
res.data.forEach(n => {
|
||||
if(this.ids.indexOf(n.id) == -1) {
|
||||
this.ids.push(n.id);
|
||||
this.notifications.push(n);
|
||||
} else {
|
||||
}
|
||||
});
|
||||
}
|
||||
this.filteredIterations++;
|
||||
if(this.filterPaginationTimeout && this.filterPaginationTimeout < 500) {
|
||||
clearTimeout(this.filterPaginationTimeout);
|
||||
}
|
||||
if(!res.data || !res.data.length) {
|
||||
this.canLoadMoreFiltered = false;
|
||||
}
|
||||
if(!res.data.length) {
|
||||
this.canLoadMoreFiltered = false;
|
||||
}
|
||||
let ids = res.data.map(n => n.id);
|
||||
this.filteredMaxId = Math.min(...ids);
|
||||
let types = this.tabs[this.tabIndex].types;
|
||||
let data = res.data.filter(n => types.includes(n.type));
|
||||
this.filteredFeed.push(...data);
|
||||
this.filteredIsIntersecting = false;
|
||||
if(this.filteredFeed.length < 10) {
|
||||
setTimeout(() => this.enterFilteredIntersect(), 500);
|
||||
}
|
||||
this.filterPaginationTimeout = setTimeout(() => {
|
||||
this.canLoadMoreFiltered = false;
|
||||
}, 2000);
|
||||
})
|
||||
.catch(err => {
|
||||
this.canLoadMoreFiltered = false;
|
||||
})
|
||||
},
|
||||
|
||||
fetchFollowRequests() {
|
||||
axios.get('/account/follow-requests.json')
|
||||
.then(res => {
|
||||
if(this.followRequestsPage == 1) {
|
||||
this.followRequests = res.data;
|
||||
this.followRequestsChecked = true;
|
||||
} else {
|
||||
this.followRequests.accounts.push(...res.data.accounts);
|
||||
}
|
||||
this.followRequestsPage++;
|
||||
});
|
||||
},
|
||||
|
||||
showFollowRequests() {
|
||||
this.tabSwitching = false;
|
||||
this.filteredEmpty = false;
|
||||
this.filteredIterations = 0;
|
||||
this.tabIndex = 10;
|
||||
},
|
||||
|
||||
handleFollowRequest(action, index) {
|
||||
if(!window.confirm('Are you sure you want to ' + action + ' this follow request?')) {
|
||||
return;
|
||||
}
|
||||
|
||||
axios.post('/account/follow-requests', {
|
||||
action: action,
|
||||
id: this.followRequests.accounts[index].rid
|
||||
})
|
||||
.then(res => {
|
||||
this.followRequests.count--;
|
||||
this.followRequests.accounts.splice(index, 1);
|
||||
this.toggleTab(0);
|
||||
})
|
||||
},
|
||||
|
||||
truncate(str, len = 40) {
|
||||
return _.truncate(str, { length: len });
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.notification-metro-component {
|
||||
.notification-filters {
|
||||
.nav-link {
|
||||
font-size: 12px;
|
||||
|
||||
&.active {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
&-icon:not(.active) {
|
||||
opacity: 0.5;
|
||||
}
|
||||
|
||||
&:not(.active) {
|
||||
color: #9ca3af;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
Loading…
Reference in New Issue