Skip to content

Commit 817164a

Browse files
authored
Merge pull request #18 from maybeanerd/chore-update-from-upstream
chore: update from upstream
2 parents a98070f + e7209f3 commit 817164a

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

56 files changed

+2143
-1780
lines changed

.github/workflows/ci.yml

+1
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ jobs:
3232

3333
- name: 🧪 Test project
3434
run: pnpm test:ci
35+
timeout-minutes: 10
3536

3637
- name: 📝 Lint
3738
run: pnpm lint

CONTRIBUTING.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,7 @@ Simple approach used by most websites of relying on direction set in HTML elemen
8383
We've added some `UnoCSS` utilities styles to help you with that:
8484
- Do not use `left/right` padding and margin: for example `pl-1`. Use `padding-inline-start/end` instead. So `pl-1` should be `ps-1`, `pr-1` should be `pe-1`. The same rules apply to margin.
8585
- Do not use `rtl-` classes, such as `rtl-left-0`.
86-
- For icons that should be rotated for RTL, add `class="rtl-flip"`. This can only be used for icons outside of elements with `dir="auto"`, such as timeline, and is the only exception from the rule above. For icons inside the timeline, it might not work as expected.
86+
- For icons that should be rotated for RTL, add `class="rtl-flip"`. This can only be used for icons outside of elements with `dir="auto"`, such as timeline, and is the only exception to the rule above. For icons inside the timeline, it might not work as expected.
8787
- For absolute positioned elements, don't use `left/right`: for example `left-0`. Use `inset-inline-start/end` instead. `UnoCSS` shortcuts are `inset-is` for `inset-inline-start` and `inset-ie` for `inset-inline-end`. Example: `left-0` should be replaced with `inset-is-0`.
8888
- If you need to change the border radius for an entire left or right side, use `border-inline-start/end`. `UnoCSS` shortcuts are `rounded-is` for left side, `rounded-ie` for right side. Example: `rounded-l-5` should be replaced with `rounded-ie-5`.
8989
- If you need to change the border radius for one corner, use `border-start-end-radius` and similar rules. `UnoCSS` shortcuts are `rounded` + top/bottom as either `-bs` (top) or `-be` (bottom) + left/right as either `-is` (left) or `-ie` (right). Example: `rounded-tl-0` should be replaced with `rounded-bs-is-0`.

components/common/CommonPaginator.vue

+3-1
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import type { UnwrapRef } from 'vue'
88
const {
99
paginator,
1010
stream,
11+
eventType,
1112
keyProp = 'id',
1213
virtualScroller = false,
1314
preprocess,
@@ -17,6 +18,7 @@ const {
1718
keyProp?: keyof T
1819
virtualScroller?: boolean
1920
stream?: mastodon.streaming.Subscription
21+
eventType?: 'update' | 'notification'
2022
preprocess?: (items: (U | T)[]) => U[]
2123
endMessage?: boolean | string
2224
}>()
@@ -44,7 +46,7 @@ defineSlots<{
4446
const { t } = useI18n()
4547
const nuxtApp = useNuxtApp()
4648
47-
const { items, prevItems, update, state, endAnchor, error } = usePaginator(paginator, toRef(() => stream), preprocess)
49+
const { items, prevItems, update, state, endAnchor, error } = usePaginator(paginator, toRef(() => stream), eventType, preprocess)
4850
4951
nuxtApp.hook('elk-logo:click', () => {
5052
update()

components/common/CommonTabs.vue

+2-2
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,8 @@ const tabs = computed(() => {
1919
})
2020
})
2121
22-
function toValidName(otpion: string) {
23-
return otpion.toLowerCase().replace(/[^a-zA-Z0-9]/g, '-')
22+
function toValidName(option: string) {
23+
return option.toLowerCase().replace(/[^a-zA-Z0-9]/g, '-')
2424
}
2525
2626
useCommands(() => command

components/help/HelpPreview.vue

+5-3
Original file line numberDiff line numberDiff line change
@@ -30,10 +30,12 @@ const vAutoFocus = (el: HTMLElement) => el.focus()
3030
</NuxtLink>
3131
{{ $t('help.desc_para6') }}
3232
</p>
33-
{{ $t('help.desc_para3') }}
33+
<NuxtLink hover:text-primary href="https://github.com/sponsors/elk-zone" target="_blank">
34+
{{ $t('help.desc_para3') }}
35+
</NuxtLink>
3436
<p flex="~ gap-2 wrap" mxa>
3537
<template v-for="team of crabTeamMembers" :key="team.github">
36-
<NuxtLink :href="`https://github.com/sponsors/${team.github}`" target="_blank" external rounded-full transition duration-300 border="~ transparent" hover="scale-105 border-primary">
38+
<NuxtLink :href="team.link" target="_blank" external rounded-full transition duration-300 border="~ transparent" hover="scale-105 border-primary">
3739
<img :src="`/avatars/${team.github}-100x100.png`" :alt="team.display" rounded-full w-15 h-15 height="60" width="60">
3840
</NuxtLink>
3941
</template>
@@ -45,7 +47,7 @@ const vAutoFocus = (el: HTMLElement) => el.focus()
4547
</p>
4648
<p flex="~ gap-2 wrap" mxa>
4749
<template v-for="team of elkTeamMembers" :key="team.github">
48-
<NuxtLink :href="`https://github.com/sponsors/${team.github}`" target="_blank" external rounded-full transition duration-300 border="~ transparent" hover="scale-105 border-primary">
50+
<NuxtLink :href="team.link" target="_blank" external rounded-full transition duration-300 border="~ transparent" hover="scale-105 border-primary">
4951
<img :src="`/avatars/${team.github}-100x100.png`" :alt="team.display" rounded-full w-15 h-15 height="60" width="60">
5052
</NuxtLink>
5153
</template>

components/modal/ModalMediaPreview.vue

+1-1
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ onUnmounted(() => locked.value = false)
3737
</script>
3838

3939
<template>
40-
<div relative h-full w-full flex pt-12 w-100vh @click="onClick">
40+
<div relative h-full w-full flex pt-12 @click="onClick">
4141
<button
4242
v-if="hasNext" pointer-events-auto btn-action-icon bg="black/20" :aria-label="$t('action.previous')"
4343
hover:bg="black/40" dark:bg="white/30" dark-hover:bg="white/20" absolute top="1/2" right-1 z5

components/modal/ModalMediaPreviewCarousel.vue

+11-5
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ const emit = defineEmits<{
1515
const modelValue = defineModel<number>({ required: true })
1616
1717
const slideGap = 20
18-
const doubleTapTreshold = 250
18+
const doubleTapThreshold = 250
1919
2020
const view = ref()
2121
const slider = ref()
@@ -36,6 +36,8 @@ const isPinching = ref(false)
3636
const maxZoomOut = ref(1)
3737
const isZoomedIn = computed(() => scale.value > 1)
3838
39+
const enableAutoplay = usePreferences('enableAutoplay')
40+
3941
function goToFocusedSlide() {
4042
scale.value = 1
4143
x.value = slide.value[modelValue.value].offsetLeft * scale.value
@@ -147,7 +149,7 @@ function handleLastDrag(tap: boolean, swipe: Vector2, movement: Vector2, positio
147149
let lastTapAt = 0
148150
function handleTap([positionX, positionY]: Vector2) {
149151
const now = Date.now()
150-
const isDoubleTap = now - lastTapAt < doubleTapTreshold
152+
const isDoubleTap = now - lastTapAt < doubleTapThreshold
151153
lastTapAt = now
152154
153155
if (!isDoubleTap)
@@ -218,7 +220,7 @@ function handleZoomDrag([deltaX, deltaY]: Vector2) {
218220
function handleSlideDrag([movementX, movementY]: Vector2) {
219221
goToFocusedSlide()
220222
221-
if (Math.abs(movementY) > Math.abs(movementX)) // vertical movement is more then horizontal
223+
if (Math.abs(movementY) > Math.abs(movementX)) // vertical movement is more than horizontal
222224
y.value -= movementY / scale.value
223225
else
224226
x.value -= movementX / scale.value
@@ -264,16 +266,20 @@ const imageStyle = computed(() => ({
264266
items-center
265267
justify-center
266268
>
267-
<img
269+
<component
270+
:is="item.type === 'gifv' ? 'video' : 'img'"
268271
ref="image"
272+
:autoplay="enableAutoplay"
273+
controls
274+
loop
269275
select-none
270276
max-w-full
271277
max-h-full
272278
:style="imageStyle"
273279
:draggable="false"
274280
:src="item.url || item.previewUrl"
275281
:alt="item.description || ''"
276-
>
282+
/>
277283
</div>
278284
</div>
279285
</div>

components/nav/NavUser.vue

+7-1
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,13 @@ const { busy, oauth, singleInstanceServer } = useSignIn()
3434
<strong>{{ currentServer }}</strong>
3535
</i18n-t>
3636
</button>
37-
<button v-else btn-solid text-sm px-2 py-1 text-center xl:hidden @click="openSigninDialog()">
37+
<button
38+
v-else
39+
flex="~ row"
40+
gap-x-1 items-center justify-center btn-solid text-sm px-2 py-1 xl:hidden
41+
@click="openSigninDialog()"
42+
>
43+
<span aria-hidden="true" block i-ri:login-circle-line class="rtl-flip" />
3844
{{ $t('action.sign_in') }}
3945
</button>
4046
</template>

components/notification/NotificationPaginator.vue

+2-1
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ function includeNotificationsForStatusCard({ type, status }: mastodon.v1.Notific
2525
2626
// Group by type (and status when applicable)
2727
function groupId(item: mastodon.v1.Notification): string {
28-
// If the update is related to an status, group notifications from the same account (boost + favorite the same status)
28+
// If the update is related to a status, group notifications from the same account (boost + favorite the same status)
2929
const id = item.status
3030
? {
3131
status: item.status?.id,
@@ -171,6 +171,7 @@ const { formatNumber } = useHumanReadableNumber()
171171
:paginator="paginator"
172172
:preprocess="preprocess"
173173
:stream="stream"
174+
eventType="notification"
174175
:virtualScroller="virtualScroller"
175176
>
176177
<template #updater="{ number, update }">

components/publish/PublishWidget.vue

+11-3
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,9 @@ function editPollOptionDraft(event: Event, index: number) {
8787
}
8888
8989
function deletePollOption(index: number) {
90-
draft.value.params.poll!.options = draft.value.params.poll!.options.slice().splice(index, 1)
90+
const newPollOptions = draft.value.params.poll!.options.slice()
91+
newPollOptions.splice(index, 1)
92+
draft.value.params.poll!.options = newPollOptions
9193
trimPollOptions()
9294
}
9395
@@ -156,6 +158,8 @@ const isExceedingCharacterLimit = computed(() => {
156158
157159
const postLanguageDisplay = computed(() => languagesNameList.find(i => i.code === (draft.value.params.language || preferredLanguage))?.nativeName)
158160
161+
const isDM = computed(() => draft.value.params.visibility === 'direct')
162+
159163
async function handlePaste(evt: ClipboardEvent) {
160164
const files = evt.clipboardData?.files
161165
if (!files || files.length === 0)
@@ -275,12 +279,16 @@ onDeactivated(() => {
275279
</ol>
276280
</CommonErrorMessage>
277281

278-
<div relative flex-1 flex flex-col>
282+
<div relative flex-1 flex flex-col min-h-30>
279283
<EditorContent
280284
:editor="editor"
281285
flex max-w-full
282-
:class="shouldExpanded ? 'min-h-30 md:max-h-[calc(100vh-200px)] sm:max-h-[calc(100vh-400px)] max-h-35 of-y-auto overscroll-contain' : ''"
286+
:class="{
287+
'md:max-h-[calc(100vh-200px)] sm:max-h-[calc(100vh-400px)] max-h-35 of-y-auto overscroll-contain': shouldExpanded,
288+
'py2 px3.5 bg-dm rounded-4 me--1 ms--1 mt--1': isDM,
289+
}"
283290
@keydown="stopQuestionMarkPropagation"
291+
@keydown.esc.prevent="editor?.commands.blur()"
284292
/>
285293
</div>
286294

components/search/SearchWidget.vue

+1
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,7 @@ function activate() {
8282
placeholder-text-secondary
8383
@keydown.down.prevent="shift(1)"
8484
@keydown.up.prevent="shift(-1)"
85+
@keydown.esc.prevent="input?.blur()"
8586
@keypress.enter="activate"
8687
>
8788
<button v-if="query.length" btn-action-icon text-secondary @click="query = ''; input?.focus()">

components/settings/SettingsItem.vue

+4-1
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,11 @@ const props = defineProps<{
1010
external?: true
1111
large?: true
1212
match?: boolean
13+
target?: string
1314
}>()
1415
1516
const router = useRouter()
17+
const scrollOnClick = computed(() => props.to && !(props.target === '_blank' || props.external))
1618
1719
useCommand({
1820
scope: 'Settings',
@@ -39,11 +41,12 @@ useCommand({
3941
:disabled="disabled"
4042
:to="to"
4143
:external="external"
44+
:target="target"
4245
exact-active-class="text-primary"
4346
:class="disabled ? 'op25 pointer-events-none ' : match ? 'text-primary' : ''"
4447
block w-full group focus:outline-none
4548
:tabindex="disabled ? -1 : null"
46-
@click="to ? $scrollToTop() : undefined"
49+
@click="scrollOnClick ? $scrollToTop() : undefined"
4750
>
4851
<div
4952
w-full flex px5 py3 md:gap2 gap4 items-center

components/settings/SettingsToggleItem.vue

+1-1
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ const { disabled = false } = defineProps<{
1616
:class="disabled ? 'opacity-50 cursor-not-allowed' : ''"
1717
>
1818
<div
19-
w-full flex w-fit px5 py3 md:gap2 gap4 items-center
19+
w-full flex px5 py3 md:gap2 gap4 items-center
2020
transition-250
2121
:class="disabled ? '' : 'group-hover:bg-active'"
2222
group-focus-visible:ring="2 current"

components/status/StatusActions.vue

+3-3
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ function reply() {
5555

5656
<div flex-1>
5757
<StatusActionButton
58-
:content="$t('action.boost')"
58+
:content="$t(status.reblogged ? 'action.boosted' : 'action.boost')"
5959
:text="!getPreferences(userSettings, 'hideBoostCount') && status.reblogsCount ? status.reblogsCount : ''"
6060
color="text-green" hover="text-green" elk-group-hover="bg-green/10"
6161
icon="i-ri:repeat-line"
@@ -77,7 +77,7 @@ function reply() {
7777

7878
<div flex-1>
7979
<StatusActionButton
80-
:content="$t('action.favourite')"
80+
:content="$t(status.favourited ? 'action.favourited' : 'action.favourite')"
8181
:text="!getPreferences(userSettings, 'hideFavoriteCount') && status.favouritesCount ? status.favouritesCount : ''"
8282
:color="useStarFavoriteIcon ? 'text-yellow' : 'text-rose'"
8383
:hover="useStarFavoriteIcon ? 'text-yellow' : 'text-rose'"
@@ -100,7 +100,7 @@ function reply() {
100100

101101
<div flex-none>
102102
<StatusActionButton
103-
:content="$t('action.bookmark')"
103+
:content="$t(status.bookmarked ? 'action.bookmarked' : 'action.bookmark')"
104104
:color="useStarFavoriteIcon ? 'text-rose' : 'text-yellow'"
105105
:hover="useStarFavoriteIcon ? 'text-rose' : 'text-yellow'"
106106
:elk-group-hover="useStarFavoriteIcon ? 'bg-rose/10' : 'bg-yellow/10' "

components/status/StatusActionsMore.vue

+1-1
Original file line numberDiff line numberDiff line change
@@ -144,7 +144,7 @@ function showFavoritedAndBoostedBy() {
144144

145145
<template #popper>
146146
<div flex="~ col">
147-
<template v-if="getPreferences(userSettings, 'zenMode')">
147+
<template v-if="getPreferences(userSettings, 'zenMode') && !details">
148148
<CommonDropdownItem
149149
:text="$t('action.reply')"
150150
icon="i-ri:chat-1-line"

components/status/StatusAttachment.vue

+13-3
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,7 @@ const video = ref<HTMLVideoElement | undefined>()
6868
const prefersReducedMotion = usePreferredReducedMotion()
6969
const isAudio = computed(() => attachment.type === 'audio')
7070
const isVideo = computed(() => attachment.type === 'video')
71+
const isGif = computed(() => attachment.type === 'gifv')
7172
7273
const enableAutoplay = usePreferences('enableAutoplay')
7374
@@ -164,7 +165,7 @@ watch(shouldLoadAttachment, () => {
164165
<button
165166
type="button"
166167
relative
167-
@click="!shouldLoadAttachment ? loadAttachment() : null"
168+
@click="!shouldLoadAttachment ? loadAttachment() : openMediaPreview(attachments ? attachments : [attachment], attachments?.indexOf(attachment) || 0)"
168169
>
169170
<video
170171
ref="video"
@@ -248,12 +249,13 @@ watch(shouldLoadAttachment, () => {
248249
</button>
249250
</template>
250251
<div
251-
v-if="attachment.description && !getPreferences(userSettings, 'hideAltIndicatorOnPosts')" :class="isAudio ? [] : [
252+
:class="isAudio ? [] : [
252253
'absolute left-2',
253254
isVideo ? 'top-2' : 'bottom-2',
254255
]"
256+
flex gap-col-2
255257
>
256-
<VDropdown :distance="6" placement="bottom-start">
258+
<VDropdown v-if="attachment.description && !getPreferences(userSettings, 'hideAltIndicatorOnPosts')" :distance="6" placement="bottom-start">
257259
<button
258260
font-bold text-sm
259261
:class="isAudio
@@ -281,6 +283,14 @@ watch(shouldLoadAttachment, () => {
281283
</div>
282284
</template>
283285
</VDropdown>
286+
<div v-if="isGif && !getPreferences(userSettings, 'hideGifIndicatorOnPosts')">
287+
<button
288+
aria-hidden font-bold text-sm
289+
rounded-1 bg-black:65 text-white px1.2 py0.2 pointer-events-none
290+
>
291+
{{ $t('status.gif') }}
292+
</button>
293+
</div>
284294
</div>
285295
</div>
286296
</template>

components/status/StatusContent.vue

+1-2
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ const allowEmbeddedMedia = computed(() => status.card?.html && embeddedMediaPref
3737
<div
3838
space-y-3
3939
:class="{
40-
'pt2 pb0.5 px3.5 bg-dm rounded-4 me--1': isDM,
40+
'py2 px3.5 bg-dm rounded-4 me--1': isDM,
4141
'ms--3.5 mt--1 ms--1': isDM && context !== 'details',
4242
}"
4343
>
@@ -68,7 +68,6 @@ const allowEmbeddedMedia = computed(() => status.card?.html && embeddedMediaPref
6868
:status="status.reblog" border="~ rounded"
6969
:actions="false"
7070
/>
71-
<div v-if="isDM" />
7271
</StatusSpoiler>
7372
</div>
7473
</template>

components/status/StatusDetails.vue

+1-1
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ useHydratedHead({
3131

3232
<template>
3333
<div :id="`status-${status.id}`" flex flex-col gap-2 pt2 pb1 ps-3 pe-4 relative :lang="status.language ?? undefined" aria-roledescription="status-details">
34-
<StatusActionsMore :status="status" absolute inset-ie-2 top-2 @after-edit="$emit('refetchStatus')" />
34+
<StatusActionsMore :status="status" :details="true" absolute inset-ie-2 top-2 @after-edit="$emit('refetchStatus')" />
3535
<NuxtLink :to="getAccountRoute(status.account)" rounded-full hover:bg-active transition-100 pe5 me-a>
3636
<AccountHoverWrapper :account="status.account">
3737
<AccountInfo :account="status.account" />

components/status/StatusLink.vue

+2-1
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,8 @@ function onclick(evt: MouseEvent | KeyboardEvent) {
1414
const path = evt.composedPath() as HTMLElement[]
1515
const el = path.find(el => ['A', 'BUTTON', 'IMG', 'VIDEO'].includes(el.tagName?.toUpperCase()))
1616
const text = window.getSelection()?.toString()
17-
if (!el && !text)
17+
const isCustomEmoji = el?.parentElement?.classList.contains('custom-emoji')
18+
if ((!el && !text) || isCustomEmoji)
1819
go(evt)
1920
}
2021

0 commit comments

Comments
 (0)