Compare commits

...

27 commits
dev ... main

Author SHA1 Message Date
Ayo
9264207406 feat(yolk): rename service in docker-file
Some checks failed
ci / ci (push) Has been cancelled
build & push docker container / docker (push) Has been cancelled
2025-08-08 22:11:14 +02:00
Ayo
4babfe9c46 feat(yolk): use redis in docker-compose 2025-08-08 22:08:05 +02:00
Ayo
fe3f416f54 chore: add TODO 2025-08-08 21:54:57 +02:00
Ayo
69506f7d99 Merge branch 'main' of github.com:ayoayco/elk 2025-08-08 21:33:38 +02:00
renovate[bot]
78fd25ac10
chore(deps): update devdependencies (#3344)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-08-05 12:51:54 +01:00
renovate[bot]
7fc8aa7bc2
chore(deps): update dependency @antfu/eslint-config to v5 (#3345)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-08-04 08:20:28 +01:00
Ayo
f8a702704f Merge branch 'main' of github.com:ayoayco/elk 2025-07-30 15:45:54 +02:00
nove-b
da26c38e59
fix(ui): Asterisk pairs are removed in code block (#3326)
Co-authored-by: TAKAHASHI Shuuji <shuuji3@gmail.com>
2025-07-29 08:20:09 +00:00
Simon Ramsay
e8e2192e75
feat: pass origin as website when loging into server (#3299) 2025-07-29 00:02:18 +00:00
Ayo
2d6ba0cab5 feat(yolk): disable singServerInstance 2025-07-28 14:24:47 +02:00
Ayo
1db09a2a41 feat(yolk): change config to single server social.ayco.io 2025-07-28 13:40:22 +02:00
Ayo
7f733512a2 chore(yolk): remove --prod on Dockerfile deps installation 2025-07-28 13:25:01 +02:00
Ayo Ayco
31364c1b63
fix: error accessing thumbnail when instance is not defined (#3342) 2025-07-28 10:35:11 +00:00
Ayo
e170e22621 Merge branch 'dev' of github.com:ayoayco/elk 2025-07-28 12:02:11 +02:00
Ayo
078ca947aa Merge branch 'main' of github.com:elk-zone/elk into dev 2025-07-28 11:57:00 +02:00
Ayo
a57ce2db7b fix: error accessing thumbnail when instance is not defined 2025-07-28 11:56:38 +02:00
TAKAHASHI Shuuji
317929504e
Merge pull request #3340
chore(deps): update dependency nuxt-component-meta to v0.13.0
2025-07-28 16:57:35 +09:00
TAKAHASHI Shuuji
3ef80d56ef
Merge pull request #3341
fix(deps): update dependency browser-fs-access to ^0.38.0
2025-07-28 15:11:29 +09:00
renovate[bot]
cfb68319fe
fix(deps): update dependency browser-fs-access to ^0.38.0 2025-07-28 00:47:37 +00:00
renovate[bot]
f3d1ac9fca
chore(deps): update dependency nuxt-component-meta to v0.13.0 2025-07-28 00:47:10 +00:00
Ayo
5b073ee32a chore: skip dev dependencies on prod Dockerfile 2025-07-27 21:23:13 +02:00
Ayo
ebf11b5d57 style(yolk): normal nav title color 2025-07-27 18:39:31 +02:00
Ayo
2780036983 feat(yolk): replace client_name 2025-07-27 18:39:04 +02:00
Ayo
f202edd5fd feat(yolk): replace icons & logo 2025-07-27 18:38:45 +02:00
Ayo
a876d81f51 chore(yolk): add background to README 2025-07-27 10:52:36 +02:00
Ayo
e09e4d5b4d feat(yolk): change app name & logo 2025-07-27 10:50:27 +02:00
renovate[bot]
b8144db9ac
chore(deps): update lint (#3337)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: TAKAHASHI Shuuji <shuuji3@gmail.com>
2025-07-27 04:38:35 +00:00
53 changed files with 2252 additions and 1742 deletions

View file

@ -1,27 +1,16 @@
<p align="center">
<a href="https://elk.zone" target="_blank" rel="noopener noreferrer">
<img width="160" height="160" src="./public/logo.svg" alt="Elk logo">
</a>
</p>
# Yolk
<h1 align="center"/>Elk <sup><em>alpha</em></sup></h1>
Hi! Yolk is my custom fork of [Elk](https://github.com/elk-zon/elk), a nimble Mastodon client.
<p align="center">
A nimble Mastodon web client
</p>
I [decided](https://social.ayco.io/@ayo/114921112446517000) to have a personal fork of Elk because I really like the cross-account functionalities I use it for (e.g., I can open the Explore tab of my fosstodon account, then engage in a post with my self-hosted account, etc)... but I find sometimes I want to change little things which will make the app a bit more opinionated on my tastes (e.g., icons, colors, spacing, etc)... and some behavioral features.
<br/>
<p align="center">
<a href="https://chat.elk.zone"><img src="https://img.shields.io/badge/chat-discord-blue?style=flat&logo=discord" alt="discord chat"></a>
<a href="https://volta.net/elk-zone/elk?utm_source=elk_readme"><img src="https://user-images.githubusercontent.com/904724/209143798-32345f6c-3cf8-4e06-9659-f4ace4a6acde.svg" alt="Open board on Volta"></a>
</p>
<br/>
I think doing this will make me use it as my main app daily. I have been switching between multiple apps because each one have strengths & weaknesses of their own.
<p align="center">
<a href="https://elk.zone/" target="_blank" rel="noopener noreferrer" >
<img src="./public/elk-og.png" alt="Elk screenshots" width="600" height="auto">
</a>
</p>
Crucial fixes (if I find them), quality of life improvements, and mastodon API feature parity will still go upstream to the main Elk project.
~ Ayo Ayco
---
## ⚠️ Elk is in Alpha
@ -50,56 +39,8 @@ One could put Elk behind popular reverse proxies with SSL Handling like Traefik,
> [!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.
### 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:
- [elk.fedified.com](https://elk.fedified.com) - Use Elk to log into any compatible instance
- [elk.mastodon.com.pl](https://elk.mastodon.com.pl) - Use Elk for the `mastodon.com.pl` Server
- [elk.me.uk](https://elk.me.uk) - Use Elk to log into any compatible instance, hosted on Google Cloud Run with no Cloudflare proxy
- [elk.h4.io](https://elk.h4.io) - Use Elk for the `h4.io` Server
- [elk.universeodon.com](https://elk.universeodon.com) - Use Elk for the Universeodon Server
- [elk.vmst.io](https://elk.vmst.io) - Use Elk for the `vmst.io` Server
- [elk.hostux.social](https://elk.hostux.social) - Use Elk for the `hostux.social` Server
- [elk.cupoftea.social](https://elk.cupoftea.social) - Use Elk for the `cupoftea.social` Server
- [elk.aus.social](https://elk.aus.social) - Use Elk for the `aus.social` Server
- [elk.mstdn.ca](https://elk.mstdn.ca) - Use Elk for the `mstdn.ca` Server
- [elk.mastodonapp.uk](https://elk.mastodonapp.uk) - Use Elk for the `mastodonapp.uk` Server
- [elk.bolha.us](https://elk.bolha.us) - Use Elk for the `bolha.us` Server
- [crab.bumscode.com](https://crab.bumscode.com) - Use [crab](https://github.com/maybeanerd/crab) - a soft fork of Elk - for the `bumscode.com` Server
> **Note**: Community deployments are **NOT** maintained by the Elk team. It may not be synced with Elk's source code. Please do your own research about the host servers before using them.
## 💖 Sponsors
We are grateful for the generous sponsorship and help of:
<a href="https://nuxtlabs.com/" target="_blank" rel="noopener noreferrer" >
<img src="./images/nuxtlabs.svg" alt="NuxtLabs" height="85">
</a>
<br><br>
<a href="https://stackblitz.com/" target="_blank" rel="noopener noreferrer" >
<img src="./images/stackblitz.svg" alt="StackBlitz" height="85">
</a>
<br><br>
And all the companies and individuals sponsoring Elk Team and the members. If you're enjoying the app, consider sponsoring us:
- [Elk Team's GitHub Sponsors](https://github.com/sponsors/elk-zone)
Or you can sponsor our core team members individually:
- [Anthony Fu](https://github.com/sponsors/antfu)
- [Daniel Roe](https://github.com/sponsors/danielroe)
- [三咲智子 Kevin Deng](https://github.com/sponsors/sxzz)
- [Patak](https://github.com/sponsors/patak-dev)
We would also appreciate sponsoring other contributors to the Elk project. If someone helps you solve an issue or implement a feature you wanted, supporting them would help make this project and OS more sustainable.
## 📍 Roadmap
[Open board on Volta](https://volta.net/elk-zone/elk)
## 🧑‍💻 Contributing
We're really excited that you're interested in contributing to Elk! Before submitting your contribution, please read through the following guide.

View file

@ -2,47 +2,13 @@
</script>
<template>
<span shrink-0 aspect="1/1" sm:h-8 xl:h-10 class="rtl-flip"><svg
<span shrink-0 aspect="1/1" sm:h-8 xl:h-10 class="rtl-flip">
<!-- <svg
xmlns="http://www.w3.org/2000/svg" w-full
aspect="1/1" sm:h-8 xl:h-10 sm:w-8 xl:w-10 viewBox="0 0 250 250" fill="none"
>
<mask
id="a"
width="240"
height="234"
x="4"
y="1"
maskUnits="userSpaceOnUse"
style="mask-type:alpha"
>
<path
id="path19"
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"
/>
</mask>
<g
id="g28"
mask="url(#a)"
transform="matrix(0.90923731,0,0,1.0049564,13.520015,-3.1040835)"
>
<path
id="path22"
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"
/>
<path
id="path24"
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"
/>
<path
id="path26"
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"
/>
</g>
</svg>
> -->
<svg xmlns="http://www.w3.org/2000/svg" width="48" height="48" viewBox="0 0 48 48"><defs><mask id="ipTEgg0"><g fill="none" stroke="#fff" stroke-width="4"><circle cx="24" cy="24" r="10" fill="#555555" stroke-linecap="round" stroke-linejoin="round" /><path d="M44 24c0 2.633-.508 5.146-1.433 7.448c-.936 2.331-4.129.071-7.346 3.521c-3.216 3.45-.71 6.267-3.204 7.36A19.9 19.9 0 0 1 24 44C12.954 44 4 35.046 4 24S12.954 4 24 4s20 8.954 20 20Z" /><path stroke-linecap="round" d="M20 25s.21 1.21 1 2s2 1 2 1" /></g></mask></defs><path fill="#ff8d00" d="M0 0h48v48H0z" mask="url(#ipTEgg0)" /></svg>
</span>
</template>

View file

@ -29,8 +29,9 @@ router.afterEach(() => {
@click.prevent="onClickLogo"
>
<NavLogo shrink-0 aspect="1/1" sm:h-8 xl:h-10 class="rtl-flip" />
<div v-show="isHydrated" hidden xl:block text-secondary>
{{ $t('app_name') }} <sup text-sm italic mt-1>{{ env === 'release' ? 'alpha' : env }}</sup>
<div v-show="isHydrated" hidden xl:block>
<span pr-1>{{ $t('app_name') }}</span>
<sup text-sm italic mt-1>{{ env === 'release' ? 'alpha' : env }}</sup>
</div>
</NuxtLink>
<div hidden xl:flex items-center me-6 mt-2 gap-1>

View file

@ -104,11 +104,12 @@ export function parseMastodonHTML(
.replace(/</g, '&lt;')
.replace(/>/g, '&gt;')
.replace(/`/g, '&#96;')
.replace(/\*/g, '&ast;')
const classes = lang ? ` class="language-${lang}"` : ''
return `><pre><code${classes}>${code}</code></pre>`
})
.replace(/`([^`\n]*)`/g, (_1, raw) => {
return raw ? `<code>${htmlToText(raw).replace(/</g, '&lt;').replace(/>/g, '&gt;')}</code>` : ''
return raw ? `<code>${htmlToText(raw).replace(/</g, '&lt;').replace(/>/g, '&gt;').replace(/\*/g, '&ast;')}</code>` : ''
})
}

View file

@ -95,9 +95,9 @@ export async function toggleMuteAccount(relationship: mastodon.v1.Relationship,
relationship!.muting = !relationship!.muting
relationship = relationship!.muting
? await client.value.v1.accounts.$select(account.id).mute({
duration,
notifications,
})
duration,
notifications,
})
: await client.value.v1.accounts.$select(account.id).unmute()
}

View file

@ -1,6 +1,6 @@
import type { mastodon } from 'masto'
export const APP_NAME = 'Elk'
export const APP_NAME = 'Yolk'
export const DEFAULT_POST_CHARS_LIMIT = 500
export const DEFAULT_FONT_SIZE = '15px'

View file

@ -10,6 +10,6 @@ catch (err) {
<template>
<MainContent text-base grid gap-3 m3>
<img rounded-3 :src="instance.thumbnail.url">
<img v-if="instance !== undefined" rounded-3 :src="instance.thumbnail.url">
</MainContent>
</template>

View file

@ -38,7 +38,7 @@ export default defineNuxtPlugin(({ $scrollToTop }) => {
}
whenever(logicAnd(isAuthenticated, notUsingInput, keys.c), defaultPublishDialog)
const instanceDomain = currentInstance.value ? getInstanceDomain(currentInstance.value) : 'm.webtoo.ls'
const instanceDomain = currentInstance.value ? getInstanceDomain(currentInstance.value) : 'social.ayco.io'
whenever(logicAnd(notUsingInput, useMagicSequence(['g', 'h'])), () => navigateTo('/home'))
whenever(logicAnd(isAuthenticated, notUsingInput, useMagicSequence(['g', 'n'])), () => navigateTo('/notifications'))
// TODO: always overridden by 'c' (compose) shortcut

View file

@ -1,12 +1,10 @@
services:
elk:
redis:
image: redis:latest
yolk:
image: ayoayco/yolk:latest
build:
context: .
dockerfile: Dockerfile
volumes:
# make sure this directory has the same ownership as the elk user from the Dockerfile
# otherwise Elk will not be able to store configs for accounts
# e.q. mkdir ./elk-storage; sudo chown 911:911 ./elk-storage
- './elk-storage:/elk/data'
ports:
- 5314:5314

View file

@ -13,6 +13,6 @@
},
"devDependencies": {
"@nuxt-themes/docus": "^1.15.1",
"nuxt": "^3.17.7"
"nuxt": "^3.18.1"
}
}

View file

@ -85,7 +85,7 @@
},
"app_desc_short": "منصة تواصل ماستودون رشيقة",
"app_logo": "Elk شعار",
"app_name": "Elk",
"app_name": "Yolk",
"attachment": {
"edit_title": "وصف",
"remove_label": "قم بإزالة المرفق"

View file

@ -89,7 +89,7 @@
},
"app_desc_short": "Un client web àgil Mastodon",
"app_logo": "Logotip d'Elk",
"app_name": "Elk",
"app_name": "Yolk",
"attachment": {
"edit_title": "Descripció",
"remove_label": "Elimina el fitxer adjunt"

View file

@ -78,7 +78,7 @@
},
"app_desc_short": "ڕاژەخوازێکی وێبی ماستۆدۆن",
"app_logo": "Elk لۆگۆی",
"app_name": "Elk",
"app_name": "Yolk",
"attachment": {
"edit_title": "وەسف",
"remove_label": "لابردنی لکێندراو"

View file

@ -49,7 +49,7 @@
},
"app_desc_short": "Elk - hbitý webklient pro Mastodon.",
"app_logo": "logo Elk",
"app_name": "Elk",
"app_name": "Yolk",
"command": {
"activate": "Aktivovat",
"complete": "Dokončit",

View file

@ -70,7 +70,7 @@
},
"app_desc_short": "Cleient gwe ystwyth ar gyfer Mastodon",
"app_logo": "Logo Elk",
"app_name": "Elk",
"app_name": "Yolk",
"attachment": {
"edit_title": "Disgrifiad",
"remove_label": "Tunnu atodiad"

View file

@ -91,7 +91,7 @@
},
"app_desc_short": "Ein flinker Mastodon Web-Client",
"app_logo": "Elk Logo",
"app_name": "Elk",
"app_name": "Yolk",
"attachment": {
"edit_title": "Beschreibung",
"remove_label": "Anhang entfernen"

View file

@ -86,7 +86,7 @@
},
"app_desc_short": "Ένας ελαφρώς προσαρμοσμένος πελάτης για το Mastodon",
"app_logo": "Λογότυπο Elk",
"app_name": "Elk",
"app_name": "Yolk",
"attachment": {
"edit_title": "Περιγραφή",
"remove_label": "Αφαίρεση επισύναψης"

View file

@ -89,7 +89,7 @@
},
"app_desc_short": "A nimble Mastodon web client",
"app_logo": "Elk Logo",
"app_name": "Elk",
"app_name": "Yolk",
"attachment": {
"edit_title": "Description",
"remove_label": "Remove attachment"

View file

@ -89,7 +89,7 @@
},
"app_desc_short": "Un cliente web ágil para Mastodon",
"app_logo": "Logotipo de Elk",
"app_name": "Elk",
"app_name": "Yolk",
"attachment": {
"edit_title": "Descripción",
"remove_label": "Eliminar fichero adjunto"

View file

@ -89,7 +89,7 @@
},
"app_desc_short": "Mastodon web-bezero arin bat",
"app_logo": "Elk-en logoa",
"app_name": "Elk",
"app_name": "Yolk",
"attachment": {
"edit_title": "Deskribapena",
"remove_label": "Kendu erantsitakoak"

View file

@ -85,7 +85,7 @@
},
"app_desc_short": "یک کارخواه وب چابک برای ماستودون",
"app_logo": "لوگوی نرم‌افزار",
"app_name": "Elk",
"app_name": "Yolk",
"attachment": {
"edit_title": "توضیحات",
"remove_label": "حذف پیوست"

View file

@ -89,7 +89,7 @@
},
"app_desc_short": "Ketterä verkkosovellus Mastodonille",
"app_logo": "Elk-logo",
"app_name": "Elk",
"app_name": "Yolk",
"attachment": {
"edit_title": "Kuvaus",
"remove_label": "Poista liite"

View file

@ -80,7 +80,7 @@
},
"app_desc_short": "Un client Mastodon fait avec 🧡",
"app_logo": "Logo Elk",
"app_name": "Elk",
"app_name": "Yolk",
"attachment": {
"edit_title": "Description",
"remove_label": "Retirer le fichier attaché"

View file

@ -85,7 +85,7 @@
},
"app_desc_short": "Un cliente web áxil para Mastodon",
"app_logo": "Logo de Elk",
"app_name": "Elk",
"app_name": "Yolk",
"attachment": {
"edit_title": "Descrición",
"remove_label": "Quitar o anexo"

View file

@ -89,7 +89,7 @@
},
"app_desc_short": "Egy fürge Mastodon kliens",
"app_logo": "Elk Logó",
"app_name": "Elk",
"app_name": "Yolk",
"attachment": {
"edit_title": "Leírás",
"remove_label": "Melléklet eltávolítása"

View file

@ -85,7 +85,7 @@
},
"app_desc_short": "Klien web Mastodon yang gesit",
"app_logo": "Logo Elk",
"app_name": "Elk",
"app_name": "Yolk",
"attachment": {
"edit_title": "Deskripsi",
"remove_label": "Hapus lampiran"

View file

@ -89,7 +89,7 @@
},
"app_desc_short": "Un client web agile per Mastodon",
"app_logo": "Logo Elk",
"app_name": "Elk",
"app_name": "Yolk",
"attachment": {
"edit_title": "Descrizione",
"remove_label": "Rimuovi allegato"

View file

@ -89,7 +89,7 @@
},
"app_desc_short": "軽快なMastodonウェブクライアント",
"app_logo": "Elkのロゴ",
"app_name": "Elk",
"app_name": "Yolk",
"attachment": {
"edit_title": "説明文",
"remove_label": "添付を削除"

View file

@ -69,7 +69,7 @@
},
"app_desc_short": "민첩한 마스토돈 웹 클라이언트",
"app_logo": "Elk 로고",
"app_name": "Elk",
"app_name": "Yolk",
"attachment": {
"edit_title": "설명",
"remove_label": "첨부파일 삭제"

View file

@ -89,7 +89,7 @@
},
"app_desc_short": "Een vlotte Mastodon web client",
"app_logo": "Elk Logo",
"app_name": "Elk",
"app_name": "Yolk",
"attachment": {
"edit_title": "Omschrijving",
"remove_label": "Verwijder bijlage"

View file

@ -77,7 +77,7 @@
},
"app_desc_short": "Aplikacja webowa dla Mastodon",
"app_logo": "Elk Logo",
"app_name": "Elk",
"app_name": "Yolk",
"attachment": {
"edit_title": "Opis",
"remove_label": "Usuń załącznik"

View file

@ -89,7 +89,7 @@
},
"app_desc_short": "Uma ágil aplicação web para o Mastodon",
"app_logo": "Logo do Elk",
"app_name": "Elk",
"app_name": "Yolk",
"attachment": {
"edit_title": "Descrição",
"remove_label": "Remover anexo"

View file

@ -78,7 +78,7 @@
},
"app_desc_short": "Открытый веб-клиент для Mastodon",
"app_logo": "Логотип Elk",
"app_name": "Elk",
"app_name": "Yolk",
"attachment": {
"edit_title": "Описание",
"remove_label": "Удалить файл"

View file

@ -77,7 +77,7 @@
},
"app_desc_short": "เว็บหน้าบ้านมาสโตดอนที่ปราดเปรียว",
"app_logo": "โลโก้ Elk",
"app_name": "Elk",
"app_name": "Yolk",
"attachment": {
"edit_title": "อธิบาย",
"remove_label": "เอาสิ่งแนบออก"

View file

@ -89,7 +89,7 @@
},
"app_desc_short": "Isang mabilis na web client ng Mastodon",
"app_logo": "Logo ng Elk",
"app_name": "Elk",
"app_name": "Yolk",
"attachment": {
"edit_title": "Paglalarawan",
"remove_label": "Tanggalin ang attachment"

View file

@ -77,7 +77,7 @@
},
"app_desc_short": "Hızlı bir Mastodon web istemcisi",
"app_logo": "Elk Logosu",
"app_name": "Elk",
"app_name": "Yolk",
"attachment": {
"edit_title": "Açıklama",
"remove_label": "Eki kaldır"

View file

@ -87,7 +87,7 @@
},
"app_desc_short": "Спритний вебклієнт для Mastodon",
"app_logo": "Лоґо Elk",
"app_name": "Elk",
"app_name": "Yolk",
"attachment": {
"edit_title": "Опис",
"remove_label": "Вилучити вкладення"

View file

@ -89,7 +89,7 @@
},
"app_desc_short": "Một ứng dụng web Mastodon nhanh nhẹn",
"app_logo": "Elk Logo",
"app_name": "Elk",
"app_name": "Yolk",
"attachment": {
"edit_title": "Mô tả",
"remove_label": "Xóa file đính kèm"

View file

@ -1,5 +1,4 @@
import type { Ref } from 'vue'
import type { UnwrapNestedRefs } from 'vue'
import type { Ref, UnwrapNestedRefs } from 'vue'
export interface PwaInjection {
isInstalled: boolean

View file

@ -1,8 +1,20 @@
import { Store } from 'tauri-plugin-store-api'
import { createStorage } from 'unstorage'
import redisDriver from 'unstorage/drivers/redis'
const store = new Store('.servers.dat')
const storage = createStorage()
/**
* TODO: Use redis as storage
* - docs: https://unstorage.unjs.io/drivers/redis
* - then we can probably remove need for `/elk/data` (see docker-compose)
*/
const storage = createStorage({
driver: redisDriver({
base: 'unstorage:elk:',
}),
})
storage.mount('servers', {
getKeys() {
return store.keys()

View file

@ -173,7 +173,7 @@ export default defineNuxtConfig({
// our default translation server #76
translateApi: '',
// Use the instance where Elk has its Mastodon account as the default
defaultServer: 'm.webtoo.ls',
defaultServer: 'social.ayco.io',
singleInstance: false,
},
storage: {

View file

@ -68,7 +68,7 @@
"@vueuse/motion": "2.2.6",
"@vueuse/nuxt": "^13.2.0",
"blurhash": "^2.0.5",
"browser-fs-access": "^0.35.0",
"browser-fs-access": "^0.38.0",
"cheerio": "^1.0.0",
"chroma-js": "^3.0.0",
"emoji-mart": "^5.5.2",
@ -82,6 +82,7 @@
"happy-dom": "^16.0.0",
"idb-keyval": "^6.2.1",
"ignore-dependency-scripts": "^1.0.1",
"ioredis": "^5.7.0",
"iso-639-1": "^3.0.0",
"js-yaml": "^4.1.0",
"lru-cache": "^11.0.0",
@ -117,7 +118,7 @@
"ws": "^8.15.1"
},
"devDependencies": {
"@antfu/eslint-config": "^4.13.1",
"@antfu/eslint-config": "^5.1.0",
"@antfu/ni": "^24.4.0",
"@types/chroma-js": "^3.1.1",
"@types/file-saver": "^2.0.7",
@ -127,20 +128,20 @@
"@types/wicg-file-system-access": "^2023.10.6",
"@types/ws": "^8.18.1",
"@unlazy/nuxt": "^0.12.4",
"@unocss/eslint-config": "^66.3.3",
"@unocss/eslint-config": "^66.4.1",
"@vue/test-utils": "2.4.6",
"bumpp": "^10.2.0",
"bumpp": "^10.2.2",
"consola": "^3.4.2",
"eslint": "^9.27.0",
"eslint": "^9.32.0",
"eslint-plugin-format": "^1.0.1",
"flat": "^6.0.1",
"fs-extra": "^11.3.0",
"lint-staged": "^15.5.2",
"nuxt": "^3.17.7",
"prettier": "^3.5.3",
"nuxt": "^3.18.1",
"prettier": "^3.6.2",
"sharp": "^0.34.3",
"sharp-ico": "^0.1.5",
"simple-git-hooks": "^2.13.0",
"simple-git-hooks": "^2.13.1",
"tsx": "^4.20.3",
"typescript": "^5.4.4",
"vitest": "3.2.4",
@ -152,7 +153,7 @@
}
},
"resolutions": {
"nuxt-component-meta": "0.12.1",
"nuxt-component-meta": "0.13.0",
"unstorage": "^1.16.1",
"vitest": "3.2.4",
"vue": "^3.5.4"

28
page-lifecycle.d.ts vendored
View file

@ -1,17 +1,17 @@
declare module 'page-lifecycle/dist/lifecycle.mjs' {
type PageLifecycleState = 'active' | 'passive' | 'hidden' | 'frozen' | 'terminated'
type PageLifecycleState = 'active' | 'passive' | 'hidden' | 'frozen' | 'terminated'
interface PageLifecycleEvent extends Event {
newState: PageLifecycleState
oldState: PageLifecycleState
}
interface PageLifecycle extends EventTarget {
get state(): PageLifecycleState
get pageWasDiscarded(): boolean
addUnsavedChanges: (id: symbol | any) => void
removeUnsavedChanges: (id: symbol | any) => void
addEventListener: (type: string, listener: (evt: PageLifecycleEvent) => void) => void
}
const lifecycle: PageLifecycle
export default lifecycle
interface PageLifecycleEvent extends Event {
newState: PageLifecycleState
oldState: PageLifecycleState
}
interface PageLifecycle extends EventTarget {
get state(): PageLifecycleState
get pageWasDiscarded(): boolean
addUnsavedChanges: (id: symbol | any) => void
removeUnsavedChanges: (id: symbol | any) => void
addEventListener: (type: string, listener: (evt: PageLifecycleEvent) => void) => void
}
const lifecycle: PageLifecycle
export default lifecycle
}

File diff suppressed because it is too large Load diff

Binary file not shown.

Before

Width:  |  Height:  |  Size: 993 B

After

Width:  |  Height:  |  Size: 4.2 KiB

View file

@ -1,42 +1 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
width="250"
height="250"
fill="none"
version="1.1"
id="svg30"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<defs
id="defs34" />
<mask
id="a"
width="240"
height="234"
x="4"
y="1"
maskUnits="userSpaceOnUse"
style="mask-type:alpha">
<path
fill="white"
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>
<g
mask="url(#a)"
id="g28"
transform="matrix(0.90923731,0,0,1.0049564,13.520015,-3.1040835)">
<path
fill="#91BA4D"
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
fill="#20461A"
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
fill="#20461A"
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>
</svg>
<svg xmlns="http://www.w3.org/2000/svg" width="192" height="192" viewBox="0 0 48 48"><defs><mask id="ipTEgg0"><g fill="none" stroke="#fff" stroke-width="4"><circle cx="24" cy="24" r="10" fill="#555555" stroke-linecap="round" stroke-linejoin="round"/><path d="M44 24c0 2.633-.508 5.146-1.433 7.448c-.936 2.331-4.129.071-7.346 3.521c-3.216 3.45-.71 6.267-3.204 7.36A19.9 19.9 0 0 1 24 44C12.954 44 4 35.046 4 24S12.954 4 24 4s20 8.954 20 20Z"/><path stroke-linecap="round" d="M20 25s.21 1.21 1 2s2 1 2 1"/></g></mask></defs><path fill="#ff8d00" d="M0 0h48v48H0z" mask="url(#ipTEgg0)"/></svg>

Before

Width:  |  Height:  |  Size: 2.9 KiB

After

Width:  |  Height:  |  Size: 589 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 965 B

After

Width:  |  Height:  |  Size: 4.2 KiB

View file

@ -1,42 +1 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
width="250"
height="250"
fill="none"
version="1.1"
id="svg30"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<defs
id="defs34" />
<mask
id="a"
width="240"
height="234"
x="4"
y="1"
maskUnits="userSpaceOnUse"
style="mask-type:alpha">
<path
fill="white"
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>
<g
mask="url(#a)"
id="g28"
transform="matrix(0.90923731,0,0,1.0049564,13.520015,-3.1040835)">
<path
fill="#5AB1CC"
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
fill="#1E4E5E"
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
fill="#1E4E5E"
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>
</svg>
<svg xmlns="http://www.w3.org/2000/svg" width="192" height="192" viewBox="0 0 48 48"><defs><mask id="ipTEgg0"><g fill="none" stroke="#fff" stroke-width="4"><circle cx="24" cy="24" r="10" fill="#555555" stroke-linecap="round" stroke-linejoin="round"/><path d="M44 24c0 2.633-.508 5.146-1.433 7.448c-.936 2.331-4.129.071-7.346 3.521c-3.216 3.45-.71 6.267-3.204 7.36A19.9 19.9 0 0 1 24 44C12.954 44 4 35.046 4 24S12.954 4 24 4s20 8.954 20 20Z"/><path stroke-linecap="round" d="M20 25s.21 1.21 1 2s2 1 2 1"/></g></mask></defs><path fill="#ff8d00" d="M0 0h48v48H0z" mask="url(#ipTEgg0)"/></svg>

Before

Width:  |  Height:  |  Size: 2.9 KiB

After

Width:  |  Height:  |  Size: 589 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1 KiB

After

Width:  |  Height:  |  Size: 4.2 KiB

View file

@ -1,42 +1 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
width="250"
height="250"
fill="none"
version="1.1"
id="svg30"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<defs
id="defs34" />
<mask
id="a"
width="240"
height="234"
x="4"
y="1"
maskUnits="userSpaceOnUse"
style="mask-type:alpha">
<path
fill="white"
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>
<g
mask="url(#a)"
id="g28"
transform="matrix(0.90923731,0,0,1.0049564,13.520015,-3.1040835)">
<path
fill="#ea9e44"
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
fill="#c16929"
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
fill="#c16929"
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>
</svg>
<svg xmlns="http://www.w3.org/2000/svg" width="192" height="192" viewBox="0 0 48 48"><defs><mask id="ipTEgg0"><g fill="none" stroke="#fff" stroke-width="4"><circle cx="24" cy="24" r="10" fill="#555555" stroke-linecap="round" stroke-linejoin="round"/><path d="M44 24c0 2.633-.508 5.146-1.433 7.448c-.936 2.331-4.129.071-7.346 3.521c-3.216 3.45-.71 6.267-3.204 7.36A19.9 19.9 0 0 1 24 44C12.954 44 4 35.046 4 24S12.954 4 24 4s20 8.954 20 20Z"/><path stroke-linecap="round" d="M20 25s.21 1.21 1 2s2 1 2 1"/></g></mask></defs><path fill="#ff8d00" d="M0 0h48v48H0z" mask="url(#ipTEgg0)"/></svg>

Before

Width:  |  Height:  |  Size: 2.9 KiB

After

Width:  |  Height:  |  Size: 589 B

View file

@ -60,7 +60,7 @@ async function fetchAppInfo(origin: string, server: string) {
},
body: {
client_name: APP_NAME + (env !== 'release' ? ` (${env})` : ''),
website: 'https://elk.zone',
website: origin,
redirect_uris: getRedirectURI(origin, server),
scopes: 'read write follow push',
},

View file

@ -1,5 +1,12 @@
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
exports[`content-rich > asterisk paris in code block 1`] = `"<p><pre class="code-block">1 * 2 * 3</pre></p>"`;
exports[`content-rich > asterisk paris in inline code 1`] = `
"<p><code>1 * 2 * 3</code></p>
"
`;
exports[`content-rich > block with backticks 1`] = `"<p><pre class="code-block">[(\`number string) (\`tag string)]</pre></p>"`;
exports[`content-rich > block with injected html, with a known language 1`] = `

View file

@ -186,6 +186,16 @@ describe('content-rich', () => {
`)
expect(formatted).toMatchSnapshot()
})
it ('asterisk paris in inline code', async () => {
const { formatted } = await render('<p>`1 * 2 * 3`</p>')
expect(formatted).toMatchSnapshot()
})
it ('asterisk paris in code block', async () => {
const { formatted } = await render('<p>```<br />1 * 2 * 3<br />```</p>')
expect(formatted).toMatchSnapshot()
})
})
describe('editor', () => {