merge-requests/1699/head
Henry Jameson 2 years ago
parent 0cbfcb99a9
commit fddb531ed2

@ -16,7 +16,11 @@
:class="classes" :class="classes"
> >
<div class="underlay" /> <div class="underlay" />
<div id="sidebar" class="column -scrollable" :class="{ '-show-scrollbar': showScrollbars }"> <div
id="sidebar"
class="column -scrollable"
:class="{ '-show-scrollbar': showScrollbars }"
>
<user-panel /> <user-panel />
<template v-if="layoutType !== 'mobile'"> <template v-if="layoutType !== 'mobile'">
<nav-panel /> <nav-panel />
@ -26,7 +30,11 @@
<div id="notifs-sidebar" /> <div id="notifs-sidebar" />
</template> </template>
</div> </div>
<div id="main-scroller" class="column main" :class="{ '-full-height': isChats }"> <div
id="main-scroller"
class="column main"
:class="{ '-full-height': isChats }"
>
<div <div
v-if="!currentUser" v-if="!currentUser"
class="login-hint panel panel-default" class="login-hint panel panel-default"
@ -40,7 +48,11 @@
</div> </div>
<router-view /> <router-view />
</div> </div>
<div id="notifs-column" class="column -scrollable" :class="{ '-show-scrollbar': showScrollbars }"/> <div
id="notifs-column"
class="column -scrollable"
:class="{ '-show-scrollbar': showScrollbars }"
/>
</div> </div>
<MediaModal /> <MediaModal />
<shout-panel <shout-panel

@ -156,7 +156,7 @@ const setSettings = async ({ apiConfig, staticConfig, store }) => {
copyInstanceOption('hideSitename') copyInstanceOption('hideSitename')
copyInstanceOption('sidebarRight') copyInstanceOption('sidebarRight')
return store.dispatch('setTheme', config['theme']) return store.dispatch('setTheme', config.theme)
} }
const getTOS = async ({ store }) => { const getTOS = async ({ store }) => {
@ -197,7 +197,7 @@ const getStickers = async ({ store }) => {
const stickers = (await Promise.all( const stickers = (await Promise.all(
Object.entries(values).map(async ([name, path]) => { Object.entries(values).map(async ([name, path]) => {
const resPack = await window.fetch(path + 'pack.json') const resPack = await window.fetch(path + 'pack.json')
var meta = {} let meta = {}
if (resPack.ok) { if (resPack.ok) {
meta = await resPack.json() meta = await resPack.json()
} }

@ -31,7 +31,8 @@ export default (store) => {
} }
let routes = [ let routes = [
{ name: 'root', {
name: 'root',
path: '/', path: '/',
redirect: _to => { redirect: _to => {
return (store.state.users.currentUser return (store.state.users.currentUser
@ -45,12 +46,14 @@ export default (store) => {
{ name: 'tag-timeline', path: '/tag/:tag', component: TagTimeline }, { name: 'tag-timeline', path: '/tag/:tag', component: TagTimeline },
{ name: 'bookmarks', path: '/bookmarks', component: BookmarkTimeline }, { name: 'bookmarks', path: '/bookmarks', component: BookmarkTimeline },
{ name: 'conversation', path: '/notice/:id', component: ConversationPage, meta: { dontScroll: true } }, { name: 'conversation', path: '/notice/:id', component: ConversationPage, meta: { dontScroll: true } },
{ name: 'remote-user-profile-acct', {
name: 'remote-user-profile-acct',
path: '/remote-users/:_(@)?:username([^/@]+)@:hostname([^/@]+)', path: '/remote-users/:_(@)?:username([^/@]+)@:hostname([^/@]+)',
component: RemoteUserResolver, component: RemoteUserResolver,
beforeEnter: validateAuthenticatedRoute beforeEnter: validateAuthenticatedRoute
}, },
{ name: 'remote-user-profile', {
name: 'remote-user-profile',
path: '/remote-users/:hostname/:username', path: '/remote-users/:hostname/:username',
component: RemoteUserResolver, component: RemoteUserResolver,
beforeEnter: validateAuthenticatedRoute beforeEnter: validateAuthenticatedRoute

@ -6,7 +6,7 @@
:bound-to="{ x: 'container' }" :bound-to="{ x: 'container' }"
remove-padding remove-padding
> >
<template v-slot:content> <template #content>
<div class="dropdown-menu"> <div class="dropdown-menu">
<template v-if="relationship.following"> <template v-if="relationship.following">
<button <button
@ -57,7 +57,7 @@
</button> </button>
</div> </div>
</template> </template>
<template v-slot:trigger> <template #trigger>
<button class="button-unstyled ellipsis-button"> <button class="button-unstyled ellipsis-button">
<FAIcon <FAIcon
class="icon" class="icon"

@ -1,10 +1,13 @@
<template> <template>
<div class="basic-user-card"> <div class="basic-user-card">
<router-link @click.prevent :to="userProfileLink(user)"> <router-link
:to="userProfileLink(user)"
@click.prevent
>
<UserPopover <UserPopover
:userId="user.id" :user-id="user.id"
:overlayCenters="true" :overlay-centers="true"
overlayCentersSelector=".avatar" overlay-centers-selector=".avatar"
> >
<UserAvatar <UserAvatar
class="user-avatar avatar" class="user-avatar avatar"

@ -107,7 +107,7 @@ const Chat = {
} }
}) })
}, },
'$route': function () { $route: function () {
this.startFetching() this.startFetching()
}, },
mastoUserSocketStatus (newValue) { mastoUserSocketStatus (newValue) {

@ -23,7 +23,7 @@
class="timeline" class="timeline"
> >
<List :items="sortedChatList"> <List :items="sortedChatList">
<template v-slot:item="{item}"> <template #item="{item}">
<ChatListItem <ChatListItem
:key="item.id" :key="item.id"
:compact="false" :compact="false"

@ -16,7 +16,7 @@
> >
<UserPopover <UserPopover
v-if="chatViewItem.isHead" v-if="chatViewItem.isHead"
:userId="author.id" :user-id="author.id"
> >
<UserAvatar <UserAvatar
:compact="true" :compact="true"
@ -50,7 +50,7 @@
@show="menuOpened = true" @show="menuOpened = true"
@close="menuOpened = false" @close="menuOpened = false"
> >
<template v-slot:content> <template #content>
<div class="dropdown-menu"> <div class="dropdown-menu">
<button <button
class="button-default dropdown-item dropdown-item-icon" class="button-default dropdown-item dropdown-item-icon"
@ -60,7 +60,7 @@
</button> </button>
</div> </div>
</template> </template>
<template v-slot:trigger> <template #trigger>
<button <button
class="button-default menu-icon" class="button-default menu-icon"
:title="$t('chats.more')" :title="$t('chats.more')"
@ -75,7 +75,7 @@
:status="messageForStatusContent" :status="messageForStatusContent"
:full-content="true" :full-content="true"
> >
<template v-slot:footer> <template #footer>
<span <span
class="created-at" class="created-at"
> >

@ -4,9 +4,9 @@
:title="title" :title="title"
> >
<UserPopover <UserPopover
class="avatar-container"
v-if="withAvatar && user" v-if="withAvatar && user"
:userId="user.id" class="avatar-container"
:user-id="user.id"
> >
<UserAvatar <UserAvatar
class="titlebar-avatar" class="titlebar-avatar"

@ -22,12 +22,12 @@
<script> <script>
export default { export default {
emits: ['update:modelValue'],
props: [ props: [
'modelValue', 'modelValue',
'indeterminate', 'indeterminate',
'disabled' 'disabled'
] ],
emits: ['update:modelValue']
} }
</script> </script>

@ -46,7 +46,6 @@
</div> </div>
</div> </div>
</template> </template>
<style lang="scss" src="./color_input.scss"></style>
<script> <script>
import Checkbox from '../checkbox/checkbox.vue' import Checkbox from '../checkbox/checkbox.vue'
import { hex2rgb } from '../../services/color_convert/color_convert.js' import { hex2rgb } from '../../services/color_convert/color_convert.js'
@ -108,6 +107,7 @@ export default {
} }
} }
</script> </script>
<style lang="scss" src="./color_input.scss"></style>
<style lang="scss"> <style lang="scss">
.color-control { .color-control {

@ -271,7 +271,7 @@ const conversation = {
result[irid] = result[irid] || [] result[irid] = result[irid] || []
result[irid].push({ result[irid].push({
name: `#${i}`, name: `#${i}`,
id: id id
}) })
} }
i++ i++

@ -31,8 +31,8 @@
keypath="status.show_all_conversation_with_icon" keypath="status.show_all_conversation_with_icon"
tag="button" tag="button"
class="button-unstyled -link" class="button-unstyled -link"
@click.prevent="diveToTopLevel"
scope="global" scope="global"
@click.prevent="diveToTopLevel"
> >
<template #icon> <template #icon>
<FAIcon <FAIcon

@ -46,21 +46,25 @@ export default {
enableMask () { return this.supportsMask && this.$store.state.instance.logoMask }, enableMask () { return this.supportsMask && this.$store.state.instance.logoMask },
logoStyle () { logoStyle () {
return { return {
'visibility': this.enableMask ? 'hidden' : 'visible' visibility: this.enableMask ? 'hidden' : 'visible'
} }
}, },
logoMaskStyle () { logoMaskStyle () {
return this.enableMask ? { return this.enableMask
? {
'mask-image': `url(${this.$store.state.instance.logo})` 'mask-image': `url(${this.$store.state.instance.logo})`
} : { }
: {
'background-color': this.enableMask ? '' : 'transparent' 'background-color': this.enableMask ? '' : 'transparent'
} }
}, },
logoBgStyle () { logoBgStyle () {
return Object.assign({ return Object.assign({
'margin': `${this.$store.state.instance.logoMargin} 0`, margin: `${this.$store.state.instance.logoMargin} 0`,
opacity: this.searchBarHidden ? 1 : 0 opacity: this.searchBarHidden ? 1 : 0
}, this.enableMask ? {} : { }, this.enableMask
? {}
: {
'background-color': this.enableMask ? '' : 'transparent' 'background-color': this.enableMask ? '' : 'transparent'
}) })
}, },

@ -9,7 +9,7 @@
class="btn button-default" class="btn button-default"
> >
{{ $t('domain_mute_card.unmute') }} {{ $t('domain_mute_card.unmute') }}
<template v-slot:progress> <template #progress>
{{ $t('domain_mute_card.unmute_progress') }} {{ $t('domain_mute_card.unmute_progress') }}
</template> </template>
</ProgressButton> </ProgressButton>
@ -19,7 +19,7 @@
class="btn button-default" class="btn button-default"
> >
{{ $t('domain_mute_card.mute') }} {{ $t('domain_mute_card.mute') }}
<template v-slot:progress> <template #progress>
{{ $t('domain_mute_card.mute_progress') }} {{ $t('domain_mute_card.mute_progress') }}
</template> </template>
</ProgressButton> </ProgressButton>

@ -321,7 +321,7 @@ const EmojiInput = {
} }
}, },
scrollIntoView () { scrollIntoView () {
const rootRef = this.$refs['picker'].$el const rootRef = this.$refs.picker.$el
/* Scroller is either `window` (replies in TL), sidebar (main post form, /* Scroller is either `window` (replies in TL), sidebar (main post form,
* replies in notifs) or mobile post form. Note that getting and setting * replies in notifs) or mobile post form. Note that getting and setting
* scroll is different for `Window` and `Element`s * scroll is different for `Window` and `Element`s

@ -25,7 +25,7 @@ const filterByKeyword = (list, keyword = '') => {
if (keyword === '') return list if (keyword === '') return list
const keywordLowercase = keyword.toLowerCase() const keywordLowercase = keyword.toLowerCase()
let orderedEmojiList = [] const orderedEmojiList = []
for (const emoji of list) { for (const emoji of list) {
const indexOfKeyword = emoji.displayText.toLowerCase().indexOf(keywordLowercase) const indexOfKeyword = emoji.displayText.toLowerCase().indexOf(keywordLowercase)
if (indexOfKeyword > -1) { if (indexOfKeyword > -1) {

@ -7,7 +7,7 @@
:bound-to="{ x: 'container' }" :bound-to="{ x: 'container' }"
remove-padding remove-padding
> >
<template v-slot:content="{close}"> <template #content="{close}">
<div class="dropdown-menu"> <div class="dropdown-menu">
<button <button
v-if="canMute && !status.thread_muted" v-if="canMute && !status.thread_muted"
@ -120,7 +120,7 @@
</button> </button>
</div> </div>
</template> </template>
<template v-slot:trigger> <template #trigger>
<span class="button-unstyled popover-trigger"> <span class="button-unstyled popover-trigger">
<FAIcon <FAIcon
class="fa-scale-110 fa-old-padding" class="fa-scale-110 fa-old-padding"

@ -95,7 +95,7 @@ const ImageCropper = {
const fileInput = this.$refs.input const fileInput = this.$refs.input
if (fileInput.files != null && fileInput.files[0] != null) { if (fileInput.files != null && fileInput.files[0] != null) {
this.file = fileInput.files[0] this.file = fileInput.files[0]
let reader = new window.FileReader() const reader = new window.FileReader()
reader.onload = (e) => { reader.onload = (e) => {
this.dataUrl = e.target.result this.dataUrl = e.target.result
this.$emit('open') this.$emit('open')

@ -12,7 +12,7 @@ const Interactions = {
data () { data () {
return { return {
allowFollowingMove: this.$store.state.users.currentUser.allow_following_move, allowFollowingMove: this.$store.state.users.currentUser.allow_following_move,
filterMode: tabModeDict['mentions'] filterMode: tabModeDict.mentions
} }
}, },
methods: { methods: {

@ -25,6 +25,7 @@ import Select from '../select/select.vue'
export default { export default {
components: { components: {
// eslint-disable-next-line vue/no-reserved-component-names
Select Select
}, },
props: { props: {

@ -83,7 +83,7 @@ const LoginForm = {
}, },
clearError () { this.error = false }, clearError () { this.error = false },
focusOnPasswordInput () { focusOnPasswordInput () {
let passwordInput = this.$refs.passwordInput const passwordInput = this.$refs.passwordInput
passwordInput.focus() passwordInput.focus()
passwordInput.setSelectionRange(0, passwordInput.value.length) passwordInput.setSelectionRange(0, passwordInput.value.length)
} }

@ -42,7 +42,8 @@ const mediaUpload = {
.then((fileData) => { .then((fileData) => {
self.$emit('uploaded', fileData) self.$emit('uploaded', fileData)
self.decreaseUploadCount() self.decreaseUploadCount()
}, (error) => { // eslint-disable-line handle-callback-err }, (error) => {
console.error('Error uploading file', error)
self.$emit('upload-failed', 'default') self.$emit('upload-failed', 'default')
self.decreaseUploadCount() self.decreaseUploadCount()
}) })
@ -73,7 +74,7 @@ const mediaUpload = {
'disabled' 'disabled'
], ],
watch: { watch: {
'dropFiles': function (fileInfos) { dropFiles: function (fileInfos) {
if (!this.uploading) { if (!this.uploading) {
this.multiUpload(fileInfos) this.multiUpload(fileInfos)
} }

@ -12,7 +12,7 @@
/><!-- eslint-enable vue/no-v-html --> /><!-- eslint-enable vue/no-v-html -->
<UserPopover <UserPopover
v-else v-else
:userId="user.id" :user-id="user.id"
:disabled="!shouldShowTooltip" :disabled="!shouldShowTooltip"
> >
<span <span
@ -54,7 +54,10 @@
:class="{ '-you': shouldBoldenYou }" :class="{ '-you': shouldBoldenYou }"
> {{ ' ' + $t('status.you') }}</span> > {{ ' ' + $t('status.you') }}</span>
<!-- eslint-enable vue/no-v-html --> <!-- eslint-enable vue/no-v-html -->
</a><span class="full" ref="full"> </a><span
ref="full"
class="full"
>
<!-- eslint-disable vue/no-v-html --> <!-- eslint-disable vue/no-v-html -->
@<span v-html="userName" /><span v-html="'@' + serverName" /> @<span v-html="userName" /><span v-html="'@' + serverName" />
<!-- eslint-enable vue/no-v-html --> <!-- eslint-enable vue/no-v-html -->

@ -67,11 +67,10 @@
</a> </a>
</div> </div>
<div <div
class="mobile-notifications"
id="mobile-notifications" id="mobile-notifications"
class="mobile-notifications"
@scroll="onScroll" @scroll="onScroll"
> />
</div>
</div> </div>
<SideDrawer <SideDrawer
ref="sideDrawer" ref="sideDrawer"

@ -12,6 +12,9 @@
<script> <script>
export default { export default {
provide: {
popoversZLayer: 'modals'
},
props: { props: {
isOpen: { isOpen: {
type: Boolean, type: Boolean,
@ -22,14 +25,11 @@ export default {
default: false default: false
} }
}, },
provide: {
popoversZLayer: 'modals'
},
computed: { computed: {
classes () { classes () {
return { return {
'modal-background': !this.noBackground, 'modal-background': !this.noBackground,
'open': this.isOpen open: this.isOpen
} }
} }
} }

@ -8,7 +8,7 @@
@show="setToggled(true)" @show="setToggled(true)"
@close="setToggled(false)" @close="setToggled(false)"
> >
<template v-slot:content> <template #content>
<div class="dropdown-menu"> <div class="dropdown-menu">
<span v-if="user.is_local"> <span v-if="user.is_local">
<button <button
@ -122,7 +122,7 @@
</span> </span>
</div> </div>
</template> </template>
<template v-slot:trigger> <template #trigger>
<button <button
class="btn button-default btn-block moderation-tools-button" class="btn button-default btn-block moderation-tools-button"
:class="{ toggled }" :class="{ toggled }"
@ -137,11 +137,11 @@
v-if="showDeleteUserDialog" v-if="showDeleteUserDialog"
:on-cancel="deleteUserDialog.bind(this, false)" :on-cancel="deleteUserDialog.bind(this, false)"
> >
<template v-slot:header> <template #header>
{{ $t('user_card.admin_menu.delete_user') }} {{ $t('user_card.admin_menu.delete_user') }}
</template> </template>
<p>{{ $t('user_card.admin_menu.delete_user_confirmation') }}</p> <p>{{ $t('user_card.admin_menu.delete_user_confirmation') }}</p>
<template v-slot:footer> <template #footer>
<button <button
class="btn button-default" class="btn button-default"
@click="deleteUserDialog(false)" @click="deleteUserDialog(false)"

@ -9,10 +9,10 @@ import { get } from 'lodash'
*/ */
const toInstanceReasonObject = (instances, info, key) => { const toInstanceReasonObject = (instances, info, key) => {
return instances.map(instance => { return instances.map(instance => {
if (info[key] && info[key][instance] && info[key][instance]['reason']) { if (info[key] && info[key][instance] && info[key][instance].reason) {
return { instance: instance, reason: info[key][instance]['reason'] } return { instance, reason: info[key][instance].reason }
} }
return { instance: instance, reason: '' } return { instance, reason: '' }
}) })
} }

@ -37,8 +37,8 @@
@click.prevent @click.prevent
> >
<UserPopover <UserPopover
:userId="notification.from_profile.id" :user-id="notification.from_profile.id"
:overlayCenters="true" :overlay-centers="true"
> >
<UserAvatar <UserAvatar
class="post-avatar" class="post-avatar"

@ -5,7 +5,7 @@
placement="bottom" placement="bottom"
:bound-to="{ x: 'container' }" :bound-to="{ x: 'container' }"
> >
<template v-slot:content> <template #content>
<div class="dropdown-menu"> <div class="dropdown-menu">
<button <button
class="button-default dropdown-item" class="button-default dropdown-item"
@ -72,7 +72,7 @@
</button> </button>
</div> </div>
</template> </template>
<template v-slot:trigger> <template #trigger>
<button class="filter-trigger-button button-unstyled"> <button class="filter-trigger-button button-unstyled">
<FAIcon icon="filter" /> <FAIcon icon="filter" />
</button> </button>

@ -1,5 +1,8 @@
<template> <template>
<teleport :disabled="minimalMode || disableTeleport" :to="teleportTarget"> <teleport
:disabled="minimalMode || disableTeleport"
:to="teleportTarget"
>
<div <div
:class="{ minimal: minimalMode }" :class="{ minimal: minimalMode }"
class="Notifications" class="Notifications"

@ -104,18 +104,22 @@ const Popover = {
// What are the screen bounds for the popover? Viewport vs container // What are the screen bounds for the popover? Viewport vs container
// when using viewport, using default margin values to dodge the navbar // when using viewport, using default margin values to dodge the navbar
const xBounds = this.boundTo && this.boundTo.x === 'container' ? { const xBounds = this.boundTo && this.boundTo.x === 'container'
? {
min: parentScreenBox.left + (margin.left || 0), min: parentScreenBox.left + (margin.left || 0),
max: parentScreenBox.right - (margin.right || 0) max: parentScreenBox.right - (margin.right || 0)
} : { }
: {
min: 0 + (margin.left || 10), min: 0 + (margin.left || 10),
max: window.innerWidth - (margin.right || 10) max: window.innerWidth - (margin.right || 10)
} }
const yBounds = this.boundTo && this.boundTo.y === 'container' ? { const yBounds = this.boundTo && this.boundTo.y === 'container'
? {
min: parentScreenBox.top + (margin.top || 0), min: parentScreenBox.top + (margin.top || 0),
max: parentScreenBox.bottom - (margin.bottom || 0) max: parentScreenBox.bottom - (margin.bottom || 0)
} : { }
: {
min: 0 + (margin.top || 50), min: 0 + (margin.top || 50),
max: window.innerHeight - (margin.bottom || 5) max: window.innerHeight - (margin.bottom || 5)
} }

@ -41,7 +41,7 @@ const buildMentionsString = ({ user, attentions = [] }, currentUser) => {
allAttentions = uniqBy(allAttentions, 'id') allAttentions = uniqBy(allAttentions, 'id')
allAttentions = reject(allAttentions, { id: currentUser.id }) allAttentions = reject(allAttentions, { id: currentUser.id })
let mentions = map(allAttentions, (attention) => { const mentions = map(allAttentions, (attention) => {
return `@${attention.screen_name}` return `@${attention.screen_name}`
}) })
@ -242,7 +242,7 @@ const PostStatusForm = {
}) })
}, },
watch: { watch: {
'newStatus': { newStatus: {
deep: true, deep: true,
handler () { handler () {
this.statusChanged() this.statusChanged()
@ -273,7 +273,7 @@ const PostStatusForm = {
this.$refs.textarea.focus() this.$refs.textarea.focus()
}) })
} }
let el = this.$el.querySelector('textarea') const el = this.$el.querySelector('textarea')
el.style.height = 'auto' el.style.height = 'auto'
el.style.height = undefined el.style.height = undefined
this.error = null this.error = null
@ -392,7 +392,7 @@ const PostStatusForm = {
this.$emit('resize', { delayed: true }) this.$emit('resize', { delayed: true })
}, },
removeMediaFile (fileInfo) { removeMediaFile (fileInfo) {
let index = this.newStatus.files.indexOf(fileInfo) const index = this.newStatus.files.indexOf(fileInfo)
this.newStatus.files.splice(index, 1) this.newStatus.files.splice(index, 1)
this.$emit('resize') this.$emit('resize')
}, },
@ -462,7 +462,7 @@ const PostStatusForm = {
}, },
onEmojiInputInput (e) { onEmojiInputInput (e) {
this.$nextTick(() => { this.$nextTick(() => {
this.resize(this.$refs['textarea']) this.resize(this.$refs.textarea)
}) })
}, },
resize (e) { resize (e) {
@ -477,8 +477,8 @@ const PostStatusForm = {
return return
} }
const formRef = this.$refs['form'] const formRef = this.$refs.form
const bottomRef = this.$refs['bottom'] const bottomRef = this.$refs.bottom
/* Scroller is either `window` (replies in TL), sidebar (main post form, /* Scroller is either `window` (replies in TL), sidebar (main post form,
* replies in notifs) or mobile post form. Note that getting and setting * replies in notifs) or mobile post form. Note that getting and setting
* scroll is different for `Window` and `Element`s * scroll is different for `Window` and `Element`s
@ -564,7 +564,7 @@ const PostStatusForm = {
this.$refs['emoji-input'].resize() this.$refs['emoji-input'].resize()
}, },
showEmojiPicker () { showEmojiPicker () {
this.$refs['textarea'].focus() this.$refs.textarea.focus()
this.$refs['emoji-input'].triggerShowPicker() this.$refs['emoji-input'].triggerShowPicker()
}, },
clearError () { clearError () {

@ -45,7 +45,7 @@ const ReactButton = {
emojis () { emojis () {
if (this.filterWord !== '') { if (this.filterWord !== '') {
const filterWordLowercase = trim(this.filterWord.toLowerCase()) const filterWordLowercase = trim(this.filterWord.toLowerCase())
let orderedEmojiList = [] const orderedEmojiList = []
for (const emoji of this.$store.state.instance.emoji) { for (const emoji of this.$store.state.instance.emoji) {
if (emoji.replacement === this.filterWord) return [emoji] if (emoji.replacement === this.filterWord) return [emoji]

@ -9,13 +9,13 @@
popover-class="ReactButton popover-default" popover-class="ReactButton popover-default"
@show="focusInput" @show="focusInput"
> >
<template v-slot:content="{close}"> <template #content="{close}">
<div class="reaction-picker-filter"> <div class="reaction-picker-filter">
<input <input
v-model="filterWord" v-model="filterWord"
@input="$event.target.composing = false"
size="1" size="1"
:placeholder="$t('emoji.search_emoji')" :placeholder="$t('emoji.search_emoji')"
@input="$event.target.composing = false"
> >
</div> </div>
<div class="reaction-picker"> <div class="reaction-picker">
@ -41,7 +41,7 @@
<div class="reaction-bottom-fader" /> <div class="reaction-bottom-fader" />
</div> </div>
</template> </template>
<template v-slot:trigger> <template #trigger>
<span <span
class="button-unstyled popover-trigger" class="button-unstyled popover-trigger"
:title="$t('tool_tip.add_reaction')" :title="$t('tool_tip.add_reaction')"

@ -16,7 +16,7 @@ const SearchBar = {
error: false error: false
}), }),
watch: { watch: {
'$route': function (route) { $route: function (route) {
if (route.name === 'search') { if (route.name === 'search') {
this.searchTerm = route.query.query this.searchTerm = route.query.query
} }

@ -24,7 +24,7 @@
:items="items" :items="items"
:get-key="getKey" :get-key="getKey"
> >
<template v-slot:item="{item}"> <template #item="{item}">
<div <div
class="selectable-list-item-inner" class="selectable-list-item-inner"
:class="{ 'selectable-list-item-selected-inner': isSelected(item) }" :class="{ 'selectable-list-item-selected-inner': isSelected(item) }"
@ -41,7 +41,7 @@
/> />
</div> </div>
</template> </template>
<template v-slot:empty> <template #empty>
<slot name="empty" /> <slot name="empty" />
</template> </template>
</List> </List>

@ -6,14 +6,14 @@
<Popover <Popover
trigger="hover" trigger="hover"
> >
<template v-slot:trigger> <template #trigger>
&nbsp; &nbsp;
<FAIcon <FAIcon
icon="wrench" icon="wrench"
:aria-label="$t('settings.setting_changed')" :aria-label="$t('settings.setting_changed')"
/> />
</template> </template>
<template v-slot:content> <template #content>
<div class="modified-tooltip"> <div class="modified-tooltip">
{{ $t('settings.setting_changed') }} {{ $t('settings.setting_changed') }}
</div> </div>

@ -6,14 +6,14 @@
<Popover <Popover
trigger="hover" trigger="hover"
> >
<template v-slot:trigger> <template #trigger>
&nbsp; &nbsp;
<FAIcon <FAIcon
icon="server" icon="server"
:aria-label="$t('settings.setting_server_side')" :aria-label="$t('settings.setting_server_side')"
/> />
</template> </template>
<template v-slot:content> <template #content>
<div class="serverside-tooltip"> <div class="serverside-tooltip">
{{ $t('settings.setting_server_side') }} {{ $t('settings.setting_server_side') }}
</div> </div>

@ -53,7 +53,7 @@
:bound-to="{ x: 'container' }" :bound-to="{ x: 'container' }"
remove-padding remove-padding
> >
<template v-slot:trigger> <template #trigger>
<button <button
class="btn button-default" class="btn button-default"
:title="$t('general.close')" :title="$t('general.close')"
@ -65,7 +65,7 @@
/> />
</button> </button>
</template> </template>
<template v-slot:content="{close}"> <template #content="{close}">
<div class="dropdown-menu"> <div class="dropdown-menu">
<button <button
class="button-default dropdown-item dropdown-item-icon" class="button-default dropdown-item dropdown-item-icon"

@ -75,12 +75,18 @@
</BooleanSetting> </BooleanSetting>
</li> </li>
<li> <li>
<BooleanSetting path="userPopoverZoom" expert="1"> <BooleanSetting
path="userPopoverZoom"
expert="1"
>
{{ $t('settings.user_popover_avatar_zoom') }} {{ $t('settings.user_popover_avatar_zoom') }}
</BooleanSetting> </BooleanSetting>
</li> </li>
<li> <li>
<BooleanSetting path="userPopoverOverlay" expert="1"> <BooleanSetting
path="userPopoverOverlay"
expert="1"
>
{{ $t('settings.user_popover_avatar_overlay') }} {{ $t('settings.user_popover_avatar_overlay') }}
</BooleanSetting> </BooleanSetting>
</li> </li>

@ -10,7 +10,7 @@
:query="queryUserIds" :query="queryUserIds"
:placeholder="$t('settings.search_user_to_block')" :placeholder="$t('settings.search_user_to_block')"
> >
<template v-slot="row"> <template #default="row">
<BlockCard <BlockCard
:user-id="row.item" :user-id="row.item"
/> />
@ -21,7 +21,7 @@
:refresh="true" :refresh="true"
:get-key="i => i" :get-key="i => i"
> >
<template v-slot:header="{selected}"> <template #header="{selected}">
<div class="bulk-actions"> <div class="bulk-actions">
<ProgressButton <ProgressButton
v-if="selected.length > 0" v-if="selected.length > 0"
@ -29,7 +29,7 @@
:click="() => blockUsers(selected)" :click="() => blockUsers(selected)"
> >
{{ $t('user_card.block') }} {{ $t('user_card.block') }}
<template v-slot:progress> <template #progress>
{{ $t('user_card.block_progress') }} {{ $t('user_card.block_progress') }}
</template> </template>
</ProgressButton> </ProgressButton>
@ -39,16 +39,16 @@
:click="() => unblockUsers(selected)" :click="() => unblockUsers(selected)"
> >
{{ $t('user_card.unblock') }} {{ $t('user_card.unblock') }}
<template v-slot:progress> <template #progress>
{{ $t('user_card.unblock_progress') }} {{ $t('user_card.unblock_progress') }}
</template> </template>
</ProgressButton> </ProgressButton>
</div> </div>
</template> </template>
<template v-slot:item="{item}"> <template #item="{item}">
<BlockCard :user-id="item" /> <BlockCard :user-id="item" />
</template> </template>
<template v-slot:empty> <template #empty>
{{ $t('settings.no_blocks') }} {{ $t('settings.no_blocks') }}
</template> </template>
</BlockList> </BlockList>
@ -63,7 +63,7 @@
:query="queryUserIds" :query="queryUserIds"
:placeholder="$t('settings.search_user_to_mute')" :placeholder="$t('settings.search_user_to_mute')"
> >
<template v-slot="row"> <template #default="row">
<MuteCard <MuteCard
:user-id="row.item" :user-id="row.item"
/> />
@ -74,7 +74,7 @@
:refresh="true" :refresh="true"
:get-key="i => i" :get-key="i => i"
> >
<template v-slot:header="{selected}"> <template #header="{selected}">
<div class="bulk-actions"> <div class="bulk-actions">
<ProgressButton <ProgressButton
v-if="selected.length > 0" v-if="selected.length > 0"
@ -82,7 +82,7 @@
:click="() => muteUsers(selected)" :click="() => muteUsers(selected)"
> >
{{ $t('user_card.mute') }} {{ $t('user_card.mute') }}
<template v-slot:progress> <template #progress>
{{ $t('user_card.mute_progress') }} {{ $t('user_card.mute_progress') }}
</template> </template>
</ProgressButton> </ProgressButton>
@ -92,16 +92,16 @@
:click="() => unmuteUsers(selected)" :click="() => unmuteUsers(selected)"
> >
{{ $t('user_card.unmute') }} {{ $t('user_card.unmute') }}
<template v-slot:progress> <template #progress>
{{ $t('user_card.unmute_progress') }} {{ $t('user_card.unmute_progress') }}
</template> </template>
</ProgressButton> </ProgressButton>
</div> </div>
</template> </template>
<template v-slot:item="{item}"> <template #item="{item}">
<MuteCard :user-id="item" /> <MuteCard :user-id="item" />
</template> </template>
<template v-slot:empty> <template #empty>
{{ $t('settings.no_mutes') }} {{ $t('settings.no_mutes') }}
</template> </template>
</MuteList> </MuteList>
@ -114,7 +114,7 @@
:query="queryKnownDomains" :query="queryKnownDomains"
:placeholder="$t('settings.type_domains_to_mute')" :placeholder="$t('settings.type_domains_to_mute')"
> >
<template v-slot="row"> <template #default="row">
<DomainMuteCard <DomainMuteCard
:domain="row.item" :domain="row.item"
/> />
@ -125,7 +125,7 @@
:refresh="true" :refresh="true"
:get-key="i => i" :get-key="i => i"
> >
<template v-slot:header="{selected}"> <template #header="{selected}">
<div class="bulk-actions"> <div class="bulk-actions">
<ProgressButton <ProgressButton
v-if="selected.length > 0" v-if="selected.length > 0"
@ -133,16 +133,16 @@
:click="() => unmuteDomains(selected)" :click="() => unmuteDomains(selected)"
> >
{{ $t('domain_mute_card.unmute') }} {{ $t('domain_mute_card.unmute') }}
<template v-slot:progress> <template #progress>
{{ $t('domain_mute_card.unmute_progress') }} {{ $t('domain_mute_card.unmute_progress') }}
</template> </template>
</ProgressButton> </ProgressButton>
</div> </div>
</template> </template>
<template v-slot:item="{item}"> <template #item="{item}">
<DomainMuteCard :domain="item" /> <DomainMuteCard :domain="item" />
</template> </template>
<template v-slot:empty> <template #empty>
{{ $t('settings.no_mutes') }} {{ $t('settings.no_mutes') }}
</template> </template>
</DomainMuteList> </DomainMuteList>

@ -71,10 +71,12 @@ const ProfileTab = {
}) })
}, },
emojiSuggestor () { emojiSuggestor () {
return suggestor({ emoji: [ return suggestor({
emoji: [
...this.$store.state.instance.emoji, ...this.$store.state.instance.emoji,
...this.$store.state.instance.customEmoji ...this.$store.state.instance.customEmoji
] }) ]
})
}, },
userSuggestor () { userSuggestor () {
return suggestor({ store: this.$store }) return suggestor({ store: this.$store })

@ -117,8 +117,8 @@
<button <button
v-if="!isDefaultAvatar && pickAvatarBtnVisible" v-if="!isDefaultAvatar && pickAvatarBtnVisible"
:title="$t('settings.reset_avatar')" :title="$t('settings.reset_avatar')"
@click="resetAvatar"
class="button-unstyled reset-button" class="button-unstyled reset-button"
@click="resetAvatar"
> >
<FAIcon <FAIcon
icon="times" icon="times"

@ -32,8 +32,8 @@ const Mfa = {
components: { components: {
'recovery-codes': RecoveryCodes, 'recovery-codes': RecoveryCodes,
'totp-item': TOTP, 'totp-item': TOTP,
'qrcode': VueQrcode, qrcode: VueQrcode,
'confirm': Confirm confirm: Confirm
}, },
computed: { computed: {
canSetupOTP () { canSetupOTP () {
@ -139,7 +139,7 @@ const Mfa = {
// fetch settings from server // fetch settings from server
async fetchSettings () { async fetchSettings () {
let result = await this.backendInteractor.settingsMFA() const result = await this.backendInteractor.settingsMFA()
if (result.error) return if (result.error) return
this.settings = result.settings this.settings = result.settings
this.settings.available = true this.settings.available = true

@ -10,7 +10,7 @@ export default {
inProgress: false // progress peform request to disable otp method inProgress: false // progress peform request to disable otp method
}), }),
components: { components: {
'confirm': Confirm confirm: Confirm
}, },
computed: { computed: {
isActivated () { isActivated () {

@ -29,7 +29,10 @@
{{ $t('settings.style.preview.content') }} {{ $t('settings.style.preview.content') }}
</h4> </h4>
<i18n-t scope="global" keypath="settings.style.preview.text"> <i18n-t
scope="global"
keypath="settings.style.preview.text"
>
<code style="font-family: var(--postCodeFont)"> <code style="font-family: var(--postCodeFont)">
{{ $t('settings.style.preview.mono') }} {{ $t('settings.style.preview.mono') }}
</code> </code>

@ -112,9 +112,11 @@ export default {
return hex2rgb(this.selected.color) return hex2rgb(this.selected.color)
}, },
style () { style () {
return this.ready ? { return this.ready
? {
boxShadow: getCssShadow(this.fallback) boxShadow: getCssShadow(this.fallback)
} : {} }
: {}
} }
} }
} }

@ -17,8 +17,8 @@ const StaffPanel = {
const groupedStaffAccounts = groupBy(staffAccounts, 'role') const groupedStaffAccounts = groupBy(staffAccounts, 'role')
return [ return [
{ role: 'admin', users: groupedStaffAccounts['admin'] }, { role: 'admin', users: groupedStaffAccounts.admin },
{ role: 'moderator', users: groupedStaffAccounts['moderator'] } { role: 'moderator', users: groupedStaffAccounts.moderator }
].filter(group => group.users) ].filter(group => group.users)
}, },
...mapGetters([ ...mapGetters([

@ -448,7 +448,7 @@ const Status = {
scrollIfHighlighted (highlightId) { scrollIfHighlighted (highlightId) {
const id = highlightId const id = highlightId
if (this.status.id === id) { if (this.status.id === id) {
let rect = this.$el.getBoundingClientRect() const rect = this.$el.getBoundingClientRect()
if (rect.top < 100) { if (rect.top < 100) {
// Post is above screen, match its top to screen top // Post is above screen, match its top to screen top
window.scrollBy(0, rect.top - 100) window.scrollBy(0, rect.top - 100)
@ -463,7 +463,7 @@ const Status = {
} }
}, },
watch: { watch: {
'highlight': function (id) { highlight: function (id) {
this.scrollIfHighlighted(id) this.scrollIfHighlighted(id)
}, },
'status.repeat_num': function (num) { 'status.repeat_num': function (num) {
@ -478,7 +478,7 @@ const Status = {
this.$store.dispatch('fetchFavs', this.status.id) this.$store.dispatch('fetchFavs', this.status.id)
} }
}, },
'isSuspendable': function (val) { isSuspendable: function (val) {
this.suspendable = val this.suspendable = val
} }
} }

@ -122,10 +122,13 @@
v-if="!noHeading" v-if="!noHeading"
class="left-side" class="left-side"
> >
<a :href="$router.resolve(userProfileLink).href" @click.prevent> <a
:href="$router.resolve(userProfileLink).href"
@click.prevent
>
<UserPopover <UserPopover
:userId="status.user.id" :user-id="status.user.id"
:overlayCenters="true" :overlay-centers="true"
> >
<UserAvatar <UserAvatar
class="post-avatar" class="post-avatar"

@ -1,16 +1,16 @@
<template> <template>
<Popover <Popover
ref="popover"
trigger="hover" trigger="hover"
:stay-on-click="true" :stay-on-click="true"
popover-class="popover-default status-popover" popover-class="popover-default status-popover"
:bound-to="{ x: 'container' }" :bound-to="{ x: 'container' }"
@show="enter" @show="enter"
ref="popover"
> >
<template v-slot:trigger> <template #trigger>
<slot /> <slot />
</template> </template>
<template v-slot:content> <template #content>
<Status <Status
v-if="status" v-if="status"
:is-preview="true" :is-preview="true"

@ -31,8 +31,8 @@ const StickerPicker = {
fetch(sticker) fetch(sticker)
.then((res) => { .then((res) => {
res.blob().then((blob) => { res.blob().then((blob) => {
var file = new File([blob], name, { mimetype: 'image/png' }) const file = new File([blob], name, { mimetype: 'image/png' })
var formData = new FormData() const formData = new FormData()
formData.append('file', file) formData.append('file', file)
statusPosterService.uploadMedia({ store, formData }) statusPosterService.uploadMedia({ store, formData })
.then((fileData) => { .then((fileData) => {

@ -46,7 +46,10 @@
</div> </div>
</div> </div>
<div :class="classes.footer"> <div :class="classes.footer">
<teleport :to="footerSlipgate" :disabled="!embedded || !footerSlipgate"> <teleport
:to="footerSlipgate"
:disabled="!embedded || !footerSlipgate"
>
<div <div
v-if="count===0" v-if="count===0"
class="new-status-notification text-center faint" class="new-status-notification text-center faint"

@ -4,7 +4,7 @@
class="TimelineQuickSettings" class="TimelineQuickSettings"
:bound-to="{ x: 'container' }" :bound-to="{ x: 'container' }"
> >
<template v-slot:content> <template #content>
<div class="dropdown-menu"> <div class="dropdown-menu">
<div v-if="loggedIn"> <div v-if="loggedIn">
<button <button
@ -80,7 +80,7 @@
</button> </button>
</div> </div>
</template> </template>
<template v-slot:trigger> <template #trigger>
<button class="button-unstyled"> <button class="button-unstyled">
<FAIcon icon="filter" /> <FAIcon icon="filter" />
</button> </button>

@ -11,9 +11,9 @@ library.add(faChevronDown)
// because nav panel benefits from the same information. // because nav panel benefits from the same information.
export const timelineNames = () => { export const timelineNames = () => {
return { return {
'friends': 'nav.home_timeline', friends: 'nav.home_timeline',
'bookmarks': 'nav.bookmarks', bookmarks: 'nav.bookmarks',
'dms': 'nav.dms', dms: 'nav.dms',
'public-timeline': 'nav.public_tl', 'public-timeline': 'nav.public_tl',
'public-external-timeline': 'nav.twkn' 'public-external-timeline': 'nav.twkn'
} }

@ -9,10 +9,10 @@
@show="openMenu" @show="openMenu"
@close="() => isOpen = false" @close="() => isOpen = false"
> >
<template v-slot:content> <template #content>
<TimelineMenuContent /> <TimelineMenuContent />
</template> </template>
<template v-slot:trigger> <template #trigger>
<span class="button-unstyled title timeline-menu-title"> <span class="button-unstyled title timeline-menu-title">
<span class="timeline-title">{{ timelineName() }}</span> <span class="timeline-title">{{ timelineName() }}</span>
<span> <span>

@ -67,7 +67,7 @@ export default {
style () { style () {
return { return {
backgroundImage: [ backgroundImage: [
`linear-gradient(to bottom, var(--profileTint), var(--profileTint))`, 'linear-gradient(to bottom, var(--profileTint), var(--profileTint))',
`url(${this.user.cover_photo})` `url(${this.user.cover_photo})`
].join(', ') ].join(', ')
} }

@ -29,10 +29,10 @@
</a> </a>
<UserAvatar <UserAvatar
v-else-if="typeof avatarAction === 'function'" v-else-if="typeof avatarAction === 'function'"
@click="avatarAction"
class="user-info-avatar" class="user-info-avatar"
:better-shadow="betterShadow" :better-shadow="betterShadow"
:user="user" :user="user"
@click="avatarAction"
/> />
<router-link <router-link
v-else v-else

@ -4,10 +4,10 @@
placement="top" placement="top"
:offset="{ y: 5 }" :offset="{ y: 5 }"
> >
<template v-slot:trigger> <template #trigger>
<slot /> <slot />
</template> </template>
<template v-slot:content> <template #content>
<div class="user-list-popover"> <div class="user-list-popover">
<template v-if="users.length"> <template v-if="users.length">
<div <div

@ -6,10 +6,10 @@
:overlay-centers="overlayCenters && userPopoverOverlay" :overlay-centers="overlayCenters && userPopoverOverlay"
:disabled="disabled" :disabled="disabled"
> >
<template v-slot:trigger> <template #trigger>
<slot /> <slot />
</template> </template>
<template v-slot:content={close}> <template #content="{close}">
<UserCard <UserCard
class="user-popover" class="user-popover"
:user-id="userId" :user-id="userId"

@ -56,7 +56,7 @@
:user-id="userId" :user-id="userId"
:pinned-status-ids="user.pinnedStatusIds" :pinned-status-ids="user.pinnedStatusIds"
:in-profile="true" :in-profile="true"
:footerSlipgate="footerRef" :footer-slipgate="footerRef"
/> />
<div <div
v-if="followsTabVisible" v-if="followsTabVisible"
@ -65,7 +65,7 @@
:disabled="!user.friends_count" :disabled="!user.friends_count"
> >
<FriendList :user-id="userId"> <FriendList :user-id="userId">
<template v-slot:item="{item}"> <template #item="{item}">
<FollowCard :user="item" /> <FollowCard :user="item" />
</template> </template>
</FriendList> </FriendList>
@ -77,7 +77,7 @@
:disabled="!user.followers_count" :disabled="!user.followers_count"
> >
<FollowerList :user-id="userId"> <FollowerList :user-id="userId">
<template v-slot:item="{item}"> <template #item="{item}">
<FollowCard <FollowCard
:user="item" :user="item"
:no-follows-you="isUs" :no-follows-you="isUs"
@ -95,7 +95,7 @@
:timeline="media" :timeline="media"
:user-id="userId" :user-id="userId"
:in-profile="true" :in-profile="true"
:footerSlipgate="footerRef" :footer-slipgate="footerRef"
/> />
<Timeline <Timeline
v-if="isUs" v-if="isUs"
@ -107,10 +107,13 @@
timeline-name="favorites" timeline-name="favorites"
:timeline="favorites" :timeline="favorites"
:in-profile="true" :in-profile="true"
:footerSlipgate="footerRef" :footer-slipgate="footerRef"
/> />
</tab-switcher> </tab-switcher>
<div class="panel-footer" :ref="setFooterRef"></div> <div
:ref="setFooterRef"
class="panel-footer"
/>
</div> </div>
<div <div
v-else v-else

@ -45,7 +45,7 @@
</div> </div>
<div class="user-reporting-panel-right"> <div class="user-reporting-panel-right">
<List :items="statuses"> <List :items="statuses">
<template v-slot:item="{item}"> <template #item="{item}">
<div class="status-fadein user-reporting-panel-sitem"> <div class="status-fadein user-reporting-panel-sitem">
<Status <Status
:in-conversation="false" :in-conversation="false"

@ -28,7 +28,7 @@ const WhoToFollow = {
getWhoToFollow () { getWhoToFollow () {
const credentials = this.$store.state.users.currentUser.credentials const credentials = this.$store.state.users.currentUser.credentials
if (credentials) { if (credentials) {
apiService.suggestions({ credentials: credentials }) apiService.suggestions({ credentials })
.then((reply) => { .then((reply) => {
this.showWhoToFollow(reply) this.showWhoToFollow(reply)
}) })

@ -6,9 +6,9 @@ function showWhoToFollow (panel, reply) {
const shuffled = shuffle(reply) const shuffled = shuffle(reply)
panel.usersToFollow.forEach((toFollow, index) => { panel.usersToFollow.forEach((toFollow, index) => {
let user = shuffled[index] const user = shuffled[index]
let img = user.avatar || this.$store.state.instance.defaultAvatar const img = user.avatar || this.$store.state.instance.defaultAvatar
let name = user.acct const name = user.acct
toFollow.img = img toFollow.img = img
toFollow.name = name toFollow.name = name
@ -24,12 +24,12 @@ function showWhoToFollow (panel, reply) {
} }
function getWhoToFollow (panel) { function getWhoToFollow (panel) {
var credentials = panel.$store.state.users.currentUser.credentials const credentials = panel.$store.state.users.currentUser.credentials
if (credentials) { if (credentials) {
panel.usersToFollow.forEach(toFollow => { panel.usersToFollow.forEach(toFollow => {
toFollow.name = 'Loading...' toFollow.name = 'Loading...'
}) })
apiService.suggestions({ credentials: credentials }) apiService.suggestions({ credentials })
.then((reply) => { .then((reply) => {
showWhoToFollow(panel, reply) showWhoToFollow(panel, reply)
}) })

@ -46,7 +46,7 @@ const messages = {
}, },
setLanguage: async (i18n, language) => { setLanguage: async (i18n, language) => {
if (loaders[language]) { if (loaders[language]) {
let messages = await loaders[language]() const messages = await loaders[language]()
i18n.setLocaleMessage(language, messages.default) i18n.setLocaleMessage(language, messages.default)
} }
i18n.locale = language i18n.locale = language

@ -3,8 +3,8 @@
// meant to be used to load the partial i18n we need for // meant to be used to load the partial i18n we need for
// the service worker. // the service worker.
module.exports = function (source) { module.exports = function (source) {
var object = JSON.parse(source) const object = JSON.parse(source)
var smol = { const smol = {
notifications: object.notifications || {} notifications: object.notifications || {}
} }

@ -5,7 +5,9 @@ import { each, get, set, cloneDeep } from 'lodash'
let loaded = false let loaded = false
const defaultReducer = (state, paths) => ( const defaultReducer = (state, paths) => (
paths.length === 0 ? state : paths.reduce((substate, path) => { paths.length === 0
? state
: paths.reduce((substate, path) => {
set(substate, path, get(state, path)) set(substate, path, get(state, path))
return substate return substate
}, {}) }, {})
@ -30,7 +32,7 @@ export default function createPersistedState ({
key = 'vuex-lz', key = 'vuex-lz',
paths = [], paths = [],
getState = (key, storage) => { getState = (key, storage) => {
let value = storage.getItem(key) const value = storage.getItem(key)
return value return value
}, },
setState = (key, state, storage) => { setState = (key, state, storage) => {

@ -233,7 +233,7 @@ const api = {
// Follow requests // Follow requests
startFetchingFollowRequests (store) { startFetchingFollowRequests (store) {
if (store.state.fetchers['followRequests']) return if (store.state.fetchers.followRequests) return
const fetcher = store.state.backendInteractor.startFetchingFollowRequests({ store }) const fetcher = store.state.backendInteractor.startFetchingFollowRequests({ store })
store.commit('addFetcher', { fetcherName: 'followRequests', fetcher }) store.commit('addFetcher', { fetcherName: 'followRequests', fetcher })
@ -244,7 +244,7 @@ const api = {
store.commit('removeFetcher', { fetcherName: 'followRequests', fetcher }) store.commit('removeFetcher', { fetcherName: 'followRequests', fetcher })
}, },
removeFollowRequest (store, request) { removeFollowRequest (store, request) {
let requests = store.state.followRequests.filter((it) => it !== request) const requests = store.state.followRequests.filter((it) => it !== request)
store.commit('setFollowRequests', requests) store.commit('setFollowRequests', requests)
}, },

@ -147,7 +147,7 @@ const config = {
const knownKeys = new Set(Object.keys(defaultState)) const knownKeys = new Set(Object.keys(defaultState))
const presentKeys = new Set(Object.keys(data)) const presentKeys = new Set(Object.keys(data))
const intersection = new Set() const intersection = new Set()
for (let elem of presentKeys) { for (const elem of presentKeys) {
if (knownKeys.has(elem)) { if (knownKeys.has(elem)) {
intersection.add(elem) intersection.add(elem)
} }

@ -2,8 +2,8 @@ import { capitalize } from 'lodash'
export function humanizeErrors (errors) { export function humanizeErrors (errors) {
return Object.entries(errors).reduce((errs, [k, val]) => { return Object.entries(errors).reduce((errs, [k, val]) => {
let message = val.reduce((acc, message) => { const message = val.reduce((acc, message) => {
let key = capitalize(k.replace(/_/g, ' ')) const key = capitalize(k.replace(/_/g, ' '))
return acc + [key, message].join(' ') + '. ' return acc + [key, message].join(' ') + '. '
}, '') }, '')
return [...errs, message] return [...errs, message]

@ -39,53 +39,53 @@ const notificationsApi = ({ rootState, commit }, { path, value, oldValue }) => {
* If no api is specified, defaultApi is used (see above) * If no api is specified, defaultApi is used (see above)
*/ */
export const settingsMap = { export const settingsMap = {
'defaultScope': 'source.privacy', defaultScope: 'source.privacy',
'defaultNSFW': 'source.sensitive', // BROKEN: pleroma/pleroma#2837 defaultNSFW: 'source.sensitive', // BROKEN: pleroma/pleroma#2837
'stripRichContent': { stripRichContent: {
get: 'source.pleroma.no_rich_text', get: 'source.pleroma.no_rich_text',
set: 'no_rich_text' set: 'no_rich_text'
}, },
// Privacy // Privacy
'locked': 'locked', locked: 'locked',
'acceptChatMessages': { acceptChatMessages: {
get: 'pleroma.accepts_chat_messages', get: 'pleroma.accepts_chat_messages',
set: 'accepts_chat_messages' set: 'accepts_chat_messages'
}, },
'allowFollowingMove': { allowFollowingMove: {
get: 'pleroma.allow_following_move', get: 'pleroma.allow_following_move',
set: 'allow_following_move' set: 'allow_following_move'
}, },
'discoverable': { discoverable: {
get: 'source.pleroma.discoverable', get: 'source.pleroma.discoverable',
set: 'discoverable' set: 'discoverable'
}, },
'hideFavorites': { hideFavorites: {
get: 'pleroma.hide_favorites', get: 'pleroma.hide_favorites',
set: 'hide_favorites' set: 'hide_favorites'
}, },
'hideFollowers': { hideFollowers: {
get: 'pleroma.hide_followers', get: 'pleroma.hide_followers',
set: 'hide_followers' set: 'hide_followers'
}, },
'hideFollows': { hideFollows: {
get: 'pleroma.hide_follows', get: 'pleroma.hide_follows',
set: 'hide_follows' set: 'hide_follows'
}, },
'hideFollowersCount': { hideFollowersCount: {
get: 'pleroma.hide_followers_count', get: 'pleroma.hide_followers_count',
set: 'hide_followers_count' set: 'hide_followers_count'
}, },
'hideFollowsCount': { hideFollowsCount: {
get: 'pleroma.hide_follows_count', get: 'pleroma.hide_follows_count',
set: 'hide_follows_count' set: 'hide_follows_count'
}, },
// NotificationSettingsAPIs // NotificationSettingsAPIs
'webPushHideContents': { webPushHideContents: {
get: 'pleroma.notification_settings.hide_notification_contents', get: 'pleroma.notification_settings.hide_notification_contents',
set: 'hide_notification_contents', set: 'hide_notification_contents',
api: notificationsApi api: notificationsApi
}, },
'blockNotificationsFromStrangers': { blockNotificationsFromStrangers: {
get: 'pleroma.notification_settings.block_from_strangers', get: 'pleroma.notification_settings.block_from_strangers',
set: 'block_from_strangers', set: 'block_from_strangers',
api: notificationsApi api: notificationsApi

@ -245,10 +245,10 @@ const addNewStatuses = (state, { statuses, showImmediately = false, timeline, us
} }
const processors = { const processors = {
'status': (status) => { status: (status) => {
addStatus(status, showImmediately) addStatus(status, showImmediately)
}, },
'retweet': (status) => { retweet: (status) => {
// RetweetedStatuses are never shown immediately // RetweetedStatuses are never shown immediately
const retweetedStatus = addStatus(status.retweeted_status, false, false) const retweetedStatus = addStatus(status.retweeted_status, false, false)
@ -270,7 +270,7 @@ const addNewStatuses = (state, { statuses, showImmediately = false, timeline, us
retweet.retweeted_status = retweetedStatus retweet.retweeted_status = retweetedStatus
}, },
'favorite': (favorite) => { favorite: (favorite) => {
// Only update if this is a new favorite. // Only update if this is a new favorite.
// Ignore our own favorites because we get info about likes as response to like request // Ignore our own favorites because we get info about likes as response to like request
if (!state.favorites.has(favorite.id)) { if (!state.favorites.has(favorite.id)) {
@ -278,7 +278,7 @@ const addNewStatuses = (state, { statuses, showImmediately = false, timeline, us
favoriteStatus(favorite) favoriteStatus(favorite)
} }
}, },
'deletion': (deletion) => { deletion: (deletion) => {
const uri = deletion.uri const uri = deletion.uri
const status = find(allStatuses, { uri }) const status = find(allStatuses, { uri })
if (!status) { if (!status) {
@ -292,10 +292,10 @@ const addNewStatuses = (state, { statuses, showImmediately = false, timeline, us
remove(timelineObject.visibleStatuses, { uri }) remove(timelineObject.visibleStatuses, { uri })
} }
}, },
'follow': (follow) => { follow: (follow) => {
// NOOP, it is known status but we don't do anything about it for now // NOOP, it is known status but we don't do anything about it for now
}, },
'default': (unknown) => { default: (unknown) => {
console.log('unknown status type') console.log('unknown status type')
console.log(unknown) console.log(unknown)
} }
@ -303,7 +303,7 @@ const addNewStatuses = (state, { statuses, showImmediately = false, timeline, us
each(statuses, (status) => { each(statuses, (status) => {
const type = status.type const type = status.type
const processor = processors[type] || processors['default'] const processor = processors[type] || processors.default
processor(status) processor(status)
}) })
@ -522,7 +522,7 @@ export const mutations = {
}, },
addEmojiReactionsBy (state, { id, emojiReactions, currentUser }) { addEmojiReactionsBy (state, { id, emojiReactions, currentUser }) {
const status = state.allStatusesObject[id] const status = state.allStatusesObject[id]
status['emoji_reactions'] = emojiReactions status.emoji_reactions = emojiReactions
}, },
addOwnReaction (state, { id, emoji, currentUser }) { addOwnReaction (state, { id, emoji, currentUser }) {
const status = state.allStatusesObject[id] const status = state.allStatusesObject[id]
@ -543,7 +543,7 @@ export const mutations = {
if (reactionIndex >= 0) { if (reactionIndex >= 0) {
status.emoji_reactions[reactionIndex] = newReaction status.emoji_reactions[reactionIndex] = newReaction
} else { } else {
status['emoji_reactions'] = [...status.emoji_reactions, newReaction] status.emoji_reactions = [...status.emoji_reactions, newReaction]
} }
}, },
removeOwnReaction (state, { id, emoji, currentUser }) { removeOwnReaction (state, { id, emoji, currentUser }) {
@ -564,7 +564,7 @@ export const mutations = {
if (newReaction.count > 0) { if (newReaction.count > 0) {
status.emoji_reactions[reactionIndex] = newReaction status.emoji_reactions[reactionIndex] = newReaction
} else { } else {
status['emoji_reactions'] = status.emoji_reactions.filter(r => r.name !== emoji) status.emoji_reactions = status.emoji_reactions.filter(r => r.name !== emoji)
} }
}, },
updateStatusWithPoll (state, { id, poll }) { updateStatusWithPoll (state, { id, poll }) {

@ -103,23 +103,23 @@ export const mutations = {
const user = state.usersObject[id] const user = state.usersObject[id]
const tags = user.tags || [] const tags = user.tags || []
const newTags = tags.concat([tag]) const newTags = tags.concat([tag])
user['tags'] = newTags user.tags = newTags
}, },
untagUser (state, { user: { id }, tag }) { untagUser (state, { user: { id }, tag }) {
const user = state.usersObject[id] const user = state.usersObject[id]
const tags = user.tags || [] const tags = user.tags || []
const newTags = tags.filter(t => t !== tag) const newTags = tags.filter(t => t !== tag)
user['tags'] = newTags user.tags = newTags
}, },
updateRight (state, { user: { id }, right, value }) { updateRight (state, { user: { id }, right, value }) {
const user = state.usersObject[id] const user = state.usersObject[id]
let newRights = user.rights const newRights = user.rights
newRights[right] = value newRights[right] = value
user['rights'] = newRights user.rights = newRights
}, },
updateActivationStatus (state, { user: { id }, deactivated }) { updateActivationStatus (state, { user: { id }, deactivated }) {
const user = state.usersObject[id] const user = state.usersObject[id]
user['deactivated'] = deactivated user.deactivated = deactivated
}, },
setCurrentUser (state, user) { setCurrentUser (state, user) {
state.lastLoginName = user.screen_name state.lastLoginName = user.screen_name
@ -148,13 +148,13 @@ export const mutations = {
clearFriends (state, userId) { clearFriends (state, userId) {
const user = state.usersObject[userId] const user = state.usersObject[userId]
if (user) { if (user) {
user['friendIds'] = [] user.friendIds = []
} }
}, },
clearFollowers (state, userId) { clearFollowers (state, userId) {
const user = state.usersObject[userId] const user = state.usersObject[userId]
if (user) { if (user) {
user['followerIds'] = [] user.followerIds = []
} }
}, },
addNewUsers (state, users) { addNewUsers (state, users) {
@ -222,7 +222,7 @@ export const mutations = {
}, },
setColor (state, { user: { id }, highlighted }) { setColor (state, { user: { id }, highlighted }) {
const user = state.usersObject[id] const user = state.usersObject[id]
user['highlight'] = highlighted user.highlight = highlighted
}, },
signUpPending (state) { signUpPending (state) {
state.signUpPending = true state.signUpPending = true
@ -393,7 +393,7 @@ const users = {
toggleActivationStatus ({ rootState, commit }, { user }) { toggleActivationStatus ({ rootState, commit }, { user }) {
const api = user.deactivated ? rootState.api.backendInteractor.activateUser : rootState.api.backendInteractor.deactivateUser const api = user.deactivated ? rootState.api.backendInteractor.activateUser : rootState.api.backendInteractor.deactivateUser
api({ user }) api({ user })
.then((user) => { let deactivated = !user.is_active; commit('updateActivationStatus', { user, deactivated }) }) .then((user) => { const deactivated = !user.is_active; commit('updateActivationStatus', { user, deactivated }) })
}, },
registerPushNotifications (store) { registerPushNotifications (store) {
const token = store.state.currentUser.credentials const token = store.state.currentUser.credentials
@ -457,17 +457,17 @@ const users = {
async signUp (store, userInfo) { async signUp (store, userInfo) {
store.commit('signUpPending') store.commit('signUpPending')
let rootState = store.rootState const rootState = store.rootState
try { try {
let data = await rootState.api.backendInteractor.register( const data = await rootState.api.backendInteractor.register(
{ params: { ...userInfo } } { params: { ...userInfo } }
) )
store.commit('signUpSuccess') store.commit('signUpSuccess')
store.commit('setToken', data.access_token) store.commit('setToken', data.access_token)
store.dispatch('loginUser', data.access_token) store.dispatch('loginUser', data.access_token)
} catch (e) { } catch (e) {
let errors = e.message const errors = e.message
store.commit('signUpFailure', errors) store.commit('signUpFailure', errors)
throw e throw e
} }

@ -76,7 +76,7 @@ const MASTODON_PIN_OWN_STATUS = id => `/api/v1/statuses/${id}/pin`
const MASTODON_UNPIN_OWN_STATUS = id => `/api/v1/statuses/${id}/unpin` const MASTODON_UNPIN_OWN_STATUS = id => `/api/v1/statuses/${id}/unpin`
const MASTODON_MUTE_CONVERSATION = id => `/api/v1/statuses/${id}/mute` const MASTODON_MUTE_CONVERSATION = id => `/api/v1/statuses/${id}/mute`
const MASTODON_UNMUTE_CONVERSATION = id => `/api/v1/statuses/${id}/unmute` const MASTODON_UNMUTE_CONVERSATION = id => `/api/v1/statuses/${id}/unmute`
const MASTODON_SEARCH_2 = `/api/v2/search` const MASTODON_SEARCH_2 = '/api/v2/search'
const MASTODON_USER_SEARCH_URL = '/api/v1/accounts/search' const MASTODON_USER_SEARCH_URL = '/api/v1/accounts/search'
const MASTODON_DOMAIN_BLOCKS_URL = '/api/v1/domain_blocks' const MASTODON_DOMAIN_BLOCKS_URL = '/api/v1/domain_blocks'
const MASTODON_STREAMING = '/api/v1/streaming' const MASTODON_STREAMING = '/api/v1/streaming'
@ -84,7 +84,7 @@ const MASTODON_KNOWN_DOMAIN_LIST_URL = '/api/v1/instance/peers'
const PLEROMA_EMOJI_REACTIONS_URL = id => `/api/v1/pleroma/statuses/${id}/reactions` const PLEROMA_EMOJI_REACTIONS_URL = id => `/api/v1/pleroma/statuses/${id}/reactions`
const PLEROMA_EMOJI_REACT_URL = (id, emoji) => `/api/v1/pleroma/statuses/${id}/reactions/${emoji}` const PLEROMA_EMOJI_REACT_URL = (id, emoji) => `/api/v1/pleroma/statuses/${id}/reactions/${emoji}`
const PLEROMA_EMOJI_UNREACT_URL = (id, emoji) => `/api/v1/pleroma/statuses/${id}/reactions/${emoji}` const PLEROMA_EMOJI_UNREACT_URL = (id, emoji) => `/api/v1/pleroma/statuses/${id}/reactions/${emoji}`
const PLEROMA_CHATS_URL = `/api/v1/pleroma/chats` const PLEROMA_CHATS_URL = '/api/v1/pleroma/chats'
const PLEROMA_CHAT_URL = id => `/api/v1/pleroma/chats/by-account-id/${id}` const PLEROMA_CHAT_URL = id => `/api/v1/pleroma/chats/by-account-id/${id}`
const PLEROMA_CHAT_MESSAGES_URL = id => `/api/v1/pleroma/chats/${id}/messages` const PLEROMA_CHAT_MESSAGES_URL = id => `/api/v1/pleroma/chats/${id}/messages`
const PLEROMA_CHAT_READ_URL = id => `/api/v1/pleroma/chats/${id}/read` const PLEROMA_CHAT_READ_URL = id => `/api/v1/pleroma/chats/${id}/read`
@ -93,7 +93,7 @@ const PLEROMA_BACKUP_URL = '/api/v1/pleroma/backups'
const oldfetch = window.fetch const oldfetch = window.fetch
let fetch = (url, options) => { const fetch = (url, options) => {
options = options || {} options = options || {}
const baseUrl = '' const baseUrl = ''
const fullUrl = baseUrl + url const fullUrl = baseUrl + url
@ -105,7 +105,7 @@ const promisedRequest = ({ method, url, params, payload, credentials, headers =
const options = { const options = {
method, method,
headers: { headers: {
'Accept': 'application/json', Accept: 'application/json',
'Content-Type': 'application/json', 'Content-Type': 'application/json',
...headers ...headers
} }
@ -229,16 +229,16 @@ const getCaptcha = () => fetch('/api/pleroma/captcha').then(resp => resp.json())
const authHeaders = (accessToken) => { const authHeaders = (accessToken) => {
if (accessToken) { if (accessToken) {
return { 'Authorization': `Bearer ${accessToken}` } return { Authorization: `Bearer ${accessToken}` }
} else { } else {
return { } return { }
} }
} }
const followUser = ({ id, credentials, ...options }) => { const followUser = ({ id, credentials, ...options }) => {
let url = MASTODON_FOLLOW_URL(id) const url = MASTODON_FOLLOW_URL(id)
const form = {} const form = {}
if (options.reblogs !== undefined) { form['reblogs'] = options.reblogs } if (options.reblogs !== undefined) { form.reblogs = options.reblogs }
return fetch(url, { return fetch(url, {
body: JSON.stringify(form), body: JSON.stringify(form),
headers: { headers: {
@ -250,7 +250,7 @@ const followUser = ({ id, credentials, ...options }) => {
} }
const unfollowUser = ({ id, credentials }) => { const unfollowUser = ({ id, credentials }) => {
let url = MASTODON_UNFOLLOW_URL(id) const url = MASTODON_UNFOLLOW_URL(id)
return fetch(url, { return fetch(url, {
headers: authHeaders(credentials), headers: authHeaders(credentials),
method: 'POST' method: 'POST'
@ -292,7 +292,7 @@ const unblockUser = ({ id, credentials }) => {
} }
const approveUser = ({ id, credentials }) => { const approveUser = ({ id, credentials }) => {
let url = MASTODON_APPROVE_USER_URL(id) const url = MASTODON_APPROVE_USER_URL(id)
return fetch(url, { return fetch(url, {
headers: authHeaders(credentials), headers: authHeaders(credentials),
method: 'POST' method: 'POST'
@ -300,7 +300,7 @@ const approveUser = ({ id, credentials }) => {
} }
const denyUser = ({ id, credentials }) => { const denyUser = ({ id, credentials }) => {
let url = MASTODON_DENY_USER_URL(id) const url = MASTODON_DENY_USER_URL(id)
return fetch(url, { return fetch(url, {
headers: authHeaders(credentials), headers: authHeaders(credentials),
method: 'POST' method: 'POST'
@ -308,13 +308,13 @@ const denyUser = ({ id, credentials }) => {
} }
const fetchUser = ({ id, credentials }) => { const fetchUser = ({ id, credentials }) => {
let url = `${MASTODON_USER_URL}/${id}` const url = `${MASTODON_USER_URL}/${id}`
return promisedRequest({ url, credentials }) return promisedRequest({ url, credentials })
.then((data) => parseUser(data)) .then((data) => parseUser(data))
} }
const fetchUserRelationship = ({ id, credentials }) => { const fetchUserRelationship = ({ id, credentials }) => {
let url = `${MASTODON_USER_RELATIONSHIPS_URL}/?id=${id}` const url = `${MASTODON_USER_RELATIONSHIPS_URL}/?id=${id}`
return fetch(url, { headers: authHeaders(credentials) }) return fetch(url, { headers: authHeaders(credentials) })
.then((response) => { .then((response) => {
return new Promise((resolve, reject) => response.json() return new Promise((resolve, reject) => response.json()
@ -333,7 +333,7 @@ const fetchFriends = ({ id, maxId, sinceId, limit = 20, credentials }) => {
maxId && `max_id=${maxId}`, maxId && `max_id=${maxId}`,
sinceId && `since_id=${sinceId}`, sinceId && `since_id=${sinceId}`,
limit && `limit=${limit}`, limit && `limit=${limit}`,
`with_relationships=true` 'with_relationships=true'
].filter(_ => _).join('&') ].filter(_ => _).join('&')
url = url + (args ? '?' + args : '') url = url + (args ? '?' + args : '')
@ -368,7 +368,7 @@ const fetchFollowers = ({ id, maxId, sinceId, limit = 20, credentials }) => {
maxId && `max_id=${maxId}`, maxId && `max_id=${maxId}`,
sinceId && `since_id=${sinceId}`, sinceId && `since_id=${sinceId}`,
limit && `limit=${limit}`, limit && `limit=${limit}`,
`with_relationships=true` 'with_relationships=true'
].filter(_ => _).join('&') ].filter(_ => _).join('&')
url += args ? '?' + args : '' url += args ? '?' + args : ''
@ -385,7 +385,7 @@ const fetchFollowRequests = ({ credentials }) => {
} }
const fetchConversation = ({ id, credentials }) => { const fetchConversation = ({ id, credentials }) => {
let urlContext = MASTODON_STATUS_CONTEXT_URL(id) const urlContext = MASTODON_STATUS_CONTEXT_URL(id)
return fetch(urlContext, { headers: authHeaders(credentials) }) return fetch(urlContext, { headers: authHeaders(credentials) })
.then((data) => { .then((data) => {
if (data.ok) { if (data.ok) {
@ -401,7 +401,7 @@ const fetchConversation = ({ id, credentials }) => {
} }
const fetchStatus = ({ id, credentials }) => { const fetchStatus = ({ id, credentials }) => {
let url = MASTODON_STATUS_URL(id) const url = MASTODON_STATUS_URL(id)
return fetch(url, { headers: authHeaders(credentials) }) return fetch(url, { headers: authHeaders(credentials) })
.then((data) => { .then((data) => {
if (data.ok) { if (data.ok) {
@ -425,7 +425,7 @@ const tagUser = ({ tag, credentials, user }) => {
return fetch(TAG_USER_URL, { return fetch(TAG_USER_URL, {
method: 'PUT', method: 'PUT',
headers: headers, headers,
body: JSON.stringify(form) body: JSON.stringify(form)
}) })
} }
@ -442,7 +442,7 @@ const untagUser = ({ tag, credentials, user }) => {
return fetch(TAG_USER_URL, { return fetch(TAG_USER_URL, {
method: 'DELETE', method: 'DELETE',
headers: headers, headers,
body: JSON.stringify(body) body: JSON.stringify(body)
}) })
} }
@ -495,7 +495,7 @@ const deleteUser = ({ credentials, user }) => {
return fetch(`${ADMIN_USERS_URL}?nickname=${screenName}`, { return fetch(`${ADMIN_USERS_URL}?nickname=${screenName}`, {
method: 'DELETE', method: 'DELETE',
headers: headers headers
}) })
} }
@ -514,7 +514,7 @@ const fetchTimeline = ({
friends: MASTODON_USER_HOME_TIMELINE_URL, friends: MASTODON_USER_HOME_TIMELINE_URL,
dms: MASTODON_DIRECT_MESSAGES_TIMELINE_URL, dms: MASTODON_DIRECT_MESSAGES_TIMELINE_URL,
notifications: MASTODON_USER_NOTIFICATIONS_URL, notifications: MASTODON_USER_NOTIFICATIONS_URL,
'publicAndExternal': MASTODON_PUBLIC_TIMELINE, publicAndExternal: MASTODON_PUBLIC_TIMELINE,
user: MASTODON_USER_TIMELINE_URL, user: MASTODON_USER_TIMELINE_URL,
media: MASTODON_USER_TIMELINE_URL, media: MASTODON_USER_TIMELINE_URL,
favorites: MASTODON_USER_FAVORITES_TIMELINE_URL, favorites: MASTODON_USER_FAVORITES_TIMELINE_URL,
@ -688,7 +688,7 @@ const postStatus = ({
form.append('preview', 'true') form.append('preview', 'true')
} }
let postHeaders = authHeaders(credentials) const postHeaders = authHeaders(credentials)
if (idempotencyKey) { if (idempotencyKey) {
postHeaders['idempotency-key'] = idempotencyKey postHeaders['idempotency-key'] = idempotencyKey
} }
@ -993,7 +993,7 @@ const vote = ({ pollId, choices, credentials }) => {
method: 'POST', method: 'POST',
credentials, credentials,
payload: { payload: {
choices: choices choices
} }
}) })
} }
@ -1053,8 +1053,8 @@ const reportUser = ({ credentials, userId, statusIds, comment, forward }) => {
url: MASTODON_REPORT_USER_URL, url: MASTODON_REPORT_USER_URL,
method: 'POST', method: 'POST',
payload: { payload: {
'account_id': userId, account_id: userId,
'status_ids': statusIds, status_ids: statusIds,
comment, comment,
forward forward
}, },
@ -1076,7 +1076,7 @@ const searchUsers = ({ credentials, query }) => {
const search2 = ({ credentials, q, resolve, limit, offset, following }) => { const search2 = ({ credentials, q, resolve, limit, offset, following }) => {
let url = MASTODON_SEARCH_2 let url = MASTODON_SEARCH_2
let params = [] const params = []
if (q) { if (q) {
params.push(['q', encodeURIComponent(q)]) params.push(['q', encodeURIComponent(q)])
@ -1100,7 +1100,7 @@ const search2 = ({ credentials, q, resolve, limit, offset, following }) => {
params.push(['with_relationships', true]) params.push(['with_relationships', true])
let queryString = map(params, (param) => `${param[0]}=${param[1]}`).join('&') const queryString = map(params, (param) => `${param[0]}=${param[1]}`).join('&')
url += `?${queryString}` url += `?${queryString}`
return fetch(url, { headers: authHeaders(credentials) }) return fetch(url, { headers: authHeaders(credentials) })
@ -1254,12 +1254,12 @@ export const handleMastoWS = (wsEvent) => {
} }
export const WSConnectionStatus = Object.freeze({ export const WSConnectionStatus = Object.freeze({
'JOINED': 1, JOINED: 1,
'CLOSED': 2, CLOSED: 2,
'ERROR': 3, ERROR: 3,
'DISABLED': 4, DISABLED: 4,
'STARTING': 5, STARTING: 5,
'STARTING_INITIAL': 6 STARTING_INITIAL: 6
}) })
const chats = ({ credentials }) => { const chats = ({ credentials }) => {
@ -1297,11 +1297,11 @@ const chatMessages = ({ id, credentials, maxId, sinceId, limit = 20 }) => {
const sendChatMessage = ({ id, content, mediaId = null, idempotencyKey, credentials }) => { const sendChatMessage = ({ id, content, mediaId = null, idempotencyKey, credentials }) => {
const payload = { const payload = {
'content': content content
} }
if (mediaId) { if (mediaId) {
payload['media_id'] = mediaId payload.media_id = mediaId
} }
const headers = {} const headers = {}
@ -1313,7 +1313,7 @@ const sendChatMessage = ({ id, content, mediaId = null, idempotencyKey, credenti
return promisedRequest({ return promisedRequest({
url: PLEROMA_CHAT_MESSAGES_URL(id), url: PLEROMA_CHAT_MESSAGES_URL(id),
method: 'POST', method: 'POST',
payload: payload, payload,
credentials, credentials,
headers headers
}) })
@ -1324,7 +1324,7 @@ const readChat = ({ id, lastReadId, credentials }) => {
url: PLEROMA_CHAT_READ_URL(id), url: PLEROMA_CHAT_READ_URL(id),
method: 'POST', method: 'POST',
payload: { payload: {
'last_read_id': lastReadId last_read_id: lastReadId
}, },
credentials credentials
}) })

@ -7,7 +7,7 @@ const empty = (chatId) => {
messages: [], messages: [],
newMessageCount: 0, newMessageCount: 0,
lastSeenMessageId: '0', lastSeenMessageId: '0',
chatId: chatId, chatId,
minId: undefined, minId: undefined,
maxId: undefined maxId: undefined
} }
@ -101,7 +101,7 @@ const add = (storage, { messages: newMessages, updateMaxId = true }) => {
storage.messages = storage.messages.filter(msg => msg.id !== message.id) storage.messages = storage.messages.filter(msg => msg.id !== message.id)
} }
Object.assign(fakeMessage, message, { error: false }) Object.assign(fakeMessage, message, { error: false })
delete fakeMessage['fakeId'] delete fakeMessage.fakeId
storage.idIndex[fakeMessage.id] = fakeMessage storage.idIndex[fakeMessage.id] = fakeMessage
delete storage.idIndex[message.fakeId] delete storage.idIndex[message.fakeId]
@ -178,7 +178,7 @@ const getView = (storage) => {
id: date.getTime().toString() id: date.getTime().toString()
}) })
previousMessage['isTail'] = true previousMessage.isTail = true
currentMessageChainId = undefined currentMessageChainId = undefined
afterDate = true afterDate = true
} }
@ -193,15 +193,15 @@ const getView = (storage) => {
// end a message chian // end a message chian
if ((nextMessage && nextMessage.account_id) !== message.account_id) { if ((nextMessage && nextMessage.account_id) !== message.account_id) {
object['isTail'] = true object.isTail = true
currentMessageChainId = undefined currentMessageChainId = undefined
} }
// start a new message chain // start a new message chain
if ((previousMessage && previousMessage.data && previousMessage.data.account_id) !== message.account_id || afterDate) { if ((previousMessage && previousMessage.data && previousMessage.data.account_id) !== message.account_id || afterDate) {
currentMessageChainId = _.uniqueId() currentMessageChainId = _.uniqueId()
object['isHead'] = true object.isHead = true
object['messageChainId'] = currentMessageChainId object.messageChainId = currentMessageChainId
} }
result.push(object) result.push(object)

@ -25,7 +25,7 @@ export const buildFakeMessage = ({ content, chatId, attachments, userId, idempot
chat_id: chatId, chat_id: chatId,
created_at: new Date(), created_at: new Date(),
id: `${new Date().getTime()}`, id: `${new Date().getTime()}`,
attachments: attachments, attachments,
account_id: userId, account_id: userId,
idempotency_key: idempotencyKey, idempotency_key: idempotencyKey,
emojis: [], emojis: [],

@ -144,11 +144,13 @@ export const invert = (rgb) => {
*/ */
export const hex2rgb = (hex) => { export const hex2rgb = (hex) => {
const result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex) const result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex)
return result ? { return result
? {
r: parseInt(result[1], 16), r: parseInt(result[1], 16),
g: parseInt(result[2], 16), g: parseInt(result[2], 16),
b: parseInt(result[3], 16) b: parseInt(result[3], 16)
} : null }
: null
} }
/** /**

@ -35,7 +35,7 @@ export const addPositionToWords = (words) => {
} }
export const splitByWhitespaceBoundary = (str) => { export const splitByWhitespaceBoundary = (str) => {
let result = [] const result = []
let currentWord = '' let currentWord = ''
for (let i = 0; i < str.length; i++) { for (let i = 0; i < str.length; i++) {
const currentChar = str[i] const currentChar = str[i]

@ -10,7 +10,7 @@ export const relativeTime = (date, nowThreshold = 1) => {
if (typeof date === 'string') date = Date.parse(date) if (typeof date === 'string') date = Date.parse(date)
const round = Date.now() > date ? Math.floor : Math.ceil const round = Date.now() > date ? Math.floor : Math.ceil
const d = Math.abs(Date.now() - date) const d = Math.abs(Date.now() - date)
let r = { num: round(d / YEAR), key: 'time.unit.years' } const r = { num: round(d / YEAR), key: 'time.unit.years' }
if (d < nowThreshold * SECOND) { if (d < nowThreshold * SECOND) {
r.num = 0 r.num = 0
r.key = 'time.now' r.key = 'time.now'

@ -371,8 +371,8 @@ export const parseStatus = (data) => {
export const parseNotification = (data) => { export const parseNotification = (data) => {
const mastoDict = { const mastoDict = {
'favourite': 'like', favourite: 'like',
'reblog': 'repeat' reblog: 'repeat'
} }
const masto = !data.hasOwnProperty('ntype') const masto = !data.hasOwnProperty('ntype')
const output = {} const output = {}

@ -1,7 +1,7 @@
const fileSizeFormat = (num) => { const fileSizeFormat = (num) => {
var exponent let exponent
var unit let unit
var units = ['B', 'KiB', 'MiB', 'GiB', 'TiB'] const units = ['B', 'KiB', 'MiB', 'GiB', 'TiB']
if (num < 1) { if (num < 1) {
return num + ' ' + units[0] return num + ' ' + units[0]
} }
@ -9,7 +9,7 @@ const fileSizeFormat = (num) => {
exponent = Math.min(Math.floor(Math.log(num) / Math.log(1024)), units.length - 1) exponent = Math.min(Math.floor(Math.log(num) / Math.log(1024)), units.length - 1)
num = (num / Math.pow(1024, exponent)).toFixed(2) * 1 num = (num / Math.pow(1024, exponent)).toFixed(2) * 1
unit = units[exponent] unit = units[exponent]
return { num: num, unit: unit } return { num, unit }
} }
const fileSizeFormatService = { const fileSizeFormatService = {
fileSizeFormat fileSizeFormat

@ -46,7 +46,7 @@ export const convertHtmlToLines = (html = '') => {
// All block-level elements that aren't empty elements, i.e. not <hr> // All block-level elements that aren't empty elements, i.e. not <hr>
const nonEmptyElements = new Set(visualLineElements) const nonEmptyElements = new Set(visualLineElements)
// Difference // Difference
for (let elem of emptyElements) { for (const elem of emptyElements) {
nonEmptyElements.delete(elem) nonEmptyElements.delete(elem)
} }
@ -56,7 +56,7 @@ export const convertHtmlToLines = (html = '') => {
...emptyElements.values() ...emptyElements.values()
]) ])
let buffer = [] // Current output buffer const buffer = [] // Current output buffer
const level = [] // How deep we are in tags and which tags were there const level = [] // How deep we are in tags and which tags were there
let textBuffer = '' // Current line content let textBuffer = '' // Current line content
let tagBuffer = null // Current tag buffer, if null = we are not currently reading a tag let tagBuffer = null // Current tag buffer, if null = we are not currently reading a tag

@ -50,7 +50,7 @@ export const processTextForEmoji = (text, emojis, processor) => {
if (char === ':') { if (char === ':') {
const next = text.slice(i + 1) const next = text.slice(i + 1)
let found = false let found = false
for (let emoji of emojis) { for (const emoji of emojis) {
if (next.slice(0, emoji.shortcode.length + 1) === (emoji.shortcode + ':')) { if (next.slice(0, emoji.shortcode.length + 1) === (emoji.shortcode + ':')) {
found = emoji found = emoji
break break

@ -3,9 +3,9 @@ import ISO6391 from 'iso-639-1'
import _ from 'lodash' import _ from 'lodash'
const specialLanguageCodes = { const specialLanguageCodes = {
'ja_easy': 'ja', ja_easy: 'ja',
'zh_Hant': 'zh-HANT', zh_Hant: 'zh-HANT',
'zh': 'zh-Hans' zh: 'zh-Hans'
} }
const internalToBrowserLocale = code => specialLanguageCodes[code] || code const internalToBrowserLocale = code => specialLanguageCodes[code] || code
@ -14,16 +14,16 @@ const internalToBackendLocale = code => internalToBrowserLocale(code).replace('_
const getLanguageName = (code) => { const getLanguageName = (code) => {
const specialLanguageNames = { const specialLanguageNames = {
'ja_easy': 'やさしいにほんご', ja_easy: 'やさしいにほんご',
'zh': '简体中文', zh: '简体中文',
'zh_Hant': '繁體中文' zh_Hant: '繁體中文'
} }
const languageName = specialLanguageNames[code] || ISO6391.getNativeName(code) const languageName = specialLanguageNames[code] || ISO6391.getNativeName(code)
const browserLocale = internalToBrowserLocale(code) const browserLocale = internalToBrowserLocale(code)
return languageName.charAt(0).toLocaleUpperCase(browserLocale) + languageName.slice(1) return languageName.charAt(0).toLocaleUpperCase(browserLocale) + languageName.slice(1)
} }
const languages = _.map(languagesObject.languages, (code) => ({ code: code, name: getLanguageName(code) })).sort((a, b) => a.name.localeCompare(b.name)) const languages = _.map(languagesObject.languages, (code) => ({ code, name: getLanguageName(code) })).sort((a, b) => a.name.localeCompare(b.name))
const localeService = { const localeService = {
internalToBrowserLocale, internalToBrowserLocale,

@ -1,6 +1,6 @@
import { reduce } from 'lodash' import { reduce } from 'lodash'
const MASTODON_PASSWORD_RESET_URL = `/auth/password` const MASTODON_PASSWORD_RESET_URL = '/auth/password'
const resetPassword = ({ instance, email }) => { const resetPassword = ({ instance, email }) => {
const params = { email } const params = { email }

@ -12,20 +12,20 @@ const fetchAndUpdate = ({ store, credentials, older = false, since }) => {
const timelineData = rootState.statuses.notifications const timelineData = rootState.statuses.notifications
const hideMutedPosts = getters.mergedConfig.hideMutedPosts const hideMutedPosts = getters.mergedConfig.hideMutedPosts
args['withMuted'] = !hideMutedPosts args.withMuted = !hideMutedPosts
args['timeline'] = 'notifications' args.timeline = 'notifications'
if (older) { if (older) {
if (timelineData.minId !== Number.POSITIVE_INFINITY) { if (timelineData.minId !== Number.POSITIVE_INFINITY) {
args['until'] = timelineData.minId args.until = timelineData.minId
} }
return fetchNotifications({ store, args, older }) return fetchNotifications({ store, args, older })
} else { } else {
// fetch new notifications // fetch new notifications
if (since === undefined && timelineData.maxId !== Number.POSITIVE_INFINITY) { if (since === undefined && timelineData.maxId !== Number.POSITIVE_INFINITY) {
args['since'] = timelineData.maxId args.since = timelineData.maxId
} else if (since !== null) { } else if (since !== null) {
args['since'] = since args.since = since
} }
const result = fetchNotifications({ store, args, older }) const result = fetchNotifications({ store, args, older })
@ -38,7 +38,7 @@ const fetchAndUpdate = ({ store, credentials, older = false, since }) => {
const readNotifsIds = notifications.filter(n => n.seen).map(n => n.id) const readNotifsIds = notifications.filter(n => n.seen).map(n => n.id)
const numUnseenNotifs = notifications.length - readNotifsIds.length const numUnseenNotifs = notifications.length - readNotifsIds.length
if (numUnseenNotifs > 0 && readNotifsIds.length > 0) { if (numUnseenNotifs > 0 && readNotifsIds.length > 0) {
args['since'] = Math.max(...readNotifsIds) args.since = Math.max(...readNotifsIds)
fetchNotifications({ store, args, older }) fetchNotifications({ store, args, older })
} }

@ -43,7 +43,7 @@ function deleteSubscriptionFromBackEnd (token) {
method: 'DELETE', method: 'DELETE',
headers: { headers: {
'Content-Type': 'application/json', 'Content-Type': 'application/json',
'Authorization': `Bearer ${token}` Authorization: `Bearer ${token}`
} }
}).then((response) => { }).then((response) => {
if (!response.ok) throw new Error('Bad status code from server.') if (!response.ok) throw new Error('Bad status code from server.')
@ -56,7 +56,7 @@ function sendSubscriptionToBackEnd (subscription, token, notificationVisibility)
method: 'POST', method: 'POST',
headers: { headers: {
'Content-Type': 'application/json', 'Content-Type': 'application/json',
'Authorization': `Bearer ${token}` Authorization: `Bearer ${token}`
}, },
body: JSON.stringify({ body: JSON.stringify({
subscription, subscription,

@ -39,7 +39,7 @@ import { LAYERS, DEFAULT_OPACITY, SLOT_INHERITANCE } from './pleromafe.js'
export const CURRENT_VERSION = 3 export const CURRENT_VERSION = 3
export const getLayersArray = (layer, data = LAYERS) => { export const getLayersArray = (layer, data = LAYERS) => {
let array = [layer] const array = [layer]
let parent = data[layer] let parent = data[layer]
while (parent) { while (parent) {
array.unshift(parent) array.unshift(parent)

@ -34,20 +34,20 @@ const fetchAndUpdate = ({
const loggedIn = !!rootState.users.currentUser const loggedIn = !!rootState.users.currentUser
if (older) { if (older) {
args['until'] = until || timelineData.minId args.until = until || timelineData.minId
} else { } else {
if (since === undefined) { if (since === undefined) {
args['since'] = timelineData.maxId args.since = timelineData.maxId
} else if (since !== null) { } else if (since !== null) {
args['since'] = since args.since = since
} }
} }
args['userId'] = userId args.userId = userId
args['tag'] = tag args.tag = tag
args['withMuted'] = !hideMutedPosts args.withMuted = !hideMutedPosts
if (loggedIn && ['friends', 'public', 'publicAndExternal'].includes(timeline)) { if (loggedIn && ['friends', 'public', 'publicAndExternal'].includes(timeline)) {
args['replyVisibility'] = replyVisibility args.replyVisibility = replyVisibility
} }
const numStatusesBeforeFetch = timelineData.statuses.length const numStatusesBeforeFetch = timelineData.statuses.length
@ -60,7 +60,7 @@ const fetchAndUpdate = ({
const { data: statuses, pagination } = response const { data: statuses, pagination } = response
if (!older && statuses.length >= 20 && !timelineData.loading && numStatusesBeforeFetch > 0) { if (!older && statuses.length >= 20 && !timelineData.loading && numStatusesBeforeFetch > 0) {
store.dispatch('queueFlush', { timeline: timeline, id: timelineData.maxId }) store.dispatch('queueFlush', { timeline, id: timelineData.maxId })
} }
update({ store, statuses, timeline, showImmediately, userId, pagination }) update({ store, statuses, timeline, showImmediately, userId, pagination })
return { statuses, pagination } return { statuses, pagination }

@ -36,7 +36,7 @@ const highlightStyle = (prefs) => {
'linear-gradient(to right,', 'linear-gradient(to right,',
`${solidColor} ,`, `${solidColor} ,`,
`${solidColor} 2px,`, `${solidColor} 2px,`,
`transparent 6px` 'transparent 6px'
].join(' '), ].join(' '),
backgroundPosition: '0 0', backgroundPosition: '0 0',
...customProps ...customProps

@ -57,8 +57,8 @@ self.addEventListener('notificationclick', (event) => {
event.notification.close() event.notification.close()
event.waitUntil(getWindowClients().then((list) => { event.waitUntil(getWindowClients().then((list) => {
for (var i = 0; i < list.length; i++) { for (let i = 0; i < list.length; i++) {
var client = list[i] const client = list[i]
if (client.url === '/' && 'focus' in client) { return client.focus() } if (client.url === '/' && 'focus' in client) { return client.focus() }
} }

@ -16,7 +16,7 @@ exports.assertion = function (selector, count) {
return res.value return res.value
} }
this.command = function (cb) { this.command = function (cb) {
var self = this const self = this
return this.api.execute(function (selector) { return this.api.execute(function (selector) {
return document.querySelectorAll(selector).length return document.querySelectorAll(selector).length
}, [selector], function (res) { }, [selector], function (res) {

@ -1,45 +1,45 @@
require('@babel/register') require('@babel/register')
var config = require('../../config') const config = require('../../config')
// http://nightwatchjs.org/guide#settings-file // http://nightwatchjs.org/guide#settings-file
module.exports = { module.exports = {
'src_folders': ['test/e2e/specs'], src_folders: ['test/e2e/specs'],
'output_folder': 'test/e2e/reports', output_folder: 'test/e2e/reports',
'custom_assertions_path': ['test/e2e/custom-assertions'], custom_assertions_path: ['test/e2e/custom-assertions'],
'selenium': { selenium: {
'start_process': true, start_process: true,
'server_path': 'node_modules/selenium-server/lib/runner/selenium-server-standalone-2.53.1.jar', server_path: 'node_modules/selenium-server/lib/runner/selenium-server-standalone-2.53.1.jar',
'host': '127.0.0.1', host: '127.0.0.1',
'port': 4444, port: 4444,
'cli_args': { cli_args: {
'webdriver.chrome.driver': require('chromedriver').path 'webdriver.chrome.driver': require('chromedriver').path
} }
}, },
'test_settings': { test_settings: {
'default': { default: {
'selenium_port': 4444, selenium_port: 4444,
'selenium_host': 'localhost', selenium_host: 'localhost',
'silent': true, silent: true,
'globals': { globals: {
'devServerURL': 'http://localhost:' + (process.env.PORT || config.dev.port) devServerURL: 'http://localhost:' + (process.env.PORT || config.dev.port)
} }
}, },
'chrome': { chrome: {
'desiredCapabilities': { desiredCapabilities: {
'browserName': 'chrome', browserName: 'chrome',
'javascriptEnabled': true, javascriptEnabled: true,
'acceptSslCerts': true acceptSslCerts: true
} }
}, },
'firefox': { firefox: {
'desiredCapabilities': { desiredCapabilities: {
'browserName': 'firefox', browserName: 'firefox',
'javascriptEnabled': true, javascriptEnabled: true,
'acceptSslCerts': true acceptSslCerts: true
} }
} }
} }

@ -1,6 +1,6 @@
// 1. start the dev server using production config // 1. start the dev server using production config
process.env.NODE_ENV = 'testing' process.env.NODE_ENV = 'testing'
var server = require('../../build/dev-server.js') const server = require('../../build/dev-server.js')
// 2. run the nightwatch test suite against it // 2. run the nightwatch test suite against it
// to run in additional browsers: // to run in additional browsers:
@ -9,7 +9,7 @@ var server = require('../../build/dev-server.js')
// or override the environment flag, for example: `npm run e2e -- --env chrome,firefox` // or override the environment flag, for example: `npm run e2e -- --env chrome,firefox`
// For more information on Nightwatch's config file, see // For more information on Nightwatch's config file, see
// http://nightwatchjs.org/guide#settings-file // http://nightwatchjs.org/guide#settings-file
var opts = process.argv.slice(2) let opts = process.argv.slice(2)
if (opts.indexOf('--config') === -1) { if (opts.indexOf('--config') === -1) {
opts = opts.concat(['--config', 'test/e2e/nightwatch.conf.js']) opts = opts.concat(['--config', 'test/e2e/nightwatch.conf.js'])
} }
@ -17,8 +17,8 @@ if (opts.indexOf('--env') === -1) {
opts = opts.concat(['--env', 'chrome']) opts = opts.concat(['--env', 'chrome'])
} }
var spawn = require('cross-spawn') const spawn = require('cross-spawn')
var runner = spawn('./node_modules/.bin/nightwatch', opts, { stdio: 'inherit' }) const runner = spawn('./node_modules/.bin/nightwatch', opts, { stdio: 'inherit' })
runner.on('exit', function (code) { runner.on('exit', function (code) {
server.close() server.close()

@ -4,14 +4,14 @@
// https://github.com/webpack/karma-webpack // https://github.com/webpack/karma-webpack
// var path = require('path') // var path = require('path')
var merge = require('webpack-merge') const merge = require('webpack-merge')
var HtmlWebpackPlugin = require('html-webpack-plugin') const HtmlWebpackPlugin = require('html-webpack-plugin')
var baseConfig = require('../../build/webpack.base.conf') const baseConfig = require('../../build/webpack.base.conf')
var utils = require('../../build/utils') const utils = require('../../build/utils')
var webpack = require('webpack') const webpack = require('webpack')
// var projectRoot = path.resolve(__dirname, '../../') // var projectRoot = path.resolve(__dirname, '../../')
var webpackConfig = merge(baseConfig, { const webpackConfig = merge(baseConfig, {
// use inline sourcemap for karma-sourcemap-loader // use inline sourcemap for karma-sourcemap-loader
module: { module: {
rules: utils.styleLoaders() rules: utils.styleLoaders()
@ -63,7 +63,7 @@ module.exports = function (config) {
frameworks: ['mocha', 'sinon-chai'], frameworks: ['mocha', 'sinon-chai'],
reporters: ['mocha'], reporters: ['mocha'],
customLaunchers: { customLaunchers: {
'FirefoxHeadless': { FirefoxHeadless: {
base: 'Firefox', base: 'Firefox',
flags: [ flags: [
'-headless' '-headless'

@ -29,7 +29,7 @@ const generateInput = (value, padEmoji = true) => {
modelValue: value modelValue: value
}, },
slots: { slots: {
'default': () => h('input', '') default: () => h('input', '')
} }
}) })
return wrapper return wrapper

@ -4,7 +4,7 @@ import RichContent from 'src/components/rich_content/rich_content.jsx'
const attentions = [] const attentions = []
const global = { const global = {
mocks: { mocks: {
'$store': { $store: {
state: {}, state: {},
getters: { getters: {
mergedConfig: () => ({ mergedConfig: () => ({

@ -163,7 +163,7 @@ const localProfileStore = createStore({
currentUser: { currentUser: {
credentials: '' credentials: ''
}, },
usersObject: { 100: localUser, 'testuser': localUser }, usersObject: { 100: localUser, testuser: localUser },
users: [localUser], users: [localUser],
relationships: {} relationships: {}
} }

@ -314,8 +314,8 @@ describe('API Entities normalizer', () => {
const linkHeader = '<https://example.com/api/v1/notifications?max_id=861676>; rel="next", <https://example.com/api/v1/notifications?min_id=861741>; rel="prev"' const linkHeader = '<https://example.com/api/v1/notifications?max_id=861676>; rel="next", <https://example.com/api/v1/notifications?min_id=861741>; rel="prev"'
const result = parseLinkHeaderPagination(linkHeader) const result = parseLinkHeaderPagination(linkHeader)
expect(result).to.eql({ expect(result).to.eql({
'maxId': 861676, maxId: 861676,
'minId': 861741 minId: 861741
}) })
}) })
@ -323,8 +323,8 @@ describe('API Entities normalizer', () => {
const linkHeader = '<http://example.com/api/v1/timelines/home?max_id=9waQx5IIS48qVue2Ai>; rel="next", <http://example.com/api/v1/timelines/home?min_id=9wi61nIPnfn674xgie>; rel="prev"' const linkHeader = '<http://example.com/api/v1/timelines/home?max_id=9waQx5IIS48qVue2Ai>; rel="next", <http://example.com/api/v1/timelines/home?min_id=9wi61nIPnfn674xgie>; rel="prev"'
const result = parseLinkHeaderPagination(linkHeader, { flakeId: true }) const result = parseLinkHeaderPagination(linkHeader, { flakeId: true })
expect(result).to.eql({ expect(result).to.eql({
'maxId': '9waQx5IIS48qVue2Ai', maxId: '9waQx5IIS48qVue2Ai',
'minId': '9wi61nIPnfn674xgie' minId: '9wi61nIPnfn674xgie'
}) })
}) })
}) })

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save