aboutsummaryrefslogtreecommitdiff
path: root/src/components
diff options
context:
space:
mode:
Diffstat (limited to 'src/components')
-rw-r--r--src/components/announcement/announcement.js105
-rw-r--r--src/components/announcement/announcement.vue136
-rw-r--r--src/components/announcement_editor/announcement_editor.js13
-rw-r--r--src/components/announcement_editor/announcement_editor.vue60
-rw-r--r--src/components/announcements_page/announcements_page.js55
-rw-r--r--src/components/announcements_page/announcements_page.vue79
-rw-r--r--src/components/mobile_nav/mobile_nav.js2
-rw-r--r--src/components/mobile_nav/mobile_nav.vue2
-rw-r--r--src/components/nav_panel/nav_panel.js11
-rw-r--r--src/components/navigation/filter.js5
-rw-r--r--src/components/navigation/navigation.js7
-rw-r--r--src/components/navigation/navigation_pins.js10
-rw-r--r--src/components/notifications/notifications.js4
-rw-r--r--src/components/settings_modal/tabs/mutes_and_blocks_tab.vue2
-rw-r--r--src/components/settings_modal/tabs/security_tab/security_tab.vue2
-rw-r--r--src/components/side_drawer/side_drawer.js5
-rw-r--r--src/components/side_drawer/side_drawer.vue20
-rw-r--r--src/components/timeline_menu/timeline_menu.js21
18 files changed, 522 insertions, 17 deletions
diff --git a/src/components/announcement/announcement.js b/src/components/announcement/announcement.js
new file mode 100644
index 00000000..c10c7d90
--- /dev/null
+++ b/src/components/announcement/announcement.js
@@ -0,0 +1,105 @@
+import { mapState } from 'vuex'
+import AnnouncementEditor from '../announcement_editor/announcement_editor.vue'
+import RichContent from '../rich_content/rich_content.jsx'
+import localeService from '../../services/locale/locale.service.js'
+
+const Announcement = {
+ components: {
+ AnnouncementEditor,
+ RichContent
+ },
+ data () {
+ return {
+ editing: false,
+ editedAnnouncement: {
+ content: '',
+ startsAt: undefined,
+ endsAt: undefined,
+ allDay: undefined
+ },
+ editError: ''
+ }
+ },
+ props: {
+ announcement: Object
+ },
+ computed: {
+ ...mapState({
+ currentUser: state => state.users.currentUser
+ }),
+ content () {
+ return this.announcement.content
+ },
+ isRead () {
+ return this.announcement.read
+ },
+ publishedAt () {
+ const time = this.announcement.published_at
+ if (!time) {
+ return
+ }
+
+ return this.formatTimeOrDate(time, localeService.internalToBrowserLocale(this.$i18n.locale))
+ },
+ startsAt () {
+ const time = this.announcement.starts_at
+ if (!time) {
+ return
+ }
+
+ return this.formatTimeOrDate(time, localeService.internalToBrowserLocale(this.$i18n.locale))
+ },
+ endsAt () {
+ const time = this.announcement.ends_at
+ if (!time) {
+ return
+ }
+
+ return this.formatTimeOrDate(time, localeService.internalToBrowserLocale(this.$i18n.locale))
+ },
+ inactive () {
+ return this.announcement.inactive
+ }
+ },
+ methods: {
+ markAsRead () {
+ if (!this.isRead) {
+ return this.$store.dispatch('markAnnouncementAsRead', this.announcement.id)
+ }
+ },
+ deleteAnnouncement () {
+ return this.$store.dispatch('deleteAnnouncement', this.announcement.id)
+ },
+ formatTimeOrDate (time, locale) {
+ const d = new Date(time)
+ return this.announcement.all_day ? d.toLocaleDateString(locale) : d.toLocaleString(locale)
+ },
+ enterEditMode () {
+ this.editedAnnouncement.content = this.announcement.pleroma.raw_content
+ this.editedAnnouncement.startsAt = this.announcement.starts_at
+ this.editedAnnouncement.endsAt = this.announcement.ends_at
+ this.editedAnnouncement.allDay = this.announcement.all_day
+ this.editing = true
+ },
+ submitEdit () {
+ this.$store.dispatch('editAnnouncement', {
+ id: this.announcement.id,
+ ...this.editedAnnouncement
+ })
+ .then(() => {
+ this.editing = false
+ })
+ .catch(error => {
+ this.editError = error.error
+ })
+ },
+ cancelEdit () {
+ this.editing = false
+ },
+ clearError () {
+ this.editError = undefined
+ }
+ }
+}
+
+export default Announcement
diff --git a/src/components/announcement/announcement.vue b/src/components/announcement/announcement.vue
new file mode 100644
index 00000000..5f64232a
--- /dev/null
+++ b/src/components/announcement/announcement.vue
@@ -0,0 +1,136 @@
+<template>
+ <div class="announcement">
+ <div class="heading">
+ <h4>{{ $t('announcements.title') }}</h4>
+ </div>
+ <div class="body">
+ <rich-content
+ v-if="!editing"
+ :html="content"
+ :emoji="announcement.emojis"
+ :handle-links="true"
+ />
+ <announcement-editor
+ v-else
+ :announcement="editedAnnouncement"
+ />
+ </div>
+ <div class="footer">
+ <div
+ v-if="!editing"
+ class="times"
+ >
+ <span v-if="publishedAt">
+ {{ $t('announcements.published_time_display', { time: publishedAt }) }}
+ </span>
+ <span v-if="startsAt">
+ {{ $t('announcements.start_time_display', { time: startsAt }) }}
+ </span>
+ <span v-if="endsAt">
+ {{ $t('announcements.end_time_display', { time: endsAt }) }}
+ </span>
+ </div>
+ <div
+ v-if="!editing"
+ class="actions"
+ >
+ <button
+ v-if="currentUser"
+ class="btn button-default"
+ :class="{ toggled: isRead }"
+ :disabled="inactive"
+ :title="inactive ? $t('announcements.inactive_message') : ''"
+ @click="markAsRead"
+ >
+ {{ $t('announcements.mark_as_read_action') }}
+ </button>
+ <button
+ v-if="currentUser && currentUser.role === 'admin'"
+ class="btn button-default"
+ @click="enterEditMode"
+ >
+ {{ $t('announcements.edit_action') }}
+ </button>
+ <button
+ v-if="currentUser && currentUser.role === 'admin'"
+ class="btn button-default"
+ @click="deleteAnnouncement"
+ >
+ {{ $t('announcements.delete_action') }}
+ </button>
+ </div>
+ <div
+ v-else
+ class="actions"
+ >
+ <button
+ class="btn button-default"
+ @click="submitEdit"
+ >
+ {{ $t('announcements.submit_edit_action') }}
+ </button>
+ <button
+ class="btn button-default"
+ @click="cancelEdit"
+ >
+ {{ $t('announcements.cancel_edit_action') }}
+ </button>
+ <div
+ v-if="editing && editError"
+ class="alert error"
+ >
+ {{ $t('announcements.edit_error', { error }) }}
+ <button
+ class="button-unstyled"
+ @click="clearError"
+ >
+ <FAIcon
+ class="fa-scale-110 fa-old-padding"
+ icon="times"
+ :title="$t('announcements.close_error')"
+ />
+ </button>
+ </div>
+ </div>
+ </div>
+ </div>
+</template>
+
+<script src="./announcement.js"></script>
+
+<style lang="scss">
+@import "../../variables";
+
+.announcement {
+ border-bottom-width: 1px;
+ border-bottom-style: solid;
+ border-bottom-color: var(--border, $fallback--border);
+ border-radius: 0;
+ padding: var(--status-margin, $status-margin);
+
+ .heading, .body {
+ margin-bottom: var(--status-margin, $status-margin);
+ }
+
+ .footer {
+ display: flex;
+ flex-direction: column;
+ .times {
+ display: flex;
+ flex-direction: column;
+ }
+ }
+
+ .footer .actions {
+ display: flex;
+ flex-direction: row;
+ justify-content: space-evenly;
+
+ .btn {
+ flex: 1;
+ margin: 1em;
+ max-width: 10em;
+ }
+ }
+}
+</style>
diff --git a/src/components/announcement_editor/announcement_editor.js b/src/components/announcement_editor/announcement_editor.js
new file mode 100644
index 00000000..79a03afe
--- /dev/null
+++ b/src/components/announcement_editor/announcement_editor.js
@@ -0,0 +1,13 @@
+import Checkbox from '../checkbox/checkbox.vue'
+
+const AnnouncementEditor = {
+ components: {
+ Checkbox
+ },
+ props: {
+ announcement: Object,
+ disabled: Boolean
+ }
+}
+
+export default AnnouncementEditor
diff --git a/src/components/announcement_editor/announcement_editor.vue b/src/components/announcement_editor/announcement_editor.vue
new file mode 100644
index 00000000..0f29f9f7
--- /dev/null
+++ b/src/components/announcement_editor/announcement_editor.vue
@@ -0,0 +1,60 @@
+<template>
+ <div class="announcement-editor">
+ <textarea
+ ref="textarea"
+ v-model="announcement.content"
+ class="post-textarea"
+ rows="1"
+ cols="1"
+ :placeholder="$t('announcements.post_placeholder')"
+ :disabled="disabled"
+ />
+ <span class="announcement-metadata">
+ <label for="announcement-start-time">{{ $t('announcements.start_time_prompt') }}</label>
+ <input
+ id="announcement-start-time"
+ v-model="announcement.startsAt"
+ :type="announcement.allDay ? 'date' : 'datetime-local'"
+ :disabled="disabled"
+ >
+ </span>
+ <span class="announcement-metadata">
+ <label for="announcement-end-time">{{ $t('announcements.end_time_prompt') }}</label>
+ <input
+ id="announcement-end-time"
+ v-model="announcement.endsAt"
+ :type="announcement.allDay ? 'date' : 'datetime-local'"
+ :disabled="disabled"
+ >
+ </span>
+ <span class="announcement-metadata">
+ <Checkbox
+ id="announcement-all-day"
+ v-model="announcement.allDay"
+ :disabled="disabled"
+ />
+ <label for="announcement-all-day">{{ $t('announcements.all_day_prompt') }}</label>
+ </span>
+ </div>
+</template>
+
+<script src="./announcement_editor.js"></script>
+
+<style lang="scss">
+.announcement-editor {
+ display: flex;
+ align-items: stretch;
+ flex-direction: column;
+
+ .announcement-metadata {
+ margin-top: 0.5em;
+ }
+
+ .post-textarea {
+ resize: vertical;
+ height: 10em;
+ overflow: none;
+ box-sizing: content-box;
+ }
+}
+</style>
diff --git a/src/components/announcements_page/announcements_page.js b/src/components/announcements_page/announcements_page.js
new file mode 100644
index 00000000..0bb4892e
--- /dev/null
+++ b/src/components/announcements_page/announcements_page.js
@@ -0,0 +1,55 @@
+import { mapState } from 'vuex'
+import Announcement from '../announcement/announcement.vue'
+import AnnouncementEditor from '../announcement_editor/announcement_editor.vue'
+
+const AnnouncementsPage = {
+ components: {
+ Announcement,
+ AnnouncementEditor
+ },
+ data () {
+ return {
+ newAnnouncement: {
+ content: '',
+ startsAt: undefined,
+ endsAt: undefined,
+ allDay: false
+ },
+ posting: false,
+ error: undefined
+ }
+ },
+ mounted () {
+ this.$store.dispatch('fetchAnnouncements')
+ },
+ computed: {
+ ...mapState({
+ currentUser: state => state.users.currentUser
+ }),
+ announcements () {
+ return this.$store.state.announcements.announcements
+ }
+ },
+ methods: {
+ postAnnouncement () {
+ this.posting = true
+ this.$store.dispatch('postAnnouncement', this.newAnnouncement)
+ .then(() => {
+ this.newAnnouncement.content = ''
+ this.startsAt = undefined
+ this.endsAt = undefined
+ })
+ .catch(error => {
+ this.error = error.error
+ })
+ .finally(() => {
+ this.posting = false
+ })
+ },
+ clearError () {
+ this.error = undefined
+ }
+ }
+}
+
+export default AnnouncementsPage
diff --git a/src/components/announcements_page/announcements_page.vue b/src/components/announcements_page/announcements_page.vue
new file mode 100644
index 00000000..b1489dec
--- /dev/null
+++ b/src/components/announcements_page/announcements_page.vue
@@ -0,0 +1,79 @@
+<template>
+ <div class="panel panel-default announcements-page">
+ <div class="panel-heading">
+ <span>
+ {{ $t('announcements.page_header') }}
+ </span>
+ </div>
+ <div class="panel-body">
+ <section
+ v-if="currentUser && currentUser.role === 'admin'"
+ >
+ <div class="post-form">
+ <div class="heading">
+ <h4>{{ $t('announcements.post_form_header') }}</h4>
+ </div>
+ <div class="body">
+ <announcement-editor
+ :announcement="newAnnouncement"
+ :disabled="posting"
+ />
+ </div>
+ <div class="footer">
+ <button
+ class="btn button-default post-button"
+ :disabled="posting"
+ @click.prevent="postAnnouncement"
+ >
+ {{ $t('announcements.post_action') }}
+ </button>
+ <div
+ v-if="error"
+ class="alert error"
+ >
+ {{ $t('announcements.post_error', { error }) }}
+ <button
+ class="button-unstyled"
+ @click="clearError"
+ >
+ <FAIcon
+ class="fa-scale-110 fa-old-padding"
+ icon="times"
+ :title="$t('announcements.close_error')"
+ />
+ </button>
+ </div>
+ </div>
+ </div>
+ </section>
+ <section
+ v-for="announcement in announcements"
+ :key="announcement.id"
+ >
+ <announcement
+ :announcement="announcement"
+ />
+ </section>
+ </div>
+ </div>
+</template>
+
+<script src="./announcements_page.js"></script>
+
+<style lang="scss">
+@import "../../variables";
+
+.announcements-page {
+ .post-form {
+ padding: var(--status-margin, $status-margin);
+
+ .heading, .body {
+ margin-bottom: var(--status-margin, $status-margin);
+ }
+
+ .post-button {
+ min-width: 10em;
+ }
+ }
+}
+</style>
diff --git a/src/components/mobile_nav/mobile_nav.js b/src/components/mobile_nav/mobile_nav.js
index fb8ffa30..cdbbb812 100644
--- a/src/components/mobile_nav/mobile_nav.js
+++ b/src/components/mobile_nav/mobile_nav.js
@@ -54,7 +54,7 @@ const MobileNav = {
isChat () {
return this.$route.name === 'chat'
},
- ...mapGetters(['unreadChatCount']),
+ ...mapGetters(['unreadChatCount', 'unreadAnnouncementCount']),
chatsPinned () {
return new Set(this.$store.state.serverSideStorage.prefsStorage.collections.pinnedNavItems).has('chats')
}
diff --git a/src/components/mobile_nav/mobile_nav.vue b/src/components/mobile_nav/mobile_nav.vue
index d642008b..0f1fe621 100644
--- a/src/components/mobile_nav/mobile_nav.vue
+++ b/src/components/mobile_nav/mobile_nav.vue
@@ -19,7 +19,7 @@
icon="bars"
/>
<div
- v-if="unreadChatCount && !chatsPinned"
+ v-if="(unreadChatCount && !chatsPinned) || unreadAnnouncementCount"
class="alert-dot"
/>
</button>
diff --git a/src/components/nav_panel/nav_panel.js b/src/components/nav_panel/nav_panel.js
index b54f2fa2..8c9c3b11 100644
--- a/src/components/nav_panel/nav_panel.js
+++ b/src/components/nav_panel/nav_panel.js
@@ -18,7 +18,8 @@ import {
faBell,
faInfoCircle,
faStream,
- faList
+ faList,
+ faBullhorn
} from '@fortawesome/free-solid-svg-icons'
library.add(
@@ -32,7 +33,8 @@ library.add(
faBell,
faInfoCircle,
faStream,
- faList
+ faList,
+ faBullhorn
)
const NavPanel = {
props: ['forceExpand', 'forceEditMode'],
@@ -86,6 +88,7 @@ const NavPanel = {
privateMode: state => state.instance.private,
federating: state => state.instance.federating,
pleromaChatMessagesAvailable: state => state.instance.pleromaChatMessagesAvailable,
+ supportsAnnouncements: state => state.announcements.supportsAnnouncements,
pinnedItems: state => new Set(state.serverSideStorage.prefsStorage.collections.pinnedNavItems),
collapsed: state => state.serverSideStorage.prefsStorage.simple.collapseNav
}),
@@ -96,6 +99,7 @@ const NavPanel = {
.map(([k, v]) => ({ ...v, name: k })),
{
hasChats: this.pleromaChatMessagesAvailable,
+ hasAnnouncements: this.supportsAnnouncements,
isFederating: this.federating,
isPrivate: this.privateMode,
currentUser: this.currentUser
@@ -109,13 +113,14 @@ const NavPanel = {
.map(([k, v]) => ({ ...v, name: k })),
{
hasChats: this.pleromaChatMessagesAvailable,
+ hasAnnouncements: this.supportsAnnouncements,
isFederating: this.federating,
isPrivate: this.privateMode,
currentUser: this.currentUser
}
)
},
- ...mapGetters(['unreadChatCount'])
+ ...mapGetters(['unreadChatCount', 'unreadAnnouncementCount'])
}
}
diff --git a/src/components/navigation/filter.js b/src/components/navigation/filter.js
index 31b55486..e8e77f8f 100644
--- a/src/components/navigation/filter.js
+++ b/src/components/navigation/filter.js
@@ -1,11 +1,12 @@
-export const filterNavigation = (list = [], { hasChats, isFederating, isPrivate, currentUser }) => {
+export const filterNavigation = (list = [], { hasChats, hasAnnouncements, isFederating, isPrivate, currentUser }) => {
return list.filter(({ criteria, anon, anonRoute }) => {
const set = new Set(criteria || [])
if (!isFederating && set.has('federating')) return false
- if (isPrivate && set.has('!private')) return false
+ if (!currentUser && isPrivate && set.has('!private')) return false
if (!currentUser && !(anon || anonRoute)) return false
if ((!currentUser || !currentUser.locked) && set.has('lockedUser')) return false
if (!hasChats && set.has('chats')) return false
+ if (!hasAnnouncements && set.has('announcements')) return false
return true
})
}
diff --git a/src/components/navigation/navigation.js b/src/components/navigation/navigation.js
index f66dd981..7f096316 100644
--- a/src/components/navigation/navigation.js
+++ b/src/components/navigation/navigation.js
@@ -71,5 +71,12 @@ export const ROOT_ITEMS = {
anon: true,
icon: 'info-circle',
label: 'nav.about'
+ },
+ announcements: {
+ route: 'announcements',
+ icon: 'bullhorn',
+ label: 'nav.announcements',
+ badgeGetter: 'unreadAnnouncementCount',
+ criteria: ['announcements']
}
}
diff --git a/src/components/navigation/navigation_pins.js b/src/components/navigation/navigation_pins.js
index 57b8d589..9dd795aa 100644
--- a/src/components/navigation/navigation_pins.js
+++ b/src/components/navigation/navigation_pins.js
@@ -56,11 +56,17 @@ const NavPanel = {
}),
pinnedList () {
if (!this.currentUser) {
- return [
+ return filterNavigation([
{ ...TIMELINES.public, name: 'public' },
{ ...TIMELINES.twkn, name: 'twkn' },
{ ...ROOT_ITEMS.about, name: 'about' }
- ]
+ ],
+ {
+ hasChats: this.pleromaChatMessagesAvailable,
+ isFederating: this.federating,
+ isPrivate: this.privateMode,
+ currentUser: this.currentUser
+ })
}
return filterNavigation(
[
diff --git a/src/components/notifications/notifications.js b/src/components/notifications/notifications.js
index c3acd9e0..dde9c93e 100644
--- a/src/components/notifications/notifications.js
+++ b/src/components/notifications/notifications.js
@@ -69,7 +69,7 @@ const Notifications = {
return this.unseenNotifications.length
},
unseenCountTitle () {
- return this.unseenCount + (this.unreadChatCount)
+ return this.unseenCount + (this.unreadChatCount) + this.unreadAnnouncementCount
},
loading () {
return this.$store.state.statuses.notifications.loading
@@ -94,7 +94,7 @@ const Notifications = {
return this.filteredNotifications.slice(0, this.unseenCount + this.seenToDisplayCount)
},
noSticky () { return this.$store.getters.mergedConfig.disableStickyHeaders },
- ...mapGetters(['unreadChatCount'])
+ ...mapGetters(['unreadChatCount', 'unreadAnnouncementCount'])
},
mounted () {
this.scrollerRef = this.$refs.root.closest('.column.-scrollable')
diff --git a/src/components/settings_modal/tabs/mutes_and_blocks_tab.vue b/src/components/settings_modal/tabs/mutes_and_blocks_tab.vue
index c515d542..ed4b15a4 100644
--- a/src/components/settings_modal/tabs/mutes_and_blocks_tab.vue
+++ b/src/components/settings_modal/tabs/mutes_and_blocks_tab.vue
@@ -56,7 +56,7 @@
<div :label="$t('settings.mutes_tab')">
<tab-switcher>
- <div label="Users">
+ <div :label="$t('settings.user_mutes')">
<div class="usersearch-wrapper">
<Autosuggest
:filter="filterUnMutedUsers"
diff --git a/src/components/settings_modal/tabs/security_tab/security_tab.vue b/src/components/settings_modal/tabs/security_tab/security_tab.vue
index c74a0c67..6e03bef4 100644
--- a/src/components/settings_modal/tabs/security_tab/security_tab.vue
+++ b/src/components/settings_modal/tabs/security_tab/security_tab.vue
@@ -241,7 +241,7 @@
class="btn button-default"
@click="confirmDelete"
>
- {{ $t('settings.save') }}
+ {{ $t('settings.delete_account') }}
</button>
</div>
</div>
diff --git a/src/components/side_drawer/side_drawer.js b/src/components/side_drawer/side_drawer.js
index bb22446b..27019577 100644
--- a/src/components/side_drawer/side_drawer.js
+++ b/src/components/side_drawer/side_drawer.js
@@ -95,9 +95,10 @@ const SideDrawer = {
}
},
...mapState({
- pleromaChatMessagesAvailable: state => state.instance.pleromaChatMessagesAvailable
+ pleromaChatMessagesAvailable: state => state.instance.pleromaChatMessagesAvailable,
+ supportsAnnouncements: state => state.announcements.supportsAnnouncements
}),
- ...mapGetters(['unreadChatCount'])
+ ...mapGetters(['unreadChatCount', 'unreadAnnouncementCount'])
},
methods: {
toggleDrawer () {
diff --git a/src/components/side_drawer/side_drawer.vue b/src/components/side_drawer/side_drawer.vue
index cbeafdd2..887596f8 100644
--- a/src/components/side_drawer/side_drawer.vue
+++ b/src/components/side_drawer/side_drawer.vue
@@ -192,6 +192,26 @@
</a>
</li>
<li
+ v-if="currentUser && supportsAnnouncements"
+ @click="toggleDrawer"
+ >
+ <router-link
+ :to="{ name: 'announcements' }"
+ >
+ <FAIcon
+ fixed-width
+ class="fa-scale-110 fa-old-padding"
+ icon="bullhorn"
+ /> {{ $t("nav.announcements") }}
+ <span
+ v-if="unreadAnnouncementCount"
+ class="badge badge-notification"
+ >
+ {{ unreadAnnouncementCount }}
+ </span>
+ </router-link>
+ </li>
+ <li
v-if="currentUser"
@click="toggleDrawer"
>
diff --git a/src/components/timeline_menu/timeline_menu.js b/src/components/timeline_menu/timeline_menu.js
index d74fbf4e..5a2a86c2 100644
--- a/src/components/timeline_menu/timeline_menu.js
+++ b/src/components/timeline_menu/timeline_menu.js
@@ -1,8 +1,10 @@
import Popover from '../popover/popover.vue'
import NavigationEntry from 'src/components/navigation/navigation_entry.vue'
+import { mapState } from 'vuex'
import { ListsMenuContent } from '../lists_menu/lists_menu_content.vue'
import { library } from '@fortawesome/fontawesome-svg-core'
import { TIMELINES } from 'src/components/navigation/navigation.js'
+import { filterNavigation } from 'src/components/navigation/filter.js'
import {
faChevronDown
} from '@fortawesome/free-solid-svg-icons'
@@ -29,8 +31,7 @@ const TimelineMenu = {
},
data () {
return {
- isOpen: false,
- timelinesList: Object.entries(TIMELINES).map(([k, v]) => ({ ...v, name: k }))
+ isOpen: false
}
},
created () {
@@ -42,6 +43,22 @@ const TimelineMenu = {
useListsMenu () {
const route = this.$route.name
return route === 'lists-timeline'
+ },
+ ...mapState({
+ currentUser: state => state.users.currentUser,
+ privateMode: state => state.instance.private,
+ federating: state => state.instance.federating
+ }),
+ timelinesList () {
+ return filterNavigation(
+ Object.entries(TIMELINES).map(([k, v]) => ({ ...v, name: k })),
+ {
+ hasChats: this.pleromaChatMessagesAvailable,
+ isFederating: this.federating,
+ isPrivate: this.privateMode,
+ currentUser: this.currentUser
+ }
+ )
}
},
methods: {