refactor: remove withDefaults
macro and clean up reactive props destructuring (#3217)
This commit is contained in:
parent
7d9712c209
commit
60b1d0224c
52 changed files with 177 additions and 232 deletions
|
@ -1,7 +1,7 @@
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import type { mastodon } from 'masto'
|
import type { mastodon } from 'masto'
|
||||||
|
|
||||||
const props = defineProps<{
|
const { account } = defineProps<{
|
||||||
account: mastodon.v1.Account
|
account: mastodon.v1.Account
|
||||||
square?: boolean
|
square?: boolean
|
||||||
}>()
|
}>()
|
||||||
|
@ -11,22 +11,22 @@ const error = ref(false)
|
||||||
|
|
||||||
const preferredMotion = usePreferredReducedMotion()
|
const preferredMotion = usePreferredReducedMotion()
|
||||||
const accountAvatarSrc = computed(() => {
|
const accountAvatarSrc = computed(() => {
|
||||||
return preferredMotion.value === 'reduce' ? (props.account?.avatarStatic ?? props.account.avatar) : props.account.avatar
|
return preferredMotion.value === 'reduce' ? (account?.avatarStatic ?? account.avatar) : account.avatar
|
||||||
})
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<img
|
<img
|
||||||
:key="props.account.avatar"
|
:key="account.avatar"
|
||||||
width="400"
|
width="400"
|
||||||
height="400"
|
height="400"
|
||||||
select-none
|
select-none
|
||||||
:src="(error || !loaded) ? 'data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7' : accountAvatarSrc"
|
:src="(error || !loaded) ? 'data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7' : accountAvatarSrc"
|
||||||
:alt="$t('account.avatar_description', [props.account.username])"
|
:alt="$t('account.avatar_description', [account.username])"
|
||||||
loading="lazy"
|
loading="lazy"
|
||||||
class="account-avatar object-cover"
|
class="account-avatar object-cover"
|
||||||
:class="(loaded ? 'bg-base' : 'bg-gray:10') + (props.square ? ' ' : ' rounded-full')"
|
:class="(loaded ? 'bg-base' : 'bg-gray:10') + (square ? ' ' : ' rounded-full')"
|
||||||
:style="{ 'clip-path': props.square ? `url(#avatar-mask)` : 'none' }"
|
:style="{ 'clip-path': square ? `url(#avatar-mask)` : 'none' }"
|
||||||
v-bind="$attrs"
|
v-bind="$attrs"
|
||||||
@load="loaded = true"
|
@load="loaded = true"
|
||||||
@error="error = true"
|
@error="error = true"
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import type { mastodon } from 'masto'
|
import type { mastodon } from 'masto'
|
||||||
|
|
||||||
const { account, hideEmojis = false } = defineProps<{
|
const { hideEmojis = false } = defineProps<{
|
||||||
account: mastodon.v1.Account
|
account: mastodon.v1.Account
|
||||||
hideEmojis?: boolean
|
hideEmojis?: boolean
|
||||||
}>()
|
}>()
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
import type { mastodon } from 'masto'
|
import type { mastodon } from 'masto'
|
||||||
import { toggleFollowAccount, useRelationship } from '~~/composables/masto/relationship'
|
import { toggleFollowAccount, useRelationship } from '~~/composables/masto/relationship'
|
||||||
|
|
||||||
const { account, command, context, ...props } = defineProps<{
|
const { account, context, command, ...props } = defineProps<{
|
||||||
account: mastodon.v1.Account
|
account: mastodon.v1.Account
|
||||||
relationship?: mastodon.v1.Relationship
|
relationship?: mastodon.v1.Relationship
|
||||||
context?: 'followedBy' | 'following'
|
context?: 'followedBy' | 'following'
|
||||||
|
|
|
@ -5,7 +5,7 @@ defineOptions({
|
||||||
inheritAttrs: false,
|
inheritAttrs: false,
|
||||||
})
|
})
|
||||||
|
|
||||||
const { account, as = 'div' } = defineProps<{
|
const { as = 'div' } = defineProps<{
|
||||||
account: mastodon.v1.Account
|
account: mastodon.v1.Account
|
||||||
as?: string
|
as?: string
|
||||||
hoverCard?: boolean
|
hoverCard?: boolean
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import type { mastodon } from 'masto'
|
import type { mastodon } from 'masto'
|
||||||
|
|
||||||
const { paginator, account, context } = defineProps<{
|
const { account, context } = defineProps<{
|
||||||
paginator: mastodon.Paginator<mastodon.v1.Account[], mastodon.DefaultPaginationParams | undefined>
|
paginator: mastodon.Paginator<mastodon.v1.Account[], mastodon.DefaultPaginationParams | undefined>
|
||||||
context?: 'following' | 'followers'
|
context?: 'following' | 'followers'
|
||||||
account?: mastodon.v1.Account
|
account?: mastodon.v1.Account
|
||||||
|
|
|
@ -5,7 +5,7 @@ defineOptions({
|
||||||
inheritAttrs: false,
|
inheritAttrs: false,
|
||||||
})
|
})
|
||||||
|
|
||||||
const { tagName, disabled } = defineProps<{
|
const { tagName } = defineProps<{
|
||||||
tagName?: string
|
tagName?: string
|
||||||
disabled?: boolean
|
disabled?: boolean
|
||||||
}>()
|
}>()
|
||||||
|
|
|
@ -1,17 +1,16 @@
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import type { AriaLive } from '~/composables/aria'
|
import type { AriaLive } from '~/composables/aria'
|
||||||
|
|
||||||
// tsc complaining when using $defineProps
|
const {
|
||||||
withDefaults(defineProps<{
|
ariaLive = 'polite',
|
||||||
title: string
|
heading = 'h2',
|
||||||
|
messageKey = (message: any) => message,
|
||||||
|
} = defineProps<{
|
||||||
ariaLive?: AriaLive
|
ariaLive?: AriaLive
|
||||||
messageKey?: (message: any) => any
|
|
||||||
heading?: 'h2' | 'h3' | 'h4' | 'h5' | 'h6'
|
heading?: 'h2' | 'h3' | 'h4' | 'h5' | 'h6'
|
||||||
}>(), {
|
title: string
|
||||||
heading: 'h2',
|
messageKey?: (message: any) => any
|
||||||
messageKey: (message: any) => message,
|
}>()
|
||||||
ariaLive: 'polite',
|
|
||||||
})
|
|
||||||
|
|
||||||
const { announceLogs, appendLogs, clearLogs, logs } = useAriaLog()
|
const { announceLogs, appendLogs, clearLogs, logs } = useAriaLog()
|
||||||
|
|
||||||
|
|
|
@ -1,12 +1,9 @@
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import type { AriaLive } from '~/composables/aria'
|
import type { AriaLive } from '~/composables/aria'
|
||||||
|
|
||||||
// tsc complaining when using $defineProps
|
const { ariaLive = 'polite' } = defineProps<{
|
||||||
withDefaults(defineProps<{
|
|
||||||
ariaLive?: AriaLive
|
ariaLive?: AriaLive
|
||||||
}>(), {
|
}>()
|
||||||
ariaLive: 'polite',
|
|
||||||
})
|
|
||||||
|
|
||||||
const { announceStatus, clearStatus, status } = useAriaStatus()
|
const { announceStatus, clearStatus, status } = useAriaStatus()
|
||||||
|
|
||||||
|
|
|
@ -1,11 +1,7 @@
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import type { ResolvedCommand } from '~/composables/command'
|
import type { ResolvedCommand } from '~/composables/command'
|
||||||
|
|
||||||
const {
|
const { active = false } = defineProps<{
|
||||||
cmd,
|
|
||||||
index,
|
|
||||||
active = false,
|
|
||||||
} = defineProps<{
|
|
||||||
cmd: ResolvedCommand
|
cmd: ResolvedCommand
|
||||||
index: number
|
index: number
|
||||||
active?: boolean
|
active?: boolean
|
||||||
|
|
|
@ -1,11 +1,11 @@
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
const props = defineProps<{
|
const { name } = defineProps<{
|
||||||
name: string
|
name: string
|
||||||
}>()
|
}>()
|
||||||
|
|
||||||
const isMac = useIsMac()
|
const isMac = useIsMac()
|
||||||
|
|
||||||
const keys = computed(() => props.name.toLowerCase().split('+'))
|
const keys = computed(() => name.toLowerCase().split('+'))
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
|
|
|
@ -3,7 +3,7 @@ defineOptions({
|
||||||
inheritAttrs: false,
|
inheritAttrs: false,
|
||||||
})
|
})
|
||||||
|
|
||||||
const { blurhash = '', src, srcset, shouldLoadImage = true } = defineProps<{
|
const { blurhash = '', shouldLoadImage = true } = defineProps<{
|
||||||
blurhash?: string
|
blurhash?: string
|
||||||
src: string
|
src: string
|
||||||
srcset?: string
|
srcset?: string
|
||||||
|
|
|
@ -3,25 +3,18 @@ import type { Boundaries } from 'vue-advanced-cropper'
|
||||||
import { Cropper } from 'vue-advanced-cropper'
|
import { Cropper } from 'vue-advanced-cropper'
|
||||||
import 'vue-advanced-cropper/dist/style.css'
|
import 'vue-advanced-cropper/dist/style.css'
|
||||||
|
|
||||||
export interface Props {
|
const { stencilAspectRatio = 1 / 1, stencilSizePercentage = 0.9 } = defineProps<{
|
||||||
/** Crop frame aspect ratio (width/height), default 1/1 */
|
/** Crop frame aspect ratio (width/height), default 1/1 */
|
||||||
stencilAspectRatio?: number
|
stencilAspectRatio?: number
|
||||||
/** The ratio of the longest edge of the cut box to the length of the cut screen, default 0.9, not more than 1 */
|
/** The ratio of the longest edge of the cut box to the length of the cut screen, default 0.9, not more than 1 */
|
||||||
stencilSizePercentage?: number
|
stencilSizePercentage?: number
|
||||||
}
|
}>()
|
||||||
const props = withDefaults(defineProps<Props>(), {
|
|
||||||
stencilAspectRatio: 1 / 1,
|
|
||||||
stencilSizePercentage: 0.9,
|
|
||||||
})
|
|
||||||
|
|
||||||
const file = defineModel<File | null>()
|
const file = defineModel<File | null>()
|
||||||
|
|
||||||
const cropperDialog = ref(false)
|
const cropperDialog = ref(false)
|
||||||
|
|
||||||
const cropper = ref<InstanceType<typeof Cropper>>()
|
const cropper = ref<InstanceType<typeof Cropper>>()
|
||||||
|
|
||||||
const cropperFlag = ref(false)
|
const cropperFlag = ref(false)
|
||||||
|
|
||||||
const cropperImage = reactive({
|
const cropperImage = reactive({
|
||||||
src: '',
|
src: '',
|
||||||
type: 'image/jpg',
|
type: 'image/jpg',
|
||||||
|
@ -29,8 +22,8 @@ const cropperImage = reactive({
|
||||||
|
|
||||||
function stencilSize({ boundaries }: { boundaries: Boundaries }) {
|
function stencilSize({ boundaries }: { boundaries: Boundaries }) {
|
||||||
return {
|
return {
|
||||||
width: boundaries.width * props.stencilSizePercentage,
|
width: boundaries.width * stencilSizePercentage,
|
||||||
height: boundaries.height * props.stencilSizePercentage,
|
height: boundaries.height * stencilSizePercentage,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -82,7 +75,7 @@ function cropImage() {
|
||||||
}"
|
}"
|
||||||
:stencil-size="stencilSize"
|
:stencil-size="stencilSize"
|
||||||
:stencil-props="{
|
:stencil-props="{
|
||||||
aspectRatio: props.stencilAspectRatio,
|
aspectRatio: stencilAspectRatio,
|
||||||
movable: false,
|
movable: false,
|
||||||
resizable: false,
|
resizable: false,
|
||||||
handlers: {},
|
handlers: {},
|
||||||
|
|
|
@ -2,21 +2,21 @@
|
||||||
import type { FileWithHandle } from 'browser-fs-access'
|
import type { FileWithHandle } from 'browser-fs-access'
|
||||||
import { fileOpen } from 'browser-fs-access'
|
import { fileOpen } from 'browser-fs-access'
|
||||||
|
|
||||||
const props = withDefaults(defineProps<{
|
const {
|
||||||
|
original,
|
||||||
|
allowedFileTypes = ['image/jpeg', 'image/png'],
|
||||||
|
allowedFileSize = 1024 * 1024 * 5, // 5 MB
|
||||||
|
} = defineProps<{
|
||||||
/** The image src before change */
|
/** The image src before change */
|
||||||
original?: string
|
original?: string
|
||||||
/** Allowed file types */
|
/** Allowed file types */
|
||||||
allowedFileTypes?: string[]
|
allowedFileTypes?: string[]
|
||||||
/** Allowed file size */
|
/** Allowed file size */
|
||||||
allowedFileSize?: number
|
allowedFileSize?: number
|
||||||
|
|
||||||
imgClass?: string
|
imgClass?: string
|
||||||
|
|
||||||
loading?: boolean
|
loading?: boolean
|
||||||
}>(), {
|
}>()
|
||||||
allowedFileTypes: () => ['image/jpeg', 'image/png'],
|
|
||||||
allowedFileSize: 1024 * 1024 * 5, // 5 MB
|
|
||||||
})
|
|
||||||
const emit = defineEmits<{
|
const emit = defineEmits<{
|
||||||
(event: 'pick', value: FileWithHandle): void
|
(event: 'pick', value: FileWithHandle): void
|
||||||
(event: 'error', code: number, message: string): void
|
(event: 'error', code: number, message: string): void
|
||||||
|
@ -26,7 +26,7 @@ const file = defineModel<FileWithHandle | null>()
|
||||||
|
|
||||||
const { t } = useI18n()
|
const { t } = useI18n()
|
||||||
|
|
||||||
const defaultImage = computed(() => props.original || '')
|
const defaultImage = computed(() => original || '')
|
||||||
/** Preview of selected images */
|
/** Preview of selected images */
|
||||||
const previewImage = ref('')
|
const previewImage = ref('')
|
||||||
/** The current images on display */
|
/** The current images on display */
|
||||||
|
@ -37,14 +37,14 @@ async function pickImage() {
|
||||||
return
|
return
|
||||||
const image = await fileOpen({
|
const image = await fileOpen({
|
||||||
description: 'Image',
|
description: 'Image',
|
||||||
mimeTypes: props.allowedFileTypes,
|
mimeTypes: allowedFileTypes,
|
||||||
})
|
})
|
||||||
|
|
||||||
if (!props.allowedFileTypes.includes(image.type)) {
|
if (!allowedFileTypes.includes(image.type)) {
|
||||||
emit('error', 1, t('error.unsupported_file_format'))
|
emit('error', 1, t('error.unsupported_file_format'))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
else if (image.size > props.allowedFileSize) {
|
else if (image.size > allowedFileSize) {
|
||||||
emit('error', 2, t('error.file_size_cannot_exceed_n_mb', [5]))
|
emit('error', 2, t('error.file_size_cannot_exceed_n_mb', [5]))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
const {
|
const {
|
||||||
zIndex = 100,
|
zIndex = 100,
|
||||||
background = 'transparent',
|
background = 'transparent',
|
||||||
} = $defineProps<{
|
} = defineProps<{
|
||||||
zIndex?: number
|
zIndex?: number
|
||||||
background?: string
|
background?: string
|
||||||
}>()
|
}>()
|
||||||
|
|
|
@ -6,10 +6,10 @@ import 'vue-virtual-scroller/dist/vue-virtual-scroller.css'
|
||||||
|
|
||||||
const {
|
const {
|
||||||
paginator,
|
paginator,
|
||||||
stream,
|
|
||||||
eventType,
|
|
||||||
keyProp = 'id',
|
keyProp = 'id',
|
||||||
virtualScroller = false,
|
virtualScroller = false,
|
||||||
|
stream,
|
||||||
|
eventType,
|
||||||
preprocess,
|
preprocess,
|
||||||
endMessage = true,
|
endMessage = true,
|
||||||
} = defineProps<{
|
} = defineProps<{
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import type { CommonRouteTabMoreOption, CommonRouteTabOption } from '~/types'
|
import type { CommonRouteTabMoreOption, CommonRouteTabOption } from '~/types'
|
||||||
|
|
||||||
const { options, command, replace, preventScrollTop = false, moreOptions } = defineProps<{
|
const { options, command, preventScrollTop = false } = defineProps<{
|
||||||
options: CommonRouteTabOption[]
|
options: CommonRouteTabOption[]
|
||||||
moreOptions?: CommonRouteTabMoreOption
|
moreOptions?: CommonRouteTabMoreOption
|
||||||
command?: boolean
|
command?: boolean
|
||||||
|
|
|
@ -3,16 +3,16 @@ defineOptions({
|
||||||
inheritAttrs: false,
|
inheritAttrs: false,
|
||||||
})
|
})
|
||||||
|
|
||||||
const props = defineProps<{
|
const { count } = defineProps<{
|
||||||
count: number
|
count: number
|
||||||
keypath: string
|
keypath: string
|
||||||
}>()
|
}>()
|
||||||
|
|
||||||
const { formatHumanReadableNumber, formatNumber, forSR } = useHumanReadableNumber()
|
const { formatHumanReadableNumber, formatNumber, forSR } = useHumanReadableNumber()
|
||||||
|
|
||||||
const useSR = computed(() => forSR(props.count))
|
const useSR = computed(() => forSR(count))
|
||||||
const rawNumber = computed(() => formatNumber(props.count))
|
const rawNumber = computed(() => formatNumber(count))
|
||||||
const humanReadableNumber = computed(() => formatHumanReadableNumber(props.count))
|
const humanReadableNumber = computed(() => formatHumanReadableNumber(count))
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
|
|
|
@ -4,7 +4,6 @@ const {
|
||||||
text,
|
text,
|
||||||
description,
|
description,
|
||||||
icon,
|
icon,
|
||||||
checked,
|
|
||||||
command,
|
command,
|
||||||
} = defineProps<{
|
} = defineProps<{
|
||||||
is?: string
|
is?: string
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
const props = defineProps<{
|
const { code, lang } = defineProps<{
|
||||||
code: string
|
code: string
|
||||||
lang?: string
|
lang?: string
|
||||||
}>()
|
}>()
|
||||||
|
|
||||||
const raw = computed(() => decodeURIComponent(props.code).replace(/'/g, '\''))
|
const raw = computed(() => decodeURIComponent(code).replace(/'/g, '\''))
|
||||||
|
|
||||||
const langMap: Record<string, string> = {
|
const langMap: Record<string, string> = {
|
||||||
js: 'javascript',
|
js: 'javascript',
|
||||||
|
@ -13,7 +13,7 @@ const langMap: Record<string, string> = {
|
||||||
}
|
}
|
||||||
|
|
||||||
const highlighted = computed(() => {
|
const highlighted = computed(() => {
|
||||||
return props.lang ? highlightCode(raw.value, (langMap[props.lang] || props.lang) as any) : raw
|
return lang ? highlightCode(raw.value, (langMap[lang] || lang) as any) : raw
|
||||||
})
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import type { mastodon } from 'masto'
|
import type { mastodon } from 'masto'
|
||||||
|
|
||||||
const { paginator } = defineProps<{
|
defineProps<{
|
||||||
paginator: mastodon.Paginator<mastodon.v1.Conversation[], mastodon.DefaultPaginationParams>
|
paginator: mastodon.Paginator<mastodon.v1.Conversation[], mastodon.DefaultPaginationParams>
|
||||||
}>()
|
}>()
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
const { as, alt, dataEmojiId } = defineProps<{
|
const { alt, dataEmojiId } = defineProps<{
|
||||||
as: string
|
as: string
|
||||||
alt?: string
|
alt?: string
|
||||||
dataEmojiId?: string
|
dataEmojiId?: string
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import type { ConfirmDialogChoice, ConfirmDialogOptions } from '~/types'
|
import type { ConfirmDialogChoice, ConfirmDialogOptions } from '~/types'
|
||||||
|
|
||||||
const props = defineProps<ConfirmDialogOptions>()
|
const { extraOptionType } = defineProps<ConfirmDialogOptions>()
|
||||||
|
|
||||||
const emit = defineEmits<{
|
const emit = defineEmits<{
|
||||||
(evt: 'choice', choice: ConfirmDialogChoice): void
|
(evt: 'choice', choice: ConfirmDialogChoice): void
|
||||||
|
@ -11,7 +11,7 @@ const hasDuration = ref(false)
|
||||||
const isValidDuration = ref(true)
|
const isValidDuration = ref(true)
|
||||||
const duration = ref(60 * 60) // default to 1 hour
|
const duration = ref(60 * 60) // default to 1 hour
|
||||||
const shouldMuteNotifications = ref(true)
|
const shouldMuteNotifications = ref(true)
|
||||||
const isMute = computed(() => props.extraOptionType === 'mute')
|
const isMute = computed(() => extraOptionType === 'mute')
|
||||||
|
|
||||||
function handleChoice(choice: ConfirmDialogChoice['choice']) {
|
function handleChoice(choice: ConfirmDialogChoice['choice']) {
|
||||||
const dialogChoice = {
|
const dialogChoice = {
|
||||||
|
|
|
@ -1,51 +1,27 @@
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { useFocusTrap } from '@vueuse/integrations/useFocusTrap'
|
import { useFocusTrap } from '@vueuse/integrations/useFocusTrap'
|
||||||
|
|
||||||
export interface Props {
|
|
||||||
/**
|
|
||||||
* level of depth
|
|
||||||
*
|
|
||||||
* @default 100
|
|
||||||
*/
|
|
||||||
zIndex?: number
|
|
||||||
|
|
||||||
/**
|
|
||||||
* whether to allow close dialog by clicking mask layer
|
|
||||||
*
|
|
||||||
* @default true
|
|
||||||
*/
|
|
||||||
closeByMask?: boolean
|
|
||||||
|
|
||||||
/**
|
|
||||||
* use v-if, destroy all the internal elements after closed
|
|
||||||
*
|
|
||||||
* @default true
|
|
||||||
*/
|
|
||||||
useVIf?: boolean
|
|
||||||
|
|
||||||
/**
|
|
||||||
* keep the dialog opened even when in other views
|
|
||||||
*
|
|
||||||
* @default false
|
|
||||||
*/
|
|
||||||
keepAlive?: boolean
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The aria-labelledby id for the dialog.
|
|
||||||
*/
|
|
||||||
dialogLabelledBy?: string
|
|
||||||
}
|
|
||||||
|
|
||||||
defineOptions({
|
defineOptions({
|
||||||
inheritAttrs: false,
|
inheritAttrs: false,
|
||||||
})
|
})
|
||||||
|
|
||||||
const props = withDefaults(defineProps<Props>(), {
|
const {
|
||||||
zIndex: 100,
|
zIndex = 100,
|
||||||
closeByMask: true,
|
closeByMask = true,
|
||||||
useVIf: true,
|
useVIf = true,
|
||||||
keepAlive: false,
|
keepAlive = false,
|
||||||
})
|
} = defineProps<{
|
||||||
|
// level of depth
|
||||||
|
zIndex?: number
|
||||||
|
// whether to allow close dialog by clicking mask layer
|
||||||
|
closeByMask?: boolean
|
||||||
|
// use v-if, destroy all the internal elements after closed
|
||||||
|
useVIf?: boolean
|
||||||
|
// keep the dialog opened even when in other views
|
||||||
|
keepAlive?: boolean
|
||||||
|
// The aria-labelledby id for the dialog.
|
||||||
|
dialogLabelledBy?: string
|
||||||
|
}>()
|
||||||
|
|
||||||
const emit = defineEmits<{
|
const emit = defineEmits<{
|
||||||
/** v-model dialog visibility */
|
/** v-model dialog visibility */
|
||||||
|
@ -85,7 +61,7 @@ function close() {
|
||||||
}
|
}
|
||||||
|
|
||||||
function clickMask() {
|
function clickMask() {
|
||||||
if (props.closeByMask)
|
if (closeByMask)
|
||||||
close()
|
close()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -97,7 +73,7 @@ watch(visible, (value) => {
|
||||||
|
|
||||||
const notInCurrentPage = computed(() => deactivated.value || routePath.value !== route.path)
|
const notInCurrentPage = computed(() => deactivated.value || routePath.value !== route.path)
|
||||||
watch(notInCurrentPage, (value) => {
|
watch(notInCurrentPage, (value) => {
|
||||||
if (props.keepAlive)
|
if (keepAlive)
|
||||||
return
|
return
|
||||||
if (value)
|
if (value)
|
||||||
close()
|
close()
|
||||||
|
@ -106,7 +82,7 @@ watch(notInCurrentPage, (value) => {
|
||||||
// controls the state of v-if.
|
// controls the state of v-if.
|
||||||
// when useVIf is toggled, v-if has the same state as modelValue, otherwise v-if is true
|
// when useVIf is toggled, v-if has the same state as modelValue, otherwise v-if is true
|
||||||
const isVIf = computed(() => {
|
const isVIf = computed(() => {
|
||||||
return props.useVIf
|
return useVIf
|
||||||
? visible.value
|
? visible.value
|
||||||
: true
|
: true
|
||||||
})
|
})
|
||||||
|
@ -114,7 +90,7 @@ const isVIf = computed(() => {
|
||||||
// controls the state of v-show.
|
// controls the state of v-show.
|
||||||
// when useVIf is toggled, v-show is true, otherwise it has the same state as modelValue
|
// when useVIf is toggled, v-show is true, otherwise it has the same state as modelValue
|
||||||
const isVShow = computed(() => {
|
const isVShow = computed(() => {
|
||||||
return !props.useVIf
|
return !useVIf
|
||||||
? visible.value
|
? visible.value
|
||||||
: true
|
: true
|
||||||
})
|
})
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { STORAGE_KEY_LAST_ACCESSED_EXPLORE_ROUTE, STORAGE_KEY_LAST_ACCESSED_NOTIFICATION_ROUTE } from '~/constants'
|
import { STORAGE_KEY_LAST_ACCESSED_EXPLORE_ROUTE, STORAGE_KEY_LAST_ACCESSED_NOTIFICATION_ROUTE } from '~/constants'
|
||||||
|
|
||||||
const { command } = defineProps<{
|
defineProps<{
|
||||||
command?: boolean
|
command?: boolean
|
||||||
}>()
|
}>()
|
||||||
const { notifications } = useNotifications()
|
const { notifications } = useNotifications()
|
||||||
|
|
|
@ -1,13 +1,11 @@
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
const props = withDefaults(defineProps<{
|
const { text, icon, to, userOnly = false, command } = defineProps<{
|
||||||
text?: string
|
text?: string
|
||||||
icon: string
|
icon: string
|
||||||
to: string | Record<string, string>
|
to: string | Record<string, string>
|
||||||
userOnly?: boolean
|
userOnly?: boolean
|
||||||
command?: boolean
|
command?: boolean
|
||||||
}>(), {
|
}>()
|
||||||
userOnly: false,
|
|
||||||
})
|
|
||||||
|
|
||||||
defineSlots<{
|
defineSlots<{
|
||||||
icon: (props: object) => void
|
icon: (props: object) => void
|
||||||
|
@ -19,12 +17,12 @@ const router = useRouter()
|
||||||
useCommand({
|
useCommand({
|
||||||
scope: 'Navigation',
|
scope: 'Navigation',
|
||||||
|
|
||||||
name: () => props.text ?? (typeof props.to === 'string' ? props.to as string : props.to.name),
|
name: () => text ?? (typeof to === 'string' ? to as string : to.name),
|
||||||
icon: () => props.icon,
|
icon: () => icon,
|
||||||
visible: () => props.command,
|
visible: () => command,
|
||||||
|
|
||||||
onActivate() {
|
onActivate() {
|
||||||
router.push(props.to)
|
router.push(to)
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -39,8 +37,8 @@ onHydrated(async () => {
|
||||||
|
|
||||||
// Optimize rendering for the common case of being logged in, only show visual feedback for disabled user-only items
|
// Optimize rendering for the common case of being logged in, only show visual feedback for disabled user-only items
|
||||||
// when we know there is no user.
|
// when we know there is no user.
|
||||||
const noUserDisable = computed(() => !isHydrated.value || (props.userOnly && !currentUser.value))
|
const noUserDisable = computed(() => !isHydrated.value || (userOnly && !currentUser.value))
|
||||||
const noUserVisual = computed(() => isHydrated.value && props.userOnly && !currentUser.value)
|
const noUserVisual = computed(() => isHydrated.value && userOnly && !currentUser.value)
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
|
|
|
@ -4,6 +4,7 @@ import { STORAGE_KEY_LAST_ACCESSED_NOTIFICATION_ROUTE } from '~/constants'
|
||||||
defineProps<{
|
defineProps<{
|
||||||
activeClass: string
|
activeClass: string
|
||||||
}>()
|
}>()
|
||||||
|
|
||||||
const { notifications } = useNotifications()
|
const { notifications } = useNotifications()
|
||||||
const lastAccessedNotificationRoute = useLocalStorage(STORAGE_KEY_LAST_ACCESSED_NOTIFICATION_ROUTE, '')
|
const lastAccessedNotificationRoute = useLocalStorage(STORAGE_KEY_LAST_ACCESSED_NOTIFICATION_ROUTE, '')
|
||||||
</script>
|
</script>
|
||||||
|
|
|
@ -4,7 +4,7 @@ import type { GroupedAccountLike, NotificationSlot } from '~/types'
|
||||||
// @ts-expect-error missing types
|
// @ts-expect-error missing types
|
||||||
import { DynamicScrollerItem } from 'vue-virtual-scroller'
|
import { DynamicScrollerItem } from 'vue-virtual-scroller'
|
||||||
|
|
||||||
const { paginator, stream } = defineProps<{
|
defineProps<{
|
||||||
paginator: mastodon.Paginator<mastodon.v1.Notification[], mastodon.rest.v1.ListNotificationsParams>
|
paginator: mastodon.Paginator<mastodon.v1.Notification[], mastodon.rest.v1.ListNotificationsParams>
|
||||||
stream?: mastodon.streaming.Subscription
|
stream?: mastodon.streaming.Subscription
|
||||||
}>()
|
}>()
|
||||||
|
|
|
@ -1,14 +1,12 @@
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import type { mastodon } from 'masto'
|
import type { mastodon } from 'masto'
|
||||||
|
|
||||||
const props = withDefaults(defineProps<{
|
const { attachment, removable = true } = defineProps<{
|
||||||
attachment: mastodon.v1.MediaAttachment
|
attachment: mastodon.v1.MediaAttachment
|
||||||
alt?: string
|
alt?: string
|
||||||
removable?: boolean
|
removable?: boolean
|
||||||
dialogLabelledBy?: string
|
dialogLabelledBy?: string
|
||||||
}>(), {
|
}>()
|
||||||
removable: true,
|
|
||||||
})
|
|
||||||
|
|
||||||
const emit = defineEmits<{
|
const emit = defineEmits<{
|
||||||
(evt: 'remove'): void
|
(evt: 'remove'): void
|
||||||
|
@ -19,7 +17,7 @@ const emit = defineEmits<{
|
||||||
const maxDescriptionLength = 1500
|
const maxDescriptionLength = 1500
|
||||||
|
|
||||||
const isEditDialogOpen = ref(false)
|
const isEditDialogOpen = ref(false)
|
||||||
const description = ref(props.attachment.description ?? '')
|
const description = ref(attachment.description ?? '')
|
||||||
|
|
||||||
function toggleApply() {
|
function toggleApply() {
|
||||||
isEditDialogOpen.value = false
|
isEditDialogOpen.value = false
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import type { Editor } from '@tiptap/core'
|
import type { Editor } from '@tiptap/core'
|
||||||
|
|
||||||
const { editor } = defineProps<{
|
defineProps<{
|
||||||
editor: Editor
|
editor: Editor
|
||||||
}>()
|
}>()
|
||||||
</script>
|
</script>
|
||||||
|
|
|
@ -1,16 +1,16 @@
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
const props = defineProps<{
|
const { draftKey, draftItemIndex } = defineProps<{
|
||||||
draftKey: string
|
draftKey: string
|
||||||
draftItemIndex: number
|
draftItemIndex: number
|
||||||
}>()
|
}>()
|
||||||
|
|
||||||
const { threadIsActive, addThreadItem, threadItems, removeThreadItem } = useThreadComposer(props.draftKey)
|
const { threadIsActive, addThreadItem, threadItems, removeThreadItem } = useThreadComposer(draftKey)
|
||||||
|
|
||||||
const isRemovableItem = computed(() => threadIsActive.value && props.draftItemIndex < threadItems.value.length - 1)
|
const isRemovableItem = computed(() => threadIsActive.value && draftItemIndex < threadItems.value.length - 1)
|
||||||
|
|
||||||
function addOrRemoveItem() {
|
function addOrRemoveItem() {
|
||||||
if (isRemovableItem.value)
|
if (isRemovableItem.value)
|
||||||
removeThreadItem(props.draftItemIndex)
|
removeThreadItem(draftItemIndex)
|
||||||
|
|
||||||
else
|
else
|
||||||
addThreadItem()
|
addThreadItem()
|
||||||
|
@ -19,7 +19,7 @@ function addOrRemoveItem() {
|
||||||
const { t } = useI18n()
|
const { t } = useI18n()
|
||||||
|
|
||||||
const label = computed(() => {
|
const label = computed(() => {
|
||||||
if (!isRemovableItem.value && props.draftItemIndex === 0)
|
if (!isRemovableItem.value && draftItemIndex === 0)
|
||||||
return t('tooltip.start_thread')
|
return t('tooltip.start_thread')
|
||||||
|
|
||||||
return isRemovableItem.value ? t('tooltip.remove_thread_item') : t('tooltip.add_thread_item')
|
return isRemovableItem.value ? t('tooltip.remove_thread_item') : t('tooltip.add_thread_item')
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
const { editing } = defineProps<{
|
defineProps<{
|
||||||
editing?: boolean
|
editing?: boolean
|
||||||
}>()
|
}>()
|
||||||
|
|
||||||
|
|
|
@ -10,7 +10,6 @@ const {
|
||||||
draftItemIndex,
|
draftItemIndex,
|
||||||
expanded = false,
|
expanded = false,
|
||||||
placeholder,
|
placeholder,
|
||||||
dialogLabelledBy,
|
|
||||||
initial = getDefaultDraftItem,
|
initial = getDefaultDraftItem,
|
||||||
} = defineProps<{
|
} = defineProps<{
|
||||||
draftKey: string
|
draftKey: string
|
||||||
|
|
|
@ -6,10 +6,6 @@ const {
|
||||||
draftKey,
|
draftKey,
|
||||||
initial = getDefaultDraftItem,
|
initial = getDefaultDraftItem,
|
||||||
expanded = false,
|
expanded = false,
|
||||||
placeholder,
|
|
||||||
dialogLabelledBy,
|
|
||||||
inReplyToId,
|
|
||||||
inReplyToVisibility,
|
|
||||||
} = defineProps<{
|
} = defineProps<{
|
||||||
draftKey: string
|
draftKey: string
|
||||||
initial?: () => DraftItem
|
initial?: () => DraftItem
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
const props = defineProps<{
|
const { text, description, icon, to, command, external, target } = defineProps<{
|
||||||
text?: string
|
text?: string
|
||||||
content?: string
|
content?: string
|
||||||
description?: string
|
description?: string
|
||||||
|
@ -14,24 +14,24 @@ const props = defineProps<{
|
||||||
}>()
|
}>()
|
||||||
|
|
||||||
const router = useRouter()
|
const router = useRouter()
|
||||||
const scrollOnClick = computed(() => props.to && !(props.target === '_blank' || props.external))
|
const scrollOnClick = computed(() => to && !(target === '_blank' || external))
|
||||||
|
|
||||||
useCommand({
|
useCommand({
|
||||||
scope: 'Settings',
|
scope: 'Settings',
|
||||||
|
|
||||||
name: () => props.text
|
name: () => text
|
||||||
?? (props.to
|
?? (to
|
||||||
? typeof props.to === 'string'
|
? typeof to === 'string'
|
||||||
? props.to
|
? to
|
||||||
: props.to.name
|
: to.name
|
||||||
: ''
|
: ''
|
||||||
),
|
),
|
||||||
description: () => props.description,
|
description: () => description,
|
||||||
icon: () => props.icon || '',
|
icon: () => icon || '',
|
||||||
visible: () => props.command && props.to,
|
visible: () => command && to,
|
||||||
|
|
||||||
onActivate() {
|
onActivate() {
|
||||||
router.push(props.to!)
|
router.push(to!)
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import type { mastodon } from 'masto'
|
import type { mastodon } from 'masto'
|
||||||
|
|
||||||
const { account, link = true } = defineProps<{
|
const { link = true } = defineProps<{
|
||||||
account: mastodon.v1.Account
|
account: mastodon.v1.Account
|
||||||
link?: boolean
|
link?: boolean
|
||||||
}>()
|
}>()
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import type { mastodon } from 'masto'
|
import type { mastodon } from 'masto'
|
||||||
|
|
||||||
const props = defineProps<{
|
const { details, command, ...props } = defineProps<{
|
||||||
status: mastodon.v1.Status
|
status: mastodon.v1.Status
|
||||||
details?: boolean
|
details?: boolean
|
||||||
command?: boolean
|
command?: boolean
|
||||||
|
@ -9,8 +9,6 @@ const props = defineProps<{
|
||||||
|
|
||||||
const focusEditor = inject<typeof noop>('focus-editor', noop)
|
const focusEditor = inject<typeof noop>('focus-editor', noop)
|
||||||
|
|
||||||
const { details, command } = props // TODO
|
|
||||||
|
|
||||||
const userSettings = useUserSettings()
|
const userSettings = useUserSettings()
|
||||||
const useStarFavoriteIcon = usePreferences('useStarFavoriteIcon')
|
const useStarFavoriteIcon = usePreferences('useStarFavoriteIcon')
|
||||||
|
|
||||||
|
@ -21,7 +19,7 @@ const {
|
||||||
toggleBookmark,
|
toggleBookmark,
|
||||||
toggleFavourite,
|
toggleFavourite,
|
||||||
toggleReblog,
|
toggleReblog,
|
||||||
} = useStatusActions(props)
|
} = useStatusActions({ status: props.status })
|
||||||
|
|
||||||
function reply() {
|
function reply() {
|
||||||
if (!checkLogin())
|
if (!checkLogin())
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
import type { mastodon } from 'masto'
|
import type { mastodon } from 'masto'
|
||||||
import { toggleBlockAccount, toggleMuteAccount, useRelationship } from '~~/composables/masto/relationship'
|
import { toggleBlockAccount, toggleMuteAccount, useRelationship } from '~~/composables/masto/relationship'
|
||||||
|
|
||||||
const props = defineProps<{
|
const { details, ...props } = defineProps<{
|
||||||
status: mastodon.v1.Status
|
status: mastodon.v1.Status
|
||||||
details?: boolean
|
details?: boolean
|
||||||
command?: boolean
|
command?: boolean
|
||||||
|
@ -22,7 +22,7 @@ const {
|
||||||
togglePin,
|
togglePin,
|
||||||
toggleReblog,
|
toggleReblog,
|
||||||
toggleMute,
|
toggleMute,
|
||||||
} = useStatusActions(props)
|
} = useStatusActions({ status: props.status })
|
||||||
|
|
||||||
const clipboard = useClipboard()
|
const clipboard = useClipboard()
|
||||||
const router = useRouter()
|
const router = useRouter()
|
||||||
|
@ -109,7 +109,7 @@ async function deleteAndRedraft() {
|
||||||
function reply() {
|
function reply() {
|
||||||
if (!checkLogin())
|
if (!checkLogin())
|
||||||
return
|
return
|
||||||
if (props.details) {
|
if (details) {
|
||||||
focusEditor()
|
focusEditor()
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
|
|
@ -1,28 +1,25 @@
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import type { mastodon } from 'masto'
|
import type { mastodon } from 'masto'
|
||||||
|
|
||||||
const props = withDefaults(
|
const { actions = true, older, newer, hasOlder, hasNewer, main, ...props } = defineProps<{
|
||||||
defineProps<{
|
status: mastodon.v1.Status
|
||||||
status: mastodon.v1.Status
|
actions?: boolean
|
||||||
actions?: boolean
|
context?: mastodon.v2.FilterContext
|
||||||
context?: mastodon.v2.FilterContext
|
hover?: boolean
|
||||||
hover?: boolean
|
inNotification?: boolean
|
||||||
inNotification?: boolean
|
isPreview?: boolean
|
||||||
isPreview?: boolean
|
|
||||||
|
|
||||||
// If we know the prev and next status in the timeline, we can simplify the card
|
// If we know the prev and next status in the timeline, we can simplify the card
|
||||||
older?: mastodon.v1.Status
|
older?: mastodon.v1.Status
|
||||||
newer?: mastodon.v1.Status
|
newer?: mastodon.v1.Status
|
||||||
// Manual overrides
|
// Manual overrides
|
||||||
hasOlder?: boolean
|
hasOlder?: boolean
|
||||||
hasNewer?: boolean
|
hasNewer?: boolean
|
||||||
|
|
||||||
// When looking into a detailed view of a post, we can simplify the replying badges
|
// When looking into a detailed view of a post, we can simplify the replying badges
|
||||||
// to the main expanded post
|
// to the main expanded post
|
||||||
main?: mastodon.v1.Status
|
main?: mastodon.v1.Status
|
||||||
}>(),
|
}>()
|
||||||
{ actions: true },
|
|
||||||
)
|
|
||||||
|
|
||||||
const userSettings = useUserSettings()
|
const userSettings = useUserSettings()
|
||||||
|
|
||||||
|
@ -33,11 +30,11 @@ const status = computed(() => {
|
||||||
})
|
})
|
||||||
|
|
||||||
// Use original status, avoid connecting a reblog
|
// Use original status, avoid connecting a reblog
|
||||||
const directReply = computed(() => props.hasNewer || (!!status.value.inReplyToId && (status.value.inReplyToId === props.newer?.id || status.value.inReplyToId === props.newer?.reblog?.id)))
|
const directReply = computed(() => hasNewer || (!!status.value.inReplyToId && (status.value.inReplyToId === newer?.id || status.value.inReplyToId === newer?.reblog?.id)))
|
||||||
// Use reblogged status, connect it to further replies
|
// Use reblogged status, connect it to further replies
|
||||||
const connectReply = computed(() => props.hasOlder || status.value.id === props.older?.inReplyToId || status.value.id === props.older?.reblog?.inReplyToId)
|
const connectReply = computed(() => hasOlder || status.value.id === older?.inReplyToId || status.value.id === older?.reblog?.inReplyToId)
|
||||||
// Open a detailed status, the replies directly to it
|
// Open a detailed status, the replies directly to it
|
||||||
const replyToMain = computed(() => props.main && props.main.id === status.value.inReplyToId)
|
const replyToMain = computed(() => main && main.id === status.value.inReplyToId)
|
||||||
|
|
||||||
const rebloggedBy = computed(() => props.status.reblog ? props.status.account : null)
|
const rebloggedBy = computed(() => props.status.reblog ? props.status.account : null)
|
||||||
|
|
||||||
|
@ -64,7 +61,7 @@ const collapseRebloggedBy = computed(() => rebloggedBy.value?.id === status.valu
|
||||||
const isDM = computed(() => status.value.visibility === 'direct')
|
const isDM = computed(() => status.value.visibility === 'direct')
|
||||||
const isPinned = computed(() => status.value.pinned)
|
const isPinned = computed(() => status.value.pinned)
|
||||||
|
|
||||||
const showUpperBorder = computed(() => props.newer && !directReply.value)
|
const showUpperBorder = computed(() => newer && !directReply.value)
|
||||||
const showReplyTo = computed(() => !replyToMain.value && !directReply.value)
|
const showReplyTo = computed(() => !replyToMain.value && !directReply.value)
|
||||||
|
|
||||||
const forceShow = ref(false)
|
const forceShow = ref(false)
|
||||||
|
|
|
@ -1,14 +1,12 @@
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import type { mastodon } from 'masto'
|
import type { mastodon } from 'masto'
|
||||||
|
|
||||||
const props = withDefaults(defineProps<{
|
const { actions = true, ...props } = defineProps<{
|
||||||
status: mastodon.v1.Status
|
status: mastodon.v1.Status
|
||||||
newer?: mastodon.v1.Status
|
newer?: mastodon.v1.Status
|
||||||
command?: boolean
|
command?: boolean
|
||||||
actions?: boolean
|
actions?: boolean
|
||||||
}>(), {
|
}>()
|
||||||
actions: true,
|
|
||||||
})
|
|
||||||
|
|
||||||
defineEmits<{
|
defineEmits<{
|
||||||
(event: 'refetchStatus'): void
|
(event: 'refetchStatus'): void
|
||||||
|
|
|
@ -1,14 +1,14 @@
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import type { mastodon } from 'masto'
|
import type { mastodon } from 'masto'
|
||||||
|
|
||||||
const props = defineProps<{
|
const { status } = defineProps<{
|
||||||
status: mastodon.v1.Status
|
status: mastodon.v1.Status
|
||||||
hover?: boolean
|
hover?: boolean
|
||||||
}>()
|
}>()
|
||||||
|
|
||||||
const el = ref<HTMLElement>()
|
const el = ref<HTMLElement>()
|
||||||
const router = useRouter()
|
const router = useRouter()
|
||||||
const statusRoute = computed(() => getStatusRoute(props.status))
|
const statusRoute = computed(() => getStatusRoute(status))
|
||||||
|
|
||||||
function onclick(evt: MouseEvent | KeyboardEvent) {
|
function onclick(evt: MouseEvent | KeyboardEvent) {
|
||||||
const path = evt.composedPath() as HTMLElement[]
|
const path = evt.composedPath() as HTMLElement[]
|
||||||
|
@ -24,7 +24,7 @@ function go(evt: MouseEvent | KeyboardEvent) {
|
||||||
window.open(statusRoute.value.href)
|
window.open(statusRoute.value.href)
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
cacheStatus(props.status)
|
cacheStatus(status)
|
||||||
router.push(statusRoute.value)
|
router.push(statusRoute.value)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import type { mastodon } from 'masto'
|
import type { mastodon } from 'masto'
|
||||||
|
|
||||||
const props = defineProps<{
|
const { card } = defineProps<{
|
||||||
card: mastodon.v1.PreviewCard
|
card: mastodon.v1.PreviewCard
|
||||||
/** For the preview image, only the small image mode is displayed */
|
/** For the preview image, only the small image mode is displayed */
|
||||||
smallPictureOnly?: boolean
|
smallPictureOnly?: boolean
|
||||||
|
@ -9,7 +9,7 @@ const props = defineProps<{
|
||||||
root?: boolean
|
root?: boolean
|
||||||
}>()
|
}>()
|
||||||
|
|
||||||
const providerName = props.card.providerName
|
const providerName = card.providerName
|
||||||
|
|
||||||
const gitHubCards = usePreferences('experimentalGitHubCards')
|
const gitHubCards = usePreferences('experimentalGitHubCards')
|
||||||
</script>
|
</script>
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import type { mastodon } from 'masto'
|
import type { mastodon } from 'masto'
|
||||||
|
|
||||||
const props = defineProps<{
|
const { card, smallPictureOnly } = defineProps<{
|
||||||
card: mastodon.v1.PreviewCard
|
card: mastodon.v1.PreviewCard
|
||||||
/** For the preview image, only the small image mode is displayed */
|
/** For the preview image, only the small image mode is displayed */
|
||||||
smallPictureOnly?: boolean
|
smallPictureOnly?: boolean
|
||||||
|
@ -12,14 +12,14 @@ const props = defineProps<{
|
||||||
// mastodon's default max og image width
|
// mastodon's default max og image width
|
||||||
const ogImageWidth = 400
|
const ogImageWidth = 400
|
||||||
|
|
||||||
const alt = computed(() => `${props.card.title} - ${props.card.title}`)
|
const alt = computed(() => `${card.title} - ${card.title}`)
|
||||||
const isSquare = computed(() => (
|
const isSquare = computed(() => (
|
||||||
props.smallPictureOnly
|
smallPictureOnly
|
||||||
|| props.card.width === props.card.height
|
|| card.width === card.height
|
||||||
|| Number(props.card.width || 0) < ogImageWidth
|
|| Number(card.width || 0) < ogImageWidth
|
||||||
|| Number(props.card.height || 0) < ogImageWidth / 2
|
|| Number(card.height || 0) < ogImageWidth / 2
|
||||||
))
|
))
|
||||||
const providerName = computed(() => props.card.providerName ? props.card.providerName : new URL(props.card.url).hostname)
|
const providerName = computed(() => card.providerName ? card.providerName : new URL(card.url).hostname)
|
||||||
|
|
||||||
// TODO: handle card.type: 'photo' | 'video' | 'rich';
|
// TODO: handle card.type: 'photo' | 'video' | 'rich';
|
||||||
const cardTypeIconMap: Record<mastodon.v1.PreviewCardType, string> = {
|
const cardTypeIconMap: Record<mastodon.v1.PreviewCardType, string> = {
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
import type { mastodon } from 'masto'
|
import type { mastodon } from 'masto'
|
||||||
import reservedNames from 'github-reserved-names'
|
import reservedNames from 'github-reserved-names'
|
||||||
|
|
||||||
const props = defineProps<{
|
const { card } = defineProps<{
|
||||||
card: mastodon.v1.PreviewCard
|
card: mastodon.v1.PreviewCard
|
||||||
}>()
|
}>()
|
||||||
|
|
||||||
|
@ -30,7 +30,7 @@ interface Meta {
|
||||||
const supportedReservedRoutes = ['sponsors']
|
const supportedReservedRoutes = ['sponsors']
|
||||||
|
|
||||||
const meta = computed(() => {
|
const meta = computed(() => {
|
||||||
const { url } = props.card
|
const { url } = card
|
||||||
const path = url.split('https://github.com/')[1]
|
const path = url.split('https://github.com/')[1]
|
||||||
const [firstName, secondName] = path?.split('/') || []
|
const [firstName, secondName] = path?.split('/') || []
|
||||||
if (!firstName || (reservedNames.check(firstName) && !supportedReservedRoutes.includes(firstName)))
|
if (!firstName || (reservedNames.check(firstName) && !supportedReservedRoutes.includes(firstName)))
|
||||||
|
@ -42,7 +42,7 @@ const meta = computed(() => {
|
||||||
|
|
||||||
let type: UrlType = repo ? 'repo' : 'user'
|
let type: UrlType = repo ? 'repo' : 'user'
|
||||||
let number: string | undefined
|
let number: string | undefined
|
||||||
let details = (props.card.title ?? '').replace('GitHub - ', '').split(' · ')[0]
|
let details = (card.title ?? '').replace('GitHub - ', '').split(' · ')[0]
|
||||||
|
|
||||||
if (repo) {
|
if (repo) {
|
||||||
const repoPath = `${user}/${repo}`
|
const repoPath = `${user}/${repo}`
|
||||||
|
@ -63,7 +63,7 @@ const meta = computed(() => {
|
||||||
|
|
||||||
const avatar = `https://github.com/${user}.png?size=256`
|
const avatar = `https://github.com/${user}.png?size=256`
|
||||||
|
|
||||||
const author = props.card.authorName
|
const author = card.authorName
|
||||||
return {
|
return {
|
||||||
type,
|
type,
|
||||||
user,
|
user,
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import type { mastodon } from 'masto'
|
import type { mastodon } from 'masto'
|
||||||
|
|
||||||
const props = defineProps<{
|
const { card } = defineProps<{
|
||||||
card: mastodon.v1.PreviewCard
|
card: mastodon.v1.PreviewCard
|
||||||
/** For the preview image, only the small image mode is displayed */
|
/** For the preview image, only the small image mode is displayed */
|
||||||
smallPictureOnly?: boolean
|
smallPictureOnly?: boolean
|
||||||
|
@ -20,12 +20,12 @@ interface Meta {
|
||||||
const maxLines = 20
|
const maxLines = 20
|
||||||
|
|
||||||
const meta = computed(() => {
|
const meta = computed(() => {
|
||||||
const { description } = props.card
|
const { description } = card
|
||||||
const meta = description.match(/.*Code Snippet from (.+), lines (\S+)\n\n(.+)/s)
|
const meta = description.match(/.*Code Snippet from (.+), lines (\S+)\n\n(.+)/s)
|
||||||
const file = meta?.[1]
|
const file = meta?.[1]
|
||||||
const lines = meta?.[2]
|
const lines = meta?.[2]
|
||||||
const code = meta?.[3].split('\n').slice(0, maxLines).join('\n')
|
const code = meta?.[3].split('\n').slice(0, maxLines).join('\n')
|
||||||
const project = props.card.title?.replace(' - StackBlitz', '')
|
const project = card.title?.replace(' - StackBlitz', '')
|
||||||
return {
|
return {
|
||||||
file,
|
file,
|
||||||
lines,
|
lines,
|
||||||
|
|
|
@ -4,15 +4,15 @@ import { fetchAccountById } from '~/composables/cache'
|
||||||
|
|
||||||
type WatcherType = [status?: mastodon.v1.Status, v?: boolean]
|
type WatcherType = [status?: mastodon.v1.Status, v?: boolean]
|
||||||
|
|
||||||
const props = defineProps<{
|
const { status } = defineProps<{
|
||||||
status: mastodon.v1.Status
|
status: mastodon.v1.Status
|
||||||
isSelfReply: boolean
|
isSelfReply: boolean
|
||||||
}>()
|
}>()
|
||||||
|
|
||||||
const link = ref()
|
const link = ref()
|
||||||
const targetIsVisible = ref(false)
|
const targetIsVisible = ref(false)
|
||||||
const isSelf = computed(() => props.status.inReplyToAccountId === props.status.account.id)
|
const isSelf = computed(() => status.inReplyToAccountId === status.account.id)
|
||||||
const account = ref<mastodon.v1.Account | null | undefined>(isSelf.value ? props.status.account : undefined)
|
const account = ref<mastodon.v1.Account | null | undefined>(isSelf.value ? status.account : undefined)
|
||||||
|
|
||||||
useIntersectionObserver(
|
useIntersectionObserver(
|
||||||
link,
|
link,
|
||||||
|
@ -22,7 +22,7 @@ useIntersectionObserver(
|
||||||
)
|
)
|
||||||
|
|
||||||
watch(
|
watch(
|
||||||
() => [props.status, targetIsVisible.value] satisfies WatcherType,
|
() => [status, targetIsVisible.value] satisfies WatcherType,
|
||||||
([newStatus, newVisible]) => {
|
([newStatus, newVisible]) => {
|
||||||
if (newStatus.account && newStatus.inReplyToAccountId === newStatus.account.id) {
|
if (newStatus.account && newStatus.inReplyToAccountId === newStatus.account.id) {
|
||||||
account.value = newStatus.account
|
account.value = newStatus.account
|
||||||
|
@ -36,7 +36,7 @@ watch(
|
||||||
|
|
||||||
if (newId) {
|
if (newId) {
|
||||||
fetchAccountById(newStatus.inReplyToAccountId).then((acc) => {
|
fetchAccountById(newStatus.inReplyToAccountId).then((acc) => {
|
||||||
if (newId === props.status.inReplyToAccountId)
|
if (newId === status.inReplyToAccountId)
|
||||||
account.value = acc
|
account.value = acc
|
||||||
})
|
})
|
||||||
return
|
return
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
const props = defineProps<{
|
const { enabled, filter, sensitiveNonSpoiler } = defineProps<{
|
||||||
enabled?: boolean
|
enabled?: boolean
|
||||||
filter?: boolean
|
filter?: boolean
|
||||||
isDM?: boolean
|
isDM?: boolean
|
||||||
|
@ -10,12 +10,12 @@ const expandSpoilers = computed(() => {
|
||||||
const expandCW = currentUser.value ? getExpandSpoilersByDefault(currentUser.value.account) : false
|
const expandCW = currentUser.value ? getExpandSpoilersByDefault(currentUser.value.account) : false
|
||||||
const expandMedia = currentUser.value ? getExpandMediaByDefault(currentUser.value.account) : false
|
const expandMedia = currentUser.value ? getExpandMediaByDefault(currentUser.value.account) : false
|
||||||
|
|
||||||
return !props.filter // always prevent expansion if filtered
|
return !filter // always prevent expansion if filtered
|
||||||
&& ((props.sensitiveNonSpoiler && expandMedia)
|
&& ((sensitiveNonSpoiler && expandMedia)
|
||||||
|| (!props.sensitiveNonSpoiler && expandCW))
|
|| (!sensitiveNonSpoiler && expandCW))
|
||||||
})
|
})
|
||||||
|
|
||||||
const hideContent = props.enabled || props.sensitiveNonSpoiler
|
const hideContent = enabled || sensitiveNonSpoiler
|
||||||
const showContent = ref(expandSpoilers.value ? true : !hideContent)
|
const showContent = ref(expandSpoilers.value ? true : !hideContent)
|
||||||
const toggleContent = useToggle(showContent)
|
const toggleContent = useToggle(showContent)
|
||||||
|
|
||||||
|
@ -23,9 +23,9 @@ watchEffect(() => {
|
||||||
showContent.value = expandSpoilers.value ? true : !hideContent
|
showContent.value = expandSpoilers.value ? true : !hideContent
|
||||||
})
|
})
|
||||||
function getToggleText() {
|
function getToggleText() {
|
||||||
if (props.sensitiveNonSpoiler)
|
if (sensitiveNonSpoiler)
|
||||||
return 'status.spoiler_media_hidden'
|
return 'status.spoiler_media_hidden'
|
||||||
return props.filter ? 'status.filter_show_anyway' : 'status.spoiler_show_more'
|
return filter ? 'status.filter_show_anyway' : 'status.spoiler_show_more'
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import type { mastodon } from 'masto'
|
import type { mastodon } from 'masto'
|
||||||
|
|
||||||
const { edit } = defineProps<{
|
defineProps<{
|
||||||
edit: mastodon.v1.StatusEdit
|
edit: mastodon.v1.StatusEdit
|
||||||
}>()
|
}>()
|
||||||
</script>
|
</script>
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import type { mastodon } from 'masto'
|
import type { mastodon } from 'masto'
|
||||||
|
|
||||||
const { paginator } = defineProps<{
|
defineProps<{
|
||||||
paginator: mastodon.Paginator<mastodon.v1.Tag[], mastodon.DefaultPaginationParams>
|
paginator: mastodon.Paginator<mastodon.v1.Tag[], mastodon.DefaultPaginationParams>
|
||||||
}>()
|
}>()
|
||||||
</script>
|
</script>
|
||||||
|
|
|
@ -4,7 +4,7 @@ import type { mastodon } from 'masto'
|
||||||
import { DynamicScrollerItem } from 'vue-virtual-scroller'
|
import { DynamicScrollerItem } from 'vue-virtual-scroller'
|
||||||
import 'vue-virtual-scroller/dist/vue-virtual-scroller.css'
|
import 'vue-virtual-scroller/dist/vue-virtual-scroller.css'
|
||||||
|
|
||||||
const { paginator, stream, account, buffer = 10, endMessage = true } = defineProps<{
|
const { account, buffer = 10, endMessage = true } = defineProps<{
|
||||||
paginator: mastodon.Paginator<mastodon.v1.Status[], mastodon.rest.v1.ListAccountStatusesParams>
|
paginator: mastodon.Paginator<mastodon.v1.Status[], mastodon.rest.v1.ListAccountStatusesParams>
|
||||||
stream?: mastodon.streaming.Subscription
|
stream?: mastodon.streaming.Subscription
|
||||||
context?: mastodon.v2.FilterContext
|
context?: mastodon.v2.FilterContext
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { NodeViewContent, nodeViewProps, NodeViewWrapper } from '@tiptap/vue-3'
|
import { NodeViewContent, nodeViewProps, NodeViewWrapper } from '@tiptap/vue-3'
|
||||||
|
|
||||||
const props = defineProps(nodeViewProps)
|
const { node, updateAttributes } = defineProps(nodeViewProps)
|
||||||
|
|
||||||
const languages = [
|
const languages = [
|
||||||
'c',
|
'c',
|
||||||
|
@ -26,10 +26,10 @@ const languages = [
|
||||||
|
|
||||||
const selectedLanguage = computed({
|
const selectedLanguage = computed({
|
||||||
get() {
|
get() {
|
||||||
return props.node.attrs.language
|
return node.attrs.language
|
||||||
},
|
},
|
||||||
set(language) {
|
set(language) {
|
||||||
props.updateAttributes({ language })
|
updateAttributes({ language })
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
const { copy } = defineProps<{
|
defineProps<{
|
||||||
copy?: boolean
|
copy?: boolean
|
||||||
}>()
|
}>()
|
||||||
</script>
|
</script>
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
const { up } = defineProps<{
|
defineProps<{
|
||||||
up?: boolean
|
up?: boolean
|
||||||
}>()
|
}>()
|
||||||
</script>
|
</script>
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue