diff --git a/build/update-emoji.js b/build/update-emoji.js index dd965cf66..b2631ec6e 100644 --- a/build/update-emoji.js +++ b/build/update-emoji.js @@ -3,7 +3,7 @@ import emojis from '@kazvmoe-infra/unicode-emoji-json/data-by-group.json' with { type: 'json', } -Object.keys(emojis).map((k) => { +Object.keys(emojis).forEach((k) => { emojis[k].forEach((e) => { delete e.unicode_version delete e.emoji_version diff --git a/src/components/announcement/announcement.js b/src/components/announcement/announcement.js index ee427533f..6b45b2b90 100644 --- a/src/components/announcement/announcement.js +++ b/src/components/announcement/announcement.js @@ -29,9 +29,8 @@ const Announcement = { currentUser: (state) => state.users.currentUser, }), canEditAnnouncement() { - return ( - this.currentUser && - this.currentUser.privileges.has('announcements_manage_announcements') + return this.currentUser?.privileges.has( + 'announcements_manage_announcements', ) }, content() { diff --git a/src/components/announcements_page/announcements_page.js b/src/components/announcements_page/announcements_page.js index 0f7933e5f..802e90cf6 100644 --- a/src/components/announcements_page/announcements_page.js +++ b/src/components/announcements_page/announcements_page.js @@ -33,9 +33,8 @@ const AnnouncementsPage = { return useAnnouncementsStore().announcements }, canPostAnnouncement() { - return ( - this.currentUser && - this.currentUser.privileges.has('announcements_manage_announcements') + return this.currentUser?.privileges.has( + 'announcements_manage_announcements', ) }, }, diff --git a/src/components/attachment/attachment.js b/src/components/attachment/attachment.js index f7d6ebf10..6556b07a0 100644 --- a/src/components/attachment/attachment.js +++ b/src/components/attachment/attachment.js @@ -165,16 +165,16 @@ const Attachment = { useMediaViewerStore().setCurrentMedia(this.attachment) }, onEdit(event) { - this.edit && this.edit(this.attachment, event) + this.edit?.(this.attachment, event) }, onRemove() { - this.remove && this.remove(this.attachment) + this.remove?.(this.attachment) }, onShiftUp() { - this.shiftUp && this.shiftUp(this.attachment) + this.shiftUp?.(this.attachment) }, onShiftDn() { - this.shiftDn && this.shiftDn(this.attachment) + this.shiftDn?.(this.attachment) }, stopFlash() { this.$refs.flash.closePlayer() diff --git a/src/components/chat_message/chat_message.vue b/src/components/chat_message/chat_message.vue index 394cce4b7..88ab2fc0a 100644 --- a/src/components/chat_message/chat_message.vue +++ b/src/components/chat_message/chat_message.vue @@ -1,9 +1,9 @@ @@ -40,7 +40,10 @@ - + {{ $t('status.broken_reply') }} @@ -83,7 +86,10 @@ :user="author" /> - + @@ -98,7 +104,6 @@ @mouseenter="hovered = true" @mouseleave="hovered = false" > - - + @@ -232,7 +240,10 @@ v-else class="chat-message-date-separator" > - + diff --git a/src/components/chat_message_list/chat_message_list.vue b/src/components/chat_message_list/chat_message_list.vue index 5cdbf6871..7833730e7 100644 --- a/src/components/chat_message_list/chat_message_list.vue +++ b/src/components/chat_message_list/chat_message_list.vue @@ -7,7 +7,7 @@ :previous-item="getPreviousItem(index)" :hovered-message-chain="chatItem.messageChainId === hoveredMessageChainId" :focused="chatItem.id === focusedId" - :repliedTo="chatItem.id === repliedId" + :replied-to="chatItem.id === repliedId" @hover="onMessageHover" @delete="onMessageDelete" @reply-requested="onReplyRequested" diff --git a/src/components/chat_view/chat_view.vue b/src/components/chat_view/chat_view.vue index e6bef0f84..06862ab3c 100644 --- a/src/components/chat_view/chat_view.vue +++ b/src/components/chat_view/chat_view.vue @@ -24,7 +24,7 @@ v-if="messages[0]?.summary_raw_html" :html="messages[0].summary_raw_html" :emoji="messages[0].emojis" - /> + /> {{ $t('timeline.conversation') }} diff --git a/src/components/conversation/conversation.js b/src/components/conversation/conversation.js index 0bbf01e6a..fcde9477c 100644 --- a/src/components/conversation/conversation.js +++ b/src/components/conversation/conversation.js @@ -375,7 +375,7 @@ const conversation = { return !!(this.expanded || this.isPage) }, hiddenStyle() { - const height = (this.status && this.status.virtualHeight) || '120px' + const height = this.status?.virtualHeight || '120px' return this.virtualHidden ? { height } : {} }, threadDisplayStatus() { diff --git a/src/components/conversation/conversation.vue b/src/components/conversation/conversation.vue index 170ab41d6..0833c4f89 100644 --- a/src/components/conversation/conversation.vue +++ b/src/components/conversation/conversation.vue @@ -14,9 +14,9 @@ v-if="conversation[0]?.summary_raw_html" :html="conversation[0].summary_raw_html" :emoji="conversation[0].emojis" - /> + /> - {{ $t('timeline.conversation') }} + {{ $t('timeline.conversation') }} ({ searchBarHidden: true, supportsMask: - window.CSS && - window.CSS.supports && + window.CSS?.supports && (window.CSS.supports('mask-size', 'contain') || window.CSS.supports('-webkit-mask-size', 'contain') || window.CSS.supports('-moz-mask-size', 'contain') || diff --git a/src/components/edit_status_modal/edit_status_modal.js b/src/components/edit_status_modal/edit_status_modal.js index c3ba7e4cb..59c142d08 100644 --- a/src/components/edit_status_modal/edit_status_modal.js +++ b/src/components/edit_status_modal/edit_status_modal.js @@ -42,9 +42,7 @@ const EditStatusModal = { }, isFormVisible(val) { if (val) { - this.$nextTick( - () => this.$el && this.$el.querySelector('textarea').focus(), - ) + this.$nextTick(() => this.$el?.querySelector('textarea').focus()) } }, }, diff --git a/src/components/emoji_input/suggestor.js b/src/components/emoji_input/suggestor.js index d5e83ecb2..c31cb6717 100644 --- a/src/components/emoji_input/suggestor.js +++ b/src/components/emoji_input/suggestor.js @@ -79,7 +79,7 @@ export const suggestUsers = ({ dispatch, state }) => { const userSearch = (query) => dispatch('searchUsers', { query }) const debounceUserSearch = (query) => { - cancelUserSearch && cancelUserSearch() + cancelUserSearch?.() return new Promise((resolve, reject) => { timeout = setTimeout(() => { userSearch(query).then(resolve).catch(reject) diff --git a/src/components/flash/flash.js b/src/components/flash/flash.js index 3c25abea1..48d342d2f 100644 --- a/src/components/flash/flash.js +++ b/src/components/flash/flash.js @@ -44,7 +44,7 @@ const Flash = { }) }, closePlayer() { - this.ruffleInstance && this.ruffleInstance.remove() + this.ruffleInstance?.remove() this.player = false this.$emit('playerClosed') }, diff --git a/src/components/image_cropper/image_cropper.js b/src/components/image_cropper/image_cropper.js index c8529c8e6..b85ef6626 100644 --- a/src/components/image_cropper/image_cropper.js +++ b/src/components/image_cropper/image_cropper.js @@ -50,7 +50,7 @@ const ImageCropper = { }, readFile() { const fileInput = this.$refs.input - if (fileInput.files != null && fileInput.files[0] != null) { + if (fileInput?.files?.[0]) { this.file = fileInput.files[0] const reader = new window.FileReader() reader.onload = (e) => { diff --git a/src/components/mention_link/mention_link.js b/src/components/mention_link/mention_link.js index f1861748b..0309079e8 100644 --- a/src/components/mention_link/mention_link.js +++ b/src/components/mention_link/mention_link.js @@ -75,13 +75,11 @@ const MentionLink = { }, computed: { user() { - return ( - this.url && this.$store && this.$store.getters.findUserByUrl(this.url) - ) + return this.url && this.$store?.getters.findUserByUrl(this.url) }, isYou() { // FIXME why user !== currentUser??? - return this.user && this.user.id === this.currentUser.id + return this.user?.id === this.currentUser.id }, userName() { return this.user && this.userNameFullUi.split('@')[0] @@ -94,10 +92,10 @@ const MentionLink = { ) }, userNameFull() { - return this.user && this.user.screen_name + return this.user?.screen_name }, userNameFullUi() { - return this.user && this.user.screen_name_ui + return this.user?.screen_name_ui }, highlightData() { return this.highlight[this.user?.screen_name] diff --git a/src/components/moderation_tools/moderation_tools.js b/src/components/moderation_tools/moderation_tools.js index ca4852ab3..ba13afc8b 100644 --- a/src/components/moderation_tools/moderation_tools.js +++ b/src/components/moderation_tools/moderation_tools.js @@ -405,7 +405,7 @@ const ModerationTools = { ) }, isAdmin() { - this.$store.state.users.currentUser.role === 'admin' + return this.$store.state.users.currentUser.role === 'admin' }, }, methods: { diff --git a/src/components/mrf_transparency_panel/mrf_transparency_panel.js b/src/components/mrf_transparency_panel/mrf_transparency_panel.js index b2048984d..7f2a16186 100644 --- a/src/components/mrf_transparency_panel/mrf_transparency_panel.js +++ b/src/components/mrf_transparency_panel/mrf_transparency_panel.js @@ -11,7 +11,7 @@ import { useInstanceStore } from 'src/stores/instance.js' */ const toInstanceReasonObject = (instances, info, key) => { return instances.map((instance) => { - if (info[key] && info[key][instance] && info[key][instance].reason) { + if (info[key]?.[instance]?.reason) { return { instance, reason: info[key][instance].reason } } return { instance, reason: '' } diff --git a/src/components/navigation/filter.js b/src/components/navigation/filter.js index 0255db6aa..0cbefd3fa 100644 --- a/src/components/navigation/filter.js +++ b/src/components/navigation/filter.js @@ -15,8 +15,7 @@ export const filterNavigation = ( if (!isFederating && set.has('federating')) return false if (!currentUser && isPrivate && set.has('!private')) return false if (!currentUser && !(anon || anonRoute)) return false - if ((!currentUser || !currentUser.locked) && set.has('lockedUser')) - return false + if (!currentUser?.locked && set.has('lockedUser')) return false if (!hasChats && set.has('chats')) return false if (!hasAnnouncements && set.has('announcements')) return false if (!supportsBubbleTimeline && set.has('supportsBubbleTimeline')) diff --git a/src/components/poll/poll.js b/src/components/poll/poll.js index b93a6699d..0ce304a0a 100644 --- a/src/components/poll/poll.js +++ b/src/components/poll/poll.js @@ -39,13 +39,13 @@ export default { return storePoll || {} }, options() { - return (this.poll && this.poll.options) || [] + return this.poll?.options || [] }, expiresAt() { - return (this.poll && this.poll.expires_at) || null + return this.poll?.expires_at || null }, expired() { - return (this.poll && this.poll.expired) || false + return this.poll?.expired || false }, expirationLabel() { if (useMergedConfigStore().mergedConfig.useAbsoluteTimeFormat) { diff --git a/src/components/popover/popover.js b/src/components/popover/popover.js index 9a06c4e69..40344834b 100644 --- a/src/components/popover/popover.js +++ b/src/components/popover/popover.js @@ -129,9 +129,7 @@ const Popover = { // Popover will be anchored around this element, trigger ref is the container, so // its children are what are inside the slot. Expect only one v-slot:trigger. const anchorEl = - this.anchorEl || - (this.$refs.trigger && this.$refs.trigger.children[0]) || - this.$el + this.anchorEl || this.$refs.trigger?.children[0] || this.$el // SVGs don't have offsetWidth/Height, use fallback const anchorHeight = anchorEl.offsetHeight || anchorEl.clientHeight const anchorWidth = anchorEl.offsetWidth || anchorEl.clientWidth @@ -155,8 +153,7 @@ const Popover = { // Minor optimization, don't call a slow reflow call if we don't have to const parentScreenBox = - this.boundTo && - (this.boundTo.x === 'container' || this.boundTo.y === 'container') && + (this.boundTo?.x === 'container' || this.boundTo?.y === 'container') && this.containerBoundingClientRect() const margin = this.margin || {} @@ -164,7 +161,7 @@ const Popover = { // What are the screen bounds for the popover? Viewport vs container // when using viewport, using default margin values to dodge the navbar const xBounds = - this.boundTo && this.boundTo.x === 'container' + this.boundTo?.x === 'container' ? { min: parentScreenBox.left + (margin.left || 0), max: parentScreenBox.right - (margin.right || 0), @@ -175,7 +172,7 @@ const Popover = { } const yBounds = - this.boundTo && this.boundTo.y === 'container' + this.boundTo?.y === 'container' ? { min: parentScreenBox.top + (margin.top || 0), max: parentScreenBox.bottom - (margin.bottom || 0), @@ -247,12 +244,12 @@ const Popover = { if (bottomBoundary + content.offsetHeight > yBounds.max) usingTop = true if (topBoundary - content.offsetHeight < yBounds.min) usingTop = false - const yOffset = (this.offset && this.offset.y) || 0 + const yOffset = this.offset?.y || 0 translateY = usingTop ? topBoundary - yOffset - content.offsetHeight : bottomBoundary + yOffset - const xOffset = (this.offset && this.offset.x) || 0 + const xOffset = this.offset?.x || 0 translateX = origin.x + horizOffset + xOffset } else { // Default to whatever user wished with placement prop @@ -268,12 +265,12 @@ const Popover = { if (rightBoundary + content.offsetWidth > xBounds.max) usingLeft = true if (leftBoundary - content.offsetWidth < xBounds.min) usingLeft = false - const xOffset = (this.offset && this.offset.x) || 0 + const xOffset = this.offset?.x || 0 translateX = usingLeft ? leftBoundary - xOffset - content.offsetWidth : rightBoundary + xOffset - const yOffset = (this.offset && this.offset.y) || 0 + const yOffset = this.offset?.y || 0 translateY = origin.y + vertOffset + yOffset } @@ -298,7 +295,7 @@ const Popover = { }, 0) const wasHidden = this.hidden this.hidden = false - this.parentPopover && this.parentPopover.onChildPopoverState(this, true) + this.parentPopover?.onChildPopoverState(this, true) if (this.trigger === 'click' || this.stayOnClick) { document.addEventListener('click', this.onClickOutside) } @@ -316,7 +313,7 @@ const Popover = { if (this.disabled) return if (!this.hidden) this.$emit('close') this.hidden = true - this.parentPopover && this.parentPopover.onChildPopoverState(this, false) + this.parentPopover?.onChildPopoverState(this, false) if (this.trigger === 'click') { document.removeEventListener('click', this.onClickOutside) } @@ -366,7 +363,7 @@ const Popover = { onClickOutside(e) { if (this.disableClickOutside) return if (this.hidden) return - if (this.$refs.content && this.$refs.content.contains(e.target)) return + if (this.$refs.content?.contains(e.target)) return if (this.$el.contains(e.target)) return if (this.childrenShown.size > 0) return this.hidePopover() diff --git a/src/components/post_status_form/post_status_form.js b/src/components/post_status_form/post_status_form.js index 02a70e388..dacca5b3c 100644 --- a/src/components/post_status_form/post_status_form.js +++ b/src/components/post_status_form/post_status_form.js @@ -316,7 +316,7 @@ const PostStatusForm = { }, // -Edit isEdit() { - return typeof this.statusId !== 'undefined' && this.statusId.trim() !== '' + return this.statusId !== undefined && this.statusId.trim() !== '' }, // -Reply isReply() { @@ -619,7 +619,7 @@ const PostStatusForm = { this.newStatus.quote = null this.newStatus.nsfw = this.defaultNewStatus.nsfw this.newStatus.mediaDescriptions = {} - this.$refs.mediaUpload && this.$refs.mediaUpload.clearFile() + this.$refs.mediaUpload?.clearFile() if (this.preserveFocus) { this.$nextTick(() => { this.$refs.textarea.focus() @@ -809,7 +809,7 @@ const PostStatusForm = { } }, fileDrop(e) { - if (e.dataTransfer && e.dataTransfer.types.includes('Files')) { + if (e.dataTransfer?.types.includes('Files')) { e.preventDefault() // allow dropping text like before this.dropFiles = e.dataTransfer.files clearTimeout(this.dropStopTimeout) @@ -826,7 +826,7 @@ const PostStatusForm = { }, fileDrag(e) { e.dataTransfer.dropEffect = this.uploadFileLimitReached ? 'none' : 'copy' - if (e.dataTransfer && e.dataTransfer.types.includes('Files')) { + if (e.dataTransfer?.types.includes('Files')) { clearTimeout(this.dropStopTimeout) this.showDropIcon = 'show' } diff --git a/src/components/post_status_form/post_status_form.vue b/src/components/post_status_form/post_status_form.vue index e38786206..f282f4947 100644 --- a/src/components/post_status_form/post_status_form.vue +++ b/src/components/post_status_form/post_status_form.vue @@ -1,8 +1,8 @@ newStatus.quote.url = url" @update:id="id => newStatus.quote.id = id" diff --git a/src/components/post_status_modal/post_status_modal.js b/src/components/post_status_modal/post_status_modal.js index 973c2b1a5..e7001db9a 100644 --- a/src/components/post_status_modal/post_status_modal.js +++ b/src/components/post_status_modal/post_status_modal.js @@ -40,9 +40,7 @@ const PostStatusModal = { }, isFormVisible(val) { if (val) { - this.$nextTick( - () => this.$el && this.$el.querySelector('textarea').focus(), - ) + this.$nextTick(() => this.$el?.querySelector('textarea').focus()) } }, }, diff --git a/src/components/quote/quote_form.js b/src/components/quote/quote_form.js index cd6f9a709..b350fb0e3 100644 --- a/src/components/quote/quote_form.js +++ b/src/components/quote/quote_form.js @@ -102,7 +102,7 @@ export default { type: 'statuses', }) .then((data) => { - if (data?.statuses && data.statuses.length === 1) { + if (data?.statuses?.length === 1) { this.$emit('update:id', data.statuses[0].id) } else { this.handleError(true) diff --git a/src/components/registration/registration.js b/src/components/registration/registration.js index 60f0fd16b..bb8de17b9 100644 --- a/src/components/registration/registration.js +++ b/src/components/registration/registration.js @@ -154,7 +154,7 @@ const registration = { }) }, replaceNewlines(str) { - return str.replace(/\s*\n\s*/g, ' \n') + return str.replaceAll(/\s*\n\s*/g, ' \n') }, }, } diff --git a/src/components/rich_content/rich_content.jsx b/src/components/rich_content/rich_content.jsx index 646df5bab..a00bf2c47 100644 --- a/src/components/rich_content/rich_content.jsx +++ b/src/components/rich_content/rich_content.jsx @@ -181,7 +181,7 @@ export default { } // Processor to use with html_tree_converter - const processItem = (item, index, array, what) => { + const processItem = (item, index, array) => { // Handle text nodes - just add emoji if (typeof item === 'string') { const emptyText = item.trim() === '' @@ -251,18 +251,14 @@ export default { return ['', [mentionsLinePadding, renderImage(opener)], ''] } else if (Tag === 'a' && this.handleLinks) { // replace mentions with MentionLink - if (fullAttrs.class && fullAttrs.class.includes('mention')) { + if (fullAttrs.class?.includes('mention')) { // Handling mentions here return renderMention(attrs, children) } else { currentMentions = null } } else if (Tag === 'span') { - if ( - this.handleLinks && - fullAttrs.class && - fullAttrs.class.includes('h-card') - ) { + if (this.handleLinks && fullAttrs.class?.includes('h-card')) { return ['', children.map(processItem), ''] } } @@ -281,7 +277,7 @@ export default { // Processor for back direction (for finding "last" stuff, just easier this way) let encounteredTextReverse = false - const processItemReverse = (item, index, array, what) => { + const processItemReverse = (item, index, array) => { // Handle text nodes - just add emoji if (typeof item === 'string') { const emptyText = item.trim() === '' @@ -300,7 +296,7 @@ export default { const attrs = getAttrs(opener, () => true) // should only be this if ( - (fullAttrs.class && fullAttrs.class.includes('hashtag')) || // Pleroma style + fullAttrs.class?.includes('hashtag') || // Pleroma style fullAttrs.rel === 'tag' // Mastodon style ) { return renderHashtag(attrs, children, encounteredTextReverse) @@ -479,7 +475,7 @@ export default { > {this.collapse ? pass2.map((x) => { - if (typeof x === 'string') return x.replace(/\n/g, ' ') + if (typeof x === 'string') return x.replaceAll('\n', ' ') if (!Array.isArray(x)) return x return x.map((y) => (y.type === 'br' ? ' ' : y)) }) @@ -547,8 +543,8 @@ export const preProcessPerLine = (html, greentext) => { (string.includes('>') || string.includes('<')) ) { const cleanedString = string - .replace(/<[^>]+?>/gi, '') // remove all tags - .replace(/@\w+/gi, '') // remove mentions (even failed ones) + .replaceAll(/<[^>]+?>/gi, '') // remove all tags + .replaceAll(/@\w+/gi, '') // remove mentions (even failed ones) .trim() if (cleanedString.startsWith('>')) { return `${string}` diff --git a/src/components/search/search.js b/src/components/search/search.js index 0a1f779bb..1a5f8b51d 100644 --- a/src/components/search/search.js +++ b/src/components/search/search.js @@ -122,7 +122,7 @@ const Search = { return 'statuses' }, lastHistoryRecord(hashtag) { - return hashtag.history && hashtag.history[0] + return hashtag.history?.[0] }, }, } diff --git a/src/components/settings_modal/admin_tabs/emoji_tab.js b/src/components/settings_modal/admin_tabs/emoji_tab.js index 56361587d..7dc9e91bf 100644 --- a/src/components/settings_modal/admin_tabs/emoji_tab.js +++ b/src/components/settings_modal/admin_tabs/emoji_tab.js @@ -300,7 +300,7 @@ const EmojiTab = { sortPackFiles(nameOfPack) { // Sort by key const sorted = Object.keys(this.knownPacks[nameOfPack].files) - .sort() + .sort((a, b) => a.localeCompare(b)) .reduce((acc, key) => { if (key.length === 0) return acc acc[key] = this.knownPacks[nameOfPack].files[key] diff --git a/src/components/settings_modal/helpers/setting.js b/src/components/settings_modal/helpers/setting.js index c2f5279f6..09d3ecc2d 100644 --- a/src/components/settings_modal/helpers/setting.js +++ b/src/components/settings_modal/helpers/setting.js @@ -179,7 +179,7 @@ export default { [ 'admin_dash', 'temp_overrides', - ...this.canonPath.map((p) => p.replace(/\./g, '_DOT_')), + ...this.canonPath.map((p) => p.replaceAll('.', '_DOT_')), 'label', ].join('.'), ) @@ -198,7 +198,7 @@ export default { [ 'admin_dash', 'temp_overrides', - ...this.canonPath.map((p) => p.replace(/\./g, '_DOT_')), + ...this.canonPath.map((p) => p.replaceAll('.', '_DOT_')), 'description', ].join('.'), ) diff --git a/src/components/settings_modal/tabs/appearance_tab.js b/src/components/settings_modal/tabs/appearance_tab.js index 518345d9e..d93758f9a 100644 --- a/src/components/settings_modal/tabs/appearance_tab.js +++ b/src/components/settings_modal/tabs/appearance_tab.js @@ -257,7 +257,7 @@ const AppearanceTab = { const result = { name: `${meta.directives.name || this.$t('settings.style.themes3.palette.imported')}: ${variant}`, - key: `style.${variant.toLowerCase().replace(/ /g, '_')}`, + key: `style.${variant.toLowerCase().replaceAll(' ', '_')}`, bg, fg, text, diff --git a/src/components/settings_modal/tabs/old_theme_tab/old_theme_tab.js b/src/components/settings_modal/tabs/old_theme_tab/old_theme_tab.js index 13bcc3ae6..40df1b98e 100644 --- a/src/components/settings_modal/tabs/old_theme_tab/old_theme_tab.js +++ b/src/components/settings_modal/tabs/old_theme_tab/old_theme_tab.js @@ -319,7 +319,7 @@ export default { return useInterfaceStore().themeDataUsed }, shadowsAvailable() { - return Object.keys(DEFAULT_SHADOWS).sort() + return Object.keys(DEFAULT_SHADOWS).sort((a, b) => a.localeCompare(b)) }, currentShadowOverriden: { get() { @@ -346,7 +346,7 @@ export default { }, }, currentShadowFallback() { - return (this.previewTheme.shadows || {})[this.shadowSelected] + return this.previewTheme.shadows?.[this.shadowSelected] }, currentShadow: { get() { @@ -425,8 +425,8 @@ export default { this.dismissWarning() const version = origin === 'localStorage' && !theme.colors ? 'l1' : fileVersion - const snapshotEngineVersion = (theme || {}).themeEngineVersion - const themeEngineVersion = (source || {}).themeEngineVersion || 2 + const snapshotEngineVersion = theme?.themeEngineVersion + const themeEngineVersion = source?.themeEngineVersion || 2 const versionsMatch = themeEngineVersion === CURRENT_VERSION const sourceSnapshotMismatch = theme !== undefined && diff --git a/src/components/side_drawer/side_drawer.js b/src/components/side_drawer/side_drawer.js index 369177c7a..a1dca8161 100644 --- a/src/components/side_drawer/side_drawer.js +++ b/src/components/side_drawer/side_drawer.js @@ -61,7 +61,7 @@ const SideDrawer = { this.toggleDrawer, ) - if (this.currentUser && this.currentUser.locked) { + if (this.currentUser?.locked) { this.$store.dispatch('startFetchingFollowRequests') } }, diff --git a/src/components/status/status.js b/src/components/status/status.js index 61a553ef6..3e10a24e1 100644 --- a/src/components/status/status.js +++ b/src/components/status/status.js @@ -128,8 +128,7 @@ const Status = { computed: { showReasonMutedThread() { return ( - (this.status.thread_muted || - (this.status.reblog && this.status.reblog.thread_muted)) && + (this.status.thread_muted || this.status.reblog?.thread_muted) && !this.inConversation ) }, diff --git a/src/components/status_action_buttons/status_action_buttons.vue b/src/components/status_action_buttons/status_action_buttons.vue index 34e5e25ea..c829a1f50 100644 --- a/src/components/status_action_buttons/status_action_buttons.vue +++ b/src/components/status_action_buttons/status_action_buttons.vue @@ -20,9 +20,9 @@ :get-component="getComponent" :close="() => { /* no-op */ }" :do-action="doAction" - @emoji-picker-shown="onEmojiPickerShown" :default-button-style="useDefaultButtons" :hide-label="hideLabels" + @emoji-picker-shown="onEmojiPickerShown" /> file.type) }, collapsedStatus() { - return this.status.raw_html.replace(/(\n|)/g, ' ') + return this.status.raw_html.replaceAll('(\n|)', ' ') }, ...mapState(useMergedConfigStore, ['mergedConfig']), }, mounted() { - this.status.attentions && - this.status.attentions.forEach((attn) => { - const { id } = attn - this.$store.dispatch('fetchUserIfMissing', id) - }) + this.status.attentions?.forEach((attn) => { + const { id } = attn + this.$store.dispatch('fetchUserIfMissing', id) + }) }, methods: { onParseReady(event) { @@ -168,7 +167,7 @@ const StatusBody = { .filter((mention) => !mention.notifying) .forEach((mention) => { const { content, url } = mention - const cleanedString = content.replace(/<[^>]+?>/gi, '') // remove all tags + const cleanedString = content.replaceAll(/<[^>]+?>/gi, '') // remove all tags if (!cleanedString.startsWith('@')) return const handle = cleanedString.slice(1) const host = url.replace(/^https?:\/\//, '').replace(/\/.+?$/, '') diff --git a/src/components/still-image/still-image.js b/src/components/still-image/still-image.js index 29a4ed1de..809bd8c7d 100644 --- a/src/components/still-image/still-image.js +++ b/src/components/still-image/still-image.js @@ -51,7 +51,7 @@ const StillImage = { } const image = this.$refs.src if (!image) return - this.imageLoadHandler && this.imageLoadHandler(image) + this.imageLoadHandler?.(image) const canvas = this.$refs.canvas if (!canvas) return const width = image.naturalWidth @@ -61,7 +61,7 @@ const StillImage = { canvas.getContext('2d').drawImage(image, 0, 0, width, height) }, onError() { - this.imageLoadError && this.imageLoadError() + this.imageLoadError?.() }, }, watch: { diff --git a/src/components/tab_switcher/tab_switcher.jsx b/src/components/tab_switcher/tab_switcher.jsx index 2c86983d8..01913f709 100644 --- a/src/components/tab_switcher/tab_switcher.jsx +++ b/src/components/tab_switcher/tab_switcher.jsx @@ -111,7 +111,11 @@ export default { type="button" role="tab" > - + {props.label ? '' : props.label} diff --git a/src/components/user_card/user_card.js b/src/components/user_card/user_card.js index 9f6488b34..b6e720c6f 100644 --- a/src/components/user_card/user_card.js +++ b/src/components/user_card/user_card.js @@ -196,7 +196,7 @@ export default { }, computed: { escapedNewBio() { - return ldEscape(this.newBio).replace(/\n/g, '') + return ldEscape(this.newBio).replaceAll('\n', '') }, somethingToSave() { if (this.newName !== this.user.name_unescaped) return true diff --git a/src/lib/persisted_state.js b/src/lib/persisted_state.js index f6375dfed..aef1cc8dc 100644 --- a/src/lib/persisted_state.js +++ b/src/lib/persisted_state.js @@ -185,7 +185,7 @@ export const piniaPersistPlugin = } const fallbackValue = await storage.getItem(vuexKey) - if (fallbackValue && fallbackValue[id]) { + if (fallbackValue?.[id]) { console.info(`Migrating ${id} store data from vuex to pinia`) const res = fallbackValue[id] await storage.setItem(key, res) diff --git a/src/modules/api.js b/src/modules/api.js index e26336c05..92b849a2b 100644 --- a/src/modules/api.js +++ b/src/modules/api.js @@ -336,7 +336,7 @@ const api = { } }, disconnectFromSocket({ commit, state }) { - state.socket && state.socket.disconnect() + state.socket?.disconnect() commit('setSocket', null) }, }, diff --git a/src/modules/statuses.js b/src/modules/statuses.js index ee5e50a39..e3878e85c 100644 --- a/src/modules/statuses.js +++ b/src/modules/statuses.js @@ -134,7 +134,7 @@ const sortById = (a, b) => { const sortTimeline = (timeline) => { timeline.visibleStatuses = timeline.visibleStatuses.sort(sortById) timeline.statuses = timeline.statuses.sort(sortById) - timeline.minVisibleId = (last(timeline.visibleStatuses) || {}).id + timeline.minVisibleId = last(timeline.visibleStatuses)?.id return timeline } diff --git a/src/services/chat_utils/chat_utils.js b/src/services/chat_utils/chat_utils.js index ccf91e85c..bc02981cd 100644 --- a/src/services/chat_utils/chat_utils.js +++ b/src/services/chat_utils/chat_utils.js @@ -12,10 +12,7 @@ export const maybeShowChatNotification = (chat) => { body: chat.lastMessage.content, } - if ( - chat.lastMessage.attachment && - chat.lastMessage.attachment.type === 'image' - ) { + if (chat.lastMessage.attachment?.type === 'image') { opts.image = chat.lastMessage.attachment.preview_url } diff --git a/src/services/entity_normalizer/entity_normalizer.service.js b/src/services/entity_normalizer/entity_normalizer.service.js index d2df5e869..5b8fa5b57 100644 --- a/src/services/entity_normalizer/entity_normalizer.service.js +++ b/src/services/entity_normalizer/entity_normalizer.service.js @@ -62,8 +62,8 @@ export const parseUser = (data) => { }) output.fields_text = data.fields.map((field) => { return { - name: unescape(field.name.replace(/<[^>]*>/g, '')), - value: unescape(field.value.replace(/<[^>]*>/g, '')), + name: unescape(field.name.replaceAll(/<[^>]*>/g, '')), + value: unescape(field.value.replaceAll(/<[^>]*>/g, '')), } }) @@ -191,7 +191,7 @@ export const parseUser = (data) => { // Convert punycode to unicode for UI output.screen_name_ui = output.screen_name - if (output.screen_name && output.screen_name.includes('@')) { + if (output.screen_name?.includes('@')) { const parts = output.screen_name.split('@') const unicodeDomain = punycode.toUnicode(parts[1]) if (unicodeDomain !== parts[1]) { diff --git a/src/services/errors/errors.js b/src/services/errors/errors.js index 5fbb8da11..0742de3f4 100644 --- a/src/services/errors/errors.js +++ b/src/services/errors/errors.js @@ -3,7 +3,7 @@ import { capitalize } from 'lodash' function humanizeErrors(errors) { return Object.entries(errors).reduce((errs, [k, val]) => { const message = val.reduce((acc, message) => { - const key = capitalize(k.replace(/_/g, ' ')) + const key = capitalize(k.replaceAll('_', ' ')) return acc + [key, message].join(' ') + '. ' }, '') return [...errs, message] diff --git a/src/services/notification_utils/notification_utils.js b/src/services/notification_utils/notification_utils.js index 6cb3dbc19..46b81cc66 100644 --- a/src/services/notification_utils/notification_utils.js +++ b/src/services/notification_utils/notification_utils.js @@ -175,13 +175,7 @@ export const prepareNotificationObject = (notification, i18n) => { } // Shows first attached non-nsfw image, if any. Should add configuration for this somehow... - if ( - status && - status.attachments && - status.attachments.length > 0 && - !status.nsfw && - status.attachments[0].mimetype.startsWith('image/') - ) { + if (!status.nsfw && status?.attachments?.[0]?.mimetype.startsWith('image/')) { notifObj.image = status.attachments[0].url } diff --git a/src/services/notifications_fetcher/notifications_fetcher.service.js b/src/services/notifications_fetcher/notifications_fetcher.service.js index 8530c468c..0e0bc0277 100644 --- a/src/services/notifications_fetcher/notifications_fetcher.service.js +++ b/src/services/notifications_fetcher/notifications_fetcher.service.js @@ -66,7 +66,8 @@ const fetchAndUpdate = ({ store, credentials, older = false, sinceId }) => { const unreadNotifsIds = notifications .filter((n) => !n.seen) .map((n) => n.id) - if (readNotifsIds.length > 0 && readNotifsIds.length > 0) { + + if (readNotifsIds.length > 0 && unreadNotifsIds.length > 0) { const minId = Math.min(...unreadNotifsIds) // Oldest known unread notification if (minId !== Infinity) { args.sinceId = null // Don't use since_id since it sorta conflicts with min_id diff --git a/src/services/style_setter/style_setter.js b/src/services/style_setter/style_setter.js index cb445d2c1..4eed080c1 100644 --- a/src/services/style_setter/style_setter.js +++ b/src/services/style_setter/style_setter.js @@ -29,7 +29,7 @@ export const createStyleSheet = (id, priority = 1000) => { addRule(rule) { let newRule = rule if (!CSS.supports?.('backdrop-filter', 'blur()')) { - newRule = newRule.replace(/backdrop-filter:[^;]+;/g, '') // Remove backdrop-filter + newRule = newRule.replaceAll(/backdrop-filter:[^;]+;/g, '') // Remove backdrop-filter } if (newRule.startsWith('::-webkit')) { @@ -44,7 +44,7 @@ export const createStyleSheet = (id, priority = 1000) => { } this.rules.push( - newRule.replace(/var\(--shadowFilter\)[^;]*;/g, ''), // Remove shadowFilter references + newRule.replaceAll(/var\(--shadowFilter\)[^;]*;/g, ''), // Remove shadowFilter references ) }, } diff --git a/src/services/sw/sw.js b/src/services/sw/sw.js index b45409b28..2b7dabd41 100644 --- a/src/services/sw/sw.js +++ b/src/services/sw/sw.js @@ -1,7 +1,9 @@ /* global process */ function urlBase64ToUint8Array(base64String) { const padding = '='.repeat((4 - (base64String.length % 4)) % 4) - const base64 = (base64String + padding).replace(/-/g, '+').replace(/_/g, '/') + const base64 = (base64String + padding) + .replaceAll('-', '+') + .replace(/_/g, '/') const rawData = window.atob(base64) return Uint8Array.from([...rawData].map((char) => char.codePointAt(0))) diff --git a/src/services/theme_data/iss_utils.js b/src/services/theme_data/iss_utils.js index e5aa5cd15..67579a118 100644 --- a/src/services/theme_data/iss_utils.js +++ b/src/services/theme_data/iss_utils.js @@ -110,13 +110,6 @@ export const genericRuleToSelector = let arraySelector = Array.isArray(selector) ? selector : [selector] if (ignoreOutOfTreeSelector || liteMode) arraySelector = [arraySelector[0]] - arraySelector - .sort((a) => { - if (a.startsWith(':')) return 1 - if (/^[a-z]/.exec(a)) return -1 - else return 0 - }) - .join('') return arraySelector }) diff --git a/src/services/theme_data/theme_data.service.js b/src/services/theme_data/theme_data.service.js index cdce2cf57..cc5553936 100644 --- a/src/services/theme_data/theme_data.service.js +++ b/src/services/theme_data/theme_data.service.js @@ -244,10 +244,7 @@ export const OPACITIES = Object.entries(SLOT_INHERITANCE).reduce((acc, [k]) => { ...acc, [opacity]: { defaultValue: DEFAULT_OPACITY[opacity] || 1, - affectedSlots: [ - ...((acc[opacity] && acc[opacity].affectedSlots) || []), - k, - ], + affectedSlots: [...(acc[opacity]?.affectedSlots || []), k], }, } } else { @@ -413,7 +410,7 @@ export const getColors = (sourceColors, sourceOpacity) => outputColor.a = Number( opacityOverriden ? sourceOpacity[opacitySlot] - : (OPACITIES[opacitySlot] || {}).defaultValue, + : OPACITIES[opacitySlot]?.defaultValue, ) } } @@ -460,7 +457,7 @@ export const generatePreset = (input) => { return composePreset( colors, generateRadii(input), - generateShadows(input, colors.theme.colors, colors.mod), + generateShadows(input, colors.theme.colors), generateFonts(input), ) } diff --git a/src/services/user_highlighter/user_highlighter.js b/src/services/user_highlighter/user_highlighter.js index 697496c91..e3f94ea1a 100644 --- a/src/services/user_highlighter/user_highlighter.js +++ b/src/services/user_highlighter/user_highlighter.js @@ -47,7 +47,7 @@ const highlightStyle = (prefs) => { const highlightClass = (user) => { return ( - 'USER____' + user.screen_name?.replace(/\./g, '_').replace(/@/g, '_AT_') + 'USER____' + user.screen_name?.replaceAll('.', '_').replace(/@/g, '_AT_') ) } diff --git a/src/stores/chats.js b/src/stores/chats.js index bc5b7f101..7908da9c8 100644 --- a/src/stores/chats.js +++ b/src/stores/chats.js @@ -69,8 +69,7 @@ export const useChatsStore = defineStore('chats', { if (chat) { const isNewMessage = - (chat.lastMessage && chat.lastMessage.id) !== - (updatedChat.lastMessage && updatedChat.lastMessage.id) + chat.lastMessage?.id !== updatedChat.lastMessage?.id chat.lastMessage = updatedChat.lastMessage chat.unread = updatedChat.unread chat.updated_at = updatedChat.updated_at diff --git a/src/stores/emoji.js b/src/stores/emoji.js index 3316f8328..2d77954f1 100644 --- a/src/stores/emoji.js +++ b/src/stores/emoji.js @@ -146,7 +146,7 @@ export const useEmojiStore = defineStore('emoji', { async getStaticEmoji() { try { // See build/emojis_plugin for more details - const values = (await import('/src/assets/emoji.json')).default + const values = (await import('src/assets/emoji.json')).default const emoji = Object.keys(values).reduce((res, groupId) => { res[groupId] = values[groupId].map((e) => ({ @@ -231,7 +231,7 @@ export const useEmojiStore = defineStore('emoji', { .then((allPacks) => { // Sort by key return Object.keys(allPacks) - .sort() + .sort((a, b) => a.localeCompare(b)) .reduce((acc, key) => { if (key.length === 0) return acc acc[key] = allPacks[key] diff --git a/src/stores/interface.js b/src/stores/interface.js index 87ef65865..edc879614 100644 --- a/src/stores/interface.js +++ b/src/stores/interface.js @@ -60,8 +60,7 @@ export const useInterfaceStore = defineStore('interface', { }, browserSupport: { cssFilter: - window.CSS && - window.CSS.supports && + window.CSS?.supports && (window.CSS.supports('filter', 'drop-shadow(0 0)') || window.CSS.supports('-webkit-filter', 'drop-shadow(0 0)')), localFonts: typeof window.queryLocalFonts === 'function', @@ -578,7 +577,8 @@ export const useInterfaceStore = defineStore('interface', { return { name: x.variant, ...cleanDirectives } }) .forEach((palette) => { - const key = 'style.' + palette.name.toLowerCase().replace(/ /g, '_') + const key = + 'style.' + palette.name.toLowerCase().replaceAll(' ', '_') if (!firstStylePaletteName) firstStylePaletteName = key palettesIndex[key] = () => Promise.resolve(palette) }) diff --git a/src/stores/sync_config.js b/src/stores/sync_config.js index 87083d850..3b71478c1 100644 --- a/src/stores/sync_config.js +++ b/src/stores/sync_config.js @@ -195,10 +195,13 @@ export const _getRecentData = (cache, live, isTest) => { } export const _getAllFlags = (recent, stale) => { + const recentStorage = toRaw(recent?.flagStorage) + const staleStorage = toRaw(stale?.flagStorage) + return Array.from( new Set([ - ...Object.keys(toRaw((recent || {}).flagStorage || {})), - ...Object.keys(toRaw((stale || {}).flagStorage || {})), + ...Object.keys(recentStorage || {}), + ...Object.keys(staleStorage || {}), ]), ) } diff --git a/test/unit/specs/components/rich_content.spec.js b/test/unit/specs/components/rich_content.spec.js index fdf6c7f8f..cc79fe377 100644 --- a/test/unit/specs/components/rich_content.spec.js +++ b/test/unit/specs/components/rich_content.spec.js @@ -50,7 +50,7 @@ describe('RichContent', () => { }, }) - expect(wrapper.html().replace(/\n/g, '')).to.eql(compwrap(html)) + expect(wrapper.html().replaceAll('\n', '')).to.eql(compwrap(html)) }) it('unescapes everything as needed', () => { @@ -67,7 +67,7 @@ describe('RichContent', () => { }, }) - expect(wrapper.html().replace(/\n/g, '')).to.eql(compwrap(expected)) + expect(wrapper.html().replaceAll('\n', '')).to.eql(compwrap(expected)) }) it('replaces mention with mentionsline', () => { @@ -83,7 +83,7 @@ describe('RichContent', () => { }, }) - expect(wrapper.html().replace(/\n/g, '')).to.eql( + expect(wrapper.html().replaceAll('\n', '')).to.eql( compwrap(p(mentionsLine(1), ' how are you doing today?')), ) }) @@ -116,7 +116,7 @@ describe('RichContent', () => { }, }) - expect(wrapper.html().replace(/\n/g, '')).to.eql(compwrap(expected)) + expect(wrapper.html().replaceAll('\n', '')).to.eql(compwrap(expected)) }) it('Does not touch links if link handling is disabled', () => { @@ -211,7 +211,7 @@ describe('RichContent', () => { }, }) - expect(wrapper.html().replace(/\n/g, '')).to.eql(compwrap(expected)) + expect(wrapper.html().replaceAll('\n', '')).to.eql(compwrap(expected)) }) it("Doesn't add nonexistent emoji to post", () => { @@ -228,7 +228,7 @@ describe('RichContent', () => { }, }) - expect(wrapper.html().replace(/\n/g, '')).to.eql(compwrap(html)) + expect(wrapper.html().replaceAll('\n', '')).to.eql(compwrap(html)) }) it('Greentext + last mentions', () => { @@ -279,7 +279,7 @@ describe('RichContent', () => { }, }) - expect(wrapper.html().replace(/\n/g, '')).to.eql(compwrap(expected)) + expect(wrapper.html().replaceAll('\n', '')).to.eql(compwrap(expected)) }) it('buggy example/hashtags', () => { @@ -315,7 +315,7 @@ describe('RichContent', () => { }, }) - expect(wrapper.html().replace(/\n/g, '')).to.eql(compwrap(expected)) + expect(wrapper.html().replaceAll('\n', '')).to.eql(compwrap(expected)) }) it('rich contents of a mention are handled properly', () => { @@ -365,8 +365,8 @@ describe('RichContent', () => { expect( wrapper .html() - .replace(/\n/g, '') - .replace(//g, ''), + .replaceAll('\n', '') + .replaceAll(//g, ''), ).to.eql(compwrap(expected)) }) @@ -438,8 +438,8 @@ describe('RichContent', () => { expect( wrapper .html() - .replace(/\n/g, '') - .replace(//g, ''), + .replaceAll('\n', '') + .replaceAll(//g, ''), ).to.eql(compwrap(expected)) }) @@ -484,7 +484,7 @@ describe('RichContent', () => { }, }) - expect(wrapper.html().replace(/\n/g, '')).to.eql(compwrap(expected)) + expect(wrapper.html().replaceAll('\n', '')).to.eql(compwrap(expected)) }) it.skip('[INFORMATIVE] Performance testing, 10 000 simple posts', () => { diff --git a/test/unit/specs/modules/statuses.spec.js b/test/unit/specs/modules/statuses.spec.js index 1315724da..cd43496a9 100644 --- a/test/unit/specs/modules/statuses.spec.js +++ b/test/unit/specs/modules/statuses.spec.js @@ -107,7 +107,7 @@ describe('Statuses module', () => { showImmediately: true, timeline: 'public', }) - expect(state.timelines.public.maxId).to.eql('1') + expect(state.timelines.public.maxId).to.equal('1') mutations.addNewStatuses(state, { statuses: [secondStatus], @@ -120,7 +120,7 @@ describe('Statuses module', () => { secondStatus, status, ]) - expect(state.timelines.public.maxId).to.eql('1') + expect(state.timelines.public.maxId).to.equal('1') }) it('keeps a descending by id order in timeline.visibleStatuses and timeline.statuses', () => { @@ -340,7 +340,7 @@ describe('Statuses module', () => { expect(state.allStatusesObject['1'].emoji_reactions[0].me).to.eql(true) expect( state.allStatusesObject['1'].emoji_reactions[0].accounts[0].id, - ).to.eql('me') + ).to.equal('me') }) it('adds a new reaction', () => { @@ -362,7 +362,7 @@ describe('Statuses module', () => { expect(state.allStatusesObject['1'].emoji_reactions[0].me).to.eql(true) expect( state.allStatusesObject['1'].emoji_reactions[0].accounts[0].id, - ).to.eql('me') + ).to.equal('me') }) it('decreases count in existing reaction', () => { @@ -429,8 +429,8 @@ describe('Statuses module', () => { mutations.showNewStatuses(state, { timeline: 'public' }) expect(state.timelines.public.visibleStatuses.length).to.eql(2) - expect(state.timelines.public.minVisibleId).to.eql('10') - expect(state.timelines.public.minId).to.eql('10') + expect(state.timelines.public.minVisibleId).to.equal('10') + expect(state.timelines.public.minId).to.equal('10') }) }) diff --git a/tools/emoji_merger.js b/tools/emoji_merger.js index b49ead471..1e37134a7 100644 --- a/tools/emoji_merger.js +++ b/tools/emoji_merger.js @@ -54,7 +54,7 @@ const run = () => { // Sort by key const sorted = Object.keys(emojisObject) - .sort() + .sort((a, b) => a.localeCompare(b)) .reduce((acc, key) => { if (key.length === 0) return acc acc[key] = emojisObject[key]