Compare commits

...

11 Commits

Author SHA1 Message Date
かっこかり 2be71a034a
Merge daaea1cc34 into d522d1bf26 2025-05-04 21:30:14 +09:00
Sayamame-beans d522d1bf26
docs(changelog): add information for #15924 (#15947) 2025-05-04 20:59:24 +09:00
かっこかり daaea1cc34
Merge branch 'develop' into fix-instance-ticker-stroke 2025-05-04 20:16:12 +09:00
github-actions[bot] 080276e3e7 Bump version to 2025.5.0-alpha.1 2025-05-04 10:07:59 +00:00
syuilo 619bb2214e
New Crowdin updates (#15935)
* New translations ja-jp.yml (Chinese Traditional)

* New translations ja-jp.yml (Catalan)

* New translations ja-jp.yml (Chinese Traditional)

* New translations ja-jp.yml (English)
2025-05-04 19:00:56 +09:00
renovate[bot] c23f2ff900
chore(deps): update node.js to v22.15.0 (#15606)
* chore(deps): update node.js to v22.15.0

* chore: determine Jest args from Node.js version

* fix

* fix: `import.meta.dirname` is not supported in v20.10.0

---------

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: zyoshoka <107108195+zyoshoka@users.noreply.github.com>
2025-05-04 19:00:36 +09:00
syuilo 14d6734cb1
Fix MkPullToRefresh behaviour (#15944)
* Update MkPullToRefresh.vue

* Update MkPullToRefresh.vue

* Update MkPullToRefresh.vue
2025-05-04 18:51:30 +09:00
syuilo 3bdb1dd558 🎨 2025-05-04 17:32:09 +09:00
かっこかり e75d749784
fix(frontend): ダイアログのお知らせが画面からはみ出ることがある問題を修正 (#15878)
* fix(frontend): ダイアログのお知らせが画面からはみ出ることがある問題を修正

* Update Changelog

* 🎨

* 🎨

* enhance: スクロールしないと閉じられないように

* Update CHANGELOG.md
2025-05-04 15:50:05 +09:00
kakkokari-gtyih 675becdea2 refactor 2025-05-04 14:19:14 +09:00
kakkokari-gtyih 18c7ac84e1 fix(frontend): Instance Tickerの文字ストロークをSVG描画で復活させる 2025-05-04 14:15:17 +09:00
19 changed files with 174 additions and 40 deletions

View File

@ -5,7 +5,7 @@
"workspaceFolder": "/workspace", "workspaceFolder": "/workspace",
"features": { "features": {
"ghcr.io/devcontainers/features/node:1": { "ghcr.io/devcontainers/features/node:1": {
"version": "22.11.0" "version": "22.15.0"
}, },
"ghcr.io/devcontainers-extra/features/pnpm:2": { "ghcr.io/devcontainers-extra/features/pnpm:2": {
"version": "10.10.0" "version": "10.10.0"

View File

@ -1 +1 @@
22.11.0 22.15.0

View File

@ -1,5 +1,8 @@
## 2025.5.0 ## 2025.5.0
### Note
- DockerのNode.jsが22.15.0に更新されました
### General ### General
- -
@ -8,6 +11,7 @@
- アクセシビリティ設定からオフにすることもできます - アクセシビリティ設定からオフにすることもできます
- Enhance: タイムラインのパフォーマンスを向上 - Enhance: タイムラインのパフォーマンスを向上
- Fix: 一部のブラウザでアコーディオンメニューのアニメーションが動作しない問題を修正 - Fix: 一部のブラウザでアコーディオンメニューのアニメーションが動作しない問題を修正
- Fix: ダイアログのお知らせが画面からはみ出ることがある問題を修正
### Server ### Server
- Enhance: 凍結されたユーザのノートが各種タイムラインで表示されないように `#15775` - Enhance: 凍結されたユーザのノートが各種タイムラインで表示されないように `#15775`
@ -20,6 +24,8 @@
- Fix: チャンネルのフォロー一覧の結果が一部正しくないのを修正 (#12175) - Fix: チャンネルのフォロー一覧の結果が一部正しくないのを修正 (#12175)
- Fix: ファイルをアップロードした際にファイル名が常に untitled になる問題を修正 - Fix: ファイルをアップロードした際にファイル名が常に untitled になる問題を修正
- Fix: ファイルのアップロードに失敗することがある問題を修正 - Fix: ファイルのアップロードに失敗することがある問題を修正
- 投稿フォーム上で画像のクロップを行うと、`Invalid Param.`エラーでノートが投稿出来なくなる問題も解決されます。
- この事象によって既にノートが投稿出来ない状態になっている場合は、投稿フォーム右上のメニューから、下書きデータの「リセット」を行ってください。
## 2025.4.1 ## 2025.4.1

View File

@ -1,6 +1,6 @@
# syntax = docker/dockerfile:1.4 # syntax = docker/dockerfile:1.4
ARG NODE_VERSION=22.11.0-bookworm ARG NODE_VERSION=22.15.0-bookworm
# build assets & compile TypeScript # build assets & compile TypeScript

View File

@ -1425,6 +1425,7 @@ _settings:
ifOff: "Quan es desactiva" ifOff: "Quan es desactiva"
enableSyncThemesBetweenDevices: "Sincronitzar els temes instal·lats entre dispositius" enableSyncThemesBetweenDevices: "Sincronitzar els temes instal·lats entre dispositius"
enablePullToRefresh: "Lliscar i actualitzar " enablePullToRefresh: "Lliscar i actualitzar "
enablePullToRefresh_description: "Amb el ratolí, llisca mentre prems la roda."
_chat: _chat:
showSenderName: "Mostrar el nom del remitent" showSenderName: "Mostrar el nom del remitent"
sendOnEnter: "Introdueix per enviar" sendOnEnter: "Introdueix per enviar"

View File

@ -1348,6 +1348,7 @@ readonly: "Read only"
goToDeck: "Return to Deck" goToDeck: "Return to Deck"
federationJobs: "Federation Jobs" federationJobs: "Federation Jobs"
driveAboutTip: "In Drive, a list of files you've uploaded in the past will be displayed. <br> \nYou can reuse these files when attaching them to notes, or you can upload files in advance to post later. <br> \n<b>Be careful when deleting a file, as it will not be available in all places where it was used (such as notes, pages, avatars, banners, etc.).</b> <br> \nYou can also create folders to organize your files." driveAboutTip: "In Drive, a list of files you've uploaded in the past will be displayed. <br> \nYou can reuse these files when attaching them to notes, or you can upload files in advance to post later. <br> \n<b>Be careful when deleting a file, as it will not be available in all places where it was used (such as notes, pages, avatars, banners, etc.).</b> <br> \nYou can also create folders to organize your files."
scrollToClose: "Scroll to close"
_chat: _chat:
noMessagesYet: "No messages yet" noMessagesYet: "No messages yet"
newMessage: "New message" newMessage: "New message"
@ -1425,6 +1426,7 @@ _settings:
ifOff: "When turned off" ifOff: "When turned off"
enableSyncThemesBetweenDevices: "Synchronize installed themes across devices" enableSyncThemesBetweenDevices: "Synchronize installed themes across devices"
enablePullToRefresh: "Pull to Refresh" enablePullToRefresh: "Pull to Refresh"
enablePullToRefresh_description: "When using a mouse, drag while pressing in the scrolling wheel."
_chat: _chat:
showSenderName: "Show sender's name" showSenderName: "Show sender's name"
sendOnEnter: "Press Enter to send" sendOnEnter: "Press Enter to send"

4
locales/index.d.ts vendored
View File

@ -5413,6 +5413,10 @@ export interface Locale extends ILocale {
* *
*/ */
"driveAboutTip": string; "driveAboutTip": string;
/**
*
*/
"scrollToClose": string;
"_chat": { "_chat": {
/** /**
* *

View File

@ -1348,6 +1348,7 @@ readonly: "読み取り専用"
goToDeck: "デッキへ戻る" goToDeck: "デッキへ戻る"
federationJobs: "連合ジョブ" federationJobs: "連合ジョブ"
driveAboutTip: "ドライブでは、過去にアップロードしたファイルの一覧が表示されます。<br>\nートに添付する際に再利用したり、あとで投稿するファイルを予めアップロードしておくこともできます。<br>\n<b>ファイルを削除すると、今までそのファイルを使用した全ての場所(ノート、ページ、アバター、バナー等)からも見えなくなるので注意してください。</b><br>\nフォルダを作って整理することもできます。" driveAboutTip: "ドライブでは、過去にアップロードしたファイルの一覧が表示されます。<br>\nートに添付する際に再利用したり、あとで投稿するファイルを予めアップロードしておくこともできます。<br>\n<b>ファイルを削除すると、今までそのファイルを使用した全ての場所(ノート、ページ、アバター、バナー等)からも見えなくなるので注意してください。</b><br>\nフォルダを作って整理することもできます。"
scrollToClose: "スクロールして閉じる"
_chat: _chat:
noMessagesYet: "まだメッセージはありません" noMessagesYet: "まだメッセージはありません"

View File

@ -1348,6 +1348,7 @@ readonly: "唯讀"
goToDeck: "回去甲板" goToDeck: "回去甲板"
federationJobs: "聯邦通訊作業" federationJobs: "聯邦通訊作業"
driveAboutTip: "在「雲端硬碟」中,會顯示過去上傳的檔案列表。<br>\n可以在附加到貼文時重新利用或者事先上傳之後再用於發布。<br>\n<b>請注意,刪除檔案後,之前使用過該檔案的所有地方(貼文、頁面、大頭貼、橫幅等)也會一併無法顯示。</b><br>\n也可以建立資料夾來整理檔案。" driveAboutTip: "在「雲端硬碟」中,會顯示過去上傳的檔案列表。<br>\n可以在附加到貼文時重新利用或者事先上傳之後再用於發布。<br>\n<b>請注意,刪除檔案後,之前使用過該檔案的所有地方(貼文、頁面、大頭貼、橫幅等)也會一併無法顯示。</b><br>\n也可以建立資料夾來整理檔案。"
scrollToClose: "用滾輪關閉"
_chat: _chat:
noMessagesYet: "尚無訊息" noMessagesYet: "尚無訊息"
newMessage: "新訊息" newMessage: "新訊息"
@ -1425,6 +1426,7 @@ _settings:
ifOff: "關閉時" ifOff: "關閉時"
enableSyncThemesBetweenDevices: "在裝置之間同步已安裝的主題" enableSyncThemesBetweenDevices: "在裝置之間同步已安裝的主題"
enablePullToRefresh: "下拉更新" enablePullToRefresh: "下拉更新"
enablePullToRefresh_description: "使用滑鼠,按下並拖曳滾輪。"
_chat: _chat:
showSenderName: "顯示發送者的名稱" showSenderName: "顯示發送者的名稱"
sendOnEnter: "按下 Enter 發送訊息" sendOnEnter: "按下 Enter 發送訊息"

View File

@ -1,6 +1,6 @@
{ {
"name": "misskey", "name": "misskey",
"version": "2025.5.0-alpha.0", "version": "2025.5.0-alpha.1",
"codename": "nasubi", "codename": "nasubi",
"repository": { "repository": {
"type": "git", "type": "git",

View File

@ -1,4 +1,5 @@
import tsParser from '@typescript-eslint/parser'; import tsParser from '@typescript-eslint/parser';
import globals from 'globals';
import sharedConfig from '../shared/eslint.config.js'; import sharedConfig from '../shared/eslint.config.js';
export default [ export default [
@ -6,6 +7,13 @@ export default [
{ {
ignores: ['**/node_modules', 'built', '@types/**/*', 'migration'], ignores: ['**/node_modules', 'built', '@types/**/*', 'migration'],
}, },
{
languageOptions: {
globals: {
...globals.node,
},
},
},
{ {
files: ['**/*.ts', '**/*.tsx'], files: ['**/*.ts', '**/*.tsx'],
languageOptions: { languageOptions: {

20
packages/backend/jest.js Normal file
View File

@ -0,0 +1,20 @@
#!/usr/bin/env node
import child_process from 'node:child_process';
import path from 'node:path';
import url from 'node:url';
import semver from 'semver';
const __filename = url.fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);
const args = [];
args.push(...[
...semver.satisfies(process.version, '^20.17.0 || ^22.0.0') ? ['--no-experimental-require-module'] : [],
'--experimental-vm-modules',
'--experimental-import-meta-resolve',
path.join(__dirname, 'node_modules/jest/bin/jest.js'),
...process.argv.slice(2),
]);
child_process.spawn(process.execPath, args, { stdio: 'inherit' });

View File

@ -22,12 +22,12 @@
"typecheck": "tsc --noEmit && tsc -p test --noEmit && tsc -p test-federation --noEmit", "typecheck": "tsc --noEmit && tsc -p test --noEmit && tsc -p test-federation --noEmit",
"eslint": "eslint --quiet \"{src,test-federation}/**/*.ts\"", "eslint": "eslint --quiet \"{src,test-federation}/**/*.ts\"",
"lint": "pnpm typecheck && pnpm eslint", "lint": "pnpm typecheck && pnpm eslint",
"jest": "cross-env NODE_ENV=test node --experimental-vm-modules --experimental-import-meta-resolve node_modules/jest/bin/jest.js --forceExit --config jest.config.unit.cjs", "jest": "cross-env NODE_ENV=test node ./jest.js --forceExit --config jest.config.unit.cjs",
"jest:e2e": "cross-env NODE_ENV=test node --experimental-vm-modules --experimental-import-meta-resolve node_modules/jest/bin/jest.js --forceExit --config jest.config.e2e.cjs", "jest:e2e": "cross-env NODE_ENV=test node ./jest.js --forceExit --config jest.config.e2e.cjs",
"jest:fed": "node --experimental-vm-modules --experimental-import-meta-resolve node_modules/jest/bin/jest.js --forceExit --config jest.config.fed.cjs", "jest:fed": "node ./jest.js --forceExit --config jest.config.fed.cjs",
"jest-and-coverage": "cross-env NODE_ENV=test node --experimental-vm-modules --experimental-import-meta-resolve node_modules/jest/bin/jest.js --coverage --forceExit --config jest.config.unit.cjs", "jest-and-coverage": "cross-env NODE_ENV=test node ./jest.js --coverage --forceExit --config jest.config.unit.cjs",
"jest-and-coverage:e2e": "cross-env NODE_ENV=test node --experimental-vm-modules --experimental-import-meta-resolve node_modules/jest/bin/jest.js --coverage --forceExit --config jest.config.e2e.cjs", "jest-and-coverage:e2e": "cross-env NODE_ENV=test node ./jest.js --coverage --forceExit --config jest.config.e2e.cjs",
"jest-clear": "cross-env NODE_ENV=test node --experimental-vm-modules --experimental-import-meta-resolve node_modules/jest/bin/jest.js --clearCache", "jest-clear": "cross-env NODE_ENV=test node ./jest.js --clearCache",
"test": "pnpm jest", "test": "pnpm jest",
"test:e2e": "pnpm build && pnpm build:test && pnpm jest:e2e", "test:e2e": "pnpm build && pnpm build:test && pnpm jest:e2e",
"test:fed": "pnpm jest:fed", "test:fed": "pnpm jest:fed",

View File

@ -50,6 +50,10 @@ services:
source: ../jest.config.fed.cjs source: ../jest.config.fed.cjs
target: /misskey/packages/backend/jest.config.fed.cjs target: /misskey/packages/backend/jest.config.fed.cjs
read_only: true read_only: true
- type: bind
source: ../jest.js
target: /misskey/packages/backend/jest.js
read_only: true
- type: bind - type: bind
source: ../../misskey-js/built source: ../../misskey-js/built
target: /misskey/packages/misskey-js/built target: /misskey/packages/misskey-js/built

View File

@ -4,7 +4,7 @@ SPDX-License-Identifier: AGPL-3.0-only
--> -->
<template> <template>
<MkModal ref="modal" :zPriority="'middle'" @closed="$emit('closed')" @click="onBgClick"> <MkModal ref="modal" :zPriority="'middle'" :preferType="'dialog'" @closed="$emit('closed')" @click="onBgClick">
<div ref="rootEl" :class="$style.root"> <div ref="rootEl" :class="$style.root">
<div :class="$style.header"> <div :class="$style.header">
<span :class="$style.icon"> <span :class="$style.icon">
@ -16,13 +16,21 @@ SPDX-License-Identifier: AGPL-3.0-only
<span :class="$style.title">{{ announcement.title }}</span> <span :class="$style.title">{{ announcement.title }}</span>
</div> </div>
<div :class="$style.text"><Mfm :text="announcement.text"/></div> <div :class="$style.text"><Mfm :text="announcement.text"/></div>
<MkButton primary full @click="ok">{{ i18n.ts.ok }}</MkButton> <div ref="bottomEl"></div>
<div :class="$style.footer">
<MkButton
primary
full
:disabled="!hasReachedBottom"
@click="ok"
>{{ hasReachedBottom ? i18n.ts.close : i18n.ts.scrollToClose }}</MkButton>
</div>
</div> </div>
</MkModal> </MkModal>
</template> </template>
<script lang="ts" setup> <script lang="ts" setup>
import { onMounted, useTemplateRef } from 'vue'; import { onMounted, ref, useTemplateRef } from 'vue';
import * as Misskey from 'misskey-js'; import * as Misskey from 'misskey-js';
import * as os from '@/os.js'; import * as os from '@/os.js';
import { misskeyApi } from '@/utility/misskey-api.js'; import { misskeyApi } from '@/utility/misskey-api.js';
@ -32,12 +40,12 @@ import { i18n } from '@/i18n.js';
import { $i } from '@/i.js'; import { $i } from '@/i.js';
import { updateCurrentAccountPartial } from '@/accounts.js'; import { updateCurrentAccountPartial } from '@/accounts.js';
const props = withDefaults(defineProps<{ const props = defineProps<{
announcement: Misskey.entities.Announcement; announcement: Misskey.entities.Announcement;
}>(), { }>();
});
const rootEl = useTemplateRef('rootEl'); const rootEl = useTemplateRef('rootEl');
const bottomEl = useTemplateRef('bottomEl');
const modal = useTemplateRef('modal'); const modal = useTemplateRef('modal');
async function ok() { async function ok() {
@ -72,7 +80,34 @@ function onBgClick() {
}); });
} }
const hasReachedBottom = ref(false);
onMounted(() => { onMounted(() => {
if (bottomEl.value && rootEl.value) {
const bottomElRect = bottomEl.value.getBoundingClientRect();
const rootElRect = rootEl.value.getBoundingClientRect();
if (
bottomElRect.top >= rootElRect.top &&
bottomElRect.top <= (rootElRect.bottom - 66) // 66 75 * 0.9 (modal)
) {
hasReachedBottom.value = true;
return;
}
const observer = new IntersectionObserver(entries => {
for (const entry of entries) {
if (entry.isIntersecting) {
hasReachedBottom.value = true;
observer.disconnect();
}
}
}, {
root: rootEl.value,
rootMargin: '0px 0px -75px 0px',
});
observer.observe(bottomEl.value);
}
}); });
</script> </script>
@ -80,9 +115,12 @@ onMounted(() => {
.root { .root {
margin: auto; margin: auto;
position: relative; position: relative;
padding: 32px; padding: 32px 32px 0;
min-width: 320px; min-width: 320px;
max-width: 480px; max-width: 480px;
max-height: 100%;
overflow-y: auto;
overflow-x: hidden;
box-sizing: border-box; box-sizing: border-box;
background: var(--MI_THEME-panel); background: var(--MI_THEME-panel);
border-radius: var(--MI-radius); border-radius: var(--MI-radius);
@ -103,4 +141,14 @@ onMounted(() => {
.text { .text {
margin: 1em 0; margin: 1em 0;
} }
.footer {
position: sticky;
bottom: 0;
left: -32px;
backdrop-filter: var(--MI-blur, blur(15px));
background: color(from var(--MI_THEME-bg) srgb r g b / 0.5);
margin: 0 -32px;
padding: 24px 32px;
}
</style> </style>

View File

@ -6,7 +6,11 @@ SPDX-License-Identifier: AGPL-3.0-only
<template> <template>
<div :class="$style.root" :style="themeColorStyle"> <div :class="$style.root" :style="themeColorStyle">
<img v-if="faviconUrl" :class="$style.icon" :src="faviconUrl"/> <img v-if="faviconUrl" :class="$style.icon" :src="faviconUrl"/>
<div :class="$style.name">{{ instanceName }}</div> <div :class="$style.name">
<svg :class="$style.nameSvg" version="1.1" xmlns="http://www.w3.org/2000/svg">
<text x="0" y="0" :class="$style.nameSvgText">{{ instanceName }}</text>
</svg>
</div>
</div> </div>
</template> </template>
@ -78,10 +82,31 @@ $height: 2ex;
.name { .name {
margin-left: 4px; margin-left: 4px;
height: 100%;
line-height: 1; line-height: 1;
font-size: 0.9em; font-size: 0.9em;
font-weight: bold; font-weight: bold;
white-space: nowrap; white-space: nowrap;
overflow: visible; overflow: visible;
} }
.nameSvg {
width: auto;
height: 100%;
overflow: visible;
}
.nameSvgText {
font-family: inherit;
font-size: inherit;
font-weight: inherit;
text-rendering: optimizeLegibility;
transform: translateY(calc(100% - 2.5px)); // 2.5px
fill: currentColor;
stroke: #000;
stroke-linecap: round;
stroke-linejoin: round;
stroke-width: 2.5px;
paint-order: stroke fill markers;
}
</style> </style>

View File

@ -76,8 +76,8 @@ function unlockDownScroll() {
scrollEl.style.overscrollBehavior = 'contain'; scrollEl.style.overscrollBehavior = 'contain';
} }
function moveStart(event: PointerEvent) { function moveStartByMouse(event: MouseEvent) {
if (event.pointerType === 'mouse' && event.button !== 1) return; if (event.button !== 1) return;
if (isRefreshing.value) return; if (isRefreshing.value) return;
const scrollPos = scrollEl!.scrollTop; const scrollPos = scrollEl!.scrollTop;
@ -88,27 +88,39 @@ function moveStart(event: PointerEvent) {
lockDownScroll(); lockDownScroll();
// pull event.preventDefault(); //
window.document.body.setAttribute('inert', 'true');
isPulling.value = true; isPulling.value = true;
startScreenY = getScreenY(event); startScreenY = getScreenY(event);
pullDistance.value = 0; pullDistance.value = 0;
// PointerEvent使TouchEventMouseEvent使 window.addEventListener('mousemove', moving, { passive: true });
if (event.pointerType === 'mouse') { window.addEventListener('mouseup', () => {
window.addEventListener('mousemove', moving, { passive: true }); window.removeEventListener('mousemove', moving);
window.addEventListener('mouseup', () => { onPullRelease();
window.removeEventListener('mousemove', moving); }, { passive: true, once: true });
onPullRelease(); }
}, { passive: true, once: true });
} else { function moveStartByTouch(event: TouchEvent) {
window.addEventListener('touchmove', moving, { passive: true }); if (isRefreshing.value) return;
window.addEventListener('touchend', () => {
window.removeEventListener('touchmove', moving); const scrollPos = scrollEl!.scrollTop;
onPullRelease(); if (scrollPos !== 0) {
}, { passive: true, once: true }); unlockDownScroll();
return;
} }
lockDownScroll();
isPulling.value = true;
startScreenY = getScreenY(event);
pullDistance.value = 0;
window.addEventListener('touchmove', moving, { passive: true });
window.addEventListener('touchend', () => {
window.removeEventListener('touchmove', moving);
onPullRelease();
}, { passive: true, once: true });
} }
function moveBySystem(to: number): Promise<void> { function moveBySystem(to: number): Promise<void> {
@ -148,7 +160,6 @@ async function closeContent() {
} }
function onPullRelease() { function onPullRelease() {
window.document.body.removeAttribute('inert');
startScreenY = null; startScreenY = null;
if (isPulledEnough.value) { if (isPulledEnough.value) {
isPulledEnough.value = false; isPulledEnough.value = false;
@ -208,13 +219,15 @@ onMounted(() => {
if (rootEl.value == null) return; if (rootEl.value == null) return;
scrollEl = getScrollContainer(rootEl.value); scrollEl = getScrollContainer(rootEl.value);
lockDownScroll(); lockDownScroll();
rootEl.value.addEventListener('pointerdown', moveStart, { passive: true }); rootEl.value.addEventListener('mousedown', moveStartByMouse, { passive: false }); // preventDefault
rootEl.value.addEventListener('touchstart', moveStartByTouch, { passive: true });
rootEl.value.addEventListener('touchend', toggleScrollLockOnTouchEnd, { passive: true }); rootEl.value.addEventListener('touchend', toggleScrollLockOnTouchEnd, { passive: true });
}); });
onUnmounted(() => { onUnmounted(() => {
unlockDownScroll(); unlockDownScroll();
if (rootEl.value) rootEl.value.removeEventListener('pointerdown', moveStart); if (rootEl.value) rootEl.value.removeEventListener('mousedown', moveStartByMouse);
if (rootEl.value) rootEl.value.removeEventListener('touchstart', moveStartByTouch);
if (rootEl.value) rootEl.value.removeEventListener('touchend', toggleScrollLockOnTouchEnd); if (rootEl.value) rootEl.value.removeEventListener('touchend', toggleScrollLockOnTouchEnd);
}); });
</script> </script>

View File

@ -21,7 +21,7 @@ SPDX-License-Identifier: AGPL-3.0-only
<MkTl :events="timeline"> <MkTl :events="timeline">
<template #left="{ event }"> <template #left="{ event }">
<div> <div>
<MkAvatar :user="event.user" style="width: 24px; height: 24px;"/> <MkAvatar :user="event.user" style="width: 26px; height: 26px;"/>
</div> </div>
</template> </template>
<template #right="{ event, timestamp, delta }"> <template #right="{ event, timestamp, delta }">

View File

@ -1,7 +1,7 @@
{ {
"type": "module", "type": "module",
"name": "misskey-js", "name": "misskey-js",
"version": "2025.5.0-alpha.0", "version": "2025.5.0-alpha.1",
"description": "Misskey SDK for JavaScript", "description": "Misskey SDK for JavaScript",
"license": "MIT", "license": "MIT",
"main": "./built/index.js", "main": "./built/index.js",