forked from Mirrors/elk
chore(deps): update lint (#1928)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Co-authored-by: 三咲智子 Kevin Deng <sxzz@sxzz.moe>
This commit is contained in:
parent
2838e18ff7
commit
3c43a1cdd1
62 changed files with 464 additions and 434 deletions
|
@ -12,7 +12,7 @@ const isSelf = $(useSelfAccount(() => account))
|
||||||
const { t } = useI18n()
|
const { t } = useI18n()
|
||||||
const { client } = $(useMasto())
|
const { client } = $(useMasto())
|
||||||
|
|
||||||
const toggleMute = async () => {
|
async function toggleMute() {
|
||||||
if (!relationship!.muting && await openConfirmDialog({
|
if (!relationship!.muting && await openConfirmDialog({
|
||||||
title: t('confirm.mute_account.title', [account.acct]),
|
title: t('confirm.mute_account.title', [account.acct]),
|
||||||
confirm: t('confirm.mute_account.confirm'),
|
confirm: t('confirm.mute_account.confirm'),
|
||||||
|
@ -28,7 +28,7 @@ const toggleMute = async () => {
|
||||||
: await client.v1.accounts.unmute(account.id)
|
: await client.v1.accounts.unmute(account.id)
|
||||||
}
|
}
|
||||||
|
|
||||||
const toggleBlockUser = async () => {
|
async function toggleBlockUser() {
|
||||||
if (!relationship!.blocking && await openConfirmDialog({
|
if (!relationship!.blocking && await openConfirmDialog({
|
||||||
title: t('confirm.block_account.title', [account.acct]),
|
title: t('confirm.block_account.title', [account.acct]),
|
||||||
confirm: t('confirm.block_account.confirm'),
|
confirm: t('confirm.block_account.confirm'),
|
||||||
|
@ -40,7 +40,7 @@ const toggleBlockUser = async () => {
|
||||||
relationship = await client.v1.accounts[relationship!.blocking ? 'block' : 'unblock'](account.id)
|
relationship = await client.v1.accounts[relationship!.blocking ? 'block' : 'unblock'](account.id)
|
||||||
}
|
}
|
||||||
|
|
||||||
const toggleBlockDomain = async () => {
|
async function toggleBlockDomain() {
|
||||||
if (!relationship!.domainBlocking && await openConfirmDialog({
|
if (!relationship!.domainBlocking && await openConfirmDialog({
|
||||||
title: t('confirm.block_domain.title', [getServerName(account)]),
|
title: t('confirm.block_domain.title', [getServerName(account)]),
|
||||||
confirm: t('confirm.block_domain.confirm'),
|
confirm: t('confirm.block_domain.confirm'),
|
||||||
|
@ -52,7 +52,7 @@ const toggleBlockDomain = async () => {
|
||||||
await client.v1.domainBlocks[relationship!.domainBlocking ? 'block' : 'unblock'](getServerName(account))
|
await client.v1.domainBlocks[relationship!.domainBlocking ? 'block' : 'unblock'](getServerName(account))
|
||||||
}
|
}
|
||||||
|
|
||||||
const toggleReblogs = async () => {
|
async function toggleReblogs() {
|
||||||
if (!relationship!.showingReblogs && await openConfirmDialog({
|
if (!relationship!.showingReblogs && await openConfirmDialog({
|
||||||
title: t('confirm.show_reblogs.title', [account.acct]),
|
title: t('confirm.show_reblogs.title', [account.acct]),
|
||||||
confirm: t('confirm.show_reblogs.confirm'),
|
confirm: t('confirm.show_reblogs.confirm'),
|
||||||
|
|
|
@ -14,7 +14,7 @@ const localeMap = (locales.value as LocaleObject[]).reduce((acc, l) => {
|
||||||
let ariaLive = $ref<AriaLive>('polite')
|
let ariaLive = $ref<AriaLive>('polite')
|
||||||
let ariaMessage = $ref<string>('')
|
let ariaMessage = $ref<string>('')
|
||||||
|
|
||||||
const onMessage = (event: AriaAnnounceType, message?: string) => {
|
function onMessage(event: AriaAnnounceType, message?: string) {
|
||||||
if (event === 'announce')
|
if (event === 'announce')
|
||||||
ariaMessage = message!
|
ariaMessage = message!
|
||||||
else if (event === 'mute')
|
else if (event === 'mute')
|
||||||
|
|
|
@ -26,12 +26,14 @@ const query = $computed(() => commandMode ? '' : input.trim())
|
||||||
|
|
||||||
const { accounts, hashtags, loading } = useSearch($$(query))
|
const { accounts, hashtags, loading } = useSearch($$(query))
|
||||||
|
|
||||||
const toSearchQueryResultItem = (search: SearchResultType): QueryResultItem => ({
|
function toSearchQueryResultItem(search: SearchResultType): QueryResultItem {
|
||||||
|
return {
|
||||||
index: 0,
|
index: 0,
|
||||||
type: 'search',
|
type: 'search',
|
||||||
search,
|
search,
|
||||||
onActivate: () => router.push(search.to),
|
onActivate: () => router.push(search.to),
|
||||||
})
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const searchResult = $computed<QueryResult>(() => {
|
const searchResult = $computed<QueryResult>(() => {
|
||||||
if (query.length === 0 || loading.value)
|
if (query.length === 0 || loading.value)
|
||||||
|
@ -73,9 +75,10 @@ watch($$(result), (n, o) => {
|
||||||
active = 0
|
active = 0
|
||||||
})
|
})
|
||||||
|
|
||||||
const findItemEl = (index: number) =>
|
function findItemEl(index: number) {
|
||||||
resultEl?.querySelector(`[data-index="${index}"]`) as HTMLDivElement | null
|
return resultEl?.querySelector(`[data-index="${index}"]`) as HTMLDivElement | null
|
||||||
const onCommandActivate = (item: QueryResultItem) => {
|
}
|
||||||
|
function onCommandActivate(item: QueryResultItem) {
|
||||||
if (item.onActivate) {
|
if (item.onActivate) {
|
||||||
item.onActivate()
|
item.onActivate()
|
||||||
emit('close')
|
emit('close')
|
||||||
|
@ -85,7 +88,7 @@ const onCommandActivate = (item: QueryResultItem) => {
|
||||||
input = '> '
|
input = '> '
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
const onCommandComplete = (item: QueryResultItem) => {
|
function onCommandComplete(item: QueryResultItem) {
|
||||||
if (item.onComplete) {
|
if (item.onComplete) {
|
||||||
scopes.push(item.onComplete())
|
scopes.push(item.onComplete())
|
||||||
input = '> '
|
input = '> '
|
||||||
|
@ -95,7 +98,7 @@ const onCommandComplete = (item: QueryResultItem) => {
|
||||||
emit('close')
|
emit('close')
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
const intoView = (index: number) => {
|
function intoView(index: number) {
|
||||||
const el = findItemEl(index)
|
const el = findItemEl(index)
|
||||||
if (el)
|
if (el)
|
||||||
el.scrollIntoView({ block: 'nearest' })
|
el.scrollIntoView({ block: 'nearest' })
|
||||||
|
@ -107,7 +110,7 @@ function setActive(index: number) {
|
||||||
intoView(active)
|
intoView(active)
|
||||||
}
|
}
|
||||||
|
|
||||||
const onKeyDown = (e: KeyboardEvent) => {
|
function onKeyDown(e: KeyboardEvent) {
|
||||||
switch (e.key) {
|
switch (e.key) {
|
||||||
case 'p':
|
case 'p':
|
||||||
case 'ArrowUp': {
|
case 'ArrowUp': {
|
||||||
|
|
|
@ -30,7 +30,7 @@ const cropperImage = reactive({
|
||||||
type: 'image/jpg',
|
type: 'image/jpg',
|
||||||
})
|
})
|
||||||
|
|
||||||
const stencilSize = ({ boundaries }: { boundaries: Boundaries }) => {
|
function stencilSize({ boundaries }: { boundaries: Boundaries }) {
|
||||||
return {
|
return {
|
||||||
width: boundaries.width * props.stencilSizePercentage,
|
width: boundaries.width * props.stencilSizePercentage,
|
||||||
height: boundaries.height * props.stencilSizePercentage,
|
height: boundaries.height * props.stencilSizePercentage,
|
||||||
|
@ -55,7 +55,7 @@ watch(file, (file, _, onCleanup) => {
|
||||||
cropperFlag.value = false
|
cropperFlag.value = false
|
||||||
})
|
})
|
||||||
|
|
||||||
const cropImage = () => {
|
function cropImage() {
|
||||||
if (cropper.value && file.value) {
|
if (cropper.value && file.value) {
|
||||||
cropperFlag.value = true
|
cropperFlag.value = true
|
||||||
cropperDialog.value = false
|
cropperDialog.value = false
|
||||||
|
|
|
@ -34,7 +34,7 @@ const previewImage = ref('')
|
||||||
/** The current images on display */
|
/** The current images on display */
|
||||||
const imageSrc = computed<string>(() => previewImage.value || defaultImage.value)
|
const imageSrc = computed<string>(() => previewImage.value || defaultImage.value)
|
||||||
|
|
||||||
const pickImage = async () => {
|
async function pickImage() {
|
||||||
if (process.server)
|
if (process.server)
|
||||||
return
|
return
|
||||||
const image = await fileOpen({
|
const image = await fileOpen({
|
||||||
|
|
|
@ -9,7 +9,9 @@ defineProps<{
|
||||||
const dropdown = $ref<any>()
|
const dropdown = $ref<any>()
|
||||||
const colorMode = useColorMode()
|
const colorMode = useColorMode()
|
||||||
|
|
||||||
const hide = () => dropdown.hide()
|
function hide() {
|
||||||
|
return dropdown.hide()
|
||||||
|
}
|
||||||
provide(InjectionKeyDropdownContext, {
|
provide(InjectionKeyDropdownContext, {
|
||||||
hide,
|
hide,
|
||||||
})
|
})
|
||||||
|
|
|
@ -15,7 +15,7 @@ const { hide } = useDropdownContext() || {}
|
||||||
|
|
||||||
const el = ref<HTMLDivElement>()
|
const el = ref<HTMLDivElement>()
|
||||||
|
|
||||||
const handleClick = (evt: MouseEvent) => {
|
function handleClick(evt: MouseEvent) {
|
||||||
hide?.()
|
hide?.()
|
||||||
emit('click', evt)
|
emit('click', evt)
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,13 +25,13 @@ const input = ref<HTMLInputElement>()
|
||||||
const editBtn = ref<HTMLButtonElement>()
|
const editBtn = ref<HTMLButtonElement>()
|
||||||
const deleteBtn = ref<HTMLButtonElement>()
|
const deleteBtn = ref<HTMLButtonElement>()
|
||||||
|
|
||||||
const prepareEdit = async () => {
|
async function prepareEdit() {
|
||||||
isEditing = true
|
isEditing = true
|
||||||
actionError = undefined
|
actionError = undefined
|
||||||
await nextTick()
|
await nextTick()
|
||||||
input.value?.focus()
|
input.value?.focus()
|
||||||
}
|
}
|
||||||
const cancelEdit = async () => {
|
async function cancelEdit() {
|
||||||
isEditing = false
|
isEditing = false
|
||||||
actionError = undefined
|
actionError = undefined
|
||||||
reset()
|
reset()
|
||||||
|
|
|
@ -33,21 +33,21 @@ useEventListener('keydown', (e: KeyboardEvent) => {
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
const handlePublished = (status: mastodon.v1.Status) => {
|
function handlePublished(status: mastodon.v1.Status) {
|
||||||
lastPublishDialogStatus.value = status
|
lastPublishDialogStatus.value = status
|
||||||
isPublishDialogOpen.value = false
|
isPublishDialogOpen.value = false
|
||||||
}
|
}
|
||||||
|
|
||||||
const handlePublishClose = () => {
|
function handlePublishClose() {
|
||||||
lastPublishDialogStatus.value = null
|
lastPublishDialogStatus.value = null
|
||||||
}
|
}
|
||||||
|
|
||||||
const handleConfirmChoice = (choice: ConfirmDialogChoice) => {
|
function handleConfirmChoice(choice: ConfirmDialogChoice) {
|
||||||
confirmDialogChoice.value = choice
|
confirmDialogChoice.value = choice
|
||||||
isConfirmDialogOpen.value = false
|
isConfirmDialogOpen.value = false
|
||||||
}
|
}
|
||||||
|
|
||||||
const handleFavouritedBoostedByClose = () => {
|
function handleFavouritedBoostedByClose() {
|
||||||
isFavouritedBoostedByDialogOpen.value = false
|
isFavouritedBoostedByDialogOpen.value = false
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
|
@ -119,9 +119,11 @@ const isVShow = computed(() => {
|
||||||
: true
|
: true
|
||||||
})
|
})
|
||||||
|
|
||||||
const bindTypeToAny = ($attrs: any) => $attrs as any
|
function bindTypeToAny($attrs: any) {
|
||||||
|
return $attrs as any
|
||||||
|
}
|
||||||
|
|
||||||
const trapFocusDialog = () => {
|
function trapFocusDialog() {
|
||||||
if (isVShow.value)
|
if (isVShow.value)
|
||||||
nextTick().then(() => activate())
|
nextTick().then(() => activate())
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,28 +10,34 @@
|
||||||
x="4"
|
x="4"
|
||||||
y="1"
|
y="1"
|
||||||
maskUnits="userSpaceOnUse"
|
maskUnits="userSpaceOnUse"
|
||||||
style="mask-type:alpha">
|
style="mask-type:alpha"
|
||||||
|
>
|
||||||
<path
|
<path
|
||||||
|
id="path19"
|
||||||
fill="#D9D9D9"
|
fill="#D9D9D9"
|
||||||
d="M244 123c0 64.617-38.383 112-103 112-64.617 0-103-30.883-103-95.5C38 111.194-8.729 36.236 8 16 29.46-9.959 88.689 6 125 6c64.617 0 119 52.383 119 117Z"
|
d="M244 123c0 64.617-38.383 112-103 112-64.617 0-103-30.883-103-95.5C38 111.194-8.729 36.236 8 16 29.46-9.959 88.689 6 125 6c64.617 0 119 52.383 119 117Z"
|
||||||
id="path19" />
|
/>
|
||||||
</mask>
|
</mask>
|
||||||
<g
|
<g
|
||||||
mask="url(#a)"
|
|
||||||
id="g28"
|
id="g28"
|
||||||
transform="matrix(0.90923731,0,0,1.0049564,13.520015,-3.1040835)">
|
mask="url(#a)"
|
||||||
|
transform="matrix(0.90923731,0,0,1.0049564,13.520015,-3.1040835)"
|
||||||
|
>
|
||||||
<path
|
<path
|
||||||
|
id="path22"
|
||||||
class="body"
|
class="body"
|
||||||
d="m 116.94,88.1 c -13.344,1.552 -20.436,-2.019 -24.706,10.71 0,0 14.336,21.655 52.54,21.112 -2.135,8.848 -1.144,15.368 -1.144,23.207 0,26.079 -20.589,48.821 -65.961,48.821 -23.03,0 -51.015,4.191 -72.367,15.911 -15.175,8.305 -27.048,20.336 -32.302,37.023 l 5.956,8.461 11.4,0.155 v 47.889 l -13.91,21.966 3.998,63.645 H -6.364 L -5.22,335.773 C 1.338,331.892 16.36,321.802 29.171,306.279 46.557,285.4 59.902,255.052 44.193,217.486 l 11.744,-5.045 c 12.887,30.814 8.388,57.514 -2.898,79.013 21.58,-0.698 40.11,-2.095 55.819,-4.734 l -3.584,-43.698 12.659,-1.087 L 129.98,387 h 13.116 l 2.212,-94.459 c 10.447,-4.502 34.239,-21.034 45.372,-78.47 1.372,-6.986 2.135,-12.885 2.516,-17.93 1.754,-12.806 2.745,-27.243 3.051,-43.698 l -18.683,-5.976 h 57.42 l 5.567,-12.807 c -5.414,0.233 -11.896,-2.639 -11.896,-2.639 l 1.297,-6.209 H 242 L 176.801,90.428 c -7.244,2.794 -14.87,6.442 -20.208,10.866 -4.27,-3.105 -19.063,-12.807 -39.653,-13.195 z"
|
d="m 116.94,88.1 c -13.344,1.552 -20.436,-2.019 -24.706,10.71 0,0 14.336,21.655 52.54,21.112 -2.135,8.848 -1.144,15.368 -1.144,23.207 0,26.079 -20.589,48.821 -65.961,48.821 -23.03,0 -51.015,4.191 -72.367,15.911 -15.175,8.305 -27.048,20.336 -32.302,37.023 l 5.956,8.461 11.4,0.155 v 47.889 l -13.91,21.966 3.998,63.645 H -6.364 L -5.22,335.773 C 1.338,331.892 16.36,321.802 29.171,306.279 46.557,285.4 59.902,255.052 44.193,217.486 l 11.744,-5.045 c 12.887,30.814 8.388,57.514 -2.898,79.013 21.58,-0.698 40.11,-2.095 55.819,-4.734 l -3.584,-43.698 12.659,-1.087 L 129.98,387 h 13.116 l 2.212,-94.459 c 10.447,-4.502 34.239,-21.034 45.372,-78.47 1.372,-6.986 2.135,-12.885 2.516,-17.93 1.754,-12.806 2.745,-27.243 3.051,-43.698 l -18.683,-5.976 h 57.42 l 5.567,-12.807 c -5.414,0.233 -11.896,-2.639 -11.896,-2.639 l 1.297,-6.209 H 242 L 176.801,90.428 c -7.244,2.794 -14.87,6.442 -20.208,10.866 -4.27,-3.105 -19.063,-12.807 -39.653,-13.195 z"
|
||||||
id="path22" />
|
/>
|
||||||
<path
|
<path
|
||||||
|
id="path24"
|
||||||
class="wood"
|
class="wood"
|
||||||
d="M 6.217,24.493 18.494,21 c 5.948,21.577 13.345,33.375 22.648,39.352 8.388,5.099 19.75,5.239 31.799,4.579 C 69.433,63.767 66.154,62.137 63.104,59.886 56.317,54.841 50.522,46.458 46.175,31.246 l 12.201,-3.649 c 3.279,11.488 7.092,18.085 12.201,21.888 5.11,3.726 11.286,4.657 18.606,5.433 13.726,1.553 30.884,2.174 52.312,12.264 2.898,1.086 5.872,2.483 8.769,4.036 -0.381,-0.776 -0.762,-1.553 -1.296,-2.406 -3.66,-5.822 -10.828,-11.953 -24.097,-16.92 l 4.27,-12.109 c 21.581,7.917 30.121,19.171 33.553,28.097 3.965,10.168 1.525,18.124 1.525,18.124 -3.05,1.009 -6.1,2.406 -9.608,3.492 -6.634,-4.579 -12.887,-8.033 -18.835,-10.75 C 113.814,70.442 92.31,76.108 73.246,77.893 58.91,79.213 45.794,78.591 34.432,71.295 23.222,64.155 13.385,50.495 6.217,24.493 Z"
|
d="M 6.217,24.493 18.494,21 c 5.948,21.577 13.345,33.375 22.648,39.352 8.388,5.099 19.75,5.239 31.799,4.579 C 69.433,63.767 66.154,62.137 63.104,59.886 56.317,54.841 50.522,46.458 46.175,31.246 l 12.201,-3.649 c 3.279,11.488 7.092,18.085 12.201,21.888 5.11,3.726 11.286,4.657 18.606,5.433 13.726,1.553 30.884,2.174 52.312,12.264 2.898,1.086 5.872,2.483 8.769,4.036 -0.381,-0.776 -0.762,-1.553 -1.296,-2.406 -3.66,-5.822 -10.828,-11.953 -24.097,-16.92 l 4.27,-12.109 c 21.581,7.917 30.121,19.171 33.553,28.097 3.965,10.168 1.525,18.124 1.525,18.124 -3.05,1.009 -6.1,2.406 -9.608,3.492 -6.634,-4.579 -12.887,-8.033 -18.835,-10.75 C 113.814,70.442 92.31,76.108 73.246,77.893 58.91,79.213 45.794,78.591 34.432,71.295 23.222,64.155 13.385,50.495 6.217,24.493 Z"
|
||||||
id="path24" />
|
/>
|
||||||
<path
|
<path
|
||||||
|
id="path26"
|
||||||
class="wood"
|
class="wood"
|
||||||
d="M 90.098,45.294 C 87.582,39.55 86.057,32.487 86.743,23.794 l 12.659,0.932 c -0.763,10.555 2.897,17.696 7.015,22.353 -5.338,-0.931 -10.447,-1.04 -16.319,-1.785 z m 80.069,-1.32 8.312,-9.702 c 21.58,19.094 8.159,46.415 8.159,46.415 l -11.819,-1.32 c -0.382,-6.24 -1.144,-17.836 -6.635,-24.371 3.584,1.84 6.635,3.865 9.99,6.908 0,-5.666 -1.754,-12.341 -8.007,-17.93 z"
|
d="M 90.098,45.294 C 87.582,39.55 86.057,32.487 86.743,23.794 l 12.659,0.932 c -0.763,10.555 2.897,17.696 7.015,22.353 -5.338,-0.931 -10.447,-1.04 -16.319,-1.785 z m 80.069,-1.32 8.312,-9.702 c 21.58,19.094 8.159,46.415 8.159,46.415 l -11.819,-1.32 c -0.382,-6.24 -1.144,-17.836 -6.635,-24.371 3.584,1.84 6.635,3.865 9.99,6.908 0,-5.666 -1.754,-12.341 -8.007,-17.93 z"
|
||||||
id="path26" />
|
/>
|
||||||
</g>
|
</g>
|
||||||
</svg>
|
</svg>
|
||||||
|
|
||||||
|
|
|
@ -5,7 +5,7 @@ const back = ref<any>('')
|
||||||
|
|
||||||
const nuxtApp = useNuxtApp()
|
const nuxtApp = useNuxtApp()
|
||||||
|
|
||||||
const onClickLogo = () => {
|
function onClickLogo() {
|
||||||
nuxtApp.hooks.callHook('elk-logo:click')
|
nuxtApp.hooks.callHook('elk-logo:click')
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -14,7 +14,7 @@ const virtualScroller = false // TODO: fix flickering issue with virtual scroll
|
||||||
const groupCapacity = Number.MAX_VALUE // No limit
|
const groupCapacity = Number.MAX_VALUE // No limit
|
||||||
|
|
||||||
// Group by type (and status when applicable)
|
// Group by type (and status when applicable)
|
||||||
const groupId = (item: mastodon.v1.Notification): string => {
|
function groupId(item: mastodon.v1.Notification): string {
|
||||||
// If the update is related to an status, group notifications from the same account (boost + favorite the same status)
|
// If the update is related to an status, group notifications from the same account (boost + favorite the same status)
|
||||||
const id = item.status
|
const id = item.status
|
||||||
? {
|
? {
|
||||||
|
|
|
@ -24,7 +24,7 @@ let animateRemoveSubscription = $ref<boolean>(false)
|
||||||
let subscribeError = $ref<string>('')
|
let subscribeError = $ref<string>('')
|
||||||
let showSubscribeError = $ref<boolean>(false)
|
let showSubscribeError = $ref<boolean>(false)
|
||||||
|
|
||||||
const hideNotification = () => {
|
function hideNotification() {
|
||||||
const key = currentUser.value?.account?.acct
|
const key = currentUser.value?.account?.acct
|
||||||
if (key)
|
if (key)
|
||||||
hiddenNotification.value[key] = true
|
hiddenNotification.value[key] = true
|
||||||
|
@ -39,7 +39,7 @@ const showWarning = $computed(() => {
|
||||||
&& !(hiddenNotification.value[currentUser.value?.account?.acct ?? ''] === true)
|
&& !(hiddenNotification.value[currentUser.value?.account?.acct ?? ''] === true)
|
||||||
})
|
})
|
||||||
|
|
||||||
const saveSettings = async () => {
|
async function saveSettings() {
|
||||||
if (busy)
|
if (busy)
|
||||||
return
|
return
|
||||||
|
|
||||||
|
@ -60,7 +60,7 @@ const saveSettings = async () => {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const doSubscribe = async () => {
|
async function doSubscribe() {
|
||||||
if (busy)
|
if (busy)
|
||||||
return
|
return
|
||||||
|
|
||||||
|
@ -90,7 +90,7 @@ const doSubscribe = async () => {
|
||||||
animateSubscription = false
|
animateSubscription = false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
const removeSubscription = async () => {
|
async function removeSubscription() {
|
||||||
if (busy)
|
if (busy)
|
||||||
return
|
return
|
||||||
|
|
||||||
|
|
|
@ -20,7 +20,7 @@ const maxDescriptionLength = 1500
|
||||||
|
|
||||||
const isEditDialogOpen = ref(false)
|
const isEditDialogOpen = ref(false)
|
||||||
const description = ref(props.attachment.description ?? '')
|
const description = ref(props.attachment.description ?? '')
|
||||||
const toggleApply = () => {
|
function toggleApply() {
|
||||||
isEditDialogOpen.value = false
|
isEditDialogOpen.value = false
|
||||||
emit('setDescription', unref(description))
|
emit('setDescription', unref(description))
|
||||||
}
|
}
|
||||||
|
|
|
@ -47,7 +47,7 @@ async function openEmojiPicker() {
|
||||||
el?.appendChild(picker as any as HTMLElement)
|
el?.appendChild(picker as any as HTMLElement)
|
||||||
}
|
}
|
||||||
|
|
||||||
const hideEmojiPicker = () => {
|
function hideEmojiPicker() {
|
||||||
if (picker)
|
if (picker)
|
||||||
el?.removeChild(picker as any as HTMLElement)
|
el?.removeChild(picker as any as HTMLElement)
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,7 +11,7 @@ const currentVisibility = $computed(() =>
|
||||||
statusVisibilities.find(v => v.value === modelValue) || statusVisibilities[0],
|
statusVisibilities.find(v => v.value === modelValue) || statusVisibilities[0],
|
||||||
)
|
)
|
||||||
|
|
||||||
const chooseVisibility = (visibility: string) => {
|
function chooseVisibility(visibility: string) {
|
||||||
modelValue = visibility
|
modelValue = visibility
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
|
@ -6,7 +6,7 @@ defineProps<{
|
||||||
active: boolean
|
active: boolean
|
||||||
}>()
|
}>()
|
||||||
|
|
||||||
const onActivate = () => {
|
function onActivate() {
|
||||||
(document.activeElement as HTMLElement).blur()
|
(document.activeElement as HTMLElement).blur()
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
|
@ -38,9 +38,11 @@ const results = computed(() => {
|
||||||
// Reset index when results change
|
// Reset index when results change
|
||||||
watch([results, focused], () => index.value = -1)
|
watch([results, focused], () => index.value = -1)
|
||||||
|
|
||||||
const shift = (delta: number) => index.value = (index.value + delta % results.value.length + results.value.length) % results.value.length
|
function shift(delta: number) {
|
||||||
|
return index.value = (index.value + delta % results.value.length + results.value.length) % results.value.length
|
||||||
|
}
|
||||||
|
|
||||||
const activate = () => {
|
function activate() {
|
||||||
const currentIndex = index.value
|
const currentIndex = index.value
|
||||||
|
|
||||||
if (query.value.length === 0)
|
if (query.value.length === 0)
|
||||||
|
|
|
@ -6,7 +6,7 @@ const userSettings = useUserSettings()
|
||||||
|
|
||||||
const sizes = (new Array(11)).fill(0).map((x, i) => `${10 + i}px`) as FontSize[]
|
const sizes = (new Array(11)).fill(0).map((x, i) => `${10 + i}px`) as FontSize[]
|
||||||
|
|
||||||
const setFontSize = (e: Event) => {
|
function setFontSize(e: Event) {
|
||||||
if (e.target && 'valueAsNumber' in e.target)
|
if (e.target && 'valueAsNumber' in e.target)
|
||||||
userSettings.value.fontSize = sizes[e.target.valueAsNumber as number]
|
userSettings.value.fontSize = sizes[e.target.valueAsNumber as number]
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,7 +25,7 @@ const fieldCount = $computed(() => {
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
|
|
||||||
const chooseIcon = (i: number, text: string) => {
|
function chooseIcon(i: number, text: string) {
|
||||||
form.value.fieldsAttributes[i].name = text
|
form.value.fieldsAttributes[i].name = text
|
||||||
dropdown[i]?.hide()
|
dropdown[i]?.hide()
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,7 +22,7 @@ const {
|
||||||
toggleReblog,
|
toggleReblog,
|
||||||
} = $(useStatusActions(props))
|
} = $(useStatusActions(props))
|
||||||
|
|
||||||
const reply = () => {
|
function reply() {
|
||||||
if (!checkLogin())
|
if (!checkLogin())
|
||||||
return
|
return
|
||||||
if (details)
|
if (details)
|
||||||
|
|
|
@ -29,33 +29,33 @@ const isAuthor = $computed(() => status.account.id === currentUser.value?.accoun
|
||||||
|
|
||||||
const { client } = $(useMasto())
|
const { client } = $(useMasto())
|
||||||
|
|
||||||
const getPermalinkUrl = (status: mastodon.v1.Status) => {
|
function getPermalinkUrl(status: mastodon.v1.Status) {
|
||||||
const url = getStatusPermalinkRoute(status)
|
const url = getStatusPermalinkRoute(status)
|
||||||
if (url)
|
if (url)
|
||||||
return `${location.origin}/${url}`
|
return `${location.origin}/${url}`
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
|
||||||
const copyLink = async (status: mastodon.v1.Status) => {
|
async function copyLink(status: mastodon.v1.Status) {
|
||||||
const url = getPermalinkUrl(status)
|
const url = getPermalinkUrl(status)
|
||||||
if (url)
|
if (url)
|
||||||
await clipboard.copy(url)
|
await clipboard.copy(url)
|
||||||
}
|
}
|
||||||
|
|
||||||
const copyOriginalLink = async (status: mastodon.v1.Status) => {
|
async function copyOriginalLink(status: mastodon.v1.Status) {
|
||||||
const url = status.url
|
const url = status.url
|
||||||
if (url)
|
if (url)
|
||||||
await clipboard.copy(url)
|
await clipboard.copy(url)
|
||||||
}
|
}
|
||||||
|
|
||||||
const { share, isSupported: isShareSupported } = useShare()
|
const { share, isSupported: isShareSupported } = useShare()
|
||||||
const shareLink = async (status: mastodon.v1.Status) => {
|
async function shareLink(status: mastodon.v1.Status) {
|
||||||
const url = getPermalinkUrl(status)
|
const url = getPermalinkUrl(status)
|
||||||
if (url)
|
if (url)
|
||||||
await share({ url })
|
await share({ url })
|
||||||
}
|
}
|
||||||
|
|
||||||
const deleteStatus = async () => {
|
async function deleteStatus() {
|
||||||
if (await openConfirmDialog({
|
if (await openConfirmDialog({
|
||||||
title: t('confirm.delete_posts.title'),
|
title: t('confirm.delete_posts.title'),
|
||||||
confirm: t('confirm.delete_posts.confirm'),
|
confirm: t('confirm.delete_posts.confirm'),
|
||||||
|
@ -72,7 +72,7 @@ const deleteStatus = async () => {
|
||||||
// TODO when timeline, remove this item
|
// TODO when timeline, remove this item
|
||||||
}
|
}
|
||||||
|
|
||||||
const deleteAndRedraft = async () => {
|
async function deleteAndRedraft() {
|
||||||
// TODO confirm to delete
|
// TODO confirm to delete
|
||||||
if (process.dev) {
|
if (process.dev) {
|
||||||
// eslint-disable-next-line no-alert
|
// eslint-disable-next-line no-alert
|
||||||
|
@ -90,7 +90,7 @@ const deleteAndRedraft = async () => {
|
||||||
router.push(getStatusRoute(lastPublishDialogStatus.value))
|
router.push(getStatusRoute(lastPublishDialogStatus.value))
|
||||||
}
|
}
|
||||||
|
|
||||||
const reply = () => {
|
function reply() {
|
||||||
if (details) {
|
if (details) {
|
||||||
// TODO focus to editor
|
// TODO focus to editor
|
||||||
}
|
}
|
||||||
|
@ -107,7 +107,7 @@ async function editStatus() {
|
||||||
}, true)
|
}, true)
|
||||||
}
|
}
|
||||||
|
|
||||||
const showFavoritedAndBoostedBy = () => {
|
function showFavoritedAndBoostedBy() {
|
||||||
openFavoridedBoostedByDialog(status.id)
|
openFavoridedBoostedByDialog(status.id)
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
|
@ -15,7 +15,7 @@ const preferenceHideTranslation = usePreferences('hideTranslation')
|
||||||
const showButton = computed(() => !preferenceHideTranslation.value && isTranslationEnabled)
|
const showButton = computed(() => !preferenceHideTranslation.value && isTranslationEnabled)
|
||||||
|
|
||||||
let translating = $ref(false)
|
let translating = $ref(false)
|
||||||
const toggleTranslation = async () => {
|
async function toggleTranslation() {
|
||||||
translating = true
|
translating = true
|
||||||
try {
|
try {
|
||||||
await _toggleTranslation()
|
await _toggleTranslation()
|
||||||
|
|
|
@ -8,14 +8,15 @@ const { status } = defineProps<{
|
||||||
|
|
||||||
const paginator = useMastoClient().v1.statuses.listHistory(status.id)
|
const paginator = useMastoClient().v1.statuses.listHistory(status.id)
|
||||||
|
|
||||||
const showHistory = (edit: mastodon.v1.StatusEdit) => {
|
function showHistory(edit: mastodon.v1.StatusEdit) {
|
||||||
openEditHistoryDialog(edit)
|
openEditHistoryDialog(edit)
|
||||||
}
|
}
|
||||||
const timeAgoOptions = useTimeAgoOptions()
|
const timeAgoOptions = useTimeAgoOptions()
|
||||||
|
|
||||||
// TODO: rework, this is only reversing the first page of edits
|
// TODO: rework, this is only reversing the first page of edits
|
||||||
const reverseHistory = (items: mastodon.v1.StatusEdit[]) =>
|
function reverseHistory(items: mastodon.v1.StatusEdit[]) {
|
||||||
[...items].reverse()
|
return [...items].reverse()
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
|
|
|
@ -11,7 +11,7 @@ const emit = defineEmits<{
|
||||||
|
|
||||||
const { client } = $(useMasto())
|
const { client } = $(useMasto())
|
||||||
|
|
||||||
const toggleFollowTag = async () => {
|
async function toggleFollowTag() {
|
||||||
// We save the state so be can do an optimistic UI update, but fallback to the previous state if the API call fails
|
// We save the state so be can do an optimistic UI update, but fallback to the previous state if the API call fails
|
||||||
const previousFollowingState = tag.following
|
const previousFollowingState = tag.following
|
||||||
|
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
const { client } = $(useMasto())
|
const { client } = $(useMasto())
|
||||||
const paginator = client.v1.domainBlocks.list()
|
const paginator = client.v1.domainBlocks.list()
|
||||||
|
|
||||||
const unblock = async (domain: string) => {
|
async function unblock(domain: string) {
|
||||||
await client.v1.domainBlocks.unblock(domain)
|
await client.v1.domainBlocks.unblock(domain)
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
|
@ -3,7 +3,9 @@ import type { mastodon } from 'masto'
|
||||||
|
|
||||||
const paginator = useMastoClient().v1.timelines.listHome({ limit: 30 })
|
const paginator = useMastoClient().v1.timelines.listHome({ limit: 30 })
|
||||||
const stream = $(useStreaming(client => client.v1.stream.streamUser()))
|
const stream = $(useStreaming(client => client.v1.stream.streamUser()))
|
||||||
const reorderAndFilter = (items: mastodon.v1.Status[]) => reorderedTimeline(items, 'home')
|
function reorderAndFilter(items: mastodon.v1.Status[]) {
|
||||||
|
return reorderedTimeline(items, 'home')
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
|
|
|
@ -3,7 +3,9 @@ import type { mastodon } from 'masto'
|
||||||
|
|
||||||
const paginator = useMastoClient().v1.timelines.listPublic({ limit: 30 })
|
const paginator = useMastoClient().v1.timelines.listPublic({ limit: 30 })
|
||||||
const stream = useStreaming(client => client.v1.stream.streamPublicTimeline())
|
const stream = useStreaming(client => client.v1.stream.streamPublicTimeline())
|
||||||
const reorderAndFilter = (items: mastodon.v1.Status[]) => reorderedTimeline(items, 'public')
|
function reorderAndFilter(items: mastodon.v1.Status[]) {
|
||||||
|
return reorderedTimeline(items, 'public')
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
|
|
|
@ -4,7 +4,7 @@ import type { UserLogin } from '~/types'
|
||||||
const all = useUsers()
|
const all = useUsers()
|
||||||
const router = useRouter()
|
const router = useRouter()
|
||||||
|
|
||||||
const clickUser = (user: UserLogin) => {
|
function clickUser(user: UserLogin) {
|
||||||
if (user.account.acct === currentUser.value?.account.acct)
|
if (user.account.acct === currentUser.value?.account.acct)
|
||||||
router.push(getAccountRoute(user.account))
|
router.push(getAccountRoute(user.account))
|
||||||
else
|
else
|
||||||
|
|
|
@ -16,13 +16,13 @@ const sorted = computed(() => {
|
||||||
})
|
})
|
||||||
|
|
||||||
const router = useRouter()
|
const router = useRouter()
|
||||||
const clickUser = (user: UserLogin) => {
|
function clickUser(user: UserLogin) {
|
||||||
if (user.account.id === currentUser.value?.account.id)
|
if (user.account.id === currentUser.value?.account.id)
|
||||||
router.push(getAccountRoute(user.account))
|
router.push(getAccountRoute(user.account))
|
||||||
else
|
else
|
||||||
switchUser(user)
|
switchUser(user)
|
||||||
}
|
}
|
||||||
const processSignIn = () => {
|
function processSignIn() {
|
||||||
if (singleInstanceServer)
|
if (singleInstanceServer)
|
||||||
oauth()
|
oauth()
|
||||||
else
|
else
|
||||||
|
|
|
@ -3,7 +3,7 @@ export type AriaAnnounceType = 'announce' | 'mute' | 'unmute'
|
||||||
|
|
||||||
const ariaAnnouncer = useEventBus<AriaAnnounceType, string | undefined>(Symbol('aria-announcer'))
|
const ariaAnnouncer = useEventBus<AriaAnnounceType, string | undefined>(Symbol('aria-announcer'))
|
||||||
|
|
||||||
export const useAriaAnnouncer = () => {
|
export function useAriaAnnouncer() {
|
||||||
const announce = (message: string) => {
|
const announce = (message: string) => {
|
||||||
ariaAnnouncer.emit('announce', message)
|
ariaAnnouncer.emit('announce', message)
|
||||||
}
|
}
|
||||||
|
@ -19,7 +19,7 @@ export const useAriaAnnouncer = () => {
|
||||||
return { announce, ariaAnnouncer, mute, unmute }
|
return { announce, ariaAnnouncer, mute, unmute }
|
||||||
}
|
}
|
||||||
|
|
||||||
export const useAriaLog = () => {
|
export function useAriaLog() {
|
||||||
let logs = $ref<any[]>([])
|
let logs = $ref<any[]>([])
|
||||||
|
|
||||||
const announceLogs = (messages: any[]) => {
|
const announceLogs = (messages: any[]) => {
|
||||||
|
@ -42,7 +42,7 @@ export const useAriaLog = () => {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export const useAriaStatus = () => {
|
export function useAriaStatus() {
|
||||||
let status = $ref<any>('')
|
let status = $ref<any>('')
|
||||||
|
|
||||||
const announceStatus = (message: any) => {
|
const announceStatus = (message: any) => {
|
||||||
|
|
|
@ -78,8 +78,9 @@ export interface QueryResult {
|
||||||
grouped: Map<CommandScopeNames, QueryResultItem[]>
|
grouped: Map<CommandScopeNames, QueryResultItem[]>
|
||||||
}
|
}
|
||||||
|
|
||||||
const r = <T extends Object | undefined>(i: T | (() => T)): T =>
|
function r<T extends Object | undefined>(i: T | (() => T)): T {
|
||||||
typeof i === 'function' ? i() : i
|
return typeof i === 'function' ? i() : i
|
||||||
|
}
|
||||||
|
|
||||||
export const useCommandRegistry = defineStore('command', () => {
|
export const useCommandRegistry = defineStore('command', () => {
|
||||||
const providers = reactive(new Set<CommandProvider>())
|
const providers = reactive(new Set<CommandProvider>())
|
||||||
|
@ -237,7 +238,7 @@ export function useCommands(cmds: () => CommandProvider[]) {
|
||||||
tryOnScopeDispose(cleanup)
|
tryOnScopeDispose(cleanup)
|
||||||
}
|
}
|
||||||
|
|
||||||
export const provideGlobalCommands = () => {
|
export function provideGlobalCommands() {
|
||||||
const { locale, t } = useI18n()
|
const { locale, t } = useI18n()
|
||||||
const { locales } = useI18n() as { locales: ComputedRef<LocaleObject[]> }
|
const { locales } = useI18n() as { locales: ComputedRef<LocaleObject[]> }
|
||||||
const router = useRouter()
|
const router = useRouter()
|
||||||
|
|
|
@ -55,7 +55,7 @@ const accountFieldIconsLowercase = Object.fromEntries(
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
|
||||||
export const getAccountFieldIcon = (value: string) => {
|
export function getAccountFieldIcon(value: string) {
|
||||||
const name = value.trim().toLowerCase()
|
const name = value.trim().toLowerCase()
|
||||||
return accountFieldIconsLowercase[name] || undefined
|
return accountFieldIconsLowercase[name] || undefined
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,7 +6,7 @@ import type { ElkInstance } from '../users'
|
||||||
import type { Mutable } from '~/types/utils'
|
import type { Mutable } from '~/types/utils'
|
||||||
import type { UserLogin } from '~/types'
|
import type { UserLogin } from '~/types'
|
||||||
|
|
||||||
export const createMasto = () => {
|
export function createMasto() {
|
||||||
let client = $shallowRef<mastodon.Client>(undefined as never)
|
let client = $shallowRef<mastodon.Client>(undefined as never)
|
||||||
let params = $ref<Mutable<CreateClientParams>>()
|
let params = $ref<Mutable<CreateClientParams>>()
|
||||||
const canStreaming = $computed(() => !!params?.streamingApiUrl)
|
const canStreaming = $computed(() => !!params?.streamingApiUrl)
|
||||||
|
@ -26,8 +26,12 @@ export const createMasto = () => {
|
||||||
}
|
}
|
||||||
export type ElkMasto = ReturnType<typeof createMasto>
|
export type ElkMasto = ReturnType<typeof createMasto>
|
||||||
|
|
||||||
export const useMasto = () => useNuxtApp().$masto as ElkMasto
|
export function useMasto() {
|
||||||
export const useMastoClient = () => useMasto().client.value
|
return useNuxtApp().$masto as ElkMasto
|
||||||
|
}
|
||||||
|
export function useMastoClient() {
|
||||||
|
return useMasto().client.value
|
||||||
|
}
|
||||||
|
|
||||||
export function mastoLogin(masto: ElkMasto, user: Pick<UserLogin, 'server' | 'token'>) {
|
export function mastoLogin(masto: ElkMasto, user: Pick<UserLogin, 'server' | 'token'>) {
|
||||||
const { setParams } = $(masto)
|
const { setParams } = $(masto)
|
||||||
|
|
|
@ -2,7 +2,7 @@ import type { WsEvents } from 'masto'
|
||||||
|
|
||||||
const notifications = reactive<Record<string, undefined | [Promise<WsEvents>, string[]]>>({})
|
const notifications = reactive<Record<string, undefined | [Promise<WsEvents>, string[]]>>({})
|
||||||
|
|
||||||
export const useNotifications = () => {
|
export function useNotifications() {
|
||||||
const id = currentUser.value?.account.id
|
const id = currentUser.value?.account.id
|
||||||
|
|
||||||
const { client, canStreaming } = $(useMasto())
|
const { client, canStreaming } = $(useMasto())
|
||||||
|
|
|
@ -64,11 +64,12 @@ export function getStatusInReplyToRoute(status: mastodon.v1.Status) {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
export const navigateToStatus = ({ status, focusReply = false }: {
|
export function navigateToStatus({ status, focusReply = false }: {
|
||||||
status: mastodon.v1.Status
|
status: mastodon.v1.Status
|
||||||
focusReply?: boolean
|
focusReply?: boolean
|
||||||
}) =>
|
}) {
|
||||||
navigateTo({
|
return navigateTo({
|
||||||
path: getStatusRoute(status).href,
|
path: getStatusRoute(status).href,
|
||||||
state: { focusReply },
|
state: { focusReply },
|
||||||
})
|
})
|
||||||
|
}
|
||||||
|
|
|
@ -84,7 +84,7 @@ export function getReplyDraft(status: mastodon.v1.Status) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export const isEmptyDraft = (draft: Draft | null | undefined) => {
|
export function isEmptyDraft(draft: Draft | null | undefined) {
|
||||||
if (!draft)
|
if (!draft)
|
||||||
return true
|
return true
|
||||||
const { params, attachments } = draft
|
const { params, attachments } = draft
|
||||||
|
|
|
@ -42,7 +42,7 @@ export const supportedTranslationCodes = [
|
||||||
'zh',
|
'zh',
|
||||||
] as const
|
] as const
|
||||||
|
|
||||||
export const getLanguageCode = () => {
|
export function getLanguageCode() {
|
||||||
let code = 'en'
|
let code = 'en'
|
||||||
const getCode = (code: string) => code.replace(/-.*$/, '')
|
const getCode = (code: string) => code.replace(/-.*$/, '')
|
||||||
if (!process.server) {
|
if (!process.server) {
|
||||||
|
|
|
@ -27,13 +27,15 @@ export function emojisArrayToObject(emojis: mastodon.v1.CustomEmoji[]) {
|
||||||
|
|
||||||
export function noop() {}
|
export function noop() {}
|
||||||
|
|
||||||
export const useIsMac = () => {
|
export function useIsMac() {
|
||||||
const headers = useRequestHeaders(['user-agent'])
|
const headers = useRequestHeaders(['user-agent'])
|
||||||
return computed(() => headers['user-agent']?.includes('Macintosh')
|
return computed(() => headers['user-agent']?.includes('Macintosh')
|
||||||
?? navigator?.platform?.includes('Mac') ?? false)
|
?? navigator?.platform?.includes('Mac') ?? false)
|
||||||
}
|
}
|
||||||
|
|
||||||
export const isEmptyObject = (object: Object) => Object.keys(object).length === 0
|
export function isEmptyObject(object: Object) {
|
||||||
|
return Object.keys(object).length === 0
|
||||||
|
}
|
||||||
|
|
||||||
export function removeHTMLTags(str: string) {
|
export function removeHTMLTags(str: string) {
|
||||||
return str.replaceAll(HTMLTagRE, '')
|
return str.replaceAll(HTMLTagRE, '')
|
||||||
|
|
|
@ -6,12 +6,10 @@ import type {
|
||||||
} from '~/composables/push-notifications/types'
|
} from '~/composables/push-notifications/types'
|
||||||
import { PushSubscriptionError } from '~/composables/push-notifications/types'
|
import { PushSubscriptionError } from '~/composables/push-notifications/types'
|
||||||
|
|
||||||
export const createPushSubscription = async (
|
export async function createPushSubscription(user: RequiredUserLogin,
|
||||||
user: RequiredUserLogin,
|
|
||||||
notificationData: CreatePushNotification,
|
notificationData: CreatePushNotification,
|
||||||
policy: mastodon.v1.SubscriptionPolicy = 'all',
|
policy: mastodon.v1.SubscriptionPolicy = 'all',
|
||||||
force = false,
|
force = false): Promise<mastodon.v1.WebPushSubscription | undefined> {
|
||||||
): Promise<mastodon.v1.WebPushSubscription | undefined> => {
|
|
||||||
const { server: serverEndpoint, vapidKey } = user
|
const { server: serverEndpoint, vapidKey } = user
|
||||||
|
|
||||||
return await getRegistration()
|
return await getRegistration()
|
||||||
|
|
|
@ -13,7 +13,7 @@ const supportsPushNotifications = typeof window !== 'undefined'
|
||||||
&& 'PushManager' in window
|
&& 'PushManager' in window
|
||||||
&& 'getKey' in PushSubscription.prototype
|
&& 'getKey' in PushSubscription.prototype
|
||||||
|
|
||||||
export const usePushManager = () => {
|
export function usePushManager() {
|
||||||
const { client } = $(useMasto())
|
const { client } = $(useMasto())
|
||||||
const isSubscribed = ref(false)
|
const isSubscribed = ref(false)
|
||||||
const notificationPermission = ref<PermissionState | undefined>(
|
const notificationPermission = ref<PermissionState | undefined>(
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import type { Ref } from 'vue'
|
import type { Ref } from 'vue'
|
||||||
|
|
||||||
export const useSignIn = (input?: Ref<HTMLInputElement | undefined>) => {
|
export function useSignIn(input?: Ref<HTMLInputElement | undefined>) {
|
||||||
const singleInstanceServer = useRuntimeConfig().public.singleInstance
|
const singleInstanceServer = useRuntimeConfig().public.singleInstance
|
||||||
const userSettings = useUserSettings()
|
const userSettings = useUserSettings()
|
||||||
const users = useUsers()
|
const users = useUsers()
|
||||||
|
|
|
@ -6,10 +6,8 @@ import {
|
||||||
} from '@tiptap/core'
|
} from '@tiptap/core'
|
||||||
import { emojiRegEx, getEmojiAttributes } from '~/config/emojis'
|
import { emojiRegEx, getEmojiAttributes } from '~/config/emojis'
|
||||||
|
|
||||||
const createEmojiRule = <NR extends typeof nodeInputRule | typeof nodePasteRule>(
|
function createEmojiRule<NR extends typeof nodeInputRule | typeof nodePasteRule>(nodeRule: NR,
|
||||||
nodeRule: NR,
|
type: Parameters<NR>[0]['type']): ReturnType<NR>[] {
|
||||||
type: Parameters<NR>[0]['type'],
|
|
||||||
): ReturnType<NR>[] => {
|
|
||||||
const rule = nodeRule({
|
const rule = nodeRule({
|
||||||
find: emojiRegEx as RegExp,
|
find: emojiRegEx as RegExp,
|
||||||
type,
|
type,
|
||||||
|
|
|
@ -14,7 +14,9 @@ import TiptapEmojiList from '~/components/tiptap/TiptapEmojiList.vue'
|
||||||
export { Emoji }
|
export { Emoji }
|
||||||
|
|
||||||
export type CustomEmoji = (mastodon.v1.CustomEmoji & { custom: true })
|
export type CustomEmoji = (mastodon.v1.CustomEmoji & { custom: true })
|
||||||
export const isCustomEmoji = (emoji: CustomEmoji | Emoji): emoji is CustomEmoji => !!(emoji as CustomEmoji).custom
|
export function isCustomEmoji(emoji: CustomEmoji | Emoji): emoji is CustomEmoji {
|
||||||
|
return !!(emoji as CustomEmoji).custom
|
||||||
|
}
|
||||||
|
|
||||||
export const TiptapMentionSuggestion: Partial<SuggestionOptions> = process.server
|
export const TiptapMentionSuggestion: Partial<SuggestionOptions> = process.server
|
||||||
? {}
|
? {}
|
||||||
|
|
|
@ -19,7 +19,7 @@ import { useAsyncIDBKeyval } from '~/composables/idb'
|
||||||
|
|
||||||
const mock = process.mock
|
const mock = process.mock
|
||||||
|
|
||||||
const initializeUsers = (): Promise<Ref<UserLogin[]> | RemovableRef<UserLogin[]>> | Ref<UserLogin[]> | RemovableRef<UserLogin[]> => {
|
function initializeUsers(): Promise<Ref<UserLogin[]> | RemovableRef<UserLogin[]>> | Ref<UserLogin[]> | RemovableRef<UserLogin[]> {
|
||||||
let defaultUsers = mock ? [mock.user] : []
|
let defaultUsers = mock ? [mock.user] : []
|
||||||
|
|
||||||
// Backward compatibility with localStorage
|
// Backward compatibility with localStorage
|
||||||
|
@ -52,7 +52,9 @@ export type ElkInstance = Partial<mastodon.v1.Instance> & {
|
||||||
/** support GoToSocial */
|
/** support GoToSocial */
|
||||||
accountDomain?: string | null
|
accountDomain?: string | null
|
||||||
}
|
}
|
||||||
export const getInstanceCache = (server: string): mastodon.v1.Instance | undefined => instanceStorage.value[server]
|
export function getInstanceCache(server: string): mastodon.v1.Instance | undefined {
|
||||||
|
return instanceStorage.value[server]
|
||||||
|
}
|
||||||
|
|
||||||
export const currentUser = computed<UserLogin | undefined>(() => {
|
export const currentUser = computed<UserLogin | undefined>(() => {
|
||||||
if (currentUserHandle.value) {
|
if (currentUserHandle.value) {
|
||||||
|
@ -109,9 +111,12 @@ if (process.client) {
|
||||||
}, { immediate: true, flush: 'post' })
|
}, { immediate: true, flush: 'post' })
|
||||||
}
|
}
|
||||||
|
|
||||||
export const useUsers = () => users
|
export function useUsers() {
|
||||||
export const useSelfAccount = (user: MaybeComputedRef<mastodon.v1.Account | undefined>) =>
|
return users
|
||||||
computed(() => currentUser.value && resolveUnref(user)?.id === currentUser.value.account.id)
|
}
|
||||||
|
export function useSelfAccount(user: MaybeComputedRef<mastodon.v1.Account | undefined>) {
|
||||||
|
return computed(() => currentUser.value && resolveUnref(user)?.id === currentUser.value.account.id)
|
||||||
|
}
|
||||||
|
|
||||||
export const characterLimit = computed(() => currentInstance.value?.configuration?.statuses.maxCharacters ?? DEFAULT_POST_CHARS_LIMIT)
|
export const characterLimit = computed(() => currentInstance.value?.configuration?.statuses.maxCharacters ?? DEFAULT_POST_CHARS_LIMIT)
|
||||||
|
|
||||||
|
|
|
@ -5,7 +5,7 @@ import type { SchemaAugmentations } from '@unhead/schema'
|
||||||
|
|
||||||
export const isHydrated = ref(false)
|
export const isHydrated = ref(false)
|
||||||
|
|
||||||
export const onHydrated = (cb: () => unknown) => {
|
export function onHydrated(cb: () => unknown) {
|
||||||
watchOnce(isHydrated, () => cb(), { immediate: isHydrated.value })
|
watchOnce(isHydrated, () => cb(), { immediate: isHydrated.value })
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -28,14 +28,14 @@ export const gitBranch = process.env.BRANCH
|
||||||
export const isPreview = isPR || process.env.CONTEXT === 'deploy-preview' || process.env.CONTEXT === 'dev'
|
export const isPreview = isPR || process.env.CONTEXT === 'deploy-preview' || process.env.CONTEXT === 'dev'
|
||||||
|
|
||||||
const git = Git()
|
const git = Git()
|
||||||
export const getGitInfo = async () => {
|
export async function getGitInfo() {
|
||||||
const branch = gitBranch || await git.revparse(['--abbrev-ref', 'HEAD'])
|
const branch = gitBranch || await git.revparse(['--abbrev-ref', 'HEAD'])
|
||||||
const commit = await git.revparse(['HEAD'])
|
const commit = await git.revparse(['HEAD'])
|
||||||
const shortCommit = await git.revparse(['--short=7', 'HEAD'])
|
const shortCommit = await git.revparse(['--short=7', 'HEAD'])
|
||||||
return { branch, commit, shortCommit }
|
return { branch, commit, shortCommit }
|
||||||
}
|
}
|
||||||
|
|
||||||
export const getEnv = async () => {
|
export async function getEnv() {
|
||||||
const { commit, shortCommit, branch } = await getGitInfo()
|
const { commit, shortCommit, branch } = await getGitInfo()
|
||||||
const env = isDevelopment
|
const env = isDevelopment
|
||||||
? 'dev'
|
? 'dev'
|
||||||
|
|
|
@ -191,7 +191,7 @@ const locales: LocaleObjectData[] = [
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
|
|
||||||
const buildLocales = () => {
|
function buildLocales() {
|
||||||
const useLocales = Object.values(locales).reduce((acc, data) => {
|
const useLocales = Object.values(locales).reduce((acc, data) => {
|
||||||
const locales = countryLocaleVariants[data.code]
|
const locales = countryLocaleVariants[data.code]
|
||||||
if (locales) {
|
if (locales) {
|
||||||
|
|
|
@ -42,7 +42,7 @@ const outdatedEntries = computed<string[]>(() => {
|
||||||
return localesStatuses[locale.value]!.outdated
|
return localesStatuses[locale.value]!.outdated
|
||||||
})
|
})
|
||||||
|
|
||||||
const showDetail = (key: string, tab: Tab = 'missing', fromTab = false) => {
|
function showDetail(key: string, tab: Tab = 'missing', fromTab = false) {
|
||||||
if (key === locale.value && tab === localeTab.value) {
|
if (key === locale.value && tab === localeTab.value) {
|
||||||
if (fromTab)
|
if (fromTab)
|
||||||
return
|
return
|
||||||
|
@ -57,7 +57,7 @@ const showDetail = (key: string, tab: Tab = 'missing', fromTab = false) => {
|
||||||
nextTick().then(() => hidden.value = false)
|
nextTick().then(() => hidden.value = false)
|
||||||
}
|
}
|
||||||
|
|
||||||
const copyToClipboard = async () => {
|
async function copyToClipboard() {
|
||||||
try {
|
try {
|
||||||
await navigator.clipboard.writeText([
|
await navigator.clipboard.writeText([
|
||||||
`# ${localeTitle.value}`,
|
`# ${localeTitle.value}`,
|
||||||
|
|
|
@ -19,7 +19,7 @@ const defaultMessage = 'Something went wrong'
|
||||||
const message = error.message ?? errorCodes[error.statusCode!] ?? defaultMessage
|
const message = error.message ?? errorCodes[error.statusCode!] ?? defaultMessage
|
||||||
|
|
||||||
const state = ref<'error' | 'reloading'>('error')
|
const state = ref<'error' | 'reloading'>('error')
|
||||||
const reload = async () => {
|
async function reload() {
|
||||||
state.value = 'reloading'
|
state.value = 'reloading'
|
||||||
try {
|
try {
|
||||||
clearError({ redirect: currentUser.value ? '/home' : `/${currentServer.value}/public/local` })
|
clearError({ redirect: currentUser.value ? '/home' : `/${currentServer.value}/public/local` })
|
||||||
|
|
|
@ -31,7 +31,7 @@ export const pwaLocales = i18n.locales as LocaleObject[]
|
||||||
type WebManifestEntry = Pick<ExtendedManifestOptions, 'name' | 'short_name' | 'description'>
|
type WebManifestEntry = Pick<ExtendedManifestOptions, 'name' | 'short_name' | 'description'>
|
||||||
type RequiredWebManifestEntry = Required<WebManifestEntry & Pick<ExtendedManifestOptions, 'dir' | 'lang'>>
|
type RequiredWebManifestEntry = Required<WebManifestEntry & Pick<ExtendedManifestOptions, 'dir' | 'lang'>>
|
||||||
|
|
||||||
export const createI18n = async (): Promise<LocalizedWebManifest> => {
|
export async function createI18n(): Promise<LocalizedWebManifest> {
|
||||||
const { env } = await getEnv()
|
const { env } = await getEnv()
|
||||||
const envName = `${env === 'release' ? '' : `(${env})`}`
|
const envName = `${env === 'release' ? '' : `(${env})`}`
|
||||||
const { pwa } = await readI18nFile('en.json')
|
const { pwa } = await readI18nFile('en.json')
|
||||||
|
|
|
@ -24,4 +24,6 @@ storage.mount('servers', {
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
export const useStorage = () => storage
|
export function useStorage() {
|
||||||
|
return storage
|
||||||
|
}
|
||||||
|
|
|
@ -100,7 +100,7 @@
|
||||||
"workbox-window": "^6.5.4"
|
"workbox-window": "^6.5.4"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@antfu/eslint-config": "^0.37.0",
|
"@antfu/eslint-config": "^0.38.2",
|
||||||
"@antfu/ni": "^0.20.0",
|
"@antfu/ni": "^0.20.0",
|
||||||
"@types/chroma-js": "^2.4.0",
|
"@types/chroma-js": "^2.4.0",
|
||||||
"@types/file-saver": "^2.0.5",
|
"@types/file-saver": "^2.0.5",
|
||||||
|
@ -111,13 +111,13 @@
|
||||||
"@types/prettier": "^2.7.2",
|
"@types/prettier": "^2.7.2",
|
||||||
"@types/wicg-file-system-access": "^2020.9.5",
|
"@types/wicg-file-system-access": "^2020.9.5",
|
||||||
"bumpp": "^9.0.0",
|
"bumpp": "^9.0.0",
|
||||||
"eslint": "^8.36.0",
|
"eslint": "^8.37.0",
|
||||||
"esno": "^0.16.3",
|
"esno": "^0.16.3",
|
||||||
"flat": "^5.0.2",
|
"flat": "^5.0.2",
|
||||||
"fs-extra": "^11.1.1",
|
"fs-extra": "^11.1.1",
|
||||||
"lint-staged": "^13.2.0",
|
"lint-staged": "^13.2.0",
|
||||||
"nuxt": "3.3.1",
|
"nuxt": "3.3.1",
|
||||||
"prettier": "^2.8.6",
|
"prettier": "^2.8.7",
|
||||||
"simple-git-hooks": "^2.8.1",
|
"simple-git-hooks": "^2.8.1",
|
||||||
"typescript": "^5.0.2",
|
"typescript": "^5.0.2",
|
||||||
"vitest": "^0.29.7",
|
"vitest": "^0.29.7",
|
||||||
|
|
|
@ -43,7 +43,9 @@ async function scrollTo() {
|
||||||
}
|
}
|
||||||
|
|
||||||
const publishWidget = ref()
|
const publishWidget = ref()
|
||||||
const focusEditor = () => publishWidget.value?.focusEditor?.()
|
function focusEditor() {
|
||||||
|
return publishWidget.value?.focusEditor?.()
|
||||||
|
}
|
||||||
|
|
||||||
provide('focus-editor', focusEditor)
|
provide('focus-editor', focusEditor)
|
||||||
|
|
||||||
|
|
|
@ -10,7 +10,9 @@ const { t } = useI18n()
|
||||||
|
|
||||||
const account = await fetchAccountByHandle(handle)
|
const account = await fetchAccountByHandle(handle)
|
||||||
|
|
||||||
const reorderAndFilter = (items: mastodon.v1.Status[]) => reorderedTimeline(items, 'account')
|
function reorderAndFilter(items: mastodon.v1.Status[]) {
|
||||||
|
return reorderedTimeline(items, 'account')
|
||||||
|
}
|
||||||
|
|
||||||
const paginator = useMastoClient().v1.accounts.listStatuses(account.id, { limit: 30, excludeReplies: true })
|
const paginator = useMastoClient().v1.accounts.listStatuses(account.id, { limit: 30, excludeReplies: true })
|
||||||
|
|
||||||
|
|
|
@ -9,7 +9,7 @@ useHeadFixed({
|
||||||
let showCommit = $ref(buildInfo.env !== 'release' && buildInfo.env !== 'dev')
|
let showCommit = $ref(buildInfo.env !== 'release' && buildInfo.env !== 'dev')
|
||||||
const builtTime = useFormattedDateTime(buildInfo.time)
|
const builtTime = useFormattedDateTime(buildInfo.time)
|
||||||
|
|
||||||
const handleShowCommit = () => {
|
function handleShowCommit() {
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
showCommit = true
|
showCommit = true
|
||||||
}, 50)
|
}, 50)
|
||||||
|
|
|
@ -75,7 +75,7 @@ const { submit, submitting } = submitter(async ({ dirtyFields }) => {
|
||||||
reset()
|
reset()
|
||||||
})
|
})
|
||||||
|
|
||||||
const refreshInfo = async () => {
|
async function refreshInfo() {
|
||||||
if (!currentUser.value)
|
if (!currentUser.value)
|
||||||
return
|
return
|
||||||
// Keep the information to be edited up to date
|
// Keep the information to be edited up to date
|
||||||
|
|
561
pnpm-lock.yaml
561
pnpm-lock.yaml
File diff suppressed because it is too large
Load diff
|
@ -1,9 +1,7 @@
|
||||||
import { closeDatabases, get } from '../utils/elk-idb'
|
import { closeDatabases, get } from '../utils/elk-idb'
|
||||||
import type { MastoNotification, NotificationInfo, PushPayload, UserLogin } from './types'
|
import type { MastoNotification, NotificationInfo, PushPayload, UserLogin } from './types'
|
||||||
|
|
||||||
export const findNotification = async (
|
export async function findNotification({ access_token, notification_id/* , notification_type */ }: PushPayload): Promise<NotificationInfo | undefined> {
|
||||||
{ access_token, notification_id/* , notification_type */ }: PushPayload,
|
|
||||||
): Promise<NotificationInfo | undefined> => {
|
|
||||||
const users = await get<UserLogin[]>('elk-users')
|
const users = await get<UserLogin[]>('elk-users')
|
||||||
if (!users)
|
if (!users)
|
||||||
return undefined
|
return undefined
|
||||||
|
|
|
@ -13,7 +13,7 @@ self.addEventListener('message', (event) => {
|
||||||
clientResolves[id]()
|
clientResolves[id]()
|
||||||
})
|
})
|
||||||
|
|
||||||
export const onShareTarget = (event: FetchEvent) => {
|
export function onShareTarget(event: FetchEvent) {
|
||||||
if (!event.request.url.endsWith('/web-share-target') || event.request.method !== 'POST')
|
if (!event.request.url.endsWith('/web-share-target') || event.request.method !== 'POST')
|
||||||
return
|
return
|
||||||
|
|
||||||
|
|
|
@ -15,7 +15,7 @@ self.addEventListener('message', (event) => {
|
||||||
closeDatabaseConnections()
|
closeDatabaseConnections()
|
||||||
})
|
})
|
||||||
|
|
||||||
export const onPush = (event: PushEvent) => {
|
export function onPush(event: PushEvent) {
|
||||||
const promise = isClientFocused().then((isFocused) => {
|
const promise = isClientFocused().then((isFocused) => {
|
||||||
if (isFocused)
|
if (isFocused)
|
||||||
return Promise.resolve()
|
return Promise.resolve()
|
||||||
|
@ -35,7 +35,7 @@ export const onPush = (event: PushEvent) => {
|
||||||
event.waitUntil(promise)
|
event.waitUntil(promise)
|
||||||
}
|
}
|
||||||
|
|
||||||
export const onNotificationClick = (event: NotificationEvent) => {
|
export function onNotificationClick(event: NotificationEvent) {
|
||||||
const reactToNotificationClick = new Promise((resolve) => {
|
const reactToNotificationClick = new Promise((resolve) => {
|
||||||
event.notification.close()
|
event.notification.close()
|
||||||
resolve(openUrl(event.notification.data.url))
|
resolve(openUrl(event.notification.data.url))
|
||||||
|
|
Loading…
Reference in a new issue