Merge remote-tracking branch 'origin/develop' into migrate/vuex-to-pinia
This commit is contained in:
commit
58e18d48df
489 changed files with 31167 additions and 9871 deletions
|
|
@ -1,4 +1,4 @@
|
|||
export const filterNavigation = (list = [], { hasChats, hasAnnouncements, isFederating, isPrivate, currentUser }) => {
|
||||
export const filterNavigation = (list = [], { hasChats, hasAnnouncements, isFederating, isPrivate, currentUser, supportsBookmarkFolders }) => {
|
||||
return list.filter(({ criteria, anon, anonRoute }) => {
|
||||
const set = new Set(criteria || [])
|
||||
if (!isFederating && set.has('federating')) return false
|
||||
|
|
@ -7,6 +7,7 @@ export const filterNavigation = (list = [], { hasChats, hasAnnouncements, isFede
|
|||
if ((!currentUser || !currentUser.locked) && set.has('lockedUser')) return false
|
||||
if (!hasChats && set.has('chats')) return false
|
||||
if (!hasAnnouncements && set.has('announcements')) return false
|
||||
if (supportsBookmarkFolders && set.has('!supportsBookmarkFolders')) return false
|
||||
return true
|
||||
})
|
||||
}
|
||||
|
|
@ -17,3 +18,12 @@ export const getListEntries = store => store.allLists.map(list => ({
|
|||
labelRaw: list.title,
|
||||
iconLetter: list.title[0]
|
||||
}))
|
||||
|
||||
export const getBookmarkFolderEntries = state => state.bookmarkFolders.allFolders.map(folder => ({
|
||||
name: 'bookmark-folder-' + folder.id,
|
||||
routeObject: { name: 'bookmark-folder', params: { id: folder.id } },
|
||||
labelRaw: folder.name,
|
||||
iconEmoji: folder.emoji,
|
||||
iconEmojiUrl: folder.emoji_url,
|
||||
iconLetter: folder.name[0]
|
||||
}))
|
||||
|
|
|
|||
|
|
@ -1,11 +1,16 @@
|
|||
// routes that take :username property
|
||||
export const USERNAME_ROUTES = new Set([
|
||||
'bookmarks',
|
||||
'dms',
|
||||
'interactions',
|
||||
'notifications',
|
||||
'chat',
|
||||
'chats',
|
||||
'user-profile'
|
||||
'chats'
|
||||
])
|
||||
|
||||
// routes that take :name property
|
||||
export const NAME_ROUTES = new Set([
|
||||
'user-profile',
|
||||
'legacy-user-profile'
|
||||
])
|
||||
|
||||
export const TIMELINES = {
|
||||
|
|
@ -32,7 +37,8 @@ export const TIMELINES = {
|
|||
bookmarks: {
|
||||
route: 'bookmarks',
|
||||
icon: 'bookmark',
|
||||
label: 'nav.bookmarks'
|
||||
label: 'nav.bookmarks',
|
||||
criteria: ['!supportsBookmarkFolders']
|
||||
},
|
||||
favorites: {
|
||||
routeObject: { name: 'user-profile', query: { tab: 'favorites' } },
|
||||
|
|
@ -56,6 +62,7 @@ export const ROOT_ITEMS = {
|
|||
route: 'chats',
|
||||
icon: 'comments',
|
||||
label: 'nav.chats',
|
||||
badgeStyle: 'notification',
|
||||
badgeGetter: 'unreadChatCount',
|
||||
criteria: ['chats']
|
||||
},
|
||||
|
|
@ -63,6 +70,7 @@ export const ROOT_ITEMS = {
|
|||
route: 'friend-requests',
|
||||
icon: 'user-plus',
|
||||
label: 'nav.friend_requests',
|
||||
badgeStyle: 'notification',
|
||||
criteria: ['lockedUser'],
|
||||
badgeGetter: 'followRequestCount'
|
||||
},
|
||||
|
|
@ -77,8 +85,16 @@ export const ROOT_ITEMS = {
|
|||
icon: 'bullhorn',
|
||||
label: 'nav.announcements',
|
||||
store: 'announcements',
|
||||
badgeStyle: 'notification',
|
||||
badgeGetter: 'unreadAnnouncementCount',
|
||||
criteria: ['announcements']
|
||||
},
|
||||
drafts: {
|
||||
route: 'drafts',
|
||||
icon: 'file-pen',
|
||||
label: 'nav.drafts',
|
||||
badgeStyle: 'neutral',
|
||||
badgeGetter: 'draftCount'
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -94,7 +110,9 @@ export function routeTo (item, currentUser) {
|
|||
}
|
||||
|
||||
if (USERNAME_ROUTES.has(route.name)) {
|
||||
route.params = { username: currentUser.screen_name, name: currentUser.screen_name }
|
||||
route.params = { username: currentUser.screen_name }
|
||||
} else if (NAME_ROUTES.has(route.name)) {
|
||||
route.params = { name: currentUser.screen_name }
|
||||
}
|
||||
|
||||
return route
|
||||
|
|
|
|||
|
|
@ -1,7 +1,6 @@
|
|||
<template>
|
||||
<OptionalRouterLink
|
||||
v-slot="{ isActive, href, navigate } = {}"
|
||||
ass="ass"
|
||||
:to="routeTo"
|
||||
>
|
||||
<li
|
||||
|
|
@ -11,7 +10,7 @@
|
|||
>
|
||||
<component
|
||||
:is="routeTo ? 'a' : 'button'"
|
||||
class="main-link button-unstyled"
|
||||
class="main-link"
|
||||
:href="href"
|
||||
@click="navigate"
|
||||
>
|
||||
|
|
@ -23,11 +22,25 @@
|
|||
:icon="item.icon"
|
||||
/>
|
||||
</span>
|
||||
<img
|
||||
v-if="item.iconEmojiUrl"
|
||||
class="menu-icon iconEmoji iconEmoji-image"
|
||||
:src="item.iconEmojiUrl"
|
||||
:alt="item.iconEmoji"
|
||||
:title="item.iconEmoji"
|
||||
>
|
||||
<span
|
||||
v-if="item.iconLetter"
|
||||
class="icon iconLetter fa-scale-110 menu-icon"
|
||||
>{{ item.iconLetter }}
|
||||
v-else-if="item.iconEmoji"
|
||||
class="menu-icon iconEmoji"
|
||||
>
|
||||
<span>
|
||||
{{ item.iconEmoji }}
|
||||
</span>
|
||||
</span>
|
||||
<span
|
||||
v-else-if="item.iconLetter"
|
||||
class="icon iconLetter fa-scale-110 menu-icon"
|
||||
>{{ item.iconLetter }}</span>
|
||||
<span class="label">
|
||||
{{ item.labelRaw || $t(item.label) }}
|
||||
</span>
|
||||
|
|
@ -35,7 +48,8 @@
|
|||
<slot />
|
||||
<div
|
||||
v-if="item.badgeGetter && getters[item.badgeGetter]"
|
||||
class="badge badge-notification"
|
||||
class="badge"
|
||||
:class="[`-${item.badgeStyle}`]"
|
||||
>
|
||||
{{ getters[item.badgeGetter] }}
|
||||
</div>
|
||||
|
|
@ -69,73 +83,63 @@
|
|||
<script src="./navigation_entry.js"></script>
|
||||
|
||||
<style lang="scss">
|
||||
@import "../../variables";
|
||||
.NavigationEntry.menu-item {
|
||||
--__line-height: 2.5em;
|
||||
--__horizontal-gap: 0.5em;
|
||||
--__vertical-gap: 0.4em;
|
||||
|
||||
.NavigationEntry {
|
||||
display: flex;
|
||||
box-sizing: border-box;
|
||||
padding: var(--__vertical-gap) var(--__horizontal-gap);
|
||||
display: grid;
|
||||
grid-template-columns: 1fr;
|
||||
grid-auto-columns: var(--__line-height);
|
||||
grid-auto-flow: column;
|
||||
grid-gap: var(--__horizontal-gap);
|
||||
align-items: baseline;
|
||||
height: 3.5em;
|
||||
line-height: 3.5em;
|
||||
padding: 0 1em;
|
||||
width: 100%;
|
||||
color: $fallback--link;
|
||||
color: var(--link, $fallback--link);
|
||||
|
||||
.timelines-chevron {
|
||||
margin-right: 0;
|
||||
&[aria-expanded] {
|
||||
padding-right: var(--__horizontal-gap);
|
||||
}
|
||||
|
||||
.main-link {
|
||||
flex: 1;
|
||||
line-height: var(--__line-height);
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.menu-icon {
|
||||
margin-right: 0.8em;
|
||||
line-height: var(--__line-height);
|
||||
padding: 0;
|
||||
width: var(--__line-height);
|
||||
margin-right: var(--__horizontal-gap);
|
||||
}
|
||||
|
||||
.timelines-chevron,
|
||||
.extra-button {
|
||||
width: 3em;
|
||||
line-height: var(--__line-height);
|
||||
width: 100%;
|
||||
padding: 0;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
&:last-child {
|
||||
margin-right: -0.8em;
|
||||
.badge {
|
||||
justify-self: center;
|
||||
}
|
||||
|
||||
.iconEmoji {
|
||||
display: inline-block;
|
||||
text-align: center;
|
||||
object-fit: contain;
|
||||
vertical-align: middle;
|
||||
height: var(--__line-height);
|
||||
width: var(--__line-height);
|
||||
|
||||
> span {
|
||||
font-size: 1.5rem;
|
||||
}
|
||||
}
|
||||
|
||||
&:hover {
|
||||
background-color: $fallback--lightBg;
|
||||
background-color: var(--selectedMenu, $fallback--lightBg);
|
||||
color: $fallback--link;
|
||||
color: var(--selectedMenuText, $fallback--link);
|
||||
|
||||
--faint: var(--selectedMenuFaintText, $fallback--faint);
|
||||
--faintLink: var(--selectedMenuFaintLink, $fallback--faint);
|
||||
--lightText: var(--selectedMenuLightText, $fallback--lightText);
|
||||
|
||||
.menu-icon {
|
||||
--icon: var(--text, $fallback--icon);
|
||||
}
|
||||
}
|
||||
|
||||
&.-active {
|
||||
font-weight: bolder;
|
||||
background-color: $fallback--lightBg;
|
||||
background-color: var(--selectedMenu, $fallback--lightBg);
|
||||
color: $fallback--text;
|
||||
color: var(--selectedMenuText, $fallback--text);
|
||||
|
||||
--faint: var(--selectedMenuFaintText, $fallback--faint);
|
||||
--faintLink: var(--selectedMenuFaintLink, $fallback--faint);
|
||||
--lightText: var(--selectedMenuLightText, $fallback--lightText);
|
||||
|
||||
.menu-icon {
|
||||
--icon: var(--text, $fallback--icon);
|
||||
}
|
||||
|
||||
&:hover {
|
||||
text-decoration: underline;
|
||||
}
|
||||
img.iconEmoji {
|
||||
padding: 0.25rem;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
|
|
|||
|
|
@ -1,7 +1,9 @@
|
|||
import { mapState } from 'vuex'
|
||||
import { mapState as mapPiniaState } from 'pinia'
|
||||
import { TIMELINES, ROOT_ITEMS, routeTo } from 'src/components/navigation/navigation.js'
|
||||
import { getListEntries, filterNavigation } from 'src/components/navigation/filter.js'
|
||||
import { getBookmarkFolderEntries, getListEntries, filterNavigation } from 'src/components/navigation/filter.js'
|
||||
|
||||
import StillImage from 'src/components/still-image/still-image.vue'
|
||||
|
||||
import { library } from '@fortawesome/fontawesome-svg-core'
|
||||
import {
|
||||
|
|
@ -36,6 +38,9 @@ const NavPanel = {
|
|||
return routeTo(item, this.currentUser)
|
||||
}
|
||||
},
|
||||
components: {
|
||||
StillImage
|
||||
},
|
||||
computed: {
|
||||
getters () {
|
||||
return this.$store.getters
|
||||
|
|
@ -44,11 +49,13 @@ const NavPanel = {
|
|||
lists: getListEntries
|
||||
}),
|
||||
...mapState({
|
||||
bookmarks: getBookmarkFolderEntries,
|
||||
currentUser: state => state.users.currentUser,
|
||||
followRequestCount: state => state.api.followRequests.length,
|
||||
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)
|
||||
}),
|
||||
pinnedList () {
|
||||
|
|
@ -60,6 +67,7 @@ const NavPanel = {
|
|||
],
|
||||
{
|
||||
hasChats: this.pleromaChatMessagesAvailable,
|
||||
hasAnnouncements: this.supportsAnnouncements,
|
||||
isFederating: this.federating,
|
||||
isPrivate: this.privateMode,
|
||||
currentUser: this.currentUser
|
||||
|
|
@ -72,6 +80,7 @@ const NavPanel = {
|
|||
.filter(([k]) => this.pinnedItems.has(k))
|
||||
.map(([k, v]) => ({ ...v, name: k })),
|
||||
...this.lists.filter((k) => this.pinnedItems.has(k.name)),
|
||||
...this.bookmarks.filter((k) => this.pinnedItems.has(k.name)),
|
||||
...Object
|
||||
.entries({ ...ROOT_ITEMS })
|
||||
.filter(([k]) => this.pinnedItems.has(k))
|
||||
|
|
@ -79,6 +88,7 @@ const NavPanel = {
|
|||
],
|
||||
{
|
||||
hasChats: this.pleromaChatMessagesAvailable,
|
||||
hasAnnouncements: this.supportsAnnouncements,
|
||||
isFederating: this.federating,
|
||||
isPrivate: this.privateMode,
|
||||
currentUser: this.currentUser
|
||||
|
|
|
|||
|
|
@ -3,7 +3,8 @@
|
|||
<router-link
|
||||
v-for="item in pinnedList"
|
||||
:key="item.name"
|
||||
class="pinned-item"
|
||||
class="button-unstyled pinned-item"
|
||||
active-class="toggled"
|
||||
:to="getRouteTo(item)"
|
||||
:title="item.labelRaw || $t(item.label)"
|
||||
>
|
||||
|
|
@ -13,12 +14,18 @@
|
|||
:icon="item.icon"
|
||||
/>
|
||||
<span
|
||||
v-if="item.iconLetter"
|
||||
v-if="item.iconLetter && !item.iconEmoji"
|
||||
class="iconLetter fa-scale-110 fa-old-padding"
|
||||
>{{ item.iconLetter }}</span>
|
||||
<StillImage
|
||||
v-if="item.iconEmoji"
|
||||
class="bookmark-emoji"
|
||||
:src="item.iconEmojiUrl"
|
||||
/>
|
||||
<div
|
||||
v-if="item.badgeGetter && getters[item.badgeGetter]"
|
||||
class="alert-dot"
|
||||
class="badge -dot"
|
||||
:class="[`-${item.badgeStyle}`]"
|
||||
/>
|
||||
</router-link>
|
||||
</span>
|
||||
|
|
@ -27,23 +34,18 @@
|
|||
<script src="./navigation_pins.js"></script>
|
||||
|
||||
<style lang="scss">
|
||||
@import "../../variables";
|
||||
|
||||
.NavigationPins {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
overflow: hidden;
|
||||
height: 100%;
|
||||
|
||||
.alert-dot {
|
||||
border-radius: 100%;
|
||||
height: 0.5em;
|
||||
width: 0.5em;
|
||||
position: absolute;
|
||||
right: calc(50% - 0.75em);
|
||||
top: calc(50% - 0.5em);
|
||||
background-color: $fallback--cRed;
|
||||
background-color: var(--badgeNotification, $fallback--cRed);
|
||||
&.alert-dot-notification {
|
||||
background-color: var(--badgeNotification);
|
||||
}
|
||||
|
||||
&.alert-dot-neutral {
|
||||
background-color: var(--badgeNeutral);
|
||||
}
|
||||
|
||||
.pinned-item {
|
||||
|
|
@ -55,20 +57,21 @@
|
|||
box-sizing: border-box;
|
||||
height: 100%;
|
||||
|
||||
.bookmark-emoji {
|
||||
height: 100%;
|
||||
box-sizing: border-box;
|
||||
padding: 0.5em;
|
||||
}
|
||||
|
||||
& .bookmark-emoji,
|
||||
& .svg-inline--fa,
|
||||
& .iconLetter {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
&.router-link-active {
|
||||
color: $fallback--text;
|
||||
color: var(--panelText, $fallback--text);
|
||||
&.toggled {
|
||||
margin-bottom: -4px;
|
||||
border-bottom: 4px solid;
|
||||
|
||||
& .svg-inline--fa,
|
||||
& .iconLetter {
|
||||
color: inherit;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue