chore: bump to eslint-config `v2.8.0` (#2651)

Co-authored-by: Anthony Fu <anthonyfu117@hotmail.com>
pull/2652/head
Joaquín Sánchez 2024-03-05 15:48:58 +01:00 zatwierdzone przez GitHub
rodzic 62f70250d5
commit 9da77637b2
Nie znaleziono w bazie danych klucza dla tego podpisu
ID klucza GPG: B5690EEEBB952194
48 zmienionych plików z 896 dodań i 511 usunięć

Wyświetl plik

@ -1,15 +0,0 @@
*.css
*.png
*.ico
*.toml
*.patch
*.txt
Dockerfile
public/
public-dev/
public-staging/
https-dev-config/localhost.crt
https-dev-config/localhost.key
Dockerfile
elk-translation-status.json
docs/translation-status.json

Wyświetl plik

@ -1,19 +0,0 @@
{
"extends": "@antfu",
"ignorePatterns": ["!pages/public"],
"overrides": [
{
"files": ["locales/**.json"],
"rules": {
"jsonc/sort-keys": "error"
}
}
],
"rules": {
"vue/no-restricted-syntax":["error", {
"selector": "VElement[name='a']",
"message": "Use NuxtLink instead."
}],
"n/prefer-global/process": "off"
}
}

Wyświetl plik

@ -2,4 +2,4 @@
name: 🚀 New feature proposal name: 🚀 New feature proposal
about: Propose a new feature about: Propose a new feature
labels: 's: pending triage' labels: 's: pending triage'
--- ---

45
.vscode/settings.json vendored
Wyświetl plik

@ -5,10 +5,6 @@
"unmute", "unmute",
"unstorage" "unstorage"
], ],
"editor.codeActionsOnSave": {
"source.fixAll.eslint": true
},
"editor.formatOnSave": false,
"files.associations": { "files.associations": {
"*.css": "postcss" "*.css": "postcss"
}, },
@ -23,7 +19,44 @@
"i18n-ally.preferredDelimiter": "_", "i18n-ally.preferredDelimiter": "_",
"i18n-ally.sortKeys": true, "i18n-ally.sortKeys": true,
"i18n-ally.sourceLanguage": "en", "i18n-ally.sourceLanguage": "en",
// Enable the ESlint flat config support
"eslint.experimental.useFlatConfig": true,
// Disable the default formatter, use eslint instead
"prettier.enable": false, "prettier.enable": false,
"volar.completion.preferredTagNameCase": "pascal", "editor.formatOnSave": false,
"volar.completion.preferredAttrNameCase": "kebab"
// Auto fix
"editor.codeActionsOnSave": {
"source.fixAll": "explicit",
"source.organizeImports": "never"
},
// Silent the stylistic rules in you IDE, but still auto fix them
"eslint.rules.customizations": [
{ "rule": "style/*", "severity": "off" },
{ "rule": "*-indent", "severity": "off" },
{ "rule": "*-spacing", "severity": "off" },
{ "rule": "*-spaces", "severity": "off" },
{ "rule": "*-order", "severity": "off" },
{ "rule": "*-dangle", "severity": "off" },
{ "rule": "*-newline", "severity": "off" },
{ "rule": "*quotes", "severity": "off" },
{ "rule": "*semi", "severity": "off" }
],
// Enable eslint for all supported languages
"eslint.validate": [
"javascript",
"javascriptreact",
"typescript",
"typescriptreact",
"vue",
"html",
"markdown",
"json",
"jsonc",
"yaml"
]
} }

Wyświetl plik

@ -8,7 +8,7 @@ For guidelines on contributing to the documentation, refer to the [docs README](
### Online ### Online
You can use [StackBlitz Codeflow](https://stackblitz.com/codeflow) to fix bugs or implement features. You'll also see a Codeflow button on PRs to review them without a local setup. Once the elk repo has been cloned in Codeflow, the dev server will start automatically and print the URL to open the App. You should receive a prompt in the bottom-right suggesting to open it in the Editor or in another Tab. To learn more, check out the [Codeflow docs](https://developer.stackblitz.com/codeflow/what-is-codeflow). You can use [StackBlitz Codeflow](https://stackblitz.com/codeflow) to fix bugs or implement features. You'll also see a Codeflow button on PRs to review them without a local setup. Once the elk repo has been cloned in Codeflow, the dev server will start automatically and print the URL to open the App. You should receive a prompt in the bottom-right suggesting to open it in the Editor or in another Tab. To learn more, check out the [Codeflow docs](https://developer.stackblitz.com/codeflow/what-is-codeflow).
[![Open in Codeflow](https://developer.stackblitz.com/img/open_in_codeflow.svg)](https://pr.new/elk-zone/elk) [![Open in Codeflow](https://developer.stackblitz.com/img/open_in_codeflow.svg)](https://pr.new/elk-zone/elk)
@ -21,7 +21,6 @@ To develop and test the Elk package:
2. Ensure using the latest Node.js (16.x). 2. Ensure using the latest Node.js (16.x).
If you have [nvm](https://github.com/nvm-sh/nvm), you can run `nvm i` to install the required version. If you have [nvm](https://github.com/nvm-sh/nvm), you can run `nvm i` to install the required version.
3. The package manager used to install and link dependencies must be [pnpm](https://pnpm.io/) v7. To use it you must first enable [Corepack](https://github.com/nodejs/corepack) by running `corepack enable`. (Note: on Linux in a standard Node 16+ environment, you should follow the instructions to install via Node's `corepack` rather than using the `curl` command) 3. The package manager used to install and link dependencies must be [pnpm](https://pnpm.io/) v7. To use it you must first enable [Corepack](https://github.com/nodejs/corepack) by running `corepack enable`. (Note: on Linux in a standard Node 16+ environment, you should follow the instructions to install via Node's `corepack` rather than using the `curl` command)
4. Check out a branch where you can work and commit your changes: 4. Check out a branch where you can work and commit your changes:

Wyświetl plik

@ -39,8 +39,8 @@ The Elk team maintains a deployment at:
### Self-Host Docker Deployment ### Self-Host Docker Deployment
In order to host Elk yourself you can use the provided Dockerfile to build a container with elk. Be aware, that Elk only loads properly if the connection is done via SSL/TLS. The Docker container itself does not provide any SSL/TLS handling. You'll have to add this bit yourself. In order to host Elk yourself you can use the provided Dockerfile to build a container with elk. Be aware, that Elk only loads properly if the connection is done via SSL/TLS. The Docker container itself does not provide any SSL/TLS handling. You'll have to add this bit yourself.
One could put Elk behind popular reverse proxies with SSL Handling like Traefik, NGINX etc. One could put Elk behind popular reverse proxies with SSL Handling like Traefik, NGINX etc.
1. checkout source ```git clone https://github.com/elk-zone/elk.git``` 1. checkout source ```git clone https://github.com/elk-zone/elk.git```
1. got into new source dir: ```cd elk``` 1. got into new source dir: ```cd elk```
@ -52,7 +52,6 @@ One could put Elk behind popular reverse proxies with SSL Handling like Traefik,
> [!NOTE] > [!NOTE]
> The provided Dockerfile creates a container which will eventually run Elk as non-root user and create a persistent named Docker volume upon first start (if that volume does not yet exist). This volume is always created with root permission. Failing to change the permissions of ```/elk/data``` inside this volume to UID:GID 911 (as specified for Elk in the Dockerfile) will prevent Elk from storing it's config for user accounts. You either have to fix the permission in the created named volume, or mount a directory with the correct permission to ```/elk/data``` into the container. > The provided Dockerfile creates a container which will eventually run Elk as non-root user and create a persistent named Docker volume upon first start (if that volume does not yet exist). This volume is always created with root permission. Failing to change the permissions of ```/elk/data``` inside this volume to UID:GID 911 (as specified for Elk in the Dockerfile) will prevent Elk from storing it's config for user accounts. You either have to fix the permission in the created named volume, or mount a directory with the correct permission to ```/elk/data``` into the container.
### Ecosystem ### Ecosystem
These are known deployments using Elk as an alternative Web client for Mastodon servers or as a base for other projects in the fediverse: These are known deployments using Elk as an alternative Web client for Mastodon servers or as a base for other projects in the fediverse:
@ -107,7 +106,7 @@ We're really excited that you're interested in contributing to Elk! Before submi
### Online ### Online
You can use [StackBlitz Codeflow](https://stackblitz.com/codeflow) to fix bugs or implement features. You'll also see a Codeflow button on PRs to review them without a local setup. Once the elk repo has been cloned in Codeflow, the dev server will start automatically and print the URL to open the App. You should receive a prompt in the bottom-right suggesting to open it in the Editor or in another Tab. To learn more, check out the [Codeflow docs](https://developer.stackblitz.com/codeflow/what-is-codeflow). You can use [StackBlitz Codeflow](https://stackblitz.com/codeflow) to fix bugs or implement features. You'll also see a Codeflow button on PRs to review them without a local setup. Once the elk repo has been cloned in Codeflow, the dev server will start automatically and print the URL to open the App. You should receive a prompt in the bottom-right suggesting to open it in the Editor or in another Tab. To learn more, check out the [Codeflow docs](https://developer.stackblitz.com/codeflow/what-is-codeflow).
[![Open in Codeflow](https://developer.stackblitz.com/img/open_in_codeflow.svg)](https://pr.new/elk-zone/elk) [![Open in Codeflow](https://developer.stackblitz.com/img/open_in_codeflow.svg)](https://pr.new/elk-zone/elk)
@ -158,8 +157,8 @@ You can consult the [PWA documentation](https://docs.elk.zone/pwa) to learn more
## 👨‍💻 Contributors ## 👨‍💻 Contributors
<a href="https://github.com/elk-zone/elk/graphs/contributors"> <a href="https://github.com/elk-zone/elk/graphs/contributors">
<img src="https://contrib.rocks/image?repo=elk-zone/elk" /> <img src="https://contrib.rocks/image?repo=elk-zone/elk" />
</a> </a>
## 📄 License ## 📄 License

Wyświetl plik

@ -43,7 +43,8 @@ watch(
} }
account.value = undefined account.value = undefined
}, { immediate: true, flush: 'post' }, },
{ immediate: true, flush: 'post' },
) )
const userSettings = useUserSettings() const userSettings = useUserSettings()

Wyświetl plik

@ -1,5 +1,9 @@
<script setup lang="ts"> <script setup lang="ts">
const { as = 'div', active } = defineProps<{ as: any; active: boolean }>() const { as = 'div', active } = defineProps<{
as: any
active: boolean
}>()
const el = ref() const el = ref()
watch(() => active, (active) => { watch(() => active, (active) => {

Wyświetl plik

@ -35,8 +35,8 @@ const showWarning = computed(() => {
return false return false
return isSupported return isSupported
&& (!isSubscribed.value || !notificationPermission.value || notificationPermission.value === 'prompt') && (!isSubscribed.value || !notificationPermission.value || notificationPermission.value === 'prompt')
&& !(hiddenNotification.value[currentUser.value?.account?.acct ?? ''] === true) && !(hiddenNotification.value[currentUser.value?.account?.acct ?? ''])
}) })
async function saveSettings() { async function saveSettings() {

Wyświetl plik

@ -30,8 +30,14 @@ const draftState = useDraft(draftKey, initial)
const { draft } = draftState const { draft } = draftState
const { const {
isExceedingAttachmentLimit, isUploading, failedAttachments, isOverDropZone, isExceedingAttachmentLimit,
uploadAttachments, pickAttachments, setDescription, removeAttachment, isUploading,
failedAttachments,
isOverDropZone,
uploadAttachments,
pickAttachments,
setDescription,
removeAttachment,
dropZoneRef, dropZoneRef,
} = useUploadMediaAttachment(draft) } = useUploadMediaAttachment(draft)
@ -68,7 +74,7 @@ function trimPollOptions() {
const trimmedOptions = draft.value.params.poll!.options.slice(0, indexLastNonEmpty + 1) const trimmedOptions = draft.value.params.poll!.options.slice(0, indexLastNonEmpty + 1)
if (currentInstance.value?.configuration if (currentInstance.value?.configuration
&& trimmedOptions.length >= currentInstance.value?.configuration?.polls.maxOptions) && trimmedOptions.length >= currentInstance.value?.configuration?.polls.maxOptions)
draft.value.params.poll!.options = trimmedOptions draft.value.params.poll!.options = trimmedOptions
else else
draft.value.params.poll!.options = [...trimmedOptions, ''] draft.value.params.poll!.options = [...trimmedOptions, '']

Wyświetl plik

@ -18,12 +18,12 @@ useCommand({
scope: 'Settings', scope: 'Settings',
name: () => props.text name: () => props.text
?? (props.to ?? (props.to
? typeof props.to === 'string' ? typeof props.to === 'string'
? props.to ? props.to
: props.to.name : props.to.name
: '' : ''
), ),
description: () => props.description, description: () => props.description,
icon: () => props.icon || '', icon: () => props.icon || '',
visible: () => props.command && props.to, visible: () => props.command && props.to,

Wyświetl plik

@ -8,8 +8,7 @@ const dropdown = ref<any>()
const fieldIcons = computed(() => const fieldIcons = computed(() =>
Array.from({ length: maxAccountFieldCount.value }, (_, i) => Array.from({ length: maxAccountFieldCount.value }, (_, i) =>
getAccountFieldIcon(form.value.fieldsAttributes[i].name), getAccountFieldIcon(form.value.fieldsAttributes[i].name)),
),
) )
const fieldCount = computed(() => { const fieldCount = computed(() => {

Wyświetl plik

@ -42,7 +42,8 @@ watch(
return return
} }
account.value = undefined account.value = undefined
}, { immediate: true, flush: 'post' }, },
{ immediate: true, flush: 'post' },
) )
</script> </script>

Wyświetl plik

@ -1,5 +1,10 @@
<script setup lang="ts"> <script setup lang="ts">
const props = defineProps<{ enabled?: boolean; filter?: boolean; isDM?: boolean; sensitiveNonSpoiler?: boolean }>() const props = defineProps<{
enabled?: boolean
filter?: boolean
isDM?: boolean
sensitiveNonSpoiler?: boolean
}>()
const expandSpoilers = computed(() => { const expandSpoilers = computed(() => {
const expandCW = currentUser.value ? getExpandSpoilersByDefault(currentUser.value.account) : false const expandCW = currentUser.value ? getExpandSpoilersByDefault(currentUser.value.account) : false

Wyświetl plik

@ -170,7 +170,8 @@ export const useCommandRegistry = defineStore('command', () => {
const indexed = cmds.map((cmd, index) => ({ ...cmd, index })) const indexed = cmds.map((cmd, index) => ({ ...cmd, index }))
const grouped = new Map<CommandScopeNames, CommandQueryResultItem[]>( const grouped = new Map<CommandScopeNames, CommandQueryResultItem[]>(
scopes.map(scope => [scope, []])) scopes.map(scope => [scope, []]),
)
for (const cmd of indexed) { for (const cmd of indexed) {
const scope = cmd.scope ?? '' const scope = cmd.scope ?? ''
grouped.get(scope)!.push({ grouped.get(scope)!.push({

Wyświetl plik

@ -494,7 +494,10 @@ function _markdownProcess(value: string) {
let start = 0 let start = 0
while (true) { while (true) {
let found: { match: RegExpMatchArray; replacer: (c: (string | Node)[]) => Node } | undefined let found: {
match: RegExpMatchArray
replacer: (c: (string | Node)[]) => Node
} | undefined
for (const [re, replacer] of _markdownReplacements) { for (const [re, replacer] of _markdownReplacements) {
re.lastIndex = start re.lastIndex = start

Wyświetl plik

@ -29,8 +29,10 @@ export function useHumanReadableNumber() {
} }
} }
export function useFormattedDateTime(value: MaybeRefOrGetter<string | number | Date | undefined | null>, export function useFormattedDateTime(
options: Intl.DateTimeFormatOptions = { dateStyle: 'long', timeStyle: 'medium' }) { value: MaybeRefOrGetter<string | number | Date | undefined | null>,
options: Intl.DateTimeFormatOptions = { dateStyle: 'long', timeStyle: 'medium' },
) {
const { locale } = useI18n() const { locale } = useI18n()
const formatter = computed(() => Intl.DateTimeFormat(locale.value, options)) const formatter = computed(() => Intl.DateTimeFormat(locale.value, options))
return computed(() => { return computed(() => {

Wyświetl plik

@ -36,9 +36,11 @@ export function useMagicSequence(keys: string[]): ComputedRef<boolean> {
down = false down = false
success.value = true success.value = true
} }
}, { },
{
deep: true, deep: true,
}) },
)
return computed(() => success.value) return computed(() => success.value)
} }

Wyświetl plik

@ -36,23 +36,22 @@ export function usePublish(options: {
const { params, attachments } = draft.value const { params, attachments } = draft.value
const firstEmptyInputIndex = params.poll?.options.findIndex(option => option.trim().length === 0) const firstEmptyInputIndex = params.poll?.options.findIndex(option => option.trim().length === 0)
return isEmpty.value return isEmpty.value
|| options.isUploading.value || options.isUploading.value
|| isSending.value || isSending.value
|| (attachments.length === 0 && !params.status) || (attachments.length === 0 && !params.status)
|| failedMessages.value.length > 0 || failedMessages.value.length > 0
|| (attachments.length > 0 && params.poll !== null && params.poll !== undefined) || (attachments.length > 0 && params.poll !== null && params.poll !== undefined)
|| ((params.poll !== null && params.poll !== undefined) || ((params.poll !== null && params.poll !== undefined)
&& ( && (
(firstEmptyInputIndex !== -1 (firstEmptyInputIndex !== -1
&& firstEmptyInputIndex !== params.poll.options.length - 1 && firstEmptyInputIndex !== params.poll.options.length - 1
) )
|| params.poll.options.findLastIndex(option => option.trim().length > 0) + 1 < 2 || params.poll.options.findLastIndex(option => option.trim().length > 0) + 1 < 2
|| (new Set(params.poll.options).size !== params.poll.options.length) || (new Set(params.poll.options).size !== params.poll.options.length)
|| (currentInstance.value?.configuration?.polls.maxCharactersPerOption !== undefined || (currentInstance.value?.configuration?.polls.maxCharactersPerOption !== undefined
&& params.poll.options.find(option => option.length > currentInstance.value!.configuration!.polls.maxCharactersPerOption) !== undefined && params.poll.options.find(option => option.length > currentInstance.value!.configuration!.polls.maxCharactersPerOption) !== undefined
) )
) ))
)
}) })
watch(draft, () => { watch(draft, () => {
@ -164,7 +163,7 @@ export function useUploadMediaAttachment(draft: Ref<Draft>) {
const maxPixels = computed(() => { const maxPixels = computed(() => {
return currentInstance.value?.configuration?.mediaAttachments?.imageMatrixLimit return currentInstance.value?.configuration?.mediaAttachments?.imageMatrixLimit
?? 4096 ** 2 ?? 4096 ** 2
}) })
const loadImage = (inputFile: Blob) => new Promise<HTMLImageElement>((resolve, reject) => { const loadImage = (inputFile: Blob) => new Promise<HTMLImageElement>((resolve, reject) => {

Wyświetl plik

@ -20,7 +20,7 @@ function getDefaultVisibility(currentVisibility: mastodon.v1.StatusVisibility) {
// the post more private than the replying to post // the post more private than the replying to post
const preferredVisibility = currentUser.value?.account.source.privacy || 'public' const preferredVisibility = currentUser.value?.account.source.privacy || 'public'
return ALL_VISIBILITY.indexOf(currentVisibility) return ALL_VISIBILITY.indexOf(currentVisibility)
> ALL_VISIBILITY.indexOf(preferredVisibility) > ALL_VISIBILITY.indexOf(preferredVisibility)
? currentVisibility ? currentVisibility
: preferredVisibility : preferredVisibility
} }

Wyświetl plik

@ -95,7 +95,12 @@ export async function translateText(text: string, from: string | null | undefine
return status return status
} }
const translations = new WeakMap<mastodon.v1.Status | mastodon.v1.StatusEdit, { visible: boolean; text: string; success: boolean; error: string }>() const translations = new WeakMap<mastodon.v1.Status | mastodon.v1.StatusEdit, {
visible: boolean
text: string
success: boolean
error: string
}>()
export function useTranslation(status: mastodon.v1.Status | mastodon.v1.StatusEdit, to: string) { export function useTranslation(status: mastodon.v1.Status | mastodon.v1.StatusEdit, to: string) {
if (!translations.has(status)) if (!translations.has(status))

Wyświetl plik

@ -6,10 +6,12 @@ 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 async function createPushSubscription(user: RequiredUserLogin, export async function createPushSubscription(
user: RequiredUserLogin,
notificationData: CreatePushNotification, notificationData: CreatePushNotification,
policy: mastodon.v1.WebPushSubscriptionPolicy = 'all', policy: mastodon.v1.WebPushSubscriptionPolicy = 'all',
force = false): Promise<mastodon.v1.WebPushSubscription | undefined> { force = false,
): Promise<mastodon.v1.WebPushSubscription | undefined> {
const { server: serverEndpoint, vapidKey } = user const { server: serverEndpoint, vapidKey } = user
return await getRegistration() return await getRegistration()

Wyświetl plik

@ -87,7 +87,10 @@ export function usePushManager() {
currentUser.value.pushSubscription = await createPushSubscription( currentUser.value.pushSubscription = await createPushSubscription(
{ {
pushSubscription, server, token, vapidKey, pushSubscription,
server,
token,
vapidKey,
}, },
notificationData ?? { notificationData ?? {
alerts: { alerts: {

Wyświetl plik

@ -5,7 +5,10 @@ const highlighter = ref<Highlighter>()
const registeredLang = ref(new Map<string, boolean>()) const registeredLang = ref(new Map<string, boolean>())
let shikiImport: Promise<void> | undefined let shikiImport: Promise<void> | undefined
export function useHighlighter(lang: Lang): { promise?: Promise<void>; highlighter?: Highlighter } { export function useHighlighter(lang: Lang): {
promise?: Promise<void>
highlighter?: Highlighter
} {
if (!shikiImport) { if (!shikiImport) {
shikiImport = import('shiki') shikiImport = import('shiki')
.then(async ({ getHighlighter }) => { .then(async ({ getHighlighter }) => {

Wyświetl plik

@ -16,7 +16,11 @@ declare module '@tiptap/core' {
/** /**
* Insert a custom emoji. * Insert a custom emoji.
*/ */
insertCustomEmoji: (options: { src: string; alt?: string; title?: string }) => ReturnType insertCustomEmoji: (options: {
src: string
alt?: string
title?: string
}) => ReturnType
/** /**
* Insert a emoji. * Insert a emoji.
*/ */

Wyświetl plik

@ -20,8 +20,10 @@ function wrapHandler<T extends (...args: any[]) => any>(handler: T): T {
}) })
} }
function createEmojiRule<NR extends typeof nodeInputRule | typeof nodePasteRule>(nodeRule: NR, function createEmojiRule<NR extends typeof nodeInputRule | typeof nodePasteRule>(
type: Parameters<NR>[0]['type']): ReturnType<NR>[] { nodeRule: NR,
type: Parameters<NR>[0]['type'],
): ReturnType<NR>[] {
const rule = nodeRule({ const rule = nodeRule({
find: emojiRegEx as RegExp, find: emojiRegEx as RegExp,
type, type,
@ -86,10 +88,10 @@ export const TiptapPluginEmoji = Node.create({
find: InputRuleFinder find: InputRuleFinder
type: NodeType type: NodeType
getAttributes?: getAttributes?:
| Record<string, any> | Record<string, any>
| ((match: ExtendedRegExpMatchArray) => Record<string, any>) | ((match: ExtendedRegExpMatchArray) => Record<string, any>)
| false | false
| null | null
}) { }) {
return new InputRule({ return new InputRule({
find: config.find, find: config.find,

Wyświetl plik

@ -14,7 +14,6 @@ export default defineI18nConfig(() => {
missingWarn: true, missingWarn: true,
datetimeFormats, datetimeFormats,
numberFormats, numberFormats,
// eslint-disable-next-line @typescript-eslint/comma-dangle pluralRules,
pluralRules
} }
}) })

Wyświetl plik

@ -30,7 +30,7 @@ We use [Docus](https://docus.dev) as the site generator and deploy through Netli
When you are ready to submit work back to the main Elk repo, create a PR. When you are ready to submit work back to the main Elk repo, create a PR.
1. If it has been a bit, synchronize your fork with the upstream repo on GitHub. 1. If it has been a bit, synchronize your fork with the upstream repo on GitHub.
2. Do your work in a branch on your fork 2. Do your work in a branch on your fork
Use `git checkout -b branchNameToUse` to create a working branch separate from `main`. Use `git checkout -b branchNameToUse` to create a working branch separate from `main`.
3. Do your work in your preferred editor 3. Do your work in your preferred editor

Wyświetl plik

@ -14,10 +14,10 @@ css({
gap: '0.5rem', gap: '0.5rem',
fontSize: '1.5rem', fontSize: '1.5rem',
}, },
img: { 'img': {
flexShrink: 0, flexShrink: 0,
aspectRatio: '1/1', aspectRatio: '1/1',
height: '2.5rem' height: '2.5rem',
} },
}) })
</style> </style>

Wyświetl plik

@ -61,8 +61,8 @@ async function copyToClipboard() {
try { try {
await navigator.clipboard.writeText([ await navigator.clipboard.writeText([
`# ${localeTitle.value}`, `# ${localeTitle.value}`,
(localeTab.value === 'missing' ? missingEntries.value : outdatedEntries.value).join('\n')].join('\n'), (localeTab.value === 'missing' ? missingEntries.value : outdatedEntries.value).join('\n'),
) ].join('\n'))
copied.value = true copied.value = true
setTimeout(() => copied.value = false, 750) setTimeout(() => copied.value = false, 750)
} }

Wyświetl plik

@ -35,7 +35,6 @@ You can think of the service as something similar to Twitter, but with some key
For more details about Mastodon, see their [website](https://joinmastodon.org/), [blog](https://blog.joinmastodon.org), [docs](https://docs.joinmastodon.org), and [GitHub Repository](https://github.com/mastodon/mastodon). For more details about Mastodon, see their [website](https://joinmastodon.org/), [blog](https://blog.joinmastodon.org), [docs](https://docs.joinmastodon.org), and [GitHub Repository](https://github.com/mastodon/mastodon).
## What is a Mastodon Client? ## What is a Mastodon Client?
A Mastodon Client is software that serves up the posts and activities from a Mastodon server using the [Mastodon API](https://docs.joinmastodon.org/api/). A Mastodon Client is software that serves up the posts and activities from a Mastodon server using the [Mastodon API](https://docs.joinmastodon.org/api/).
@ -80,7 +79,6 @@ Desktop
[TheDesk](https://thedesk.top/en/), [Whalebird](https://whalebird.social/en), or [Sengi](https://nicolasconstant.github.io/sengi/) [TheDesk](https://thedesk.top/en/), [Whalebird](https://whalebird.social/en), or [Sengi](https://nicolasconstant.github.io/sengi/)
:: ::
All of these apps provide some combination of the features a typical Mastodon user expects for their account. All of these apps provide some combination of the features a typical Mastodon user expects for their account.
### Browser-based Mastodon Clients ### Browser-based Mastodon Clients

Wyświetl plik

@ -67,7 +67,6 @@ Options include:
Elk reorders timeline posts that are connected to each other to display them in a connected thread in the timelines. Elk reorders timeline posts that are connected to each other to display them in a connected thread in the timelines.
This helps keep the conversation context for a post and its replies. This helps keep the conversation context for a post and its replies.
## Improved notifications ## Improved notifications
Elk groups boosts and likes to the same post when they occur together in the notification history. Elk groups boosts and likes to the same post when they occur together in the notification history.
@ -76,7 +75,6 @@ This greatly simplifies your notification history.
<!-- ## GitHub HTML cards --> <!-- ## GitHub HTML cards -->
<!-- - markdown support <!-- - markdown support
- GitHub HTML cards - GitHub HTML cards
- and so on... --> - and so on... -->

Wyświetl plik

@ -4,7 +4,7 @@ We're really excited that you're interested in contributing to Elk! Before submi
## Online ## Online
You can use [StackBlitz Codeflow](https://stackblitz.com/codeflow) to fix bugs or implement features. You'll also see a Codeflow button on PRs to review them without a local setup. Once the elk repo has been cloned in Codeflow, the dev server will start automatically and print the URL to open the App. You should receive a prompt in the bottom-right suggesting to open it in the Editor or in another Tab. To learn more, check out the [Codeflow docs](https://developer.stackblitz.com/codeflow/what-is-codeflow). You can use [StackBlitz Codeflow](https://stackblitz.com/codeflow) to fix bugs or implement features. You'll also see a Codeflow button on PRs to review them without a local setup. Once the elk repo has been cloned in Codeflow, the dev server will start automatically and print the URL to open the App. You should receive a prompt in the bottom-right suggesting to open it in the Editor or in another Tab. To learn more, check out the [Codeflow docs](https://developer.stackblitz.com/codeflow/what-is-codeflow).
[![Open in Codeflow](https://developer.stackblitz.com/img/open_in_codeflow.svg)](https://pr.new/elk-zone/elk) [![Open in Codeflow](https://developer.stackblitz.com/img/open_in_codeflow.svg)](https://pr.new/elk-zone/elk)

Wyświetl plik

@ -69,7 +69,7 @@ If you deleted any account from your backend with push notification subscription
- Scroll down in the page and locate "Permissions > Notifications" - Scroll down in the page and locate "Permissions > Notifications"
- Click on "Configuration" button - Click on "Configuration" button
- Locate "Elk" website in the list and select it, then click on "Remove website" button - Locate "Elk" website in the list and select it, then click on "Remove website" button
- Safari (WIP) - Safari (WIP)
### Permission denied: enable notifications in your browser ### Permission denied: enable notifications in your browser
@ -186,7 +186,7 @@ To debug the PWA service worker in your mobile browser, you will need to:
- Cache: `[x]` Cache storage and `[x]` Application cache - Cache: `[x]` Cache storage and `[x]` Application cache
- Click on Clear site data button - Click on Clear site data button
- Go to `Application > Service Workers` and check the current service worker is missing or has the status deleted or reduntant. - Go to `Application > Service Workers` and check the current service worker is missing or has the status deleted or reduntant.
6) Disable port forwarding: open the "Port forwarding..." modal again on the `chrome://inspect/#devices` page and either uncheck the "Enable port forwarding" option or remove the entry from the list and click "Done". 6) Disable port forwarding: open the "Port forwarding..." modal again on the `chrome://inspect/#devices` page and either uncheck the "Enable port forwarding" option or remove the entry from the list and click "Done".
## PWA web manifest and related applications ## PWA web manifest and related applications

Wyświetl plik

@ -35,4 +35,3 @@ When we update this privacy notice, the updated version will be indicated by a n
## Contact ## Contact
If you have questions or comments about this notice, you may raise an issue at https://github.com/elk-zone/elk. If you have questions or comments about this notice, you may raise an issue at https://github.com/elk-zone/elk.

Wyświetl plik

@ -1,10 +1,10 @@
[build] [build]
publish = "dist" publish = "dist"
command = "pnpm generate" command = "pnpm generate"
# Allow previewing docs # Allow previewing docs
[[redirects]] [[redirects]]
from = "/docs/*" from = "/docs/*"
to = "/:splat" to = "/:splat"
status = 200 status = 200
force = true force = true

37
eslint.config.js 100644
Wyświetl plik

@ -0,0 +1,37 @@
// @ts-check
import antfu from '@antfu/eslint-config'
export default await antfu(
{
unocss: false,
vue: {
overrides: {
'vue/no-restricted-syntax': ['error', {
selector: 'VElement[name=\'a\']',
message: 'Use NuxtLink instead.',
}],
},
},
ignores: [
'public/**',
'public-dev/**',
'public-staging/**',
'https-dev-config/**',
'elk-translation-status.json',
'docs/translation-status.json',
],
},
{
rules: {
// TODO: migrate all process reference to `import.meta.env` and remove this rule
'node/prefer-global/process': 'off',
},
},
// Sort local files
{
files: ['locales/**.json'],
rules: {
'jsonc/sort-keys': 'error',
},
},
)

Wyświetl plik

@ -28,7 +28,8 @@ export default defineNuxtModule({
.map(async (l) => { .map(async (l) => {
const exists = await isFile(resolver.resolve(`../node_modules/@emoji-mart/data/i18n/${l}.json`)) const exists = await isFile(resolver.resolve(`../node_modules/@emoji-mart/data/i18n/${l}.json`))
return [l, exists] as [code: string, exists: boolean] return [l, exists] as [code: string, exists: boolean]
})) }),
)
.then(l => l.filter(l => l[1]).map(l => l[0])) .then(l => l.filter(l => l[1]).map(l => l[0]))
const switchStmt = locales.filter(l => l[1]).map((l) => { const switchStmt = locales.filter(l => l[1]).map((l) => {
return ` return `

Wyświetl plik

@ -10,8 +10,8 @@ export function configurePWAOptions(options: Partial<VitePWAOptions>, nuxt: Nuxt
let config: Partial< let config: Partial<
import('workbox-build').BasePartial import('workbox-build').BasePartial
& import('workbox-build').GlobPartial & import('workbox-build').GlobPartial
& import('workbox-build').RequiredGlobDirectoryPartial & import('workbox-build').RequiredGlobDirectoryPartial
> >
if (options.strategies === 'injectManifest') { if (options.strategies === 'injectManifest') {

Wyświetl plik

@ -36,7 +36,8 @@ export default defineNuxtPlugin(() => {
} }
const { const {
needRefresh, updateServiceWorker, needRefresh,
updateServiceWorker,
} = useRegisterSW({ } = useRegisterSW({
immediate: true, immediate: true,
onRegisterError() { onRegisterError() {

Wyświetl plik

@ -13,7 +13,6 @@ export default defineNuxtPlugin(() => {
} }
window.addEventListener('unhandledrejection', err => window.addEventListener('unhandledrejection', err =>
log.error(err.reason), log.error(err.reason))
)
window.addEventListener('error', err => log.error(err.error), true) window.addEventListener('error', err => log.error(err.error), true)
}) })

Wyświetl plik

@ -1,10 +1,10 @@
[build] [build]
publish = "dist" publish = "dist"
command = "pnpm run build" command = "pnpm run build"
# Redirect to Discord server # Redirect to Discord server
[[redirects]] [[redirects]]
from = "https://chat.elk.zone" from = "https://chat.elk.zone"
to = "https://discord.gg/vAZSDU9J" to = "https://discord.gg/vAZSDU9J"
status = 301 status = 301
force = true force = true

Wyświetl plik

@ -94,16 +94,42 @@ export default defineNuxtConfig({
}, },
optimizeDeps: { optimizeDeps: {
include: [ include: [
'@tiptap/vue-3', 'string-length', 'vue-virtual-scroller', 'emoji-mart', 'iso-639-1', '@tiptap/vue-3',
'@tiptap/extension-placeholder', '@tiptap/extension-document', '@tiptap/extension-paragraph', 'string-length',
'@tiptap/extension-text', '@tiptap/extension-mention', '@tiptap/extension-hard-break', 'vue-virtual-scroller',
'@tiptap/extension-bold', '@tiptap/extension-italic', '@tiptap/extension-code', 'emoji-mart',
'@tiptap/extension-history', 'prosemirror-state', 'browser-fs-access', 'blurhash', 'iso-639-1',
'@vueuse/integrations/useFocusTrap', '@tiptap/extension-code-block', 'prosemirror-highlight', '@tiptap/extension-placeholder',
'@tiptap/core', 'tippy.js', 'prosemirror-highlight/shiki', '@fnando/sparkline', '@tiptap/extension-document',
'@vueuse/gesture', 'github-reserved-names', 'file-saver', 'slimeform', 'vue-advanced-cropper', '@tiptap/extension-paragraph',
'workbox-window', 'workbox-precaching', 'workbox-routing', 'workbox-cacheable-response', '@tiptap/extension-text',
'workbox-strategies', 'workbox-expiration', '@tiptap/extension-mention',
'@tiptap/extension-hard-break',
'@tiptap/extension-bold',
'@tiptap/extension-italic',
'@tiptap/extension-code',
'@tiptap/extension-history',
'prosemirror-state',
'browser-fs-access',
'blurhash',
'@vueuse/integrations/useFocusTrap',
'@tiptap/extension-code-block',
'prosemirror-highlight',
'@tiptap/core',
'tippy.js',
'prosemirror-highlight/shiki',
'@fnando/sparkline',
'@vueuse/gesture',
'github-reserved-names',
'file-saver',
'slimeform',
'vue-advanced-cropper',
'workbox-window',
'workbox-precaching',
'workbox-routing',
'workbox-cacheable-response',
'workbox-strategies',
'workbox-expiration',
], ],
}, },
}, },
@ -249,7 +275,8 @@ export default defineNuxtConfig({
], ],
}, },
}, },
// eslint-disable-next-line @typescript-eslint/prefer-ts-expect-error
// eslint-disable-next-line ts/prefer-ts-expect-error
// @ts-ignore nuxt-security is conditional // @ts-ignore nuxt-security is conditional
security: { security: {
headers: { headers: {
@ -297,7 +324,7 @@ export default defineNuxtConfig({
}) })
declare global { declare global {
// eslint-disable-next-line @typescript-eslint/no-namespace // eslint-disable-next-line ts/no-namespace
namespace NodeJS { namespace NodeJS {
interface Process { interface Process {
mock?: Record<string, any> mock?: Record<string, any>

Wyświetl plik

@ -112,7 +112,7 @@
"ws": "^8.15.1" "ws": "^8.15.1"
}, },
"devDependencies": { "devDependencies": {
"@antfu/eslint-config": "^0.43.1", "@antfu/eslint-config": "^2.8.0",
"@antfu/ni": "^0.21.12", "@antfu/ni": "^0.21.12",
"@types/chroma-js": "^2.4.4", "@types/chroma-js": "^2.4.4",
"@types/file-saver": "^2.0.7", "@types/file-saver": "^2.0.7",
@ -124,10 +124,12 @@
"@types/wicg-file-system-access": "^2020.9.8", "@types/wicg-file-system-access": "^2020.9.8",
"@types/ws": "^8.5.10", "@types/ws": "^8.5.10",
"@unlazy/nuxt": "^0.11.1", "@unlazy/nuxt": "^0.11.1",
"@unocss/eslint-config": "^0.58.5",
"@vue/test-utils": "^2.4.4", "@vue/test-utils": "^2.4.4",
"bumpp": "^9.4.0", "bumpp": "^9.4.0",
"consola": "^3.2.3", "consola": "^3.2.3",
"eslint": "^8.49.0", "eslint": "^8.57.0",
"eslint-plugin-format": "^0.1.0",
"flat": "^5.0.2", "flat": "^5.0.2",
"fs-extra": "^11.2.0", "fs-extra": "^11.2.0",
"lint-staged": "^14.0.1", "lint-staged": "^14.0.1",

Wyświetl plik

@ -1,5 +1,4 @@
<script setup lang="ts"> <script setup lang="ts">
const { t } = useI18n() const { t } = useI18n()
useHydratedHead({ useHydratedHead({

Plik diff jest za duży Load Diff

Wyświetl plik

@ -32,7 +32,10 @@ async function handleSharedTarget(event: FetchEvent) {
} }
async function sendShareTargetMessage(client: Client, data: FormData) { async function sendShareTargetMessage(client: Client, data: FormData) {
const sharedData: { textParts: string[]; files: File[] } = { const sharedData: {
textParts: string[]
files: File[]
} = {
textParts: [], textParts: [],
files: [], files: [],
} }

Wyświetl plik

@ -67,8 +67,8 @@ if (import.meta.env.PROD) {
registerRoute( registerRoute(
({ sameOrigin, request, url }) => ({ sameOrigin, request, url }) =>
sameOrigin sameOrigin
&& request.destination === 'image' && request.destination === 'image'
&& url.pathname.startsWith('/emojis/'), && url.pathname.startsWith('/emojis/'),
new StaleWhileRevalidate({ new StaleWhileRevalidate({
cacheName: 'elk-emojis', cacheName: 'elk-emojis',
plugins: [ plugins: [