diff --git a/src/boot/after_store.js b/src/boot/after_store.js index cbacfcd0e..39fc6f6f0 100644 --- a/src/boot/after_store.js +++ b/src/boot/after_store.js @@ -266,6 +266,7 @@ const getNodeInfo = async ({ store }) => { store.dispatch('setInstanceOption', { name: 'mailerEnabled', value: metadata.mailerEnabled }) store.dispatch('setInstanceOption', { name: 'quotingAvailable', value: features.includes('quote_posting') }) store.dispatch('setInstanceOption', { name: 'groupActorAvailable', value: features.includes('pleroma:group_actors') }) + store.dispatch('setInstanceOption', { name: 'localBubbleInstances', value: metadata.localBubbleInstances ?? [] }) const uploadLimits = metadata.uploadLimits store.dispatch('setInstanceOption', { name: 'uploadlimit', value: parseInt(uploadLimits.general) }) diff --git a/src/boot/routes.js b/src/boot/routes.js index da87c6c61..02abf8ce6 100644 --- a/src/boot/routes.js +++ b/src/boot/routes.js @@ -1,4 +1,5 @@ import PublicTimeline from 'components/public_timeline/public_timeline.vue' +import BubbleTimeline from 'components/bubble_timeline/bubble_timeline.vue' import PublicAndExternalTimeline from 'components/public_and_external_timeline/public_and_external_timeline.vue' import FriendsTimeline from 'components/friends_timeline/friends_timeline.vue' import TagTimeline from 'components/tag_timeline/tag_timeline.vue' @@ -54,6 +55,7 @@ export default (store) => { { name: 'friends', path: '/main/friends', component: FriendsTimeline, beforeEnter: validateAuthenticatedRoute }, { name: 'tag-timeline', path: '/tag/:tag', component: TagTimeline }, { name: 'bookmarks', path: '/bookmarks', component: BookmarkTimeline }, + { name: 'bubble', path: '/bubble', component: BubbleTimeline }, { name: 'conversation', path: '/notice/:id', component: ConversationPage, meta: { dontScroll: true } }, { name: 'quotes', path: '/notice/:id/quotes', component: QuotesTimeline }, { diff --git a/src/components/nav_panel/nav_panel.js b/src/components/nav_panel/nav_panel.js index 681aaf05b..2cdb4c45b 100644 --- a/src/components/nav_panel/nav_panel.js +++ b/src/components/nav_panel/nav_panel.js @@ -15,6 +15,7 @@ import { library } from '@fortawesome/fontawesome-svg-core' import { faUsers, faGlobe, + faCity, faBookmark, faEnvelope, faChevronDown, @@ -31,6 +32,7 @@ import { library.add( faUsers, faGlobe, + faCity, faBookmark, faEnvelope, faChevronDown, @@ -108,7 +110,8 @@ const NavPanel = { privateMode: state => state.instance.private, federating: state => state.instance.federating, pleromaChatMessagesAvailable: state => state.instance.pleromaChatMessagesAvailable, - bookmarkFolders: state => state.instance.pleromaBookmarkFoldersAvailable + bookmarkFolders: state => state.instance.pleromaBookmarkFoldersAvailable, + bubbleTimeline: state => state.instance.localBubbleInstances.length > 0 }), timelinesItems () { return filterNavigation( @@ -121,7 +124,8 @@ const NavPanel = { isFederating: this.federating, isPrivate: this.privateMode, currentUser: this.currentUser, - supportsBookmarkFolders: this.bookmarkFolders + supportsBookmarkFolders: this.bookmarkFolders, + supportsBubbleTimeline: this.bubbleTimeline } ) }, @@ -136,7 +140,8 @@ const NavPanel = { isFederating: this.federating, isPrivate: this.privateMode, currentUser: this.currentUser, - supportsBookmarkFolders: this.bookmarkFolders + supportsBookmarkFolders: this.bookmarkFolders, + supportsBubbleTimeline: this.bubbleTimeline } ) }, diff --git a/src/components/navigation/navigation.js b/src/components/navigation/navigation.js index a8e1fc966..6702bea4e 100644 --- a/src/components/navigation/navigation.js +++ b/src/components/navigation/navigation.js @@ -27,6 +27,12 @@ export const TIMELINES = { label: 'nav.public_tl', criteria: ['!private'] }, + bubble: { + route: 'bubble', + icon: 'city', + label: 'nav.bubble', + criteria: ['supportsBubbleTimeline'] + }, twkn: { route: 'public-external-timeline', anon: true, diff --git a/src/components/timeline_menu/timeline_menu.js b/src/components/timeline_menu/timeline_menu.js index 38e6bdf4f..4c8f7b76e 100644 --- a/src/components/timeline_menu/timeline_menu.js +++ b/src/components/timeline_menu/timeline_menu.js @@ -24,7 +24,8 @@ export const timelineNames = (supportsBookmarkFolders) => { dms: 'nav.dms', 'public-timeline': 'nav.public_tl', 'public-external-timeline': 'nav.twkn', - quotes: 'nav.quotes' + quotes: 'nav.quotes', + bubble: 'nav.bubble' } } @@ -58,7 +59,8 @@ const TimelineMenu = { currentUser: state => state.users.currentUser, privateMode: state => state.instance.private, federating: state => state.instance.federating, - bookmarkFolders: state => state.instance.pleromaBookmarkFoldersAvailable + bookmarkFolders: state => state.instance.pleromaBookmarkFoldersAvailable, + bubbleTimeline: state => state.instance.localBubbleInstances.length > 0 }), timelinesList () { return filterNavigation( @@ -68,7 +70,8 @@ const TimelineMenu = { isFederating: this.federating, isPrivate: this.privateMode, currentUser: this.currentUser, - supportsBookmarkFolders: this.bookmarkFolders + supportsBookmarkFolders: this.bookmarkFolders, + supportsBubbleTimeline: this.bubbleTimeline } ) } diff --git a/src/i18n/en.json b/src/i18n/en.json index 019beba1c..5e99cc6ef 100644 --- a/src/i18n/en.json +++ b/src/i18n/en.json @@ -171,6 +171,7 @@ "interactions": "Interactions", "dms": "Direct messages", "public_tl": "Public timeline", + "bubble": "Bubble timeline", "timeline": "Timeline", "home_timeline": "Home timeline", "twkn": "Known Network", diff --git a/src/modules/statuses.js b/src/modules/statuses.js index fc922337e..efdfc5894 100644 --- a/src/modules/statuses.js +++ b/src/modules/statuses.js @@ -51,7 +51,8 @@ export const defaultState = () => ({ tag: emptyTl(), dms: emptyTl(), bookmarks: emptyTl(), - list: emptyTl() + list: emptyTl(), + bubble: emptyTl() } }) diff --git a/src/services/api/api.service.js b/src/services/api/api.service.js index ce424eab3..6de94278e 100644 --- a/src/services/api/api.service.js +++ b/src/services/api/api.service.js @@ -61,6 +61,7 @@ const MASTODON_LIST_TIMELINE_URL = id => `/api/v1/timelines/list/${id}` const MASTODON_LIST_ACCOUNTS_URL = id => `/api/v1/lists/${id}/accounts` const MASTODON_TAG_TIMELINE_URL = tag => `/api/v1/timelines/tag/${tag}` const MASTODON_BOOKMARK_TIMELINE_URL = '/api/v1/bookmarks' +const AKKOMA_BUBBLE_TIMELINE_URL = '/api/v1/timelines/bubble' const MASTODON_USER_BLOCKS_URL = '/api/v1/blocks/' const MASTODON_USER_MUTES_URL = '/api/v1/mutes/' const MASTODON_BLOCK_USER_URL = id => `/api/v1/accounts/${id}/block` @@ -707,7 +708,8 @@ const fetchTimeline = ({ publicFavorites: PLEROMA_USER_FAVORITES_TIMELINE_URL, tag: MASTODON_TAG_TIMELINE_URL, bookmarks: MASTODON_BOOKMARK_TIMELINE_URL, - quotes: PLEROMA_STATUS_QUOTES_URL + quotes: PLEROMA_STATUS_QUOTES_URL, + bubble: AKKOMA_BUBBLE_TIMELINE_URL } const isNotifications = timeline === 'notifications' const params = [] diff --git a/src/services/timeline_fetcher/timeline_fetcher.service.js b/src/services/timeline_fetcher/timeline_fetcher.service.js index fdf235af7..f64646593 100644 --- a/src/services/timeline_fetcher/timeline_fetcher.service.js +++ b/src/services/timeline_fetcher/timeline_fetcher.service.js @@ -54,7 +54,7 @@ const fetchAndUpdate = ({ args.bookmarkFolderId = bookmarkFolderId args.tag = tag args.withMuted = !hideMutedPosts - if (loggedIn && ['friends', 'public', 'publicAndExternal'].includes(timeline)) { + if (loggedIn && ['friends', 'public', 'publicAndExternal', 'bubble'].includes(timeline)) { args.replyVisibility = replyVisibility }