commit: 19fc7dda9e6d3513c8b57d7bae2bbe3c9ab87ced
parent ae159f6ad8d23ce0e3d2d765bf694f1a614c6df4
Author: Shpuld Shpuldson <shp@cock.li>
Date: Mon, 15 Mar 2021 11:02:16 +0200
merge conflict, use v-slot:trigger, fix popover svg dimensions bug
Diffstat:
17 files changed, 232 insertions(+), 125 deletions(-)
diff --git a/CHANGELOG.md b/CHANGELOG.md
@@ -4,6 +4,13 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
## [Unreleased]
+### Added
+- Added a quick settings to timeline header for easier access
+- Added option to mark posts as sensitive by default
+- Added quick filters for notifications
+
+
+## [2.3.0] - 2021-03-01
### Fixed
- Button to remove uploaded media in post status form is now properly placed and sized.
- Fixed shoutbox not working in mobile layout
@@ -15,14 +22,15 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
### Changed
- Display 'people voted' instead of 'votes' for multi-choice polls
+- Changed the "Timelines" link in side panel to toggle show all timeline options inside the panel
+- Renamed "Timeline" to "Home Timeline" to be more clear
- Optimized chat to not get horrible performance after keeping the same chat open for a long time
- When opening emoji picker or react picker, it automatically focuses the search field
+- Language picker now uses native language names
### Added
- Added reason field for registration when approval is required
-- Added a quick settings to timeline header for easier access
-- Added option to mark posts as sensitive by default
-- Added quick filters for notifications
+
## [2.2.3] - 2021-01-18
### Added
@@ -34,7 +42,6 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
### Changed
- Don't filter own posts when they hit your wordfilter
-- Language picker now uses native language names
## [2.2.2] - 2020-12-22
@@ -44,7 +51,6 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
- Added some missing unicode emoji
- Added the upload limit to the Features panel in the About page
- Support for solid color wallpaper, instance doesn't have to define a wallpaper anymore
-- Group staff members by role in the About page
### Fixed
- Fixed the occasional bug where screen would scroll 1px when typing into a reply form
diff --git a/package.json b/package.json
@@ -34,7 +34,6 @@
"punycode.js": "^2.1.0",
"v-click-outside": "^2.1.1",
"vue": "^2.6.11",
- "vue-chat-scroll": "^1.2.1",
"vue-i18n": "^7.3.2",
"vue-router": "^3.0.1",
"vue-template-compiler": "^2.6.11",
diff --git a/src/components/chat_panel/chat_panel.js b/src/components/chat_panel/chat_panel.js
@@ -35,6 +35,18 @@ const chatPanel = {
userProfileLink (user) {
return generateProfileLink(user.id, user.username, this.$store.state.instance.restrictedNicknames)
}
+ },
+ watch: {
+ messages (newVal) {
+ const scrollEl = this.$el.querySelector('.chat-window')
+ if (!scrollEl) return
+ if (scrollEl.scrollTop + scrollEl.offsetHeight + 20 > scrollEl.scrollHeight) {
+ this.$nextTick(() => {
+ if (!scrollEl) return
+ scrollEl.scrollTop = scrollEl.scrollHeight - scrollEl.offsetHeight
+ })
+ }
+ }
}
}
diff --git a/src/components/chat_panel/chat_panel.vue b/src/components/chat_panel/chat_panel.vue
@@ -10,17 +10,15 @@
@click.stop.prevent="togglePanel"
>
<div class="title">
- <span>{{ $t('shoutbox.title') }}</span>
+ {{ $t('shoutbox.title') }}
<FAIcon
v-if="floating"
icon="times"
+ class="close-icon"
/>
</div>
</div>
- <div
- v-chat-scroll
- class="chat-window"
- >
+ <div class="chat-window">
<div
v-for="message in messages"
:key="message.id"
@@ -94,6 +92,13 @@
.icon {
color: $fallback--text;
color: var(--text, $fallback--text);
+ margin-right: 0.5em;
+ }
+
+ .title {
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
}
}
diff --git a/src/components/nav_panel/nav_panel.js b/src/components/nav_panel/nav_panel.js
@@ -1,4 +1,4 @@
-import { timelineNames } from '../timeline_menu/timeline_menu.js'
+import TimelineMenuContent from '../timeline_menu/timeline_menu_content.vue'
import { mapState, mapGetters } from 'vuex'
import { library } from '@fortawesome/fontawesome-svg-core'
@@ -7,10 +7,12 @@ import {
faGlobe,
faBookmark,
faEnvelope,
- faHome,
+ faChevronDown,
+ faChevronUp,
faComments,
faBell,
- faInfoCircle
+ faInfoCircle,
+ faStream
} from '@fortawesome/free-solid-svg-icons'
library.add(
@@ -18,10 +20,12 @@ library.add(
faGlobe,
faBookmark,
faEnvelope,
- faHome,
+ faChevronDown,
+ faChevronUp,
faComments,
faBell,
- faInfoCircle
+ faInfoCircle,
+ faStream
)
const NavPanel = {
@@ -30,16 +34,20 @@ const NavPanel = {
this.$store.dispatch('startFetchingFollowRequests')
}
},
+ components: {
+ TimelineMenuContent
+ },
+ data () {
+ return {
+ showTimelines: false
+ }
+ },
+ methods: {
+ toggleTimelines () {
+ this.showTimelines = !this.showTimelines
+ }
+ },
computed: {
- onTimelineRoute () {
- return !!timelineNames()[this.$route.name]
- },
- timelinesRoute () {
- if (this.$store.state.interface.lastTimeline) {
- return this.$store.state.interface.lastTimeline
- }
- return this.currentUser ? 'friends' : 'public-timeline'
- },
...mapState({
currentUser: state => state.users.currentUser,
followRequestCount: state => state.api.followRequests.length,
diff --git a/src/components/nav_panel/nav_panel.vue b/src/components/nav_panel/nav_panel.vue
@@ -3,19 +3,33 @@
<div class="panel panel-default">
<ul>
<li v-if="currentUser || !privateMode">
- <router-link
- :to="{ name: timelinesRoute }"
- :class="onTimelineRoute && 'router-link-active'"
+ <button
+ class="button-unstyled menu-item"
+ @click="toggleTimelines"
>
<FAIcon
fixed-width
class="fa-scale-110"
- icon="home"
+ icon="stream"
/>{{ $t("nav.timelines") }}
- </router-link>
+ <FAIcon
+ class="timelines-chevron"
+ fixed-width
+ :icon="showTimelines ? 'chevron-up' : 'chevron-down'"
+ />
+ </button>
+ <div
+ v-show="showTimelines"
+ class="timelines-background"
+ >
+ <TimelineMenuContent class="timelines" />
+ </div>
</li>
<li v-if="currentUser">
- <router-link :to="{ name: 'interactions', params: { username: currentUser.screen_name } }">
+ <router-link
+ class="menu-item"
+ :to="{ name: 'interactions', params: { username: currentUser.screen_name } }"
+ >
<FAIcon
fixed-width
class="fa-scale-110"
@@ -24,7 +38,10 @@
</router-link>
</li>
<li v-if="currentUser && pleromaChatMessagesAvailable">
- <router-link :to="{ name: 'chats', params: { username: currentUser.screen_name } }">
+ <router-link
+ class="menu-item"
+ :to="{ name: 'chats', params: { username: currentUser.screen_name } }"
+ >
<div
v-if="unreadChatCount"
class="badge badge-notification"
@@ -39,7 +56,10 @@
</router-link>
</li>
<li v-if="currentUser && currentUser.locked">
- <router-link :to="{ name: 'friend-requests' }">
+ <router-link
+ class="menu-item"
+ :to="{ name: 'friend-requests' }"
+ >
<FAIcon
fixed-width
class="fa-scale-110"
@@ -54,7 +74,10 @@
</router-link>
</li>
<li>
- <router-link :to="{ name: 'about' }">
+ <router-link
+ class="menu-item"
+ :to="{ name: 'about' }"
+ >
<FAIcon
fixed-width
class="fa-scale-110"
@@ -91,14 +114,14 @@
border-color: var(--border, $fallback--border);
padding: 0;
- &:first-child a {
+ &:first-child .menu-item {
border-top-right-radius: $fallback--panelRadius;
border-top-right-radius: var(--panelRadius, $fallback--panelRadius);
border-top-left-radius: $fallback--panelRadius;
border-top-left-radius: var(--panelRadius, $fallback--panelRadius);
}
- &:last-child a {
+ &:last-child .menu-item {
border-bottom-right-radius: $fallback--panelRadius;
border-bottom-right-radius: var(--panelRadius, $fallback--panelRadius);
border-bottom-left-radius: $fallback--panelRadius;
@@ -110,13 +133,15 @@
border: none;
}
- a {
+ .menu-item {
display: block;
box-sizing: border-box;
- align-items: stretch;
height: 3.5em;
line-height: 3.5em;
padding: 0 1em;
+ width: 100%;
+ color: $fallback--link;
+ color: var(--link, $fallback--link);
&:hover {
background-color: $fallback--lightBg;
@@ -146,6 +171,25 @@
}
}
+ .timelines-chevron {
+ margin-left: 0.8em;
+ font-size: 1.1em;
+ }
+
+ .timelines-background {
+ padding: 0 0 0 0.6em;
+ background-color: $fallback--lightBg;
+ background-color: var(--selectedMenu, $fallback--lightBg);
+ border-top: 1px solid;
+ border-color: $fallback--border;
+ border-color: var(--border, $fallback--border);
+ }
+
+ .timelines {
+ background-color: $fallback--bg;
+ background-color: var(--bg, $fallback--bg);
+ }
+
.fa-scale-110 {
margin-right: 0.8em;
}
diff --git a/src/components/notifications/notification_filters.vue b/src/components/notifications/notification_filters.vue
@@ -64,9 +64,9 @@
/>{{ $t('settings.notification_visibility_moves') }}
</button>
</div>
- <div slot="trigger">
+ <template v-slot:trigger>
<FAIcon icon="filter" />
- </div>
+ </template>
</Popover>
</template>
diff --git a/src/components/popover/popover.js b/src/components/popover/popover.js
@@ -56,6 +56,9 @@ const Popover = {
// Popover will be anchored around this element, trigger ref is the container, so
// its children are what are inside the slot. Expect only one slot="trigger".
const anchorEl = (this.$refs.trigger && this.$refs.trigger.children[0]) || this.$el
+ // SVGs don't have offsetWidth/Height, use fallback
+ const anchorWidth = anchorEl.offsetWidth || anchorEl.clientWidth
+ const anchorHeight = anchorEl.offsetHeight || anchorEl.clientHeight
const screenBox = anchorEl.getBoundingClientRect()
// Screen position of the origin point for popover
const origin = { x: screenBox.left + screenBox.width * 0.5, y: screenBox.top }
@@ -114,11 +117,11 @@ const Popover = {
const yOffset = (this.offset && this.offset.y) || 0
const translateY = usingTop
- ? -anchorEl.offsetHeight + vPadding - yOffset - content.offsetHeight
+ ? -anchorHeight + vPadding - yOffset - content.offsetHeight
: yOffset
const xOffset = (this.offset && this.offset.x) || 0
- const translateX = (anchorEl.offsetWidth * 0.5) - content.offsetWidth * 0.5 + horizOffset + xOffset
+ const translateX = anchorWidth * 0.5 - content.offsetWidth * 0.5 + horizOffset + xOffset
// Note, separate translateX and translateY avoids blurry text on chromium,
// single translate or translate3d resulted in blurry text.
diff --git a/src/components/timeline_menu/timeline_menu.js b/src/components/timeline_menu/timeline_menu.js
@@ -1,29 +1,17 @@
import Popover from '../popover/popover.vue'
-import { mapState } from 'vuex'
+import TimelineMenuContent from './timeline_menu_content.vue'
import { library } from '@fortawesome/fontawesome-svg-core'
import {
- faUsers,
- faGlobe,
- faBookmark,
- faEnvelope,
- faHome,
faChevronDown
} from '@fortawesome/free-solid-svg-icons'
-library.add(
- faUsers,
- faGlobe,
- faBookmark,
- faEnvelope,
- faHome,
- faChevronDown
-)
+library.add(faChevronDown)
// Route -> i18n key mapping, exported and not in the computed
// because nav panel benefits from the same information.
export const timelineNames = () => {
return {
- 'friends': 'nav.timeline',
+ 'friends': 'nav.home_timeline',
'bookmarks': 'nav.bookmarks',
'dms': 'nav.dms',
'public-timeline': 'nav.public_tl',
@@ -33,7 +21,8 @@ export const timelineNames = () => {
const TimelineMenu = {
components: {
- Popover
+ Popover,
+ TimelineMenuContent
},
data () {
return {
@@ -41,9 +30,6 @@ const TimelineMenu = {
}
},
created () {
- if (this.currentUser && this.currentUser.locked) {
- this.$store.dispatch('startFetchingFollowRequests')
- }
if (timelineNames()[this.$route.name]) {
this.$store.dispatch('setLastTimeline', this.$route.name)
}
@@ -75,13 +61,6 @@ const TimelineMenu = {
const i18nkey = timelineNames()[this.$route.name]
return i18nkey ? this.$t(i18nkey) : route
}
- },
- computed: {
- ...mapState({
- currentUser: state => state.users.currentUser,
- privateMode: state => state.instance.private,
- federating: state => state.instance.federating
- })
}
}
diff --git a/src/components/timeline_menu/timeline_menu.vue b/src/components/timeline_menu/timeline_menu.vue
@@ -13,53 +13,7 @@
slot="content"
class="timeline-menu-popover panel panel-default"
>
- <ul>
- <li v-if="currentUser">
- <router-link :to="{ name: 'friends' }">
- <FAIcon
- fixed-width
- class="fa-scale-110 fa-old-padding "
- icon="home"
- />{{ $t("nav.timeline") }}
- </router-link>
- </li>
- <li v-if="currentUser">
- <router-link :to="{ name: 'bookmarks'}">
- <FAIcon
- fixed-width
- class="fa-scale-110 fa-old-padding "
- icon="bookmark"
- />{{ $t("nav.bookmarks") }}
- </router-link>
- </li>
- <li v-if="currentUser">
- <router-link :to="{ name: 'dms', params: { username: currentUser.screen_name } }">
- <FAIcon
- fixed-width
- class="fa-scale-110 fa-old-padding "
- icon="envelope"
- />{{ $t("nav.dms") }}
- </router-link>
- </li>
- <li v-if="currentUser || !privateMode">
- <router-link :to="{ name: 'public-timeline' }">
- <FAIcon
- fixed-width
- class="fa-scale-110 fa-old-padding "
- icon="users"
- />{{ $t("nav.public_tl") }}
- </router-link>
- </li>
- <li v-if="federating && (currentUser || !privateMode)">
- <router-link :to="{ name: 'public-external-timeline' }">
- <FAIcon
- fixed-width
- class="fa-scale-110 fa-old-padding "
- icon="globe"
- />{{ $t("nav.twkn") }}
- </router-link>
- </li>
- </ul>
+ <TimelineMenuContent />
</div>
<div
slot="trigger"
diff --git a/src/components/timeline_menu/timeline_menu_content.js b/src/components/timeline_menu/timeline_menu_content.js
@@ -0,0 +1,29 @@
+import { mapState } from 'vuex'
+import { library } from '@fortawesome/fontawesome-svg-core'
+import {
+ faUsers,
+ faGlobe,
+ faBookmark,
+ faEnvelope,
+ faHome
+} from '@fortawesome/free-solid-svg-icons'
+
+library.add(
+ faUsers,
+ faGlobe,
+ faBookmark,
+ faEnvelope,
+ faHome
+)
+
+const TimelineMenuContent = {
+ computed: {
+ ...mapState({
+ currentUser: state => state.users.currentUser,
+ privateMode: state => state.instance.private,
+ federating: state => state.instance.federating
+ })
+ }
+}
+
+export default TimelineMenuContent
diff --git a/src/components/timeline_menu/timeline_menu_content.vue b/src/components/timeline_menu/timeline_menu_content.vue
@@ -0,0 +1,66 @@
+<template>
+ <ul>
+ <li v-if="currentUser">
+ <router-link
+ class="menu-item"
+ :to="{ name: 'friends' }"
+ >
+ <FAIcon
+ fixed-width
+ class="fa-scale-110 fa-old-padding "
+ icon="home"
+ />{{ $t("nav.home_timeline") }}
+ </router-link>
+ </li>
+ <li v-if="currentUser || !privateMode">
+ <router-link
+ class="menu-item"
+ :to="{ name: 'public-timeline' }"
+ >
+ <FAIcon
+ fixed-width
+ class="fa-scale-110 fa-old-padding "
+ icon="users"
+ />{{ $t("nav.public_tl") }}
+ </router-link>
+ </li>
+ <li v-if="federating && (currentUser || !privateMode)">
+ <router-link
+ class="menu-item"
+ :to="{ name: 'public-external-timeline' }"
+ >
+ <FAIcon
+ fixed-width
+ class="fa-scale-110 fa-old-padding "
+ icon="globe"
+ />{{ $t("nav.twkn") }}
+ </router-link>
+ </li>
+ <li v-if="currentUser">
+ <router-link
+ class="menu-item"
+ :to="{ name: 'bookmarks'}"
+ >
+ <FAIcon
+ fixed-width
+ class="fa-scale-110 fa-old-padding "
+ icon="bookmark"
+ />{{ $t("nav.bookmarks") }}
+ </router-link>
+ </li>
+ <li v-if="currentUser">
+ <router-link
+ class="menu-item"
+ :to="{ name: 'dms', params: { username: currentUser.screen_name } }"
+ >
+ <FAIcon
+ fixed-width
+ class="fa-scale-110 fa-old-padding "
+ icon="envelope"
+ />{{ $t("nav.dms") }}
+ </router-link>
+ </li>
+ </ul>
+</template>
+
+<script src="./timeline_menu_content.js" ></script>
diff --git a/src/components/user_card/user_card.vue b/src/components/user_card/user_card.vue
@@ -141,10 +141,10 @@
v-model="userHighlightType"
class="userHighlightSel"
>
- <option value="disabled">No highlight</option>
- <option value="solid">Solid bg</option>
- <option value="striped">Striped bg</option>
- <option value="side">Side stripe</option>
+ <option value="disabled">{{ $t('user_card.highlight.disabled') }}</option>
+ <option value="solid">{{ $t('user_card.highlight.solid') }}</option>
+ <option value="striped">{{ $t('user_card.highlight.striped') }}</option>
+ <option value="side">{{ $t('user_card.highlight.side') }}</option>
</select>
<FAIcon
class="select-down-icon"
diff --git a/src/i18n/en.json b/src/i18n/en.json
@@ -124,6 +124,7 @@
"dms": "Direct Messages",
"public_tl": "Public Timeline",
"timeline": "Timeline",
+ "home_timeline": "Home Timeline",
"twkn": "Known Network",
"bookmarks": "Bookmarks",
"user_search": "User Search",
@@ -746,6 +747,12 @@
"quarantine": "Disallow user posts from federating",
"delete_user": "Delete user",
"delete_user_confirmation": "Are you absolutely sure? This action cannot be undone."
+ },
+ "highlight": {
+ "disabled": "No highlight",
+ "solid": "Solid bg",
+ "striped": "Striped bg",
+ "side": "Side stripe"
}
},
"user_profile": {
diff --git a/src/main.js b/src/main.js
@@ -28,7 +28,6 @@ import pushNotifications from './lib/push_notifications_plugin.js'
import messages from './i18n/messages.js'
-import VueChatScroll from 'vue-chat-scroll'
import VueClickOutside from 'v-click-outside'
import PortalVue from 'portal-vue'
import VBodyScrollLock from './directives/body_scroll_lock'
@@ -42,7 +41,6 @@ const currentLocale = (window.navigator.language || 'en').split('-')[0]
Vue.use(Vuex)
Vue.use(VueRouter)
Vue.use(VueI18n)
-Vue.use(VueChatScroll)
Vue.use(VueClickOutside)
Vue.use(PortalVue)
Vue.use(VBodyScrollLock)
diff --git a/src/modules/chat.js b/src/modules/chat.js
@@ -18,6 +18,7 @@ const chat = {
actions: {
initializeChat (store, socket) {
const channel = socket.channel('chat:public')
+
channel.on('new_msg', (msg) => {
store.commit('addMessage', msg)
})
diff --git a/yarn.lock b/yarn.lock
@@ -8923,10 +8923,6 @@ void-elements@^2.0.0:
version "2.0.1"
resolved "https://registry.yarnpkg.com/void-elements/-/void-elements-2.0.1.tgz#c066afb582bb1cb4128d60ea92392e94d5e9dbec"
-vue-chat-scroll@^1.2.1:
- version "1.3.5"
- resolved "https://registry.yarnpkg.com/vue-chat-scroll/-/vue-chat-scroll-1.3.5.tgz#a5ee5bae5058f614818a96eac5ee3be4394a2f68"
-
vue-eslint-parser@^5.0.0:
version "5.0.0"
resolved "https://registry.yarnpkg.com/vue-eslint-parser/-/vue-eslint-parser-5.0.0.tgz#00f4e4da94ec974b821a26ff0ed0f7a78402b8a1"