Merge remote-tracking branch 'upstream/develop' into neckbeard

This commit is contained in:
Your New SJW Waifu 2021-03-04 07:53:35 -06:00
commit 411ae0d9dc
16 changed files with 264 additions and 52 deletions

View File

@ -4,6 +4,11 @@ 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
## [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
@ -17,10 +22,11 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
- Display 'people voted' instead of 'votes' for multi-choice polls
- 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 option to mark posts as sensitive by default
- Group staff members by role in the About page
## [2.2.3] - 2021-01-18
### Added
@ -32,7 +38,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
@ -42,7 +47,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

View File

@ -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",

View File

@ -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
})
}
}
}
}

View File

@ -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;
}
}

View File

@ -50,74 +50,74 @@
class="button-default dropdown-item"
@click="toggleTag(tags.FORCE_NSFW)"
>
{{ $t('user_card.admin_menu.force_nsfw') }}
<span
class="menu-checkbox"
:class="{ 'menu-checkbox-checked': hasTag(tags.FORCE_NSFW) }"
/>
{{ $t('user_card.admin_menu.force_nsfw') }}
</button>
<button
class="button-default dropdown-item"
@click="toggleTag(tags.STRIP_MEDIA)"
>
{{ $t('user_card.admin_menu.strip_media') }}
<span
class="menu-checkbox"
:class="{ 'menu-checkbox-checked': hasTag(tags.STRIP_MEDIA) }"
/>
{{ $t('user_card.admin_menu.strip_media') }}
</button>
<button
class="button-default dropdown-item"
@click="toggleTag(tags.FORCE_UNLISTED)"
>
{{ $t('user_card.admin_menu.force_unlisted') }}
<span
class="menu-checkbox"
:class="{ 'menu-checkbox-checked': hasTag(tags.FORCE_UNLISTED) }"
/>
{{ $t('user_card.admin_menu.force_unlisted') }}
</button>
<button
class="button-default dropdown-item"
@click="toggleTag(tags.SANDBOX)"
>
{{ $t('user_card.admin_menu.sandbox') }}
<span
class="menu-checkbox"
:class="{ 'menu-checkbox-checked': hasTag(tags.SANDBOX) }"
/>
{{ $t('user_card.admin_menu.sandbox') }}
</button>
<button
v-if="user.is_local"
class="button-default dropdown-item"
@click="toggleTag(tags.DISABLE_REMOTE_SUBSCRIPTION)"
>
{{ $t('user_card.admin_menu.disable_remote_subscription') }}
<span
class="menu-checkbox"
:class="{ 'menu-checkbox-checked': hasTag(tags.DISABLE_REMOTE_SUBSCRIPTION) }"
/>
{{ $t('user_card.admin_menu.disable_remote_subscription') }}
</button>
<button
v-if="user.is_local"
class="button-default dropdown-item"
@click="toggleTag(tags.DISABLE_ANY_SUBSCRIPTION)"
>
{{ $t('user_card.admin_menu.disable_any_subscription') }}
<span
class="menu-checkbox"
:class="{ 'menu-checkbox-checked': hasTag(tags.DISABLE_ANY_SUBSCRIPTION) }"
/>
{{ $t('user_card.admin_menu.disable_any_subscription') }}
</button>
<button
v-if="user.is_local"
class="button-default dropdown-item"
@click="toggleTag(tags.QUARANTINE)"
>
{{ $t('user_card.admin_menu.quarantine') }}
<span
class="menu-checkbox"
:class="{ 'menu-checkbox-checked': hasTag(tags.QUARANTINE) }"
/>
{{ $t('user_card.admin_menu.quarantine') }}
</button>
</span>
</div>
@ -163,25 +163,6 @@
<style lang="scss">
@import '../../_variables.scss';
.menu-checkbox {
float: right;
min-width: 22px;
max-width: 22px;
min-height: 22px;
max-height: 22px;
line-height: 22px;
text-align: center;
border-radius: 0px;
background-color: $fallback--fg;
background-color: var(--input, $fallback--fg);
box-shadow: 0px 0px 2px black inset;
box-shadow: var(--inputShadow);
&.menu-checkbox-checked::after {
content: '✓';
}
}
.moderation-tools-popover {
height: 100%;
.trigger {

View File

@ -3,25 +3,32 @@ const Popover = {
props: {
// Action to trigger popover: either 'hover' or 'click'
trigger: String,
// Either 'top' or 'bottom'
placement: String,
// Takes object with properties 'x' and 'y', values of these can be
// 'container' for using offsetParent as boundaries for either axis
// or 'viewport'
boundTo: Object,
// Takes a selector to use as a replacement for the parent container
// for getting boundaries for x an y axis
boundToSelector: String,
// Takes a top/bottom/left/right object, how much space to leave
// between boundary and popover element
margin: Object,
// Takes a x/y object and tells how many pixels to offset from
// anchor point on either axis
offset: Object,
// Replaces the classes you may want for the popover container.
// Use 'popover-default' in addition to get the default popover
// styles with your custom class.
popoverClass: String,
// If true, subtract padding when calculating position for the popover,
// use it when popover offset looks to be different on top vs bottom.
removePadding: Boolean

View File

@ -82,10 +82,9 @@
.dropdown-item {
line-height: 21px;
margin-right: 5px;
overflow: auto;
display: block;
padding: .25rem 1.0rem .25rem 1.5rem;
padding: .5em 0.75em;
clear: both;
font-weight: 400;
text-align: inherit;
@ -101,10 +100,9 @@
--btnText: var(--popoverText, $fallback--text);
&-icon {
padding-left: 0.5rem;
svg {
margin-right: 0.25rem;
width: 22px;
margin-right: 0.75rem;
color: var(--menuPopoverIcon, $fallback--icon)
}
}
@ -123,6 +121,33 @@
}
}
.menu-checkbox {
display: inline-block;
vertical-align: middle;
min-width: 22px;
max-width: 22px;
min-height: 22px;
max-height: 22px;
line-height: 22px;
text-align: center;
border-radius: 0px;
background-color: $fallback--fg;
background-color: var(--input, $fallback--fg);
box-shadow: 0px 0px 2px black inset;
box-shadow: var(--inputShadow);
margin-right: 0.75em;
&.menu-checkbox-checked::after {
font-size: 1.25em;
content: '✓';
}
&.menu-checkbox-radio::after {
font-size: 2em;
content: '•';
}
}
}
}
</style>

View File

@ -2,12 +2,14 @@ import Status from '../status/status.vue'
import timelineFetcher from '../../services/timeline_fetcher/timeline_fetcher.service.js'
import Conversation from '../conversation/conversation.vue'
import TimelineMenu from '../timeline_menu/timeline_menu.vue'
import TimelineQuickSettings from './timeline_quick_settings.vue'
import { debounce, throttle, keyBy } from 'lodash'
import { library } from '@fortawesome/fontawesome-svg-core'
import { faCircleNotch } from '@fortawesome/free-solid-svg-icons'
import { faCircleNotch, faCog } from '@fortawesome/free-solid-svg-icons'
library.add(
faCircleNotch
faCircleNotch,
faCog
)
export const getExcludedStatusIdsByPinning = (statuses, pinnedStatusIds) => {
@ -47,7 +49,8 @@ const Timeline = {
components: {
Status,
Conversation,
TimelineMenu
TimelineMenu,
TimelineQuickSettings
},
computed: {
newStatusCount () {

View File

@ -16,6 +16,7 @@
>
{{ $t('timeline.up_to_date') }}
</div>
<TimelineQuickSettings v-if="!embedded" />
</div>
<div :class="classes.body">
<div
@ -103,9 +104,12 @@
max-width: 100%;
flex-wrap: nowrap;
align-items: center;
position: relative;
.loadmore-button {
flex-shrink: 0;
}
.loadmore-text {
flex-shrink: 0;
line-height: 1em;

View File

@ -0,0 +1,63 @@
import Popover from '../popover/popover.vue'
import BooleanSetting from '../settings_modal/helpers/boolean_setting.vue'
import { mapGetters } from 'vuex'
import { library } from '@fortawesome/fontawesome-svg-core'
import { faFilter, faFont, faWrench } from '@fortawesome/free-solid-svg-icons'
library.add(
faFilter,
faFont,
faWrench
)
const TimelineQuickSettings = {
components: {
Popover,
BooleanSetting
},
methods: {
setReplyVisibility (visibility) {
this.$store.dispatch('setOption', { name: 'replyVisibility', value: visibility })
this.$store.dispatch('queueFlushAll')
},
openTab (tab) {
this.$store.dispatch('openSettingsModalTab', tab)
}
},
computed: {
...mapGetters(['mergedConfig']),
loggedIn () {
return !!this.$store.state.users.currentUser
},
replyVisibilitySelf: {
get () { return this.mergedConfig.replyVisibility === 'self' },
set () { this.setReplyVisibility('self') }
},
replyVisibilityFollowing: {
get () { return this.mergedConfig.replyVisibility === 'following' },
set () { this.setReplyVisibility('following') }
},
replyVisibilityAll: {
get () { return this.mergedConfig.replyVisibility === 'all' },
set () { this.setReplyVisibility('all') }
},
hideMedia: {
get () { return this.mergedConfig.hideAttachments || this.mergedConfig.hideAttachmentsInConv },
set () {
const value = !this.hideMedia
this.$store.dispatch('setOption', { name: 'hideAttachments', value })
this.$store.dispatch('setOption', { name: 'hideAttachmentsInConv', value })
}
},
hideMutedPosts: {
get () { return this.mergedConfig.hideMutedPosts || this.mergedConfig.hideFilteredStatuses },
set () {
const value = !this.hideMutedPosts
this.$store.dispatch('setOption', { name: 'hideMutedPosts', value })
this.$store.dispatch('setOption', { name: 'hideFilteredStatuses', value })
}
}
}
}
export default TimelineQuickSettings

View File

@ -0,0 +1,107 @@
<template>
<Popover
trigger="click"
class="TimelineQuickSettings"
:bound-to="{ x: 'container' }"
>
<div
slot="content"
class="timeline-settings-menu dropdown-menu"
>
<div v-if="loggedIn">
<button
class="button-default dropdown-item"
@click="replyVisibilityAll = true"
>
<span
class="menu-checkbox"
:class="{ 'menu-checkbox-radio': replyVisibilityAll }"
/>{{ $t('settings.reply_visibility_all') }}
</button>
<button
class="button-default dropdown-item"
@click="replyVisibilityFollowing = true"
>
<span
class="menu-checkbox"
:class="{ 'menu-checkbox-radio': replyVisibilityFollowing }"
/>{{ $t('settings.reply_visibility_following_short') }}
</button>
<button
class="button-default dropdown-item"
@click="replyVisibilitySelf = true"
>
<span
class="menu-checkbox"
:class="{ 'menu-checkbox-radio': replyVisibilitySelf }"
/>{{ $t('settings.reply_visibility_self_short') }}
</button>
<div
role="separator"
class="dropdown-divider"
/>
</div>
<button
class="button-default dropdown-item"
@click="hideMedia = !hideMedia"
>
<span
class="menu-checkbox"
:class="{ 'menu-checkbox-checked': hideMedia }"
/>{{ $t('settings.hide_media_previews') }}
</button>
<button
class="button-default dropdown-item"
@click="hideMutedPosts = !hideMutedPosts"
>
<span
class="menu-checkbox"
:class="{ 'menu-checkbox-checked': hideMutedPosts }"
/>{{ $t('settings.hide_all_muted_posts') }}
</button>
<button
class="button-default dropdown-item dropdown-item-icon"
@click="openTab('filtering')"
>
<FAIcon icon="font" />{{ $t('settings.word_filter') }}
</button>
<button
class="button-default dropdown-item dropdown-item-icon"
@click="openTab('general')"
>
<FAIcon icon="wrench" />{{ $t('settings.more_settings') }}
</button>
</div>
<div slot="trigger">
<FAIcon icon="filter" />
</div>
</Popover>
</template>
<script src="./timeline_quick_settings.js"></script>
<style lang="scss">
.TimelineQuickSettings {
align-self: stretch;
> button {
font-size: 1.2em;
padding-left: 0.7em;
padding-right: 0.2em;
line-height: 100%;
height: 100%;
}
.dropdown-item {
margin: 0;
}
.timeline-settings-menu {
display: flex;
min-width: 12em;
flex-direction: column;
}
}
</style>

View File

@ -325,6 +325,7 @@
"export_theme": "Save preset",
"filtering": "Filtering",
"filtering_explanation": "All statuses containing these words will be muted, one per line",
"word_filter": "Word filter",
"follow_export": "Follow export",
"follow_export_button": "Export your follows to a csv file",
"follow_import": "Follow import",
@ -335,7 +336,9 @@
"general": "General",
"hide_attachments_in_convo": "Hide attachments in conversations",
"hide_attachments_in_tl": "Hide attachments in timeline",
"hide_media_previews": "Hide media previews",
"hide_muted_posts": "Hide posts of muted users",
"hide_all_muted_posts": "Hide muted posts",
"max_thumbnails": "Maximum amount of thumbnails per post",
"hide_isp": "Hide instance-specific panel",
"hide_wallpaper": "Hide instance wallpaper",
@ -405,6 +408,8 @@
"reply_visibility_all": "Show all replies",
"reply_visibility_following": "Only show replies directed at me or users I'm following",
"reply_visibility_self": "Only show replies directed at me",
"reply_visibility_following_short": "Show replies to my follows",
"reply_visibility_self_short": "Show replies to self only",
"autohide_floating_post_button": "Automatically hide New Post button (mobile)",
"saving_err": "Error saving settings",
"saving_ok": "Settings saved",
@ -459,6 +464,7 @@
"notification_mutes": "To stop receiving notifications from a specific user, use a mute.",
"notification_blocks": "Blocking a user stops all notifications as well as unsubscribes them.",
"enable_web_push_notifications": "Enable web push notifications",
"more_settings": "More settings",
"style": {
"switcher": {
"keep_color": "Keep colors",

View File

@ -413,8 +413,8 @@
"contrast": {
"hint": "コントラストは {ratio} です。{level}。({context})",
"level": {
"aa": "AAレベルガイドライン (ミニマル) を満たします",
"aaa": "AAAレベルガイドライン (レコメンデッド) を満たします",
"aa": "AAレベルガイドライン (最低限) を満たします",
"aaa": "AAAレベルガイドライン (推奨) を満たします",
"bad": "ガイドラインを満たしません"
},
"context": {
@ -573,7 +573,8 @@
"mute_export": "ミュートのエクスポート",
"allow_following_move": "フォロー中のアカウントが引っ越したとき、自動フォローを許可する",
"setting_changed": "規定の設定と異なっています",
"greentext": "引用を緑色で表示"
"greentext": "引用を緑色で表示",
"sensitive_by_default": "はじめから投稿をセンシティブとして設定"
},
"time": {
"day": "{0}日",

View File

@ -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)

View File

@ -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)
})

View File

@ -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"