Merge branch 'develop' into iceshrimp_mastodon

This commit is contained in:
naskya 2024-06-28 16:45:41 +09:00
commit a451cf664c
No known key found for this signature in database
GPG key ID: 712D413B3A9FED5C
48 changed files with 205 additions and 252 deletions

View file

@ -1 +0,0 @@
web: NODE_ENV=production npm start

View file

@ -1,98 +0,0 @@
# configuration file for git-cliff (0.1.0)
[changelog]
# changelog header
header = """
# Changelog\n
"""
# template for the changelog body
# https://tera.netlify.app/docs/#introduction
body = """
{% if version %}\
## [{{ version | trim_start_matches(pat="v") }}] - {{ timestamp | date(format="%Y-%m-%d") }}
{% else %}\
## [unreleased]
{% endif %}\
{% for group, commits in commits | group_by(attribute="group") %}
### {{ group | upper_first }}
{% for commit in commits %}
- {% if commit.breaking %}[**breaking**] {% endif %}{{ commit.message | upper_first }}\
{% endfor %}
{% endfor %}\n
"""
# remove the leading and trailing whitespace from the template
trim = true
# changelog footer
footer = """
<!-- generated by git-cliff -->
"""
[git]
# parse the commits based on https://www.conventionalcommits.org
conventional_commits = false
# filter out the commits that are not conventional
filter_unconventional = true
# process each line of a commit as an individual commit
split_commits = false
# regex for parsing and grouping commits
commit_parsers = [
{ message = "^feat", group = "Features"},
{ message = "^add", group = "Features"},
{ message = "^fix", group = "Bug Fixes"},
{ message = "^prevent", group = "Bug Fixes"},
{ message = "^doc", group = "Documentation"},
{ message = "^perf", group = "Performance"},
{ message = "^🎨", group = "Refactor"},
{ message = "^enhance", group = "Refactor"},
{ message = "^⚡️", group = "Refactor"},
{ message = "^🔥", group = "Features"},
{ message = "^🐛", group = "Bug Fixes"},
{ message = "^🚑️", group = "Bug Fixes"},
{ message = "^block", group = "Bug Fixes"},
{ message = "^✨", group = "Features"},
{ message = "^📝", group = "Documentation"},
{ message = "^🚀", group = "Features"},
{ message = "^💄", group = "Styling"},
{ message = "^✅", group = "Testing"},
{ message = "^🔒️", group = "Security"},
{ message = "^🚨", group = "Testing"},
{ message = "^💚", group = "CI"},
{ message = "^👷", group = "CI"},
{ message = "^⬇️", group = "Miscellaneous Tasks"},
{ message = "^⬆️", group = "Miscellaneous Tasks"},
{ message = "^📌", group = "Miscellaneous Tasks"},
{ message = "^", group = "Miscellaneous Tasks"},
{ message = "^", group = "Miscellaneous Tasks"},
{ message = "^♻️", group = "Refactor"},
{ message = "^🔧", group = "CI"},
{ message = "^🔨", group = "CI"},
{ message = "^🌐", group = "Localization"},
{ message = "^✏️", group = "Localization"},
{ message = "^👽️", group = "Bug Fixes"},
{ message = "^🍱", group = "Styling"},
{ message = "^♿️", group = "Styling"},
{ message = "^🩹", group = "Bug Fixes"},
{ message = "^refactor", group = "Refactor"},
{ message = "^style", group = "Styling"},
{ message = "^test", group = "Testing"},
{ message = "^chore\\(release\\): prepare for", skip = true},
{ message = "^chore", group = "Miscellaneous Tasks"},
{ message = "^update", group = "Miscellaneous Tasks"},
{ body = ".*security", group = "Security"},
]
# protect breaking changes from being skipped due to matching a skipping commit_parser
protect_breaking_commits = false
# filter out the commits that are not matched by commit parsers
filter_commits = false
# glob pattern for matching git tags
tag_pattern = "v[0-9]*"
# regex for skipping tags
skip_tags = "v0.1.0-beta.1"
# regex for ignoring tags
ignore_tags = ""
# sort the tags chronologically
date_order = false
# sort the commits inside sections by oldest/newest order
sort_commits = "oldest"
# limit the number of commits included in the changelog.
# limit_commits = 42

View file

@ -9,6 +9,9 @@ Critical security updates are indicated by the :warning: icon.
- Ported Mastodon API support from Iceshrimp, with added Firefish extensions including push notifications, post languages, schedule post support, and more.
- The old Mastodon API has been replaced with a new implementation based on Iceshrimps.
- Add ability to automatically append #Alt4Me hashtag when posting a file without an alt text ([What is #Alt4Me?](https://social.growyourown.services/@FediTips/112055775451305236))
- Fix a build issue on some aarch64 environments
- Fix bugs
**Breaking changes:**

View file

@ -20,20 +20,23 @@ Firefish depends on the following software.
## Build dependencies
- At least [Rust](https://www.rust-lang.org/) v1.74
- C/C++ compiler & build tools
- C/C++ compiler & build tools (like [GNU Make](https://www.gnu.org/software/make/))
- `build-essential` on Debian/Ubuntu Linux
- `base-devel` on Arch Linux
- `"Development Tools"` on Fedora/Red Hat Linux
- [Python 3](https://www.python.org/)
- [Perl](https://www.perl.org/)
This document shows an example procedure for installing these dependencies and Firefish on Debian 12. Note that there is much room for customizing the server setup; this document merely demonstrates a simple installation.
### Use Docker/Podman containers
If you want to use the pre-built container image, please refer to [`install-container.md`](./install-container.md).
Make sure that you can use the `sudo` command before proceeding.
## 1. Install dependencies
Make sure that you can use the `sudo` command before proceeding.
### Utilities
```sh
@ -213,7 +216,7 @@ sudo ufw status
### 2. Set up a reverse proxy
In this instruction, we use [Caddy](https://caddyserver.com/) to make the Firefish server accesible from internet. However, you can also use [Nginx](https://nginx.org/en/) if you want ([example Nginx config file](../firefish.nginx.conf)).
In this instruction, we use [Caddy](https://caddyserver.com/) to make the Firefish server accesible from internet. However, you can also use [Nginx](https://nginx.org/en/) if you want ([example Nginx config file](./firefish.nginx.conf)).
1. Install Caddy
```sh

View file

@ -446,7 +446,7 @@ tooShort: "قصير جدًا"
tooLong: "طويل جدًا"
weakPassword: "الكلمة السرية ضعيفة"
normalPassword: "الكلمة السرية جيدة"
strongPassword: "الكلمة السرية قوية"
veryStrongPassword: "الكلمة السرية قوية"
passwordMatched: "التطابق صحيح!"
passwordNotMatched: "غير متطابقتان"
signinWith: "الولوج عبر {x}"

View file

@ -586,7 +586,7 @@ unavailable: Не е свободно
tooShort: Твърде кратко
tooLong: Твърде дълго
weakPassword: Слаба парола
strongPassword: Силна парола
veryStrongPassword: Силна парола
passwordMatched: Съвпада
passwordNotMatched: Не съвпада
signinWith: Вход с {x}

View file

@ -462,7 +462,7 @@ tooShort: "খুব ছোট"
tooLong: "খুব বড়"
weakPassword: "দুর্বল পাসওয়ার্ড"
normalPassword: "সাধারণ পাসওয়ার্ড"
strongPassword: "শক্তিশালী পাসওয়ার্ড"
veryStrongPassword: "শক্তিশালী পাসওয়ার্ড"
passwordMatched: "মিলেছে"
passwordNotMatched: "মিলেনি"
signinWith: "{x} এর সাহায্যে সাইন ইন করুন"

View file

@ -1091,7 +1091,7 @@ usernameInvalidFormat: Pots fer servir lletres en majúscules o minúscules, nom
tooShort: Massa curt
tooLong: Massa llarg
weakPassword: Contrasenya amb seguretat feble
strongPassword: Contrasenya amb seguretat forta
veryStrongPassword: Contrasenya amb seguretat forta
passwordMatched: Coincidències
signinWith: Inicia sessió com {x}
signinFailed: No es pot iniciar sessió. El nom d'usuari o la contrasenya són incorrectes.

View file

@ -401,7 +401,7 @@ tooShort: "Příliš krátké"
tooLong: "Příliš dlouhé"
weakPassword: "Slabé heslo"
normalPassword: "Dobré heslo"
strongPassword: "Silné heslo"
veryStrongPassword: "Silné heslo"
passwordMatched: "Hesla se schodují"
passwordNotMatched: "Hesla se neschodují"
signinWith: "Přihlásit se s {x}"

View file

@ -480,7 +480,7 @@ tooShort: "Zu kurz"
tooLong: "Zu lang"
weakPassword: "Schwaches Passwort"
normalPassword: "Durchschnittliches Passwort"
strongPassword: "Starkes Passwort"
veryStrongPassword: "Starkes Passwort"
passwordMatched: "Stimmt überein"
passwordNotMatched: "Stimmt nicht überein"
signinWith: "Mit {x} anmelden"

View file

@ -677,7 +677,7 @@ checking: Έλεγχος...
invitationCode: Κωδικός πρόσκλησης
normalPassword: Μέτριος κωδικός
weakPassword: Αδύναμος κωδικός
strongPassword: Δυνατός κωδικός
veryStrongPassword: Δυνατός κωδικός
signinWith: Συνδεθείτε με {x}
tapSecurityKey: Βάλτε το κλειδί ασφάλειας
signinFailed: Αδυναμία σύνδεσης. Το όνομα μέλους ή ο κωδικός είναι λάθος.

View file

@ -515,8 +515,9 @@ usernameInvalidFormat: "You can use upper- and lowercase letters, numbers, and u
tooShort: "Too short"
tooLong: "Too long"
weakPassword: "Weak password"
normalPassword: "Average password"
strongPassword: "Strong password"
normalPassword: "Medium password"
strongPassword: "Good password"
veryStrongPassword: "Great password"
passwordMatched: "Matches"
passwordNotMatched: "Does not match"
signinWith: "Sign in with {x}"
@ -1239,6 +1240,7 @@ noAltTextWarning: "Some attached file(s) have no description. Did you forget to
showNoAltTextWarning: "Show a warning if you attempt to post files without a description"
showAddFileDescriptionAtFirstPost: "Automatically open a form to write a description
when you attempt to post files without a description"
addAlt4MeTag: "Automatically append #Alt4Me hashtag to your post if attached file has no description"
_emojiModPerm:
unauthorized: "None"

View file

@ -465,7 +465,7 @@ tooShort: "Demasiado corto"
tooLong: "Demasiado largo"
weakPassword: "Contraseña débil"
normalPassword: "Buena contraseña"
strongPassword: "Muy buena contraseña"
veryStrongPassword: "Muy buena contraseña"
passwordMatched: "Correcto"
passwordNotMatched: "Las contraseñas no son las mismas"
signinWith: "Inicie sesión con {x}"

View file

@ -569,7 +569,7 @@ tooShort: Liian lyhyt
tooLong: Liian pitkä
weakPassword: Heikko salasana
normalPassword: Kohtalainen salasana
strongPassword: Vahva salasana
veryStrongPassword: Vahva salasana
passwordMatched: Vastaa
signinWith: Kirjaudu sisään {x}
signinFailed: Ei voitu kirjautua sisään. Annettu käyttäjänimi tai salasana virheellinen.

View file

@ -468,7 +468,7 @@ tooShort: "Trop court"
tooLong: "Trop long"
weakPassword: "Mot de passe faible"
normalPassword: "Mot de passe acceptable"
strongPassword: "Mot de passe fort"
veryStrongPassword: "Mot de passe fort"
passwordMatched: "Les mots de passe correspondent"
passwordNotMatched: "Les mots de passe ne correspondent pas"
signinWith: "Se connecter avec {x}"

View file

@ -464,7 +464,7 @@ tooShort: "Terlalu pendek"
tooLong: "Terlalu panjang"
weakPassword: "Kata sandi lemah"
normalPassword: "Kata sandi baik"
strongPassword: "Kata sandi kuat"
veryStrongPassword: "Kata sandi kuat"
passwordMatched: "Kata sandi sama"
passwordNotMatched: "Kata sandi tidak sama"
signinWith: "Masuk dengan {x}"

View file

@ -454,7 +454,7 @@ tooShort: "Troppo breve"
tooLong: "Troppo lungo"
weakPassword: "Password debole"
normalPassword: "Password buona"
strongPassword: "Password forte"
veryStrongPassword: "Password forte"
passwordMatched: "Corretta"
passwordNotMatched: "Le password non corrispondono"
signinWith: "Accedi con {x}"

View file

@ -466,7 +466,7 @@ tooShort: "短すぎます"
tooLong: "長すぎます"
weakPassword: "弱いパスワード"
normalPassword: "普通のパスワード"
strongPassword: "強いパスワード"
veryStrongPassword: "強いパスワード"
passwordMatched: "一致しました"
passwordNotMatched: "一致していません"
signinWith: "{x}でログイン"

View file

@ -435,7 +435,7 @@ tooShort: "短すぎやろ!"
tooLong: "長すぎやろ!"
weakPassword: "へぼいパスワード"
normalPassword: "普通のパスワード"
strongPassword: "ええ感じのパスワード"
veryStrongPassword: "ええ感じのパスワード"
passwordMatched: "よし!一致や!"
passwordNotMatched: "一致しとらんで?"
signinWith: "{x}でログイン"

View file

@ -442,7 +442,7 @@ tooShort: "너무 짧습니다"
tooLong: "너무 깁니다"
weakPassword: "약한 비밀번호"
normalPassword: "좋은 비밀번호"
strongPassword: "강한 비밀번호"
veryStrongPassword: "강한 비밀번호"
passwordMatched: "일치합니다"
passwordNotMatched: "일치하지 않습니다"
signinWith: "{x}로 로그인"

View file

@ -576,7 +576,7 @@ quoteAttached: Quote
noMessagesYet: Nog geen berichten
weakPassword: Zwak wachtwoord
normalPassword: Middelmatig wachtwoord
strongPassword: Sterk wachtwoord
veryStrongPassword: Sterk wachtwoord
onlyOneFileCanBeAttached: Je kan maar één bestand toevoegen aan je bericht
invitationCode: Uitnodigingscode
checking: Controleren...

View file

@ -571,7 +571,7 @@ youHaveNoGroups: Du har ingen grupper
noHistory: Ingen historikk er tilgjengelig
aboutX: Om {x}
signinHistory: Innloggings-historikk
strongPassword: Sterkt passord
veryStrongPassword: Sterkt passord
noFollowRequests: Du har ingen utestående følgeforespørsler
openImageInNewTab: Åpne bilder i ny fane
dashboard: Dashbord

View file

@ -454,7 +454,7 @@ tooShort: "Zbyt krótka"
tooLong: "Zbyt długa"
weakPassword: "Słabe hasło"
normalPassword: "Dobre hasło"
strongPassword: "Silne hasło"
veryStrongPassword: "Silne hasło"
passwordMatched: "Pasuje"
passwordNotMatched: "Hasła nie pasują do siebie"
signinWith: "Zaloguj się z {x}"

View file

@ -464,7 +464,7 @@ tooShort: "Prea scurt"
tooLong: "Prea lung"
weakPassword: "Parolă slabă"
normalPassword: "Parolă medie"
strongPassword: "Parolă puternică"
veryStrongPassword: "Parolă puternică"
passwordMatched: "Se potrivește!"
passwordNotMatched: "Nu se potrivește"
signinWith: "Autentifică-te cu {x}"

View file

@ -460,7 +460,7 @@ tooShort: "Слишком короткий"
tooLong: "Слишком длинный"
weakPassword: "Слабый пароль"
normalPassword: "Годный пароль"
strongPassword: "Надёжный пароль"
veryStrongPassword: "Надёжный пароль"
passwordMatched: "Совпали"
passwordNotMatched: "Не совпадают"
signinWith: "Использовать {x} для входа"

View file

@ -461,7 +461,7 @@ tooShort: "Príliš krátke"
tooLong: "Príliš dlhé"
weakPassword: "Slabé heslo"
normalPassword: "Dobré heslo"
strongPassword: "Silné heslo"
veryStrongPassword: "Silné heslo"
passwordMatched: "Heslá sú rovnaké"
passwordNotMatched: "Heslá nie sú rovnaké"
signinWith: "Prihlásiť sa použitím {x}"

View file

@ -381,7 +381,7 @@ noMessagesYet: Inga meddelande ännu
newMessageExists: Det finns inga nya meddelanden
weakPassword: Svagt lösenord
normalPassword: Dugligt lösenord
strongPassword: Starkt lösenord
veryStrongPassword: Starkt lösenord
passwordMatched: Matchar
passwordNotMatched: Matchar inte
signinWith: Logga in med {x}

View file

@ -452,7 +452,7 @@ tooShort: "สั้นเกินไปนะ"
tooLong: "ยาวเกินไปนะ"
weakPassword: "รหัสผ่าน แย่มาก"
normalPassword: "รหัสผ่านปกติ"
strongPassword: "รหัสผ่านรัดกุมมาก"
veryStrongPassword: "รหัสผ่านรัดกุมมาก"
passwordMatched: "ถูกต้อง!"
passwordNotMatched: "ไม่ถูกต้อง"
signinWith: "ลงชื่อเข้าใช้ด้วย {x}"

View file

@ -521,7 +521,7 @@ newMessageExists: Yeni mesaj yok
invitations: Davetler
invitationCode: Davet kodu
signinWith: '{x} ile giriş yap'
strongPassword: Güçlü şifre
veryStrongPassword: Güçlü şifre
passwordNotMatched: Uyuşmuyor
signinFailed: Giriş yapılamadı. Şifre ve ya kullanıcı adı yanlış.
tapSecurityKey: Güvenlik anahtarınıza dokunun

View file

@ -460,7 +460,7 @@ tooShort: "Занадто короткий"
tooLong: "Занадто довгий"
weakPassword: "Слабкий пароль"
normalPassword: "Достатній пароль"
strongPassword: "Міцний пароль"
veryStrongPassword: "Міцний пароль"
passwordMatched: "Все вірно"
passwordNotMatched: "Паролі не співпадають"
signinWith: "Увійти за допомогою {x}"

View file

@ -462,7 +462,7 @@ tooShort: "Quá ngắn"
tooLong: "Quá dài"
weakPassword: "Mật khẩu yếu"
normalPassword: "Mật khẩu tạm được"
strongPassword: "Mật khẩu mạnh"
veryStrongPassword: "Mật khẩu mạnh"
passwordMatched: "Trùng khớp"
passwordNotMatched: "Không trùng khớp"
signinWith: "Đăng nhập bằng {x}"

View file

@ -451,7 +451,7 @@ tooShort: "太短"
tooLong: "太长"
weakPassword: "密码强度:弱"
normalPassword: "密码强度:中等"
strongPassword: "密码强度:强"
veryStrongPassword: "密码强度:强"
passwordMatched: "密码一致"
passwordNotMatched: "密码不一致"
signinWith: "以 {x} 登录"

View file

@ -449,7 +449,7 @@ tooShort: "過短"
tooLong: "過長"
weakPassword: "密碼強度過弱"
normalPassword: "密碼強度普通"
strongPassword: "密碼強度高"
veryStrongPassword: "密碼強度高"
passwordMatched: "密碼一致"
passwordNotMatched: "密碼不一致"
signinWith: "以{x}登錄"

View file

@ -26,7 +26,7 @@ regenerate-entities:
.PHONY: update-index
update-index: index.js index.d.ts
index.js index.d.ts: $(SRC)
index.js index.d.ts: $(SRC) package.json
NODE_OPTIONS='--max_old_space_size=3072' pnpm run build:debug
[ -f built/index.js ] && [ -f built/index.d.ts ]
rm --force index.js index.d.ts

View file

@ -46,7 +46,7 @@ export const paramDef = {
type: "string",
enum: ["all", "renote", "quote"],
nullable: true,
default: null,
default: "all",
},
},
required: ["noteId"],

View file

@ -34,7 +34,7 @@
"@types/tinycolor2": "1.4.6",
"@types/uuid": "10.0.0",
"@vitejs/plugin-vue": "5.0.5",
"@vue/runtime-core": "3.4.30",
"@vue/runtime-core": "3.4.31",
"autobind-decorator": "2.4.0",
"autosize": "6.0.1",
"broadcast-channel": "7.0.0",
@ -43,6 +43,7 @@
"chartjs-chart-matrix": "2.0.1",
"chartjs-plugin-gradient": "0.6.1",
"chartjs-plugin-zoom": "2.0.1",
"check-password-strength": "2.0.10",
"city-timezones": "1.2.1",
"compare-versions": "6.1.0",
"cropperjs": "2.0.0-rc.0",
@ -76,7 +77,6 @@
"seedrandom": "3.0.5",
"stringz": "2.1.0",
"swiper": "11.1.4",
"syuilo-password-strength": "0.0.1",
"textarea-caret": "3.1.0",
"throttle-debounce": "5.0.2",
"tinycolor2": "1.6.0",
@ -86,7 +86,7 @@
"uuid": "10.0.0",
"vite": "5.3.2",
"vite-plugin-compression": "0.5.1",
"vue": "3.4.30",
"vue": "3.4.31",
"vue-draggable-plus": "0.5.0",
"vue-plyr": "7.0.0",
"vue-prism-editor": "2.0.0-alpha.2",

View file

@ -7,7 +7,7 @@ import { alert, api, popup, popupMenu, waiting } from "@/os";
import icon from "@/scripts/icon";
import { del, get, set } from "@/scripts/idb-proxy";
import { reloadChannel, unisonReload } from "@/scripts/unison-reload";
import type { MenuButton, MenuUser } from "./types/menu";
import type { MenuUser } from "./types/menu";
// TODO: 他のタブと永続化されたstateを同期

View file

@ -1195,6 +1195,13 @@ async function post() {
}
}
if (
defaultStore.state.addAlt4MeTag &&
files.value.some((f) => f.comment == null || f.comment.length === 0)
) {
text.value = `${text.value.trimEnd()}\n#Alt4Me`;
}
const processedText = preprocess(text.value);
let postData: ApiTypes.NoteSubmitReq = {

View file

@ -52,7 +52,8 @@ const canRenote = computed(
useTooltip(buttonRef, async (showing) => {
const renotes = await os.api("notes/renotes", {
noteId: props.note.id,
limit: 11,
limit: 10,
filter: "renote",
});
const users = renotes.map((x) => x.user);

View file

@ -179,23 +179,29 @@
<template #prefix><i :class="icon('ph-lock')"></i></template>
<template #caption>
<span
v-if="passwordStrength == 'low'"
v-if="passwordStrength === 'Weak'"
style="color: var(--error)"
><i :class="icon('ph-warning ph-fw')"></i>
><i :class="icon('ph-seal-warning ph-fw')"></i>
{{ i18n.ts.weakPassword }}</span
>
<span
v-if="passwordStrength == 'medium'"
v-if="passwordStrength === 'Medium'"
style="color: var(--warn)"
><i :class="icon('ph-check ph-fw')"></i>
><i :class="icon('ph-warning ph-fw')"></i>
{{ i18n.ts.normalPassword }}</span
>
<span
v-if="passwordStrength == 'high'"
v-if="passwordStrength === 'Good'"
style="color: var(--success)"
><i :class="icon('ph-check ph-fw')"></i>
{{ i18n.ts.strongPassword }}</span
>
<span
v-if="passwordStrength === 'Great'"
style="color: var(--success)"
><i :class="icon('ph-checks ph-fw')"></i>
{{ i18n.ts.veryStrongPassword }}</span
>
</template>
</MkInput>
<MkInput
@ -273,7 +279,7 @@
<script lang="ts" setup>
import { computed, ref } from "vue";
import getPasswordStrength from "syuilo-password-strength";
import { passwordStrength as checkPasswordStrength } from "check-password-strength";
import { toUnicode } from "punycode/";
import MkButton from "./MkButton.vue";
import MkInput from "./form/input.vue";
@ -333,7 +339,7 @@ const emailState = ref<
| "unavailable"
| "error"
>(null);
const passwordStrength = ref<"" | "low" | "medium" | "high">("");
const passwordStrength = ref<"" | "Weak" | "Medium" | "Good" | "Great">("");
const passwordRetypeState = ref<null | "match" | "not-match">(null);
const submitting = ref(false);
const ToSAgreement = ref(false);
@ -423,15 +429,42 @@ function onChangeEmail(): void {
});
}
const passwordStrengthOptions = [
{
id: 0,
value: "Weak",
minDiversity: 0,
minLength: 0,
},
{
id: 1,
value: "Medium",
minDiversity: 2,
minLength: 8,
},
{
id: 2,
value: "Good",
minDiversity: 3,
minLength: 16,
},
{
id: 3,
value: "Great",
minDiversity: 4,
minLength: 32,
},
];
function onChangePassword(): void {
if (password.value === "") {
passwordStrength.value = "";
return;
}
const strength = getPasswordStrength(password.value);
passwordStrength.value =
strength > 0.7 ? "high" : strength > 0.3 ? "medium" : "low";
passwordStrength.value = checkPasswordStrength(
password.value,
passwordStrengthOptions,
).value;
}
function onChangePasswordRetype(): void {

View file

@ -127,12 +127,6 @@
<FormSwitch v-model="openServerInfo" class="_formBlock">{{
i18n.ts.openServerInfo
}}</FormSwitch>
<FormSwitch v-model="showNoAltTextWarning" class="_formBlock">{{
i18n.ts.showNoAltTextWarning
}}</FormSwitch>
<FormSwitch v-model="showAddFileDescriptionAtFirstPost" class="_formBlock">{{
i18n.ts.showAddFileDescriptionAtFirstPost
}}</FormSwitch>
<FormSwitch v-model="autocorrectNoteLanguage" class="_formBlock">{{
i18n.ts.autocorrectNoteLanguage
}}</FormSwitch>
@ -191,6 +185,15 @@
<FormSection>
<template #label>{{ i18n.ts.accessibility }}</template>
<FormSwitch v-model="showNoAltTextWarning" class="_formBlock">{{
i18n.ts.showNoAltTextWarning
}}</FormSwitch>
<FormSwitch v-if="showNoAltTextWarning" v-model="showAddFileDescriptionAtFirstPost" class="_formBlock">{{
i18n.ts.showAddFileDescriptionAtFirstPost
}}</FormSwitch>
<FormSwitch v-model="addAlt4MeTag" class="_formBlock">{{
i18n.ts.addAlt4MeTag
}}</FormSwitch>
<FormSwitch v-model="expandOnNoteClick" class="_formBlock"
>{{ i18n.ts.expandOnNoteClick
}}<template #caption>{{
@ -568,6 +571,7 @@ const mergeThreadInTimeline = computed(
const mergeRenotesInTimeline = computed(
defaultStore.makeGetterSetter("mergeRenotesInTimeline"),
);
const addAlt4MeTag = computed(defaultStore.makeGetterSetter("addAlt4MeTag"));
// This feature (along with injectPromo) is currently disabled
// function onChangeInjectFeaturedNote(v) {

View file

@ -127,6 +127,10 @@ const defaultStoreSaveKeys: (keyof (typeof defaultStore)["state"])[] = [
"showNoAltTextWarning",
"showAddFileDescriptionAtFirstPost",
"autocorrectNoteLanguage",
"addAlt4MeTag",
"addRe",
"mergeRenotesInTimeline",
"mergeThreadInTimeline",
];
const coldDeviceStorageSaveKeys: (keyof typeof ColdDeviceStorage.default)[] = [
"lightTheme",

View file

@ -449,6 +449,10 @@ export const defaultStore = markRaw(
where: "account",
default: false,
},
addAlt4MeTag: {
where: "account",
default: false,
},
autocorrectNoteLanguage: {
where: "account",
default: true,

View file

@ -1,3 +0,0 @@
{
"version": "unknown"
}

View file

@ -579,10 +579,10 @@ importers:
version: 10.0.0
'@vitejs/plugin-vue':
specifier: 5.0.5
version: 5.0.5(vite@5.3.2(@types/node@20.14.9)(sass@1.77.6)(stylus@0.57.0)(terser@5.31.0))(vue@3.4.30(typescript@5.5.2))
version: 5.0.5(vite@5.3.2(@types/node@20.14.9)(sass@1.77.6)(stylus@0.57.0)(terser@5.31.0))(vue@3.4.31(typescript@5.5.2))
'@vue/runtime-core':
specifier: 3.4.30
version: 3.4.30
specifier: 3.4.31
version: 3.4.31
autobind-decorator:
specifier: 2.4.0
version: 2.4.0
@ -607,6 +607,9 @@ importers:
chartjs-plugin-zoom:
specifier: 2.0.1
version: 2.0.1(chart.js@4.4.3)
check-password-strength:
specifier: 2.0.10
version: 2.0.10
city-timezones:
specifier: 1.2.1
version: 1.2.1
@ -639,7 +642,7 @@ importers:
version: 7.5.4
focus-trap-vue:
specifier: 4.0.3
version: 4.0.3(focus-trap@7.5.4)(vue@3.4.30(typescript@5.5.2))
version: 4.0.3(focus-trap@7.5.4)(vue@3.4.31(typescript@5.5.2))
gsap:
specifier: 3.12.5
version: 3.12.5
@ -706,9 +709,6 @@ importers:
swiper:
specifier: 11.1.4
version: 11.1.4
syuilo-password-strength:
specifier: 0.0.1
version: 0.0.1
textarea-caret:
specifier: 3.1.0
version: 3.1.0
@ -737,8 +737,8 @@ importers:
specifier: 0.5.1
version: 0.5.1(vite@5.3.2(@types/node@20.14.9)(sass@1.77.6)(stylus@0.57.0)(terser@5.31.0))
vue:
specifier: 3.4.30
version: 3.4.30(typescript@5.5.2)
specifier: 3.4.31
version: 3.4.31(typescript@5.5.2)
vue-draggable-plus:
specifier: 0.5.0
version: 0.5.0(@types/sortablejs@1.15.8)
@ -747,7 +747,7 @@ importers:
version: 7.0.0
vue-prism-editor:
specifier: 2.0.0-alpha.2
version: 2.0.0-alpha.2(vue@3.4.30(typescript@5.5.2))
version: 2.0.0-alpha.2(vue@3.4.31(typescript@5.5.2))
vue-tsc:
specifier: 2.0.22
version: 2.0.22(typescript@5.5.2)
@ -2914,26 +2914,26 @@ packages:
'@volar/typescript@2.3.1':
resolution: {integrity: sha512-OrUV6dYt/1h92+aWElexra6dp++gF/IEddvwyxeobyYfKAoKDUMsWU0iJCj0clZlfdyYaLmNEAkulJlVimxnOw==}
'@vue/compiler-core@3.4.29':
resolution: {integrity: sha512-TFKiRkKKsRCKvg/jTSSKK7mYLJEQdUiUfykbG49rubC9SfDyvT2JrzTReopWlz2MxqeLyxh9UZhvxEIBgAhtrg==}
'@vue/compiler-core@3.4.30':
resolution: {integrity: sha512-ZL8y4Xxdh8O6PSwfdZ1IpQ24PjTAieOz3jXb/MDTfDtANcKBMxg1KLm6OX2jofsaQGYfIVzd3BAG22i56/cF1w==}
'@vue/compiler-dom@3.4.29':
resolution: {integrity: sha512-A6+iZ2fKIEGnfPJejdB7b1FlJzgiD+Y/sxxKwJWg1EbJu6ZPgzaPQQ51ESGNv0CP6jm6Z7/pO6Ia8Ze6IKrX7w==}
'@vue/compiler-core@3.4.31':
resolution: {integrity: sha512-skOiodXWTV3DxfDhB4rOf3OGalpITLlgCeOwb+Y9GJpfQ8ErigdBUHomBzvG78JoVE8MJoQsb+qhZiHfKeNeEg==}
'@vue/compiler-dom@3.4.30':
resolution: {integrity: sha512-+16Sd8lYr5j/owCbr9dowcNfrHd+pz+w2/b5Lt26Oz/kB90C9yNbxQ3bYOvt7rI2bxk0nqda39hVcwDFw85c2Q==}
'@vue/compiler-dom@3.4.31':
resolution: {integrity: sha512-wK424WMXsG1IGMyDGyLqB+TbmEBFM78hIsOJ9QwUVLGrcSk0ak6zYty7Pj8ftm7nEtdU/DGQxAXp0/lM/2cEpQ==}
'@vue/compiler-sfc@2.7.16':
resolution: {integrity: sha512-KWhJ9k5nXuNtygPU7+t1rX6baZeqOYLEforUPjgNDBnLicfHCoi48H87Q8XyLZOrNNsmhuwKqtpDQWjEFe6Ekg==}
'@vue/compiler-sfc@3.4.30':
resolution: {integrity: sha512-8vElKklHn/UY8+FgUFlQrYAPbtiSB2zcgeRKW7HkpSRn/JjMRmZvuOtwDx036D1aqKNSTtXkWRfqx53Qb+HmMg==}
'@vue/compiler-sfc@3.4.31':
resolution: {integrity: sha512-einJxqEw8IIJxzmnxmJBuK2usI+lJonl53foq+9etB2HAzlPjAS/wa7r0uUpXw5ByX3/0uswVSrjNb17vJm1kQ==}
'@vue/compiler-ssr@3.4.30':
resolution: {integrity: sha512-ZJ56YZGXJDd6jky4mmM0rNaNP6kIbQu9LTKZDhcpddGe/3QIalB1WHHmZ6iZfFNyj5mSypTa4+qDJa5VIuxMSg==}
'@vue/compiler-ssr@3.4.31':
resolution: {integrity: sha512-RtefmITAje3fJ8FSg1gwgDhdKhZVntIVbwupdyZDSifZTRMiWxWehAOTCc8/KZDnBOcYQ4/9VWxsTbd3wT0hAA==}
'@vue/language-core@2.0.22':
resolution: {integrity: sha512-dNTAAtEOuMiz7N1s5tKpypnVVCtawxVSF5BukD0ELcYSw+DSbrSlYYSw8GuwvurodCeYFSHsmslE+c2sYDNoiA==}
@ -2943,26 +2943,26 @@ packages:
typescript:
optional: true
'@vue/reactivity@3.4.30':
resolution: {integrity: sha512-bVJurnCe3LS0JII8PPoAA63Zd2MBzcKrEzwdQl92eHCcxtIbxD2fhNwJpa+KkM3Y/A4T5FUnmdhgKwOf6BfbcA==}
'@vue/reactivity@3.4.31':
resolution: {integrity: sha512-VGkTani8SOoVkZNds1PfJ/T1SlAIOf8E58PGAhIOUDYPC4GAmFA2u/E14TDAFcf3vVDKunc4QqCe/SHr8xC65Q==}
'@vue/runtime-core@3.4.30':
resolution: {integrity: sha512-qaFEbnNpGz+tlnkaualomogzN8vBLkgzK55uuWjYXbYn039eOBZrWxyXWq/7qh9Bz2FPifZqGjVDl/FXiq9L2g==}
'@vue/runtime-core@3.4.31':
resolution: {integrity: sha512-LDkztxeUPazxG/p8c5JDDKPfkCDBkkiNLVNf7XZIUnJ+66GVGkP+TIh34+8LtPisZ+HMWl2zqhIw0xN5MwU1cw==}
'@vue/runtime-dom@3.4.30':
resolution: {integrity: sha512-tV6B4YiZRj5QsaJgw2THCy5C1H+2UeywO9tqgWEc21tn85qHEERndHN/CxlyXvSBFrpmlexCIdnqPuR9RM9thw==}
'@vue/runtime-dom@3.4.31':
resolution: {integrity: sha512-2Auws3mB7+lHhTFCg8E9ZWopA6Q6L455EcU7bzcQ4x6Dn4cCPuqj6S2oBZgN2a8vJRS/LSYYxwFFq2Hlx3Fsaw==}
'@vue/server-renderer@3.4.30':
resolution: {integrity: sha512-TBD3eqR1DeDc0cMrXS/vEs/PWzq1uXxnvjoqQuDGFIEHFIwuDTX/KWAQKIBjyMWLFHEeTDGYVsYci85z2UbTDg==}
'@vue/server-renderer@3.4.31':
resolution: {integrity: sha512-D5BLbdvrlR9PE3by9GaUp1gQXlCNadIZytMIb8H2h3FMWJd4oUfkUTEH2wAr3qxoRz25uxbTcbqd3WKlm9EHQA==}
peerDependencies:
vue: 3.4.30
'@vue/shared@3.4.29':
resolution: {integrity: sha512-hQ2gAQcBO/CDpC82DCrinJNgOHI2v+FA7BDW4lMSPeBpQ7sRe2OLHWe5cph1s7D8DUQAwRt18dBDfJJ220APEA==}
vue: 3.4.31
'@vue/shared@3.4.30':
resolution: {integrity: sha512-CLg+f8RQCHQnKvuHY9adMsMaQOcqclh6Z5V9TaoMgy0ut0tz848joZ7/CYFFyF/yZ5i2yaw7Fn498C+CNZVHIg==}
'@vue/shared@3.4.31':
resolution: {integrity: sha512-Yp3wtJk//8cO4NItOPpi3QkLExAr/aLBGZMmTtW9WpdwBCJpRM6zj9WgWktXAl8IDIozwNMByT45JP3tO3ACWA==}
'@webassemblyjs/ast@1.12.1':
resolution: {integrity: sha512-EKfMUOPRRUTy5UII4qJDGPpqfwjOmZ5jeGFwid9mnoqIFK+e0vqoi1qH56JpmZSzEL53jKnNzScdmftJyG5xWg==}
@ -3487,6 +3487,9 @@ packages:
peerDependencies:
chart.js: '>=3.2.0'
check-password-strength@2.0.10:
resolution: {integrity: sha512-HRM5ICPmtnNtLnTv2QrfVkq1IxI9z3bzYpDJ1k5ixwD9HtJGHuv265R6JmHOV6r8wLhQMlULnIUVpkrC2yaiCw==}
cheerio@0.22.0:
resolution: {integrity: sha512-8/MzidM6G/TgRelkzDG13y3Y9LxBjCb+8yOEZ9+wwq5gVF2w2pV0wmHvjfT0RvuxGyR7UEuK36r+yYMbT4uKgA==}
engines: {node: '>= 0.6'}
@ -7265,9 +7268,6 @@ packages:
resolution: {integrity: sha512-7SNMJKtQBJlwBUp1jxFT7bXya71cnINXPCYJ2AVhlQE4MKL7o2QiPdAXbMdWRiLeykQ2rx+7TNrnoGzvzhO+eA==}
engines: {node: '>=10.0.0'}
syuilo-password-strength@0.0.1:
resolution: {integrity: sha512-g9rPT3V1Q4WjWFZ/t5BdGC1mT/FpYnsLdBl+M5e6MlRkuE1RSR+R43wcY/3mKI59B9KEr+vxdWCuWNMD3oNHKA==}
tabbable@6.2.0:
resolution: {integrity: sha512-Cat63mxsVJlzYvN51JmVXIgNoUokrIaT2zLclCXjRd8boZ0004U4KCs/sToJ75C6sdlByWxpYnb5Boif1VSFew==}
@ -7802,8 +7802,8 @@ packages:
resolution: {integrity: sha512-4gCtFXaAA3zYZdTp5s4Hl2sozuySsgz4jy1EnpBHNfpMa9dK1ZCG7viqBPCwXtmgc8nHqUsAu3G4gtmXkkY3Sw==}
deprecated: Vue 2 has reached EOL and is no longer actively maintained. See https://v2.vuejs.org/eol/ for more details.
vue@3.4.30:
resolution: {integrity: sha512-NcxtKCwkdf1zPsr7Y8+QlDBCGqxvjLXF2EX+yi76rV5rrz90Y6gK1cq0olIhdWGgrlhs9ElHuhi9t3+W5sG5Xw==}
vue@3.4.31:
resolution: {integrity: sha512-njqRrOy7W3YLAlVqSKpBebtZpDVg21FPoaq1I7f/+qqBThK9ChAIjkRWgeP6Eat+8C+iia4P3OYqpATP21BCoQ==}
peerDependencies:
typescript: '*'
peerDependenciesMeta:
@ -10236,10 +10236,10 @@ snapshots:
'@typescript-eslint/types': 6.21.0
eslint-visitor-keys: 3.4.3
'@vitejs/plugin-vue@5.0.5(vite@5.3.2(@types/node@20.14.9)(sass@1.77.6)(stylus@0.57.0)(terser@5.31.0))(vue@3.4.30(typescript@5.5.2))':
'@vitejs/plugin-vue@5.0.5(vite@5.3.2(@types/node@20.14.9)(sass@1.77.6)(stylus@0.57.0)(terser@5.31.0))(vue@3.4.31(typescript@5.5.2))':
dependencies:
vite: 5.3.2(@types/node@20.14.9)(sass@1.77.6)(stylus@0.57.0)(terser@5.31.0)
vue: 3.4.30(typescript@5.5.2)
vue: 3.4.31(typescript@5.5.2)
'@volar/language-core@2.3.1':
dependencies:
@ -10253,14 +10253,6 @@ snapshots:
path-browserify: 1.0.1
vscode-uri: 3.0.8
'@vue/compiler-core@3.4.29':
dependencies:
'@babel/parser': 7.24.7
'@vue/shared': 3.4.29
entities: 4.5.0
estree-walker: 2.0.2
source-map-js: 1.2.0
'@vue/compiler-core@3.4.30':
dependencies:
'@babel/parser': 7.24.7
@ -10269,16 +10261,24 @@ snapshots:
estree-walker: 2.0.2
source-map-js: 1.2.0
'@vue/compiler-dom@3.4.29':
'@vue/compiler-core@3.4.31':
dependencies:
'@vue/compiler-core': 3.4.29
'@vue/shared': 3.4.29
'@babel/parser': 7.24.7
'@vue/shared': 3.4.31
entities: 4.5.0
estree-walker: 2.0.2
source-map-js: 1.2.0
'@vue/compiler-dom@3.4.30':
dependencies:
'@vue/compiler-core': 3.4.30
'@vue/shared': 3.4.30
'@vue/compiler-dom@3.4.31':
dependencies:
'@vue/compiler-core': 3.4.31
'@vue/shared': 3.4.31
'@vue/compiler-sfc@2.7.16':
dependencies:
'@babel/parser': 7.24.6
@ -10287,28 +10287,28 @@ snapshots:
optionalDependencies:
prettier: 2.8.8
'@vue/compiler-sfc@3.4.30':
'@vue/compiler-sfc@3.4.31':
dependencies:
'@babel/parser': 7.24.7
'@vue/compiler-core': 3.4.30
'@vue/compiler-dom': 3.4.30
'@vue/compiler-ssr': 3.4.30
'@vue/shared': 3.4.30
'@vue/compiler-core': 3.4.31
'@vue/compiler-dom': 3.4.31
'@vue/compiler-ssr': 3.4.31
'@vue/shared': 3.4.31
estree-walker: 2.0.2
magic-string: 0.30.10
postcss: 8.4.38
source-map-js: 1.2.0
'@vue/compiler-ssr@3.4.30':
'@vue/compiler-ssr@3.4.31':
dependencies:
'@vue/compiler-dom': 3.4.30
'@vue/shared': 3.4.30
'@vue/compiler-dom': 3.4.31
'@vue/shared': 3.4.31
'@vue/language-core@2.0.22(typescript@5.5.2)':
dependencies:
'@volar/language-core': 2.3.1
'@vue/compiler-dom': 3.4.29
'@vue/shared': 3.4.29
'@vue/compiler-dom': 3.4.30
'@vue/shared': 3.4.30
computeds: 0.0.1
minimatch: 9.0.4
muggle-string: 0.4.1
@ -10317,32 +10317,32 @@ snapshots:
optionalDependencies:
typescript: 5.5.2
'@vue/reactivity@3.4.30':
'@vue/reactivity@3.4.31':
dependencies:
'@vue/shared': 3.4.30
'@vue/shared': 3.4.31
'@vue/runtime-core@3.4.30':
'@vue/runtime-core@3.4.31':
dependencies:
'@vue/reactivity': 3.4.30
'@vue/shared': 3.4.30
'@vue/reactivity': 3.4.31
'@vue/shared': 3.4.31
'@vue/runtime-dom@3.4.30':
'@vue/runtime-dom@3.4.31':
dependencies:
'@vue/reactivity': 3.4.30
'@vue/runtime-core': 3.4.30
'@vue/shared': 3.4.30
'@vue/reactivity': 3.4.31
'@vue/runtime-core': 3.4.31
'@vue/shared': 3.4.31
csstype: 3.1.3
'@vue/server-renderer@3.4.30(vue@3.4.30(typescript@5.5.2))':
'@vue/server-renderer@3.4.31(vue@3.4.31(typescript@5.5.2))':
dependencies:
'@vue/compiler-ssr': 3.4.30
'@vue/shared': 3.4.30
vue: 3.4.30(typescript@5.5.2)
'@vue/shared@3.4.29': {}
'@vue/compiler-ssr': 3.4.31
'@vue/shared': 3.4.31
vue: 3.4.31(typescript@5.5.2)
'@vue/shared@3.4.30': {}
'@vue/shared@3.4.31': {}
'@webassemblyjs/ast@1.12.1':
dependencies:
'@webassemblyjs/helper-numbers': 1.11.6
@ -10962,6 +10962,8 @@ snapshots:
chart.js: 4.4.3
hammerjs: 2.0.8
check-password-strength@2.0.10: {}
cheerio@0.22.0:
dependencies:
css-select: 1.2.0
@ -12286,10 +12288,10 @@ snapshots:
async: 0.2.10
which: 1.3.1
focus-trap-vue@4.0.3(focus-trap@7.5.4)(vue@3.4.30(typescript@5.5.2)):
focus-trap-vue@4.0.3(focus-trap@7.5.4)(vue@3.4.31(typescript@5.5.2)):
dependencies:
focus-trap: 7.5.4
vue: 3.4.30(typescript@5.5.2)
vue: 3.4.31(typescript@5.5.2)
focus-trap@7.5.4:
dependencies:
@ -15218,8 +15220,6 @@ snapshots:
dependencies:
moment: 2.30.1
syuilo-password-strength@0.0.1: {}
tabbable@6.2.0: {}
tapable@2.2.1: {}
@ -15702,9 +15702,9 @@ snapshots:
plyr: https://codeload.github.com/sampotts/plyr/tar.gz/d434c9af16e641400aaee93188594208d88f2658
vue: 2.7.16
vue-prism-editor@2.0.0-alpha.2(vue@3.4.30(typescript@5.5.2)):
vue-prism-editor@2.0.0-alpha.2(vue@3.4.31(typescript@5.5.2)):
dependencies:
vue: 3.4.30(typescript@5.5.2)
vue: 3.4.31(typescript@5.5.2)
vue-template-compiler@2.7.16:
dependencies:
@ -15723,13 +15723,13 @@ snapshots:
'@vue/compiler-sfc': 2.7.16
csstype: 3.1.3
vue@3.4.30(typescript@5.5.2):
vue@3.4.31(typescript@5.5.2):
dependencies:
'@vue/compiler-dom': 3.4.30
'@vue/compiler-sfc': 3.4.30
'@vue/runtime-dom': 3.4.30
'@vue/server-renderer': 3.4.30(vue@3.4.30(typescript@5.5.2))
'@vue/shared': 3.4.30
'@vue/compiler-dom': 3.4.31
'@vue/compiler-sfc': 3.4.31
'@vue/runtime-dom': 3.4.31
'@vue/server-renderer': 3.4.31(vue@3.4.31(typescript@5.5.2))
'@vue/shared': 3.4.31
optionalDependencies:
typescript: 5.5.2

View file

@ -1,5 +0,0 @@
{
"version": "1.0.0",
"notes": "Welcome to Firefish!",
"screenshots": []
}

View file

@ -29,7 +29,6 @@
{"matchManagers": ["npm"], "matchPackageNames": ["mfm-js"], "automerge": false},
{"matchManagers": ["npm"], "matchPackageNames": ["rndstr"], "automerge": false},
{"matchManagers": ["npm"], "matchPackageNames": ["summaly"], "automerge": false},
{"matchManagers": ["npm"], "matchPackageNames": ["syuilo-password-strength"], "automerge": false},
{"matchManagers": ["npm"], "matchPackageNames": ["xev"], "automerge": false}
]
}