Merge pull request 'Cleanup issues found by SonarQube' (#3527) from sonarqube-cleanup into develop
Reviewed-on: https://git.pleroma.social/pleroma/pleroma-fe/pulls/3527
This commit is contained in:
commit
4f82709bf2
66 changed files with 275 additions and 343 deletions
|
|
@ -1,41 +0,0 @@
|
|||
import chalk from 'chalk'
|
||||
import semver from 'semver'
|
||||
|
||||
import packageConfig from '../package.json' with { type: 'json' }
|
||||
|
||||
var versionRequirements = [
|
||||
{
|
||||
name: 'node',
|
||||
currentVersion: semver.clean(process.version),
|
||||
versionRequirement: packageConfig.engines.node,
|
||||
},
|
||||
]
|
||||
|
||||
export default function () {
|
||||
const warnings = []
|
||||
for (let i = 0; i < versionRequirements.length; i++) {
|
||||
const mod = versionRequirements[i]
|
||||
if (!semver.satisfies(mod.currentVersion, mod.versionRequirement)) {
|
||||
warnings.push(
|
||||
mod.name +
|
||||
': ' +
|
||||
chalk.red(mod.currentVersion) +
|
||||
' should be ' +
|
||||
chalk.green(mod.versionRequirement),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
if (warnings.length) {
|
||||
console.warn(
|
||||
chalk.yellow(
|
||||
'\nTo use this template, you must update following to modules:\n',
|
||||
),
|
||||
)
|
||||
for (let i = 0; i < warnings.length; i++) {
|
||||
const warning = warnings[i]
|
||||
console.warn(' ' + warning)
|
||||
}
|
||||
process.exit(1)
|
||||
}
|
||||
}
|
||||
|
|
@ -1,8 +1,8 @@
|
|||
import childProcess from 'child_process'
|
||||
import childProcess from 'node:child_process'
|
||||
|
||||
export const getCommitHash = () => {
|
||||
const subst = '$Format:%h$'
|
||||
if (!subst.match(/Format:/)) {
|
||||
if (!/Format:/.exec(subst)) {
|
||||
return subst
|
||||
} else {
|
||||
try {
|
||||
|
|
|
|||
|
|
@ -31,7 +31,6 @@ export const buildSwPlugin = ({ swSrc, swDest }) => {
|
|||
name: 'build-sw-plugin',
|
||||
enforce: 'post',
|
||||
configResolved(resolvedConfig) {
|
||||
resolvedConfig
|
||||
config = {
|
||||
define: resolvedConfig.define,
|
||||
resolve: resolvedConfig.resolve,
|
||||
|
|
@ -60,7 +59,7 @@ export const buildSwPlugin = ({ swSrc, swDest }) => {
|
|||
sequential: true,
|
||||
async handler(_, bundle) {
|
||||
const assets = Object.keys(bundle)
|
||||
.filter((name) => !/\.map$/.test(name))
|
||||
.filter((name) => !name.endsWith('.map'))
|
||||
.map((name) => '/' + name)
|
||||
|
||||
config.plugins.push({
|
||||
|
|
|
|||
|
|
@ -1,10 +1,10 @@
|
|||
import fs from 'node:fs'
|
||||
import emojis from '@kazvmoe-infra/unicode-emoji-json/data-by-group.json' with {
|
||||
type: 'json',
|
||||
}
|
||||
import fs from 'fs'
|
||||
|
||||
Object.keys(emojis).map((k) => {
|
||||
emojis[k].map((e) => {
|
||||
emojis[k].forEach((e) => {
|
||||
delete e.unicode_version
|
||||
delete e.emoji_version
|
||||
delete e.skin_tone_support_unicode_version
|
||||
|
|
@ -12,11 +12,15 @@ Object.keys(emojis).map((k) => {
|
|||
})
|
||||
|
||||
const res = {}
|
||||
Object.keys(emojis).map((k) => {
|
||||
const groupId = k.replace('&', 'and').replace(/ /g, '-').toLowerCase()
|
||||
Object.keys(emojis).forEach((k) => {
|
||||
const groupId = k.replace('&', 'and').replaceAll(' ', '-').toLowerCase()
|
||||
res[groupId] = emojis[k]
|
||||
})
|
||||
|
||||
console.info('Updating emojis...')
|
||||
fs.writeFileSync('src/assets/emoji.json', JSON.stringify(res))
|
||||
console.info('Done.')
|
||||
try {
|
||||
fs.writeFileSync('src/assets/emoji.json', JSON.stringify(res))
|
||||
console.info('Done.')
|
||||
} catch (e) {
|
||||
console.error('Failed updating emoji', e)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,15 +1,19 @@
|
|||
FROM mcr.microsoft.com/playwright:v1.61.0-jammy
|
||||
|
||||
RUN npm install -g yarn@1.22.22
|
||||
|
||||
RUN adduser --system playwright --group --shell=/bin/bash
|
||||
|
||||
USER playwright
|
||||
|
||||
WORKDIR /app
|
||||
|
||||
ENV PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD=1
|
||||
|
||||
RUN npm install -g yarn@1.22.22
|
||||
|
||||
COPY package.json yarn.lock ./
|
||||
RUN yarn --frozen-lockfile
|
||||
|
||||
COPY . .
|
||||
COPY --chown=playwright ./build ./src ./test ./public ./static ./yarn.lock ./package.json .
|
||||
|
||||
ENV CI=1
|
||||
|
||||
|
|
|
|||
|
|
@ -31,7 +31,7 @@
|
|||
<div class="chunk" id="chunk-E">
|
||||
</div>
|
||||
</div>
|
||||
<img id="mascot" src="/static/pleromatan_apology_small.webp">
|
||||
<img id="mascot" alt="A cute mascot" src="/static/pleromatan_apology_small.webp">
|
||||
</div>
|
||||
<div id="status" class="css-ok">
|
||||
<!-- (。>﹏<) -->
|
||||
|
|
|
|||
|
|
@ -6,4 +6,4 @@
|
|||
Pleroma install containing the real ToS for your instance.</p>
|
||||
<p>See the <a href='https://docs.pleroma.social/backend/configuration/static_dir/'>Pleroma documentation</a> for more information.</p>
|
||||
<br>
|
||||
<img src="/static/logo.svg" style="display: block; margin: auto; max-width: 100%; height: 50px; object-fit: contain;" />
|
||||
<img src="/static/logo.svg" alt="Pleroma Logo" style="display: block; margin: auto; max-width: 100%; height: 50px; object-fit: contain;" />
|
||||
|
|
|
|||
|
|
@ -1,10 +1,11 @@
|
|||
// stylelint-disable rscss/class-format
|
||||
/* stylelint-disable no-descending-specificity */
|
||||
@use "panel";
|
||||
|
||||
@import '@fortawesome/fontawesome-svg-core/styles.css';
|
||||
@import '@kazvmoe-infra/pinch-zoom-element/dist/pinch-zoom.css';
|
||||
|
||||
// stylelint-disable rscss/class-format
|
||||
/* stylelint-disable no-descending-specificity */
|
||||
|
||||
:root {
|
||||
--status-margin: 0.75em;
|
||||
--post-line-height: 1.4;
|
||||
|
|
@ -934,7 +935,6 @@ option {
|
|||
|
||||
#splash {
|
||||
pointer-events: none;
|
||||
// transition: opacity 0.5s;
|
||||
|
||||
#status {
|
||||
&.css-ok {
|
||||
|
|
|
|||
|
|
@ -39,7 +39,7 @@ const USERS_URL_LIST = ({
|
|||
isAdmin && 'is_admin',
|
||||
isModerator && 'is_moderator',
|
||||
]
|
||||
.filter((x) => x)
|
||||
.filter(Boolean)
|
||||
.join(',')
|
||||
return `/api/v1/pleroma/admin/users?page=${page}&page_size=${pageSize}&filters=${filters_str}&query=${query}&name=${name}&email=${email}`
|
||||
}
|
||||
|
|
@ -236,7 +236,7 @@ export const changeStatusScope = ({
|
|||
opts: { id, sensitive, visibility },
|
||||
credentials,
|
||||
}) => {
|
||||
var payload = {}
|
||||
const payload = {}
|
||||
if (typeof sensitive !== 'undefined') {
|
||||
payload['sensitive'] = sensitive
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,12 +6,12 @@ export const paramsString = (params = {}) => {
|
|||
if (params == null || params === undefined) return ''
|
||||
|
||||
if (typeof params !== 'object' || Array.isArray(params)) {
|
||||
throw new Error('Params are not an object!')
|
||||
throw new TypeError('Params are not an object!')
|
||||
}
|
||||
|
||||
const entries = (() => {
|
||||
if (params instanceof Map) {
|
||||
return params.entries()
|
||||
return [...params.entries()]
|
||||
} else {
|
||||
return Object.entries(params)
|
||||
}
|
||||
|
|
@ -26,7 +26,7 @@ export const paramsString = (params = {}) => {
|
|||
(typeof v === 'object' && !Array.isArray(v)) ||
|
||||
typeof v === 'function'
|
||||
) {
|
||||
throw new Error('Param cannot be non-primitive!')
|
||||
throw new TypeError('Param cannot be non-primitive!')
|
||||
}
|
||||
if (Array.isArray(v)) {
|
||||
arrays.push([k, v])
|
||||
|
|
@ -42,7 +42,7 @@ export const paramsString = (params = {}) => {
|
|||
typeof v === 'function' ||
|
||||
typeof v === 'undefined'
|
||||
)
|
||||
throw new Error('Array param cannot contain non-primitives!')
|
||||
throw new TypeError('Array param cannot contain non-primitives!')
|
||||
})
|
||||
})
|
||||
|
||||
|
|
@ -109,7 +109,9 @@ export const promisedRequest = async ({
|
|||
.get('content-type')
|
||||
.split(';')
|
||||
.map((x) => x.toLowerCase().trim())
|
||||
const contentLength = parseInt(response.headers.get('content-length'))
|
||||
const contentLength = Number.parseInt(
|
||||
response.headers.get('content-length'),
|
||||
)
|
||||
if (contentLength === 0) return null
|
||||
|
||||
switch (contentType) {
|
||||
|
|
|
|||
|
|
@ -105,7 +105,7 @@ export const fetchUserByName = ({ name, credentials }) =>
|
|||
})
|
||||
.then(({ data }) => data.id)
|
||||
.catch((error) => {
|
||||
if (error && error.statusCode === 404) {
|
||||
if (error?.statusCode === 404) {
|
||||
// Either the backend does not support lookup endpoint,
|
||||
// or there is no user with such name. Fallback and treat name as id.
|
||||
return name
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import { concat, last } from 'lodash'
|
||||
import { last } from 'lodash'
|
||||
|
||||
import { paramsString, promisedRequest } from './helpers.js'
|
||||
import { fetchFriends, MASTODON_STATUS_URL } from './public.js'
|
||||
|
|
@ -220,7 +220,7 @@ export const postStatus = ({
|
|||
})
|
||||
if (pollOptions.some((option) => option !== '')) {
|
||||
const normalizedPoll = {
|
||||
expires_in: parseInt(poll.expiresIn, 10),
|
||||
expires_in: Number.parseInt(poll.expiresIn, 10),
|
||||
multiple: poll.multiple,
|
||||
}
|
||||
Object.keys(normalizedPoll).forEach((key) => {
|
||||
|
|
@ -278,7 +278,7 @@ export const editStatus = ({
|
|||
|
||||
if (pollOptions.some((option) => option !== '')) {
|
||||
const normalizedPoll = {
|
||||
expires_in: parseInt(poll.expiresIn, 10),
|
||||
expires_in: Number.parseInt(poll.expiresIn, 10),
|
||||
multiple: poll.multiple,
|
||||
}
|
||||
Object.keys(normalizedPoll).forEach((key) => {
|
||||
|
|
@ -412,7 +412,7 @@ export const exportFriends = ({ id, credentials }) => {
|
|||
credentials,
|
||||
withRelationships: true,
|
||||
})
|
||||
friends = concat(friends, users)
|
||||
friends = [...friends, ...users]
|
||||
if (users.length === 0) {
|
||||
more = false
|
||||
}
|
||||
|
|
@ -613,7 +613,7 @@ export const listAliases = ({ credentials }) =>
|
|||
method: 'GET',
|
||||
credentials,
|
||||
params: {
|
||||
_cacheBooster: new Date().getTime(),
|
||||
_cacheBooster: Date.now(),
|
||||
},
|
||||
})
|
||||
|
||||
|
|
@ -799,7 +799,7 @@ export const listBackups = ({ credentials }) =>
|
|||
method: 'GET',
|
||||
credentials,
|
||||
params: {
|
||||
_cacheBooster: new Date().getTime(),
|
||||
_cacheBooster: Date.now(),
|
||||
},
|
||||
})
|
||||
|
||||
|
|
|
|||
|
|
@ -141,13 +141,11 @@ export const handleMastoWS = (
|
|||
if (data.result === 'success') {
|
||||
console.debug('[WS] Successfully authenticated')
|
||||
onAuthenticated()
|
||||
} else if (data.error === 'already_authenticated') {
|
||||
onAuthenticated()
|
||||
} else {
|
||||
if (data.error === 'already_authenticated') {
|
||||
onAuthenticated()
|
||||
} else {
|
||||
console.error('[WS] Unable to authenticate:', data.error)
|
||||
wsEvent.target.close()
|
||||
}
|
||||
console.error('[WS] Unable to authenticate:', data.error)
|
||||
wsEvent.target.close()
|
||||
}
|
||||
}
|
||||
return null
|
||||
|
|
|
|||
|
|
@ -63,14 +63,14 @@ const parsedInitialResults = () => {
|
|||
|
||||
const decodeUTF8Base64 = (data) => {
|
||||
const rawData = atob(data)
|
||||
const array = Uint8Array.from([...rawData].map((char) => char.charCodeAt(0)))
|
||||
const array = Uint8Array.from([...rawData].map((char) => char.codePointAt(0)))
|
||||
const text = new TextDecoder().decode(array)
|
||||
return text
|
||||
}
|
||||
|
||||
const preloadFetch = async (request) => {
|
||||
const data = parsedInitialResults()
|
||||
if (!data || !data[request]) {
|
||||
if (!data?.[request]) {
|
||||
return window.fetch(request)
|
||||
}
|
||||
const decoded = decodeUTF8Base64(data[request])
|
||||
|
|
@ -170,9 +170,9 @@ const setSettings = async ({ apiConfig, staticConfig, store }) => {
|
|||
let config = {}
|
||||
if (overrides.staticConfigPreference && env === 'development') {
|
||||
console.warn('OVERRIDING API CONFIG WITH STATIC CONFIG')
|
||||
config = Object.assign({}, apiConfig, staticConfig)
|
||||
config = { ...apiConfig, ...staticConfig }
|
||||
} else {
|
||||
config = Object.assign({}, staticConfig, apiConfig)
|
||||
config = { ...staticConfig, ...apiConfig }
|
||||
}
|
||||
|
||||
Object.keys(INSTANCE_IDENTITY_DEFAULT_DEFINITIONS).forEach((source) => {
|
||||
|
|
@ -353,19 +353,19 @@ const getNodeInfo = async ({ store }) => {
|
|||
const uploadLimits = metadata.uploadLimits
|
||||
useInstanceStore().set({
|
||||
path: 'limits.uploadlimit',
|
||||
value: parseInt(uploadLimits.general),
|
||||
value: Number.parseInt(uploadLimits.general),
|
||||
})
|
||||
useInstanceStore().set({
|
||||
path: 'limits.avatarlimit',
|
||||
value: parseInt(uploadLimits.avatar),
|
||||
value: Number.parseInt(uploadLimits.avatar),
|
||||
})
|
||||
useInstanceStore().set({
|
||||
path: 'limits.backgroundlimit',
|
||||
value: parseInt(uploadLimits.background),
|
||||
value: Number.parseInt(uploadLimits.background),
|
||||
})
|
||||
useInstanceStore().set({
|
||||
path: 'limits.bannerlimit',
|
||||
value: parseInt(uploadLimits.banner),
|
||||
value: Number.parseInt(uploadLimits.banner),
|
||||
})
|
||||
useInstanceStore().set({
|
||||
path: 'limits.fieldsLimits',
|
||||
|
|
@ -409,7 +409,7 @@ const getNodeInfo = async ({ store }) => {
|
|||
|
||||
useInstanceCapabilitiesStore().set(
|
||||
'tagPolicyAvailable',
|
||||
typeof federation.mrf_policies === 'undefined'
|
||||
federation.mrf_policies === undefined
|
||||
? false
|
||||
: metadata.federation.mrf_policies.includes('TagPolicy'),
|
||||
)
|
||||
|
|
@ -420,8 +420,7 @@ const getNodeInfo = async ({ store }) => {
|
|||
})
|
||||
useInstanceStore().set({
|
||||
path: 'federating',
|
||||
value:
|
||||
typeof federation.enabled === 'undefined' ? true : federation.enabled,
|
||||
value: federation.enabled === undefined ? true : federation.enabled,
|
||||
})
|
||||
|
||||
const accountActivationRequired = metadata.accountActivationRequired
|
||||
|
|
@ -443,7 +442,7 @@ const getNodeInfo = async ({ store }) => {
|
|||
const setConfig = async ({ store }) => {
|
||||
// apiConfig, staticConfig
|
||||
const configInfos = await Promise.all([
|
||||
getBackendProvidedConfig({ store }),
|
||||
getBackendProvidedConfig(),
|
||||
getStaticConfig(),
|
||||
])
|
||||
const apiConfig = configInfos[0]
|
||||
|
|
@ -457,7 +456,7 @@ const checkOAuthToken = async ({ store }) => {
|
|||
if (oauth.userToken) {
|
||||
return store.dispatch('loginUser', oauth.userToken)
|
||||
}
|
||||
return Promise.resolve()
|
||||
return
|
||||
}
|
||||
|
||||
const afterStoreSetup = async ({ pinia, store, storageError, i18n }) => {
|
||||
|
|
@ -485,7 +484,7 @@ const afterStoreSetup = async ({ pinia, store, storageError, i18n }) => {
|
|||
if (process.env.NODE_ENV === 'development') {
|
||||
// do some checks to avoid common errors
|
||||
if (!Object.keys(allStores).length) {
|
||||
throw new Error(
|
||||
throw new TypeError(
|
||||
'No stores are available. Check the code in src/boot/after_store.js',
|
||||
)
|
||||
}
|
||||
|
|
@ -495,7 +494,7 @@ const afterStoreSetup = async ({ pinia, store, storageError, i18n }) => {
|
|||
const isStoreName = (name) => name.startsWith('use')
|
||||
if (process.env.NODE_ENV === 'development') {
|
||||
if (Object.keys(mod).filter(isStoreName).length !== 1) {
|
||||
throw new Error(
|
||||
throw new TypeError(
|
||||
'Each store file must export exactly one store as a named export. Check your code in src/stores/',
|
||||
)
|
||||
}
|
||||
|
|
@ -504,13 +503,13 @@ const afterStoreSetup = async ({ pinia, store, storageError, i18n }) => {
|
|||
if (storeFuncName && typeof mod[storeFuncName] === 'function') {
|
||||
const p = mod[storeFuncName]().$persistLoaded
|
||||
if (!(p instanceof Promise)) {
|
||||
throw new Error(
|
||||
throw new TypeError(
|
||||
`${name} store's $persistLoaded is not a Promise. The persist plugin is not applied.`,
|
||||
)
|
||||
}
|
||||
await p
|
||||
} else {
|
||||
throw new Error(
|
||||
throw new TypeError(
|
||||
`Store module ${name} does not export a 'use...' function`,
|
||||
)
|
||||
}
|
||||
|
|
@ -518,14 +517,15 @@ const afterStoreSetup = async ({ pinia, store, storageError, i18n }) => {
|
|||
)
|
||||
}
|
||||
|
||||
let newStorageError
|
||||
try {
|
||||
await waitForAllStoresToLoad()
|
||||
} catch (e) {
|
||||
console.error('Cannot load stores:', e)
|
||||
storageError = e
|
||||
newStorageError = e
|
||||
}
|
||||
|
||||
if (storageError) {
|
||||
if (storageError || newStorageError) {
|
||||
useInterfaceStore().pushGlobalNotice({
|
||||
messageKey: 'errors.storage_unavailable',
|
||||
level: 'error',
|
||||
|
|
@ -547,9 +547,7 @@ const afterStoreSetup = async ({ pinia, store, storageError, i18n }) => {
|
|||
|
||||
const overrides = window.___pleromafe_dev_overrides || {}
|
||||
const server =
|
||||
typeof overrides.target !== 'undefined'
|
||||
? overrides.target
|
||||
: window.location.origin
|
||||
overrides.target !== undefined ? overrides.target : window.location.origin
|
||||
useInstanceStore().set({ path: 'server', value: server })
|
||||
|
||||
await setConfig({ store })
|
||||
|
|
@ -561,7 +559,7 @@ const afterStoreSetup = async ({ pinia, store, storageError, i18n }) => {
|
|||
})
|
||||
} catch (e) {
|
||||
window.splashError(e)
|
||||
return Promise.reject(e)
|
||||
throw e
|
||||
}
|
||||
|
||||
applyStyleConfig(useMergedConfigStore().mergedConfig, i18n.global)
|
||||
|
|
@ -573,7 +571,7 @@ const afterStoreSetup = async ({ pinia, store, storageError, i18n }) => {
|
|||
getInstancePanel({ store }),
|
||||
getNodeInfo({ store }),
|
||||
getInstanceConfig({ store }),
|
||||
]).catch((e) => Promise.reject(e))
|
||||
])
|
||||
|
||||
getTOS({ store })
|
||||
getStickers({ store })
|
||||
|
|
@ -583,7 +581,7 @@ const afterStoreSetup = async ({ pinia, store, storageError, i18n }) => {
|
|||
routes: routes(store),
|
||||
scrollBehavior: (to, _from, savedPosition) => {
|
||||
if (to.matched.some((m) => m.meta.dontScroll)) {
|
||||
return false
|
||||
return {}
|
||||
}
|
||||
return savedPosition || { left: 0, top: 0 }
|
||||
},
|
||||
|
|
|
|||
|
|
@ -39,7 +39,7 @@ const ChatListItem = {
|
|||
messageForStatusContent() {
|
||||
const message = this.chat.lastMessage
|
||||
const messageEmojis = message ? message.emojis : []
|
||||
const isYou = message && message.account_id === this.currentUser.id
|
||||
const isYou = message?.account_id === this.currentUser.id
|
||||
const content = message ? this.attachmentInfo || message.content : ''
|
||||
const messagePreview = isYou
|
||||
? `<i>${this.$t('chats.you')}</i> ${content}`
|
||||
|
|
|
|||
|
|
@ -111,7 +111,7 @@ const ChatMessage = {
|
|||
const user = this.$store.getters.findUser(
|
||||
this.message.in_reply_to_user_id,
|
||||
)
|
||||
return user && user.screen_name_ui
|
||||
return user?.screen_name_ui
|
||||
}
|
||||
},
|
||||
replyProfileLink() {
|
||||
|
|
|
|||
|
|
@ -53,7 +53,7 @@
|
|||
:user-screen-name="message.in_reply_to_screen_name"
|
||||
/>
|
||||
<!-- v-if is there because status might not be loaded yet -->
|
||||
<template v-if="customReplyTo && customReplyTo.text.trim().length > 0">
|
||||
<template v-if="customReplyTo?.text.trim().length > 0">
|
||||
:
|
||||
<StatusBody
|
||||
class="reply-body faint"
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@
|
|||
<RichContent
|
||||
v-if="user"
|
||||
class="username"
|
||||
:title="'@'+(user && user.screen_name_ui)"
|
||||
:title="'@'+(user?.screen_name_ui)"
|
||||
:html="htmlTitle"
|
||||
:emoji="user.emoji || []"
|
||||
:allow-non-square-emoji="allowNonSquareEmoji"
|
||||
|
|
|
|||
|
|
@ -134,7 +134,7 @@ export default {
|
|||
emits: ['update:modelValue'],
|
||||
computed: {
|
||||
present() {
|
||||
return typeof this.modelValue !== 'undefined'
|
||||
return this.modelValue !== undefined
|
||||
},
|
||||
validColor() {
|
||||
return hex2rgb(this.modelValue || this.fallback)
|
||||
|
|
|
|||
|
|
@ -73,17 +73,15 @@ export default {
|
|||
}
|
||||
},
|
||||
logoBgStyle() {
|
||||
return Object.assign(
|
||||
{
|
||||
margin: `${this.logoMargin} 0`,
|
||||
opacity: this.searchBarHidden ? 1 : 0,
|
||||
},
|
||||
this.enableMask
|
||||
? {}
|
||||
: {
|
||||
'background-color': this.enableMask ? '' : 'transparent',
|
||||
},
|
||||
)
|
||||
const mask = this.enableMask
|
||||
? {}
|
||||
: { 'background-color': this.enableMask ? '' : 'transparent' }
|
||||
|
||||
return {
|
||||
margin: `${this.logoMargin} 0`,
|
||||
opacity: this.searchBarHidden ? 1 : 0,
|
||||
...mask,
|
||||
}
|
||||
},
|
||||
...mapState(useInstanceStore, ['privateMode']),
|
||||
...mapState(useInstanceStore, {
|
||||
|
|
|
|||
|
|
@ -50,7 +50,7 @@
|
|||
/>
|
||||
</button>
|
||||
<button
|
||||
v-if="currentUser && currentUser.role === 'admin'"
|
||||
v-if="currentUser?.role === 'admin'"
|
||||
class="button-unstyled nav-icon"
|
||||
target="_blank"
|
||||
:title="$t('nav.administration')"
|
||||
|
|
|
|||
|
|
@ -29,7 +29,7 @@ const FollowRequestCard = {
|
|||
notif.from_profile.id === this.user.id &&
|
||||
notif.type === 'follow_request',
|
||||
)
|
||||
return notif && notif.id
|
||||
return notif?.id
|
||||
},
|
||||
showApproveConfirmDialog() {
|
||||
this.showingApproveConfirmDialog = true
|
||||
|
|
|
|||
|
|
@ -42,7 +42,7 @@ export default {
|
|||
emits: ['update:modelValue'],
|
||||
computed: {
|
||||
present() {
|
||||
return typeof this.modelValue !== 'undefined'
|
||||
return this.modelValue !== undefined
|
||||
},
|
||||
},
|
||||
}
|
||||
|
|
|
|||
|
|
@ -89,7 +89,7 @@ export default {
|
|||
this.error = false
|
||||
|
||||
const notice = this.noticeRegex.exec(value)
|
||||
if (notice && notice.length === 4) {
|
||||
if (notice?.length === 4) {
|
||||
this.$emit('update:id', notice[3])
|
||||
} else if (value) {
|
||||
this.loading = true
|
||||
|
|
@ -102,7 +102,7 @@ export default {
|
|||
type: 'statuses',
|
||||
})
|
||||
.then((data) => {
|
||||
if (data && data.statuses && data.statuses.length === 1) {
|
||||
if (data?.statuses && data.statuses.length === 1) {
|
||||
this.$emit('update:id', data.statuses[0].id)
|
||||
} else {
|
||||
this.handleError(true)
|
||||
|
|
|
|||
|
|
@ -68,7 +68,7 @@ export default {
|
|||
emits: ['update:modelValue'],
|
||||
computed: {
|
||||
present() {
|
||||
return typeof this.modelValue !== 'undefined'
|
||||
return this.modelValue !== undefined
|
||||
},
|
||||
},
|
||||
}
|
||||
|
|
|
|||
|
|
@ -335,7 +335,7 @@ export default {
|
|||
this.pauseMfm ? '-pause' : '',
|
||||
this.scaleMfm ? '-scale' : '',
|
||||
]
|
||||
.filter((x) => x)
|
||||
.filter(Boolean)
|
||||
.join(' ')
|
||||
newAttrs['data-mfm-operator'] = mfmOperator
|
||||
switch (mfmOperator) {
|
||||
|
|
|
|||
|
|
@ -42,7 +42,7 @@ export default {
|
|||
emits: ['update:modelValue'],
|
||||
computed: {
|
||||
present() {
|
||||
return typeof this.modelValue !== 'undefined'
|
||||
return this.modelValue !== undefined
|
||||
},
|
||||
},
|
||||
}
|
||||
|
|
|
|||
|
|
@ -374,7 +374,7 @@
|
|||
class="emoji-list setting-list"
|
||||
>
|
||||
<EmojiEditingPopover
|
||||
v-if="pack && pack.remote === undefined"
|
||||
v-if="pack?.remote === undefined"
|
||||
class="emoji-item"
|
||||
placement="bottom"
|
||||
new-upload
|
||||
|
|
|
|||
|
|
@ -29,7 +29,7 @@ export default {
|
|||
...Setting.methods,
|
||||
getValue(e) {
|
||||
if (!this.truncate === 1) {
|
||||
return parseInt(e.target.value)
|
||||
return Number.parseInt(e.target.value)
|
||||
} else if (this.truncate > 1) {
|
||||
return Math.trunc(e.target.value / this.truncate) * this.truncate
|
||||
}
|
||||
|
|
|
|||
|
|
@ -159,7 +159,7 @@ export default {
|
|||
return this.source || this.defaultSource
|
||||
},
|
||||
realDraftMode() {
|
||||
return typeof this.draftMode === 'undefined'
|
||||
return this.draftMode === undefined
|
||||
? this.defaultDraftMode
|
||||
: this.draftMode
|
||||
},
|
||||
|
|
|
|||
|
|
@ -47,7 +47,7 @@ export default {
|
|||
// In case of controlled component
|
||||
if (this.activeTab) {
|
||||
return this.slots().findIndex(
|
||||
(slot) => slot && slot.props && this.activeTab === slot.props.key,
|
||||
(slot) => slot?.props && this.activeTab === slot.props.key,
|
||||
)
|
||||
} else {
|
||||
return this.active
|
||||
|
|
|
|||
|
|
@ -236,7 +236,7 @@ const AppearanceTab = {
|
|||
},
|
||||
stylePalettes() {
|
||||
const ruleset = useInterfaceStore().styleDataUsed || []
|
||||
if (!ruleset && ruleset.length === 0) return
|
||||
if (!ruleset?.length === 0) return
|
||||
const meta = ruleset.find((x) => x.component === '@meta')
|
||||
const result = ruleset
|
||||
.filter((x) => x.component.startsWith('@palette'))
|
||||
|
|
@ -401,7 +401,7 @@ const AppearanceTab = {
|
|||
}
|
||||
|
||||
theme3 = init({
|
||||
inputRuleset: [...input, paletteRule].filter((x) => x),
|
||||
inputRuleset: [...input, paletteRule].filter(Boolean),
|
||||
ultimateBackgroundColor: '#000000',
|
||||
liteMode: true,
|
||||
onlyNormalState: true,
|
||||
|
|
|
|||
|
|
@ -95,7 +95,7 @@ const DataImportExportTab = {
|
|||
return users
|
||||
.map((user) => {
|
||||
// check is it's a local user
|
||||
if (user && user.is_local) {
|
||||
if (user?.is_local) {
|
||||
// append the instance address
|
||||
return user.screen_name + '@' + location.hostname
|
||||
}
|
||||
|
|
|
|||
|
|
@ -81,7 +81,7 @@ const MutesAndBlocks = {
|
|||
return users
|
||||
.map((user) => {
|
||||
// check is it's a local user
|
||||
if (user && user.is_local) {
|
||||
if (user?.is_local) {
|
||||
// append the instance address
|
||||
return user.screen_name + '@' + location.hostname
|
||||
}
|
||||
|
|
|
|||
|
|
@ -147,7 +147,7 @@ export default {
|
|||
})
|
||||
},
|
||||
mounted() {
|
||||
if (typeof this.shadowSelected === 'undefined') {
|
||||
if (this.shadowSelected === undefined) {
|
||||
this.shadowSelected = this.shadowsAvailable[0]
|
||||
}
|
||||
},
|
||||
|
|
@ -633,17 +633,11 @@ export default {
|
|||
if (version === 0) {
|
||||
if (input.version) version = input.version
|
||||
// Old v1 naming: fg is text, btn is foreground
|
||||
if (
|
||||
typeof colors.text === 'undefined' &&
|
||||
typeof colors.fg !== 'undefined'
|
||||
) {
|
||||
if (colors.text === undefined && colors.fg !== undefined) {
|
||||
version = 1
|
||||
}
|
||||
// New v2 naming: text is text, fg is foreground
|
||||
if (
|
||||
typeof colors.text !== 'undefined' &&
|
||||
typeof colors.fg !== 'undefined'
|
||||
) {
|
||||
if (colors.text !== undefined && colors.fg !== undefined) {
|
||||
version = 2
|
||||
}
|
||||
}
|
||||
|
|
@ -679,7 +673,7 @@ export default {
|
|||
if (opacity && !this.keepOpacity) {
|
||||
this.clearOpacity()
|
||||
Object.entries(opacity).forEach(([k, v]) => {
|
||||
if (typeof v === 'undefined' || v === null || Number.isNaN(v)) return
|
||||
if (v === undefined || v === null || Number.isNaN(v)) return
|
||||
this[k + 'OpacityLocal'] = v
|
||||
})
|
||||
}
|
||||
|
|
|
|||
|
|
@ -602,7 +602,7 @@ export default {
|
|||
.map((x) => Object.entries(x.directives))
|
||||
.flat()
|
||||
})
|
||||
.filter((x) => x)
|
||||
.filter(Boolean)
|
||||
.flat()
|
||||
.map(([name, value]) => {
|
||||
const [valType, valVal] = value.split('|')
|
||||
|
|
|
|||
|
|
@ -220,7 +220,7 @@
|
|||
</router-link>
|
||||
</li>
|
||||
<li
|
||||
v-if="currentUser && currentUser.role === 'admin'"
|
||||
v-if="currentUser?.role === 'admin'"
|
||||
@click="toggleDrawer"
|
||||
>
|
||||
<button
|
||||
|
|
|
|||
|
|
@ -316,11 +316,11 @@ const Status = {
|
|||
return (
|
||||
(status.muted && !status.thread_muted) ||
|
||||
// Reprööt of a muted post according to BE
|
||||
(reblog && reblog.muted && !reblog.thread_muted) ||
|
||||
(reblog?.muted && !reblog.thread_muted) ||
|
||||
// Muted user
|
||||
relationship.muting ||
|
||||
// Muted user of a reprööt
|
||||
(relationshipReblog && relationshipReblog.muting)
|
||||
relationshipReblog?.muting
|
||||
)
|
||||
},
|
||||
shouldNotMute() {
|
||||
|
|
@ -333,7 +333,7 @@ const Status = {
|
|||
// Don't mute user's posts on user timeline (except reblogs)
|
||||
((!reblog && status.user.id === this.profileUserId) ||
|
||||
// Same as above but also allow self-reblogs
|
||||
(reblog && reblog.user.id === this.profileUserId))) ||
|
||||
reblog?.user.id === this.profileUserId)) ||
|
||||
// Don't mute statuses in muted conversation when said conversation is opened
|
||||
(this.inConversation && status.thread_muted)) &&
|
||||
// No excuses if post has muted words
|
||||
|
|
@ -374,7 +374,7 @@ const Status = {
|
|||
const user = this.$store.getters.findUser(
|
||||
this.status.in_reply_to_user_id,
|
||||
)
|
||||
return user && user.screen_name_ui
|
||||
return user?.screen_name_ui
|
||||
}
|
||||
},
|
||||
combinedFavsAndRepeatsUsers() {
|
||||
|
|
|
|||
|
|
@ -225,7 +225,7 @@
|
|||
/>
|
||||
</button>
|
||||
<button
|
||||
v-if="inThreadForest && replies && replies.length && !simpleTree"
|
||||
v-if="inThreadForest && replies?.length && !simpleTree"
|
||||
class="button-unstyled"
|
||||
:title="threadShowing ? $t('status.thread_hide') : $t('status.thread_show')"
|
||||
:aria-expanded="threadShowing ? 'true' : 'false'"
|
||||
|
|
@ -426,7 +426,7 @@
|
|||
/>
|
||||
|
||||
<div
|
||||
v-if="inConversation && !isPreview && replies && replies.length"
|
||||
v-if="inConversation && !isPreview && replies?.length"
|
||||
class="replies"
|
||||
>
|
||||
<button
|
||||
|
|
|
|||
|
|
@ -138,7 +138,7 @@ export default {
|
|||
const existingReaction = this.status.emoji_reactions.find(
|
||||
(r) => r.name === emoji,
|
||||
)
|
||||
if (existingReaction && existingReaction.me) {
|
||||
if (existingReaction?.me) {
|
||||
this.$store.dispatch('unreactWithEmoji', { id: this.status.id, emoji })
|
||||
} else {
|
||||
this.$store.dispatch('reactWithEmoji', { id: this.status.id, emoji })
|
||||
|
|
|
|||
|
|
@ -47,7 +47,7 @@ export default {
|
|||
// In case of controlled component
|
||||
if (this.activeTab) {
|
||||
return this.slots().findIndex(
|
||||
(slot) => slot && slot.props && this.activeTab === slot.props.key,
|
||||
(slot) => slot?.props && this.activeTab === slot.props.key,
|
||||
)
|
||||
} else {
|
||||
return this.active
|
||||
|
|
|
|||
|
|
@ -154,7 +154,7 @@ const Timeline = {
|
|||
})
|
||||
},
|
||||
mounted() {
|
||||
if (typeof document.hidden !== 'undefined') {
|
||||
if (document.hidden !== undefined) {
|
||||
document.addEventListener(
|
||||
'visibilitychange',
|
||||
this.handleVisibilityChange,
|
||||
|
|
@ -168,7 +168,7 @@ const Timeline = {
|
|||
unmounted() {
|
||||
window.removeEventListener('scroll', this.handleScroll)
|
||||
window.removeEventListener('keydown', this.handleShortKey)
|
||||
if (typeof document.hidden !== 'undefined')
|
||||
if (document.hidden !== undefined)
|
||||
document.removeEventListener(
|
||||
'visibilitychange',
|
||||
this.handleVisibilityChange,
|
||||
|
|
@ -231,7 +231,7 @@ const Timeline = {
|
|||
tag: this.tag,
|
||||
})
|
||||
.then(({ statuses }) => {
|
||||
if (statuses && statuses.length === 0) {
|
||||
if (statuses?.length === 0) {
|
||||
this.bottomedOut = true
|
||||
}
|
||||
})
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
<template>
|
||||
<FAIcon
|
||||
v-if="user && user.screen_name_ui_contains_non_ascii"
|
||||
v-if="user?.screen_name_ui_contains_non_ascii"
|
||||
icon="code"
|
||||
:title="$t('unicode_domain_indicator.tooltip')"
|
||||
/>
|
||||
|
|
|
|||
|
|
@ -68,7 +68,7 @@
|
|||
>
|
||||
<button
|
||||
v-if="editable"
|
||||
:disabled="newName && newName.length === 0"
|
||||
:disabled="newName?.length === 0"
|
||||
class="btn button-unstyled edit-banner-button"
|
||||
@click="changeBanner"
|
||||
>
|
||||
|
|
|
|||
|
|
@ -34,15 +34,15 @@ const VideoAttachment = {
|
|||
// If hasAudio is false, we've already marked this video to not have audio,
|
||||
// a video can't gain audio out of nowhere so don't bother checking again.
|
||||
if (!this.hasAudio) return
|
||||
if (typeof target.webkitAudioDecodedByteCount !== 'undefined') {
|
||||
if (target.webkitAudioDecodedByteCount !== undefined) {
|
||||
// non-zero if video has audio track
|
||||
if (target.webkitAudioDecodedByteCount > 0) return
|
||||
}
|
||||
if (typeof target.mozHasAudio !== 'undefined') {
|
||||
if (target.mozHasAudio !== undefined) {
|
||||
// true if video has audio track
|
||||
if (target.mozHasAudio) return
|
||||
}
|
||||
if (typeof target.audioTracks !== 'undefined') {
|
||||
if (target.audioTracks !== undefined) {
|
||||
if (target.audioTracks.length > 0) return
|
||||
}
|
||||
this.hasAudio = false
|
||||
|
|
|
|||
|
|
@ -3,14 +3,12 @@ import {
|
|||
find,
|
||||
findIndex,
|
||||
first,
|
||||
isArray,
|
||||
last,
|
||||
maxBy,
|
||||
merge,
|
||||
minBy,
|
||||
omitBy,
|
||||
remove,
|
||||
slice,
|
||||
} from 'lodash'
|
||||
|
||||
import { useInstanceCapabilitiesStore } from 'src/stores/instance_capabilities.js'
|
||||
|
|
@ -206,7 +204,7 @@ const addNewStatuses = (
|
|||
},
|
||||
) => {
|
||||
// Sanity check
|
||||
if (!isArray(statuses)) {
|
||||
if (!Array.isArray(statuses)) {
|
||||
return false
|
||||
}
|
||||
|
||||
|
|
@ -410,7 +408,7 @@ export const mutations = {
|
|||
const oldTimeline = state.timelines[timeline]
|
||||
|
||||
oldTimeline.newStatusCount = 0
|
||||
oldTimeline.visibleStatuses = slice(oldTimeline.statuses, 0, 50)
|
||||
oldTimeline.visibleStatuses = oldTimeline.statuses.slice(0, 50)
|
||||
oldTimeline.minVisibleId = last(oldTimeline.visibleStatuses).id
|
||||
oldTimeline.minId = oldTimeline.minVisibleId
|
||||
oldTimeline.visibleStatusesObject = {}
|
||||
|
|
|
|||
|
|
@ -1,14 +1,5 @@
|
|||
import Cookies from 'js-cookie'
|
||||
import {
|
||||
compact,
|
||||
concat,
|
||||
each,
|
||||
isArray,
|
||||
last,
|
||||
map,
|
||||
mergeWith,
|
||||
uniq,
|
||||
} from 'lodash'
|
||||
import { compact, each, last, map, mergeWith } from 'lodash'
|
||||
|
||||
import {
|
||||
registerPushNotifications,
|
||||
|
|
@ -76,7 +67,7 @@ export const mergeOrAdd = (arr, obj, item) => {
|
|||
}
|
||||
|
||||
const mergeArrayLength = (oldValue, newValue) => {
|
||||
if (isArray(oldValue) && isArray(newValue)) {
|
||||
if (Array.isArray(oldValue) && Array.isArray(newValue)) {
|
||||
oldValue.length = newValue.length
|
||||
return mergeWith(oldValue, newValue, mergeArrayLength)
|
||||
}
|
||||
|
|
@ -234,11 +225,11 @@ export const mutations = {
|
|||
},
|
||||
saveFriendIds(state, { id, friendIds }) {
|
||||
const user = state.usersObject[id]
|
||||
user.friendIds = uniq(concat(user.friendIds || [], friendIds))
|
||||
user.friendIds = [...new Set([...(user.friendIds || []), ...friendIds])]
|
||||
},
|
||||
saveFollowerIds(state, { id, followerIds }) {
|
||||
const user = state.usersObject[id]
|
||||
user.followerIds = uniq(concat(user.followerIds || [], followerIds))
|
||||
user.followerIds = [...new Set([user.followerIds || [], ...followerIds])]
|
||||
},
|
||||
// Because frontend doesn't have a reason to keep these stuff in memory
|
||||
// outside of viewing someones user profile.
|
||||
|
|
|
|||
|
|
@ -173,9 +173,9 @@ export const hex2rgb = (hex) => {
|
|||
|
||||
return result
|
||||
? {
|
||||
r: parseInt(result[1], 16),
|
||||
g: parseInt(result[2], 16),
|
||||
b: parseInt(result[3], 16),
|
||||
r: Number.parseInt(result[1], 16),
|
||||
g: Number.parseInt(result[2], 16),
|
||||
b: Number.parseInt(result[3], 16),
|
||||
}
|
||||
: null
|
||||
}
|
||||
|
|
@ -271,7 +271,7 @@ export const getTextColor = function (bg, text, preserve) {
|
|||
contrast = getContrastRatio(bg, convert(result).rgb)
|
||||
}
|
||||
|
||||
const base = typeof text.a !== 'undefined' ? { a: text.a } : {}
|
||||
const base = text.a !== undefined ? { a: text.a } : {}
|
||||
return Object.assign(convert(result).rgb, base)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -177,7 +177,7 @@ export const parseUser = (data) => {
|
|||
// deactivated was changed to is_active in Pleroma 2.3.0
|
||||
// so check if is_active is present
|
||||
output.deactivated =
|
||||
typeof data.pleroma.is_active !== 'undefined'
|
||||
data.pleroma.is_active !== undefined
|
||||
? !data.pleroma.is_active // new backend
|
||||
: data.pleroma.deactivated // old backend
|
||||
|
||||
|
|
@ -372,7 +372,7 @@ export const parseNotification = (data) => {
|
|||
}
|
||||
|
||||
output.created_at = new Date(data.created_at)
|
||||
output.id = parseInt(data.id)
|
||||
output.id = Number.parseInt(data.id)
|
||||
|
||||
return output
|
||||
}
|
||||
|
|
@ -385,8 +385,8 @@ export const parseLinkHeaderPagination = (linkHeader, opts = {}) => {
|
|||
const minId = parsedLinkHeader.prev?.min_id
|
||||
|
||||
return {
|
||||
maxId: flakeId ? maxId : parseInt(maxId, 10),
|
||||
minId: flakeId ? minId : parseInt(minId, 10),
|
||||
maxId: flakeId ? maxId : Number.parseInt(maxId, 10),
|
||||
minId: flakeId ? minId : Number.parseInt(minId, 10),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ export function StatusCodeError(statusCode, body, options, response) {
|
|||
this.name = 'StatusCodeError'
|
||||
this.statusCode = statusCode
|
||||
this.statusText = body.error || body.errors || body
|
||||
this.details = JSON && JSON.stringify ? JSON.stringify(body) : body
|
||||
this.details = JSON.stringify(body)
|
||||
this.errorData = body.error || body.errors
|
||||
this.message = this.statusCode + ' - ' + this.statusText
|
||||
this.error = body // legacy attribute
|
||||
|
|
|
|||
|
|
@ -1,5 +1,3 @@
|
|||
import { uniq } from 'lodash'
|
||||
|
||||
import * as DateUtils from 'src/services/date_utils/date_utils.js'
|
||||
|
||||
const pollFallbackValues = {
|
||||
|
|
@ -19,9 +17,9 @@ export const pollFormToMasto = (poll) => {
|
|||
pollFallback(poll, 'expiryAmount'),
|
||||
)
|
||||
|
||||
const options = uniq(
|
||||
pollFallback(poll, 'options').filter((option) => option !== ''),
|
||||
)
|
||||
const options = [
|
||||
...new Set(pollFallback(poll, 'options').filter((option) => option !== '')),
|
||||
]
|
||||
if (options.length < 2) {
|
||||
return { errorKey: 'polls.not_enough_options' }
|
||||
}
|
||||
|
|
|
|||
|
|
@ -125,10 +125,7 @@ const generateTheme = (inputRuleset, callbacks, debug) => {
|
|||
const processChunk = () => {
|
||||
const chunk = chunks[counter]
|
||||
Promise.all(chunk.map((x) => x())).then((result) => {
|
||||
getCssRules(
|
||||
result.filter((x) => x),
|
||||
debug,
|
||||
).forEach((rule) => {
|
||||
getCssRules(result.filter(Boolean), debug).forEach((rule) => {
|
||||
onNewRule(rule, true)
|
||||
})
|
||||
// const t1 = performance.now()
|
||||
|
|
@ -253,7 +250,9 @@ const extractStyleConfig = ({
|
|||
contentColumnWidth,
|
||||
notifsColumnWidth,
|
||||
themeEditorMinWidth:
|
||||
parseInt(themeEditorMinWidth) === 0 ? 'fit-content' : themeEditorMinWidth,
|
||||
Number.parseInt(themeEditorMinWidth) === 0
|
||||
? 'fit-content'
|
||||
: themeEditorMinWidth,
|
||||
emojiReactionsScale,
|
||||
emojiSize,
|
||||
navbarSize,
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ function urlBase64ToUint8Array(base64String) {
|
|||
const base64 = (base64String + padding).replace(/-/g, '+').replace(/_/g, '/')
|
||||
|
||||
const rawData = window.atob(base64)
|
||||
return Uint8Array.from([...rawData].map((char) => char.charCodeAt(0)))
|
||||
return Uint8Array.from([...rawData].map((char) => char.codePointAt(0)))
|
||||
}
|
||||
|
||||
export function isSWSupported() {
|
||||
|
|
|
|||
|
|
@ -104,7 +104,7 @@ export const getCssRules = (rules, debug) =>
|
|||
: '',
|
||||
' --background: ' + v,
|
||||
]
|
||||
.filter((x) => x)
|
||||
.filter(Boolean)
|
||||
.join(';\n')
|
||||
}
|
||||
const color = getCssColorString(
|
||||
|
|
@ -115,7 +115,7 @@ export const getCssRules = (rules, debug) =>
|
|||
if (rule.directives.backgroundNoCssColor !== 'yes') {
|
||||
cssDirectives.push('background-color: ' + color)
|
||||
}
|
||||
return cssDirectives.filter((x) => x).join(';\n')
|
||||
return cssDirectives.filter(Boolean).join(';\n')
|
||||
}
|
||||
case 'blur': {
|
||||
const cssDirectives = []
|
||||
|
|
@ -157,7 +157,7 @@ export const getCssRules = (rules, debug) =>
|
|||
return null
|
||||
}
|
||||
})
|
||||
.filter((x) => x)
|
||||
.filter(Boolean)
|
||||
.map((x) => ' ' + x + ';')
|
||||
.join('\n')
|
||||
|
||||
|
|
@ -172,10 +172,10 @@ export const getCssRules = (rules, debug) =>
|
|||
virtualDirectives,
|
||||
footer,
|
||||
]
|
||||
.filter((x) => x)
|
||||
.filter(Boolean)
|
||||
.join('\n')
|
||||
})
|
||||
.filter((x) => x)
|
||||
.filter(Boolean)
|
||||
|
||||
export const getScopedVersion = (rules, newScope) => {
|
||||
return rules.map((x) => {
|
||||
|
|
|
|||
|
|
@ -62,6 +62,6 @@ export const serialize = (ruleset) => {
|
|||
|
||||
return `${header} {\n${content.join(';\n')}\n}`
|
||||
})
|
||||
.filter((x) => x)
|
||||
.filter(Boolean)
|
||||
.join('\n\n')
|
||||
}
|
||||
|
|
|
|||
|
|
@ -558,9 +558,9 @@ export const convertTheme2To3 = (data) => {
|
|||
)
|
||||
|
||||
const flatExtRules = extendedRules
|
||||
.filter((x) => x)
|
||||
.filter(Boolean)
|
||||
.reduce((acc, x) => [...acc, ...x], [])
|
||||
.filter((x) => x)
|
||||
.filter(Boolean)
|
||||
.reduce((acc, x) => [...acc, ...x], [])
|
||||
|
||||
return [
|
||||
|
|
|
|||
|
|
@ -229,10 +229,7 @@ export const getLayerSlot = (
|
|||
*/
|
||||
export const SLOT_ORDERED = topoSort(
|
||||
Object.entries(SLOT_INHERITANCE)
|
||||
.sort(
|
||||
([, aV], [, bV]) =>
|
||||
((aV && aV.priority) || 0) - ((bV && bV.priority) || 0),
|
||||
)
|
||||
.sort(([, aV], [, bV]) => (aV?.priority || 0) - (bV?.priority || 0))
|
||||
.reduce((acc, [k, v]) => ({ ...acc, [k]: v }), {}),
|
||||
)
|
||||
|
||||
|
|
@ -408,7 +405,7 @@ export const getColors = (sourceColors, sourceOpacity) =>
|
|||
delete outputColor.a
|
||||
} else {
|
||||
// Otherwise try to assign opacity
|
||||
if (dependencyColor && dependencyColor.a === 0) {
|
||||
if (dependencyColor?.a === 0) {
|
||||
// transparent dependency shall make dependents transparent too
|
||||
outputColor.a = 0
|
||||
} else {
|
||||
|
|
@ -523,7 +520,7 @@ export const generateColors = (themeData) => {
|
|||
(acc, [k, v]) => {
|
||||
if (!v) return acc
|
||||
acc.solid[k] = rgb2hex(v)
|
||||
acc.complete[k] = typeof v.a === 'undefined' ? rgb2hex(v) : rgba2css(v)
|
||||
acc.complete[k] = v.a === undefined ? rgb2hex(v) : rgba2css(v)
|
||||
return acc
|
||||
},
|
||||
{ complete: {}, solid: {} },
|
||||
|
|
@ -545,7 +542,7 @@ export const generateColors = (themeData) => {
|
|||
export const generateRadii = (input) => {
|
||||
let inputRadii = input.radii || {}
|
||||
// v1 -> v2
|
||||
if (typeof input.btnRadius !== 'undefined') {
|
||||
if (input.btnRadius !== undefined) {
|
||||
inputRadii = Object.entries(input)
|
||||
.filter(([k]) => k.endsWith('Radius'))
|
||||
.reduce((acc, e) => {
|
||||
|
|
|
|||
|
|
@ -338,10 +338,10 @@ export const init = ({
|
|||
const relevantRules = ruleset.filter((r) => r.component === component.name)
|
||||
const backgrounds = relevantRules
|
||||
.map((r) => r.directives.background)
|
||||
.filter((x) => x)
|
||||
.filter(Boolean)
|
||||
const opacities = relevantRules
|
||||
.map((r) => r.directives.opacity)
|
||||
.filter((x) => x)
|
||||
.filter(Boolean)
|
||||
if (
|
||||
backgrounds.some((x) => x.match(/--parent/)) ||
|
||||
opacities.some((x) => x != null && x < 1)
|
||||
|
|
@ -596,7 +596,7 @@ export const init = ({
|
|||
const shadow = value
|
||||
.split(/,/g)
|
||||
.map((s) => s.trim())
|
||||
.filter((x) => x)
|
||||
.filter(Boolean)
|
||||
dynamicVars[k] = shadow
|
||||
if (combination.component === rootComponentName) {
|
||||
staticVars[k.substring(2)] = shadow
|
||||
|
|
@ -752,7 +752,7 @@ export const init = ({
|
|||
return processCombination(combination)
|
||||
}
|
||||
})
|
||||
.filter((x) => x)
|
||||
.filter(Boolean)
|
||||
const t2 = performance.now()
|
||||
if (debug) {
|
||||
console.debug('Eager processing took ' + (t2 - t1) + ' ms')
|
||||
|
|
|
|||
|
|
@ -11,6 +11,6 @@ const generateProfileLink = (id, screenName, restrictedNicknames) => {
|
|||
}
|
||||
}
|
||||
|
||||
const isExternal = (screenName) => screenName && screenName.includes('@')
|
||||
const isExternal = (screenName) => screenName?.includes('@')
|
||||
|
||||
export default generateProfileLink
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import { cloneDeep, differenceWith, flatten, get, isEqual, set } from 'lodash'
|
||||
import { cloneDeep, differenceWith, get, isEqual, set } from 'lodash'
|
||||
import { defineStore } from 'pinia'
|
||||
|
||||
import { useOAuthStore } from 'src/stores/oauth.js'
|
||||
|
|
@ -209,11 +209,11 @@ export const useAdminSettingsStore = defineStore('adminSettings', {
|
|||
}
|
||||
|
||||
// Getting all group-keys used in config
|
||||
const allGroupKeys = flatten(
|
||||
Object.entries(this.config).map(([group, lv1data]) =>
|
||||
const allGroupKeys = Object.entries(this.config)
|
||||
.map(([group, lv1data]) =>
|
||||
Object.keys(lv1data).map((key) => ({ group, key })),
|
||||
),
|
||||
)
|
||||
)
|
||||
.flat()
|
||||
|
||||
// Only using group-keys where there are changes detected
|
||||
const changedGroupKeys = allGroupKeys.filter(({ group, key }) => {
|
||||
|
|
|
|||
|
|
@ -74,7 +74,7 @@ export const useAnnouncementsStore = defineStore('announcements', {
|
|||
} catch (error) {
|
||||
// If and only if backend does not support announcements, it would return 404.
|
||||
// In this case, silently ignores it.
|
||||
if (error && error.statusCode === 404) {
|
||||
if (error?.statusCode === 404) {
|
||||
this.supportsAnnouncements = false
|
||||
} else {
|
||||
throw error
|
||||
|
|
|
|||
|
|
@ -747,7 +747,7 @@ export const useInterfaceStore = defineStore('interface', {
|
|||
this.styleDataUsed,
|
||||
paletteIss,
|
||||
hacks,
|
||||
].filter((x) => x)
|
||||
].filter(Boolean)
|
||||
|
||||
return applyTheme(
|
||||
rulesetArray.flat(),
|
||||
|
|
@ -790,7 +790,7 @@ export const normalizeThemeData = (input) => {
|
|||
// New theme presets don't have 'theme' property, they use 'source'
|
||||
|
||||
let out // shout, shout let it all out
|
||||
if (themeSource && themeSource.themeEngineVersion === CURRENT_VERSION) {
|
||||
if (themeSource?.themeEngineVersion === CURRENT_VERSION) {
|
||||
// There are some themes in wild that have completely broken source
|
||||
out = { ...(themeData || {}), ...themeSource }
|
||||
} else {
|
||||
|
|
|
|||
|
|
@ -4,13 +4,12 @@ import {
|
|||
clamp,
|
||||
cloneDeep,
|
||||
findLastIndex,
|
||||
flatten,
|
||||
get,
|
||||
groupBy,
|
||||
isEqual,
|
||||
last,
|
||||
set,
|
||||
take,
|
||||
takeRight,
|
||||
uniqWith,
|
||||
unset,
|
||||
} from 'lodash'
|
||||
|
|
@ -222,15 +221,16 @@ export const _mergeFlags = (recent, stale, allFlagKeys) => {
|
|||
|
||||
export const _mergeJournal = (...journals) => {
|
||||
// Ignore invalid journal entries
|
||||
const allJournals = flatten(
|
||||
journals.map((j) => (Array.isArray(j) ? j : [])),
|
||||
).filter(
|
||||
(entry) =>
|
||||
Object.hasOwn(entry, 'path') &&
|
||||
Object.hasOwn(entry, 'operation') &&
|
||||
Object.hasOwn(entry, 'args') &&
|
||||
Object.hasOwn(entry, 'timestamp'),
|
||||
)
|
||||
const allJournals = journals
|
||||
.map((j) => (Array.isArray(j) ? j : []))
|
||||
.flat()
|
||||
.filter(
|
||||
(entry) =>
|
||||
Object.hasOwn(entry, 'path') &&
|
||||
Object.hasOwn(entry, 'operation') &&
|
||||
Object.hasOwn(entry, 'args') &&
|
||||
Object.hasOwn(entry, 'timestamp'),
|
||||
)
|
||||
const grouped = groupBy(allJournals, 'path')
|
||||
const trimmedGrouped = Object.entries(grouped).map(([path, rawJournal]) => {
|
||||
const journal = rawJournal
|
||||
|
|
@ -271,13 +271,14 @@ export const _mergeJournal = (...journals) => {
|
|||
})
|
||||
} else if (path.startsWith('simple')) {
|
||||
// Only the last record is important
|
||||
return takeRight(journal)
|
||||
return [last(journal)]
|
||||
} else {
|
||||
return journal
|
||||
}
|
||||
})
|
||||
|
||||
const flat = flatten(trimmedGrouped)
|
||||
const flat = trimmedGrouped
|
||||
.flat()
|
||||
.map((data, index) => ({ data, index }))
|
||||
.toSorted(({ data: a, index: ai }, { data: b, index: bi }) => {
|
||||
if (a.timestamp === b.timestamp) {
|
||||
|
|
|
|||
|
|
@ -2,10 +2,9 @@ import {
|
|||
merge as _merge,
|
||||
clone,
|
||||
cloneDeep,
|
||||
flatten,
|
||||
groupBy,
|
||||
isEqual,
|
||||
takeRight,
|
||||
last,
|
||||
} from 'lodash'
|
||||
import { defineStore } from 'pinia'
|
||||
import { toRaw } from 'vue'
|
||||
|
|
@ -117,25 +116,26 @@ export const _getRecentData = (cache, live, isTest) => {
|
|||
|
||||
const _mergeJournal = (...journals) => {
|
||||
// Ignore invalid journal entries
|
||||
const allJournals = flatten(
|
||||
journals.map((j) => (Array.isArray(j) ? j : [])),
|
||||
).filter(
|
||||
(entry) =>
|
||||
Object.hasOwn(entry, 'user') &&
|
||||
Object.hasOwn(entry, 'operation') &&
|
||||
Object.hasOwn(entry, 'args') &&
|
||||
Object.hasOwn(entry, 'timestamp'),
|
||||
)
|
||||
const allJournals = journals
|
||||
.map((j) => (Array.isArray(j) ? j : []))
|
||||
.flat()
|
||||
.filter(
|
||||
(entry) =>
|
||||
Object.hasOwn(entry, 'user') &&
|
||||
Object.hasOwn(entry, 'operation') &&
|
||||
Object.hasOwn(entry, 'args') &&
|
||||
Object.hasOwn(entry, 'timestamp'),
|
||||
)
|
||||
const grouped = groupBy(allJournals, 'user')
|
||||
const trimmedGrouped = Object.entries(grouped).map(([user, journal]) => {
|
||||
// side effect
|
||||
journal.sort((a, b) => (a.timestamp > b.timestamp ? 1 : -1))
|
||||
|
||||
return takeRight(journal)
|
||||
return [last(journal)]
|
||||
})
|
||||
return flatten(trimmedGrouped).sort((a, b) =>
|
||||
a.timestamp > b.timestamp ? 1 : -1,
|
||||
)
|
||||
return trimmedGrouped
|
||||
.flat()
|
||||
.sort((a, b) => (a.timestamp > b.timestamp ? 1 : -1))
|
||||
}
|
||||
|
||||
export const _mergeHighlights = (recent, stale) => {
|
||||
|
|
|
|||
2
test/fixtures/setup_test.js
vendored
2
test/fixtures/setup_test.js
vendored
|
|
@ -132,7 +132,7 @@ export const waitForEvent = (
|
|||
return vi.waitFor(
|
||||
() => {
|
||||
const e = wrapper.emitted(event)
|
||||
if (e && e.length >= timesEmitted) {
|
||||
if (e?.length >= timesEmitted) {
|
||||
return
|
||||
}
|
||||
throw new Error('event is not emitted')
|
||||
|
|
|
|||
|
|
@ -7,100 +7,92 @@ import {
|
|||
} from 'src/services/entity_normalizer/entity_normalizer.service.js'
|
||||
|
||||
const makeMockUserMasto = (overrides = {}) => {
|
||||
return Object.assign(
|
||||
{
|
||||
acct: 'hj',
|
||||
avatar:
|
||||
'https://shigusegubu.club/media/1657b945-8d5b-4ce6-aafb-4c3fc5772120/8ce851029af84d55de9164e30cc7f46d60cbf12eee7e96c5c0d35d9038ddade1.png',
|
||||
avatar_static:
|
||||
'https://shigusegubu.club/media/1657b945-8d5b-4ce6-aafb-4c3fc5772120/8ce851029af84d55de9164e30cc7f46d60cbf12eee7e96c5c0d35d9038ddade1.png',
|
||||
bot: false,
|
||||
created_at: '2017-12-17T21:54:14.000Z',
|
||||
display_name: 'whatever whatever whatever witch',
|
||||
emojis: [],
|
||||
fields: [],
|
||||
followers_count: 705,
|
||||
following_count: 326,
|
||||
header:
|
||||
'https://shigusegubu.club/media/7ab024d9-2a8a-4fbc-9ce8-da06756ae2db/6aadefe4e264133bc377ab450e6b045b6f5458542a5c59e6c741f86107f0388b.png',
|
||||
header_static:
|
||||
'https://shigusegubu.club/media/7ab024d9-2a8a-4fbc-9ce8-da06756ae2db/6aadefe4e264133bc377ab450e6b045b6f5458542a5c59e6c741f86107f0388b.png',
|
||||
id: '1',
|
||||
locked: false,
|
||||
note: 'Volatile Internet Weirdo. Name pronounced as Hee Jay. JS and Java dark arts mage, Elixir trainee. I love sampo and lain. Matrix is <span><a data-user="1" href="https://shigusegubu.club/users/hj">@<span>hj</span></a></span>:matrix.heldscal.la Pronouns are whatever. Do not DM me unless it\'s truly private matter and you\'re instance\'s admin or you risk your DM to be reposted publicly.Wish i was Finnish girl.',
|
||||
pleroma: { confirmation_pending: false, tags: null },
|
||||
source: { note: '', privacy: 'public', sensitive: false },
|
||||
statuses_count: 41775,
|
||||
url: 'https://shigusegubu.club/users/hj',
|
||||
username: 'hj',
|
||||
},
|
||||
overrides,
|
||||
)
|
||||
return {
|
||||
acct: 'hj',
|
||||
avatar:
|
||||
'https://shigusegubu.club/media/1657b945-8d5b-4ce6-aafb-4c3fc5772120/8ce851029af84d55de9164e30cc7f46d60cbf12eee7e96c5c0d35d9038ddade1.png',
|
||||
avatar_static:
|
||||
'https://shigusegubu.club/media/1657b945-8d5b-4ce6-aafb-4c3fc5772120/8ce851029af84d55de9164e30cc7f46d60cbf12eee7e96c5c0d35d9038ddade1.png',
|
||||
bot: false,
|
||||
created_at: '2017-12-17T21:54:14.000Z',
|
||||
display_name: 'whatever whatever whatever witch',
|
||||
emojis: [],
|
||||
fields: [],
|
||||
followers_count: 705,
|
||||
following_count: 326,
|
||||
header:
|
||||
'https://shigusegubu.club/media/7ab024d9-2a8a-4fbc-9ce8-da06756ae2db/6aadefe4e264133bc377ab450e6b045b6f5458542a5c59e6c741f86107f0388b.png',
|
||||
header_static:
|
||||
'https://shigusegubu.club/media/7ab024d9-2a8a-4fbc-9ce8-da06756ae2db/6aadefe4e264133bc377ab450e6b045b6f5458542a5c59e6c741f86107f0388b.png',
|
||||
id: '1',
|
||||
locked: false,
|
||||
note: 'Volatile Internet Weirdo. Name pronounced as Hee Jay. JS and Java dark arts mage, Elixir trainee. I love sampo and lain. Matrix is <span><a data-user="1" href="https://shigusegubu.club/users/hj">@<span>hj</span></a></span>:matrix.heldscal.la Pronouns are whatever. Do not DM me unless it\'s truly private matter and you\'re instance\'s admin or you risk your DM to be reposted publicly.Wish i was Finnish girl.',
|
||||
pleroma: { confirmation_pending: false, tags: null },
|
||||
source: { note: '', privacy: 'public', sensitive: false },
|
||||
statuses_count: 41775,
|
||||
url: 'https://shigusegubu.club/users/hj',
|
||||
username: 'hj',
|
||||
...overrides,
|
||||
}
|
||||
}
|
||||
|
||||
const makeMockStatusMasto = (overrides = {}) => {
|
||||
return Object.assign(
|
||||
{
|
||||
account: makeMockUserMasto(),
|
||||
application: { name: 'Web', website: null },
|
||||
content:
|
||||
'<span><a data-user="14660" href="https://pleroma.soykaf.com/users/sampo">@<span>sampo</span></a></span> god i wish i was there',
|
||||
created_at: '2019-01-17T16:29:23.000Z',
|
||||
emojis: [],
|
||||
favourited: false,
|
||||
favourites_count: 1,
|
||||
id: '10423476',
|
||||
in_reply_to_account_id: '14660',
|
||||
in_reply_to_id: '10423197',
|
||||
language: null,
|
||||
media_attachments: [],
|
||||
mentions: [
|
||||
{
|
||||
acct: 'sampo@pleroma.soykaf.com',
|
||||
id: '14660',
|
||||
url: 'https://pleroma.soykaf.com/users/sampo',
|
||||
username: 'sampo',
|
||||
},
|
||||
],
|
||||
muted: false,
|
||||
reblog: null,
|
||||
reblogged: false,
|
||||
reblogs_count: 0,
|
||||
replies_count: 0,
|
||||
sensitive: false,
|
||||
spoiler_text: '',
|
||||
tags: [],
|
||||
uri: 'https://shigusegubu.club/objects/16033fbb-97c0-4f0e-b834-7abb92fb8639',
|
||||
url: 'https://shigusegubu.club/objects/16033fbb-97c0-4f0e-b834-7abb92fb8639',
|
||||
visibility: 'public',
|
||||
pleroma: {
|
||||
local: true,
|
||||
return {
|
||||
account: makeMockUserMasto(),
|
||||
application: { name: 'Web', website: null },
|
||||
content:
|
||||
'<span><a data-user="14660" href="https://pleroma.soykaf.com/users/sampo">@<span>sampo</span></a></span> god i wish i was there',
|
||||
created_at: '2019-01-17T16:29:23.000Z',
|
||||
emojis: [],
|
||||
favourited: false,
|
||||
favourites_count: 1,
|
||||
id: '10423476',
|
||||
in_reply_to_account_id: '14660',
|
||||
in_reply_to_id: '10423197',
|
||||
language: null,
|
||||
media_attachments: [],
|
||||
mentions: [
|
||||
{
|
||||
acct: 'sampo@pleroma.soykaf.com',
|
||||
id: '14660',
|
||||
url: 'https://pleroma.soykaf.com/users/sampo',
|
||||
username: 'sampo',
|
||||
},
|
||||
],
|
||||
muted: false,
|
||||
reblog: null,
|
||||
reblogged: false,
|
||||
reblogs_count: 0,
|
||||
replies_count: 0,
|
||||
sensitive: false,
|
||||
spoiler_text: '',
|
||||
tags: [],
|
||||
uri: 'https://shigusegubu.club/objects/16033fbb-97c0-4f0e-b834-7abb92fb8639',
|
||||
url: 'https://shigusegubu.club/objects/16033fbb-97c0-4f0e-b834-7abb92fb8639',
|
||||
visibility: 'public',
|
||||
pleroma: {
|
||||
local: true,
|
||||
},
|
||||
overrides,
|
||||
)
|
||||
...overrides,
|
||||
}
|
||||
}
|
||||
|
||||
const makeMockEmojiMasto = (overrides = [{}]) => {
|
||||
return [
|
||||
Object.assign(
|
||||
{
|
||||
shortcode: 'image',
|
||||
static_url: 'https://example.com/image.png',
|
||||
url: 'https://example.com/image.png',
|
||||
visible_in_picker: false,
|
||||
},
|
||||
overrides[0],
|
||||
),
|
||||
Object.assign(
|
||||
{
|
||||
shortcode: 'thinking',
|
||||
static_url: 'https://example.com/think.png',
|
||||
url: 'https://example.com/think.png',
|
||||
visible_in_picker: false,
|
||||
},
|
||||
overrides[1],
|
||||
),
|
||||
{
|
||||
shortcode: 'image',
|
||||
static_url: 'https://example.com/image.png',
|
||||
url: 'https://example.com/image.png',
|
||||
visible_in_picker: false,
|
||||
...overrides[0],
|
||||
},
|
||||
{
|
||||
shortcode: 'thinking',
|
||||
static_url: 'https://example.com/think.png',
|
||||
url: 'https://example.com/think.png',
|
||||
visible_in_picker: false,
|
||||
...overrides[1],
|
||||
},
|
||||
]
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue