Compare commits

..

No commits in common. "develop" and "2025.10.0-rc.0" have entirely different histories.

25 changed files with 2679 additions and 2604 deletions

View file

@ -1,16 +1,3 @@
## 2025.10.1
### General
- 依存関係の更新
### Client
- Fix: カスタム絵文字画面(beta)のaliasesで使用される区切り文字が一致していないのを修正 #15614
- Fix: バナー画像の幅が表示領域と一致していない問題を修正
- Fix: 一部のブラウザでバナー画像が上下中央に表示されない問題を修正
### Server
-
## 2025.10.0
### NOTE

View file

@ -334,7 +334,6 @@ fileName: "Filename"
selectFile: "Select a file"
selectFiles: "Select files"
selectFolder: "Select a folder"
unselectFolder: "Deselect folder"
selectFolders: "Select folders"
fileNotSelected: "No file selected"
renameFile: "Rename file"
@ -347,7 +346,6 @@ addFile: "Add a file"
showFile: "Show files"
emptyDrive: "Your Drive is empty"
emptyFolder: "This folder is empty"
dropHereToUpload: "Drop files here to upload"
unableToDelete: "Unable to delete"
inputNewFileName: "Enter a new filename"
inputNewDescription: "Enter new alt text"
@ -1392,8 +1390,6 @@ scheduledToPostOnX: "Note is scheduled for {x}"
schedule: "Schedule"
scheduled: "Scheduled"
widgets: "Widgets"
deviceInfo: "Device information"
deviceInfoDescription: "When making technical inquiries, including the following information may help resolve the issue."
_compression:
_quality:
high: "High quality"
@ -2018,7 +2014,6 @@ _role:
canManageAvatarDecorations: "Manage avatar decorations"
driveCapacity: "Drive capacity"
maxFileSize: "Upload-able max file size"
maxFileSize_caption: "Reverse proxies, CDNs, and other front-end components may have their own configuration settings."
alwaysMarkNsfw: "Always mark files as NSFW"
canUpdateBioMedia: "Can edit an icon or a banner image"
pinMax: "Maximum number of pinned notes"
@ -2437,7 +2432,6 @@ _auth:
scopeUser: "Operate as the following user"
pleaseLogin: "Please log in to authorize applications."
byClickingYouWillBeRedirectedToThisUrl: "When access is granted, you will automatically be redirected to the following URL"
alreadyAuthorized: "This application already has access permission."
_antennaSources:
all: "All notes"
homeTimeline: "Notes from followed users"
@ -2704,8 +2698,6 @@ _notification:
quote: "Quotes"
reaction: "Reactions"
pollEnded: "Polls ending"
scheduledNotePosted: "Scheduled note was successful"
scheduledNotePostFailed: "Scheduled note failed"
receiveFollowRequest: "Received follow requests"
followRequestAccepted: "Accepted follow requests"
roleAssigned: "Role given"

View file

@ -334,7 +334,6 @@ fileName: "Nome dell'allegato"
selectFile: "Scelta allegato"
selectFiles: "Scelta allegato"
selectFolder: "Seleziona cartella"
unselectFolder: "Deseleziona la cartella"
selectFolders: "Seleziona cartella"
fileNotSelected: "Nessun file selezionato"
renameFile: "Rinomina file"
@ -347,7 +346,6 @@ addFile: "Allega"
showFile: "Visualizza file"
emptyDrive: "Il Drive è vuoto"
emptyFolder: "La cartella è vuota"
dropHereToUpload: "Trascina qui il tuo file per caricarlo"
unableToDelete: "Eliminazione impossibile"
inputNewFileName: "Inserisci nome del nuovo file"
inputNewDescription: "Inserisci una nuova descrizione"
@ -1392,8 +1390,6 @@ scheduledToPostOnX: "Pubblicazione pianificata {x}"
schedule: "Pianificare"
scheduled: "Pianificata"
widgets: "Riquadri"
deviceInfo: "Informazioni sul dispositivo"
deviceInfoDescription: "Se ci contatti per ricevere supporto tecnico, ti preghiamo di includere le seguenti informazioni per aiutarci a risolvere il tuo problema."
_compression:
_quality:
high: "Alta qualità"
@ -2018,7 +2014,6 @@ _role:
canManageAvatarDecorations: "Gestisce le decorazioni di immagini del profilo"
driveCapacity: "Capienza del Drive"
maxFileSize: "Dimensione massima del file caricabile"
maxFileSize_caption: "Potrebbero esserci altre impostazioni nella fase precedente, come reverse proxy o CDN."
alwaysMarkNsfw: "Impostare sempre come esplicito (NSFW)"
canUpdateBioMedia: "Può aggiornare foto profilo e di testata"
pinMax: "Quantità massima di Note in primo piano"
@ -2437,7 +2432,6 @@ _auth:
scopeUser: "Sto funzionando per il seguente profilo"
pleaseLogin: "Per favore accedi al tuo account per cambiare i permessi dell'applicazione"
byClickingYouWillBeRedirectedToThisUrl: "Consentendo l'accesso, si verrà reindirizzati presso questo indirizzo URL"
alreadyAuthorized: "Questa applicazione è già autorizzata ad accedere."
_antennaSources:
all: "Tutte le note"
homeTimeline: "Note dai tuoi Following"
@ -2704,8 +2698,6 @@ _notification:
quote: "Cita"
reaction: "Reazioni"
pollEnded: "Sondaggio terminato"
scheduledNotePosted: "Nota pianificata correttamente"
scheduledNotePostFailed: "La pianificazione della Nota è fallita"
receiveFollowRequest: "Richieste di follow in arrivo"
followRequestAccepted: "Richieste di follow accettate"
roleAssigned: "Ruolo concesso"

View file

@ -1,6 +1,6 @@
{
"name": "misskey",
"version": "2025.10.1-alpha.1",
"version": "2025.10.0-rc.0",
"codename": "nasubi",
"repository": {
"type": "git",
@ -58,21 +58,21 @@
"execa": "9.6.0",
"fast-glob": "3.3.3",
"glob": "11.0.3",
"ignore-walk": "8.0.0",
"ignore-walk": "7.0.0",
"js-yaml": "4.1.0",
"postcss": "8.5.6",
"tar": "7.5.1",
"terser": "5.44.0",
"typescript": "5.9.3"
"typescript": "5.9.2"
},
"devDependencies": {
"@misskey-dev/eslint-plugin": "2.1.0",
"@types/js-yaml": "4.0.9",
"@types/node": "22.18.8",
"@typescript-eslint/eslint-plugin": "8.45.0",
"@typescript-eslint/parser": "8.45.0",
"cross-env": "10.1.0",
"cypress": "15.3.0",
"@types/node": "22.18.6",
"@typescript-eslint/eslint-plugin": "8.44.1",
"@typescript-eslint/parser": "8.44.1",
"cross-env": "7.0.3",
"cypress": "14.5.4",
"eslint": "9.36.0",
"globals": "16.4.0",
"ncp": "2.0.0",

View file

@ -39,17 +39,17 @@
},
"optionalDependencies": {
"@swc/core-android-arm64": "1.3.11",
"@swc/core-darwin-arm64": "1.13.20",
"@swc/core-darwin-x64": "1.13.20",
"@swc/core-darwin-arm64": "1.13.19",
"@swc/core-darwin-x64": "1.13.19",
"@swc/core-freebsd-x64": "1.3.11",
"@swc/core-linux-arm-gnueabihf": "1.13.20",
"@swc/core-linux-arm64-gnu": "1.13.20",
"@swc/core-linux-arm64-musl": "1.13.20",
"@swc/core-linux-x64-gnu": "1.13.20",
"@swc/core-linux-x64-musl": "1.13.20",
"@swc/core-win32-arm64-msvc": "1.13.20",
"@swc/core-win32-ia32-msvc": "1.13.20",
"@swc/core-win32-x64-msvc": "1.13.20",
"@swc/core-linux-arm-gnueabihf": "1.13.19",
"@swc/core-linux-arm64-gnu": "1.13.19",
"@swc/core-linux-arm64-musl": "1.13.19",
"@swc/core-linux-x64-gnu": "1.13.19",
"@swc/core-linux-x64-musl": "1.13.19",
"@swc/core-win32-arm64-msvc": "1.13.19",
"@swc/core-win32-ia32-msvc": "1.13.19",
"@swc/core-win32-x64-msvc": "1.13.19",
"@tensorflow/tfjs": "4.22.0",
"@tensorflow/tfjs-node": "4.22.0",
"bufferutil": "4.0.9",
@ -69,10 +69,10 @@
"utf-8-validate": "6.0.5"
},
"dependencies": {
"@aws-sdk/client-s3": "3.901.0",
"@aws-sdk/lib-storage": "3.901.0",
"@aws-sdk/client-s3": "3.896.0",
"@aws-sdk/lib-storage": "3.895.0",
"@discordapp/twemoji": "16.0.1",
"@fastify/accepts": "5.0.3",
"@fastify/accepts": "5.0.2",
"@fastify/cookie": "11.0.2",
"@fastify/cors": "10.1.0",
"@fastify/express": "4.0.2",
@ -81,7 +81,7 @@
"@fastify/static": "8.2.0",
"@fastify/view": "10.0.2",
"@misskey-dev/sharp-read-bmp": "1.2.0",
"@misskey-dev/summaly": "5.2.4",
"@misskey-dev/summaly": "5.2.3",
"@napi-rs/canvas": "0.1.80",
"@nestjs/common": "11.1.6",
"@nestjs/core": "11.1.6",
@ -103,7 +103,7 @@
"bcryptjs": "2.4.3",
"blurhash": "2.0.5",
"body-parser": "1.20.3",
"bullmq": "5.59.0",
"bullmq": "5.58.8",
"cacheable-lookup": "7.0.0",
"cbor": "9.0.2",
"chalk": "5.6.2",
@ -134,7 +134,7 @@
"json5": "2.2.3",
"jsonld": "8.3.3",
"jsrsasign": "11.1.0",
"juice": "11.0.3",
"juice": "11.0.1",
"meilisearch": "0.53.0",
"mfm-js": "0.25.0",
"microformats-parser": "2.0.4",
@ -181,7 +181,7 @@
"tsc-alias": "1.8.16",
"tsconfig-paths": "4.2.0",
"typeorm": "0.3.27",
"typescript": "5.9.3",
"typescript": "5.9.2",
"ulid": "2.4.0",
"vary": "1.1.2",
"web-push": "3.6.7",
@ -210,8 +210,8 @@
"@types/jsrsasign": "10.5.15",
"@types/mime-types": "2.1.4",
"@types/ms": "0.7.34",
"@types/node": "22.18.8",
"@types/nodemailer": "6.4.20",
"@types/node": "22.18.6",
"@types/nodemailer": "6.4.19",
"@types/oauth": "0.9.6",
"@types/oauth2orize": "1.11.5",
"@types/oauth2orize-pkce": "0.1.2",
@ -231,8 +231,8 @@
"@types/vary": "1.1.3",
"@types/web-push": "3.6.4",
"@types/ws": "8.18.1",
"@typescript-eslint/eslint-plugin": "8.45.0",
"@typescript-eslint/parser": "8.45.0",
"@typescript-eslint/eslint-plugin": "8.44.1",
"@typescript-eslint/parser": "8.44.1",
"aws-sdk-client-mock": "4.1.0",
"cross-env": "7.0.3",
"eslint-plugin-import": "2.32.0",

View file

@ -172,12 +172,8 @@ export class NoteDraftService {
me: MiLocalUser,
data: Partial<NoteDraftOptions>,
): Promise<void> {
if (data.isActuallyScheduled) {
if (data.scheduledAt == null) {
throw new IdentifiableError('94a89a43-3591-400a-9c17-dd166e71fdfa', 'scheduledAt is required when isActuallyScheduled is true');
} else if (data.scheduledAt.getTime() < Date.now()) {
throw new IdentifiableError('b34d0c1b-996f-4e34-a428-c636d98df457', 'scheduledAt must be in the future');
}
if (data.isActuallyScheduled && data.scheduledAt == null) {
throw new IdentifiableError('94a89a43-3591-400a-9c17-dd166e71fdfa', 'scheduledAt is required when isActuallyScheduled is true');
}
if (data.pollExpiresAt != null) {

View file

@ -11,11 +11,11 @@
},
"devDependencies": {
"@types/estree": "1.0.8",
"@types/node": "22.18.8",
"@typescript-eslint/eslint-plugin": "8.45.0",
"@typescript-eslint/parser": "8.45.0",
"rollup": "4.52.3",
"typescript": "5.9.3"
"@types/node": "22.18.6",
"@typescript-eslint/eslint-plugin": "8.44.1",
"@typescript-eslint/parser": "8.44.1",
"rollup": "4.52.2",
"typescript": "5.9.2"
},
"dependencies": {
"estree-walker": "3.0.3",

View file

@ -26,37 +26,37 @@
"mfm-js": "0.25.0",
"misskey-js": "workspace:*",
"punycode.js": "2.3.1",
"rollup": "4.52.3",
"rollup": "4.52.2",
"sass": "1.93.2",
"shiki": "3.13.0",
"tinycolor2": "1.6.0",
"tsc-alias": "1.8.16",
"tsconfig-paths": "4.2.0",
"typescript": "5.9.3",
"uuid": "13.0.0",
"typescript": "5.9.2",
"uuid": "11.1.0",
"vite": "7.1.7",
"vue": "3.5.22"
},
"devDependencies": {
"@misskey-dev/summaly": "5.2.4",
"@misskey-dev/summaly": "5.2.3",
"@tabler/icons-webfont": "3.35.0",
"@testing-library/vue": "8.1.0",
"@types/estree": "1.0.8",
"@types/micromatch": "4.0.9",
"@types/node": "22.18.8",
"@types/node": "22.18.6",
"@types/punycode.js": "npm:@types/punycode@2.1.4",
"@types/tinycolor2": "1.4.6",
"@types/ws": "8.18.1",
"@typescript-eslint/eslint-plugin": "8.45.0",
"@typescript-eslint/parser": "8.45.0",
"@typescript-eslint/eslint-plugin": "8.44.1",
"@typescript-eslint/parser": "8.44.1",
"@vitest/coverage-v8": "3.2.4",
"@vue/runtime-core": "3.5.22",
"acorn": "8.15.0",
"cross-env": "10.1.0",
"cross-env": "10.0.0",
"eslint-plugin-import": "2.32.0",
"eslint-plugin-vue": "10.5.0",
"fast-glob": "3.3.3",
"happy-dom": "19.0.2",
"happy-dom": "18.0.1",
"intersection-observer": "0.12.2",
"micromatch": "4.0.8",
"msw": "2.11.3",
@ -65,8 +65,8 @@
"start-server-and-test": "2.1.2",
"tsx": "4.20.6",
"vite-plugin-turbosnap": "1.0.3",
"vue-component-type-helpers": "3.1.0",
"vue-component-type-helpers": "3.0.8",
"vue-eslint-parser": "10.2.0",
"vue-tsc": "3.1.0"
"vue-tsc": "3.0.8"
}
}

View file

@ -21,13 +21,13 @@
"lint": "pnpm typecheck && pnpm eslint"
},
"devDependencies": {
"@types/node": "22.18.8",
"@typescript-eslint/eslint-plugin": "8.45.0",
"@typescript-eslint/parser": "8.45.0",
"@types/node": "22.18.6",
"@typescript-eslint/eslint-plugin": "8.44.1",
"@typescript-eslint/parser": "8.44.1",
"esbuild": "0.25.10",
"eslint-plugin-vue": "10.5.0",
"nodemon": "3.1.10",
"typescript": "5.9.3",
"typescript": "5.9.2",
"vue-eslint-parser": "10.2.0"
},
"files": [

View file

@ -24,7 +24,7 @@
"@rollup/plugin-json": "6.1.0",
"@rollup/plugin-replace": "6.0.2",
"@rollup/pluginutils": "5.3.0",
"@sentry/vue": "10.17.0",
"@sentry/vue": "10.15.0",
"@syuilo/aiscript": "1.1.2",
"@syuilo/aiscript-0-19-0": "npm:@syuilo/aiscript@^0.19.0",
"@twemoji/parser": "16.0.0",
@ -41,7 +41,7 @@
"chartjs-chart-matrix": "3.0.0",
"chartjs-plugin-gradient": "0.6.1",
"chartjs-plugin-zoom": "2.2.0",
"chromatic": "13.3.0",
"chromatic": "13.2.1",
"compare-versions": "6.1.1",
"cropperjs": "2.0.1",
"date-fns": "4.1.0",
@ -57,7 +57,7 @@
"json5": "2.2.3",
"magic-string": "0.30.19",
"matter-js": "0.20.0",
"mediabunny": "1.21.1",
"mediabunny": "1.21.0",
"mfm-js": "0.25.0",
"misskey-bubble-game": "workspace:*",
"misskey-js": "workspace:*",
@ -66,7 +66,7 @@
"punycode.js": "2.3.1",
"qr-code-styling": "1.9.2",
"qr-scanner": "1.4.2",
"rollup": "4.52.3",
"rollup": "4.52.2",
"sanitize-html": "2.17.0",
"sass": "1.93.2",
"shiki": "3.13.0",
@ -77,7 +77,7 @@
"tinycolor2": "1.6.0",
"tsc-alias": "1.8.16",
"tsconfig-paths": "4.2.0",
"typescript": "5.9.3",
"typescript": "5.9.2",
"v-code-diff": "1.13.1",
"vite": "7.1.7",
"vue": "3.5.22",
@ -85,10 +85,10 @@
"wanakana": "5.3.1"
},
"devDependencies": {
"@misskey-dev/summaly": "5.2.4",
"@misskey-dev/summaly": "5.2.3",
"@storybook/addon-essentials": "8.6.14",
"@storybook/addon-interactions": "8.6.14",
"@storybook/addon-links": "9.1.10",
"@storybook/addon-links": "9.1.8",
"@storybook/addon-mdx-gfm": "8.6.14",
"@storybook/addon-storysource": "8.6.14",
"@storybook/blocks": "8.6.14",
@ -96,38 +96,38 @@
"@storybook/core-events": "8.6.14",
"@storybook/manager-api": "8.6.14",
"@storybook/preview-api": "8.6.14",
"@storybook/react": "9.1.10",
"@storybook/react-vite": "9.1.10",
"@storybook/react": "9.1.8",
"@storybook/react-vite": "9.1.8",
"@storybook/test": "8.6.14",
"@storybook/theming": "8.6.14",
"@storybook/types": "8.6.14",
"@storybook/vue3": "9.1.10",
"@storybook/vue3-vite": "9.1.10",
"@storybook/vue3": "9.1.8",
"@storybook/vue3-vite": "9.1.8",
"@tabler/icons-webfont": "3.35.0",
"@testing-library/vue": "8.1.0",
"@types/canvas-confetti": "1.9.0",
"@types/estree": "1.0.8",
"@types/matter-js": "0.20.2",
"@types/micromatch": "4.0.9",
"@types/node": "22.18.8",
"@types/node": "22.18.6",
"@types/punycode.js": "npm:@types/punycode@2.1.4",
"@types/sanitize-html": "2.16.0",
"@types/seedrandom": "3.0.8",
"@types/throttle-debounce": "5.0.2",
"@types/tinycolor2": "1.4.6",
"@types/ws": "8.18.1",
"@typescript-eslint/eslint-plugin": "8.45.0",
"@typescript-eslint/parser": "8.45.0",
"@typescript-eslint/eslint-plugin": "8.44.1",
"@typescript-eslint/parser": "8.44.1",
"@vitest/coverage-v8": "3.2.4",
"@vue/compiler-core": "3.5.22",
"@vue/runtime-core": "3.5.22",
"acorn": "8.15.0",
"cross-env": "10.1.0",
"cypress": "15.3.0",
"cross-env": "10.0.0",
"cypress": "14.5.4",
"eslint-plugin-import": "2.32.0",
"eslint-plugin-vue": "10.5.0",
"fast-glob": "3.3.3",
"happy-dom": "19.0.2",
"happy-dom": "18.0.1",
"intersection-observer": "0.12.2",
"micromatch": "4.0.8",
"minimatch": "10.0.3",
@ -135,18 +135,18 @@
"msw-storybook-addon": "2.0.5",
"nodemon": "3.1.10",
"prettier": "3.6.2",
"react": "19.2.0",
"react-dom": "19.2.0",
"react": "19.1.1",
"react-dom": "19.1.1",
"seedrandom": "3.0.5",
"start-server-and-test": "2.1.2",
"storybook": "9.1.10",
"storybook": "9.1.8",
"storybook-addon-misskey-theme": "github:misskey-dev/storybook-addon-misskey-theme",
"tsx": "4.20.6",
"vite-plugin-turbosnap": "1.0.3",
"vitest": "3.2.4",
"vitest-fetch-mock": "0.4.5",
"vue-component-type-helpers": "3.1.0",
"vue-component-type-helpers": "3.0.8",
"vue-eslint-parser": "10.2.0",
"vue-tsc": "3.1.0"
"vue-tsc": "3.0.8"
}
}

View file

@ -66,7 +66,7 @@ export function createAiScriptEnv(opts: { storageKey: string, token?: string })
});
return confirm.canceled ? values.FALSE : values.TRUE;
}),
'Mk:toast': values.FN_NATIVE(([text]) => {
'Mk:toast': values.FN_NATIVE(async ([text]) => {
utils.assertString(text);
os.toast(text.value);
return values.NULL;

View file

@ -71,7 +71,7 @@ import {
import * as os from '@/os.js';
import { createColumn } from '@/components/grid/column.js';
import { createRow, defaultGridRowSetting, resetRow } from '@/components/grid/row.js';
import { makeHotkey } from '@/utility/hotkey.js';
import { handleKeyEvent } from '@/utility/key-event.js';
type RowHolder = {
row: GridRow,
@ -289,143 +289,161 @@ function onKeyDown(ev: KeyboardEvent) {
const max = availableBounds.value;
const bounds = rangedBounds.value;
makeHotkey({
'delete': () => {
if (rangedRows.value.length > 0) {
if (rowSetting.events.delete) {
rowSetting.events.delete(rangedRows.value);
handleKeyEvent(ev, [
{
code: 'Delete', handler: () => {
if (rangedRows.value.length > 0) {
if (rowSetting.events.delete) {
rowSetting.events.delete(rangedRows.value);
}
} else {
const context = createContext();
removeDataFromGrid(context, (cell) => {
emitCellValue(cell, undefined);
});
}
} else {
},
},
{
code: 'KeyC', modifiers: ['Control'], handler: () => {
const context = createContext();
removeDataFromGrid(context, (cell) => {
emitCellValue(cell, undefined);
copyGridDataToClipboard(data.value, context);
},
},
{
code: 'KeyV', modifiers: ['Control'], handler: async () => {
const _cells = cells.value;
const context = createContext();
await pasteToGridFromClipboard(context, (row, col, parsedValue) => {
emitCellValue(_cells[row.index].cells[col.index], parsedValue);
});
}
},
},
'ctrl+c|meta+c': () => {
const context = createContext();
copyGridDataToClipboard(data.value, context);
{
code: 'ArrowRight', modifiers: ['Control', 'Shift'], handler: () => {
updateSelectionRange({
leftTop: { col: selectedCellAddress.col, row: bounds.leftTop.row },
rightBottom: { col: max.rightBottom.col, row: bounds.rightBottom.row },
});
},
},
'ctrl+v|meta+v': async () => {
const _cells = cells.value;
const context = createContext();
await pasteToGridFromClipboard(context, (row, col, parsedValue) => {
emitCellValue(_cells[row.index].cells[col.index], parsedValue);
});
{
code: 'ArrowLeft', modifiers: ['Control', 'Shift'], handler: () => {
updateSelectionRange({
leftTop: { col: max.leftTop.col, row: bounds.leftTop.row },
rightBottom: { col: selectedCellAddress.col, row: bounds.rightBottom.row },
});
},
},
'ctrl+shift+right|meta+shift+right': () => {
updateSelectionRange({
leftTop: { col: selectedCellAddress.col, row: bounds.leftTop.row },
rightBottom: { col: max.rightBottom.col, row: bounds.rightBottom.row },
});
{
code: 'ArrowUp', modifiers: ['Control', 'Shift'], handler: () => {
updateSelectionRange({
leftTop: { col: bounds.leftTop.col, row: max.leftTop.row },
rightBottom: { col: bounds.rightBottom.col, row: selectedCellAddress.row },
});
},
},
'ctrl+shift+left|meta+shift+left': () => {
updateSelectionRange({
leftTop: { col: max.leftTop.col, row: bounds.leftTop.row },
rightBottom: { col: selectedCellAddress.col, row: bounds.rightBottom.row },
});
{
code: 'ArrowDown', modifiers: ['Control', 'Shift'], handler: () => {
updateSelectionRange({
leftTop: { col: bounds.leftTop.col, row: selectedCellAddress.row },
rightBottom: { col: bounds.rightBottom.col, row: max.rightBottom.row },
});
},
},
'ctrl+shift+up|meta+shift+up': () => {
updateSelectionRange({
leftTop: { col: bounds.leftTop.col, row: max.leftTop.row },
rightBottom: { col: bounds.rightBottom.col, row: selectedCellAddress.row },
});
{
code: 'ArrowRight', modifiers: ['Shift'], handler: () => {
updateSelectionRange({
leftTop: {
col: bounds.leftTop.col < selectedCellAddress.col
? bounds.leftTop.col + 1
: selectedCellAddress.col,
row: bounds.leftTop.row,
},
rightBottom: {
col: (bounds.rightBottom.col > selectedCellAddress.col || bounds.leftTop.col === selectedCellAddress.col)
? bounds.rightBottom.col + 1
: selectedCellAddress.col,
row: bounds.rightBottom.row,
},
});
},
},
'ctrl+shift+down|meta+shift+down': () => {
updateSelectionRange({
leftTop: { col: bounds.leftTop.col, row: selectedCellAddress.row },
rightBottom: { col: bounds.rightBottom.col, row: max.rightBottom.row },
});
{
code: 'ArrowLeft', modifiers: ['Shift'], handler: () => {
updateSelectionRange({
leftTop: {
col: (bounds.leftTop.col < selectedCellAddress.col || bounds.rightBottom.col === selectedCellAddress.col)
? bounds.leftTop.col - 1
: selectedCellAddress.col,
row: bounds.leftTop.row,
},
rightBottom: {
col: bounds.rightBottom.col > selectedCellAddress.col
? bounds.rightBottom.col - 1
: selectedCellAddress.col,
row: bounds.rightBottom.row,
},
});
},
},
'ctrl+right|meta+right': () => {
selectionCell({ col: max.rightBottom.col, row: selectedCellAddress.row });
{
code: 'ArrowUp', modifiers: ['Shift'], handler: () => {
updateSelectionRange({
leftTop: {
col: bounds.leftTop.col,
row: (bounds.leftTop.row < selectedCellAddress.row || bounds.rightBottom.row === selectedCellAddress.row)
? bounds.leftTop.row - 1
: selectedCellAddress.row,
},
rightBottom: {
col: bounds.rightBottom.col,
row: bounds.rightBottom.row > selectedCellAddress.row
? bounds.rightBottom.row - 1
: selectedCellAddress.row,
},
});
},
},
'ctrl+left|meta+left': () => {
selectionCell({ col: max.leftTop.col, row: selectedCellAddress.row });
{
code: 'ArrowDown', modifiers: ['Shift'], handler: () => {
updateSelectionRange({
leftTop: {
col: bounds.leftTop.col,
row: bounds.leftTop.row < selectedCellAddress.row
? bounds.leftTop.row + 1
: selectedCellAddress.row,
},
rightBottom: {
col: bounds.rightBottom.col,
row: (bounds.rightBottom.row > selectedCellAddress.row || bounds.leftTop.row === selectedCellAddress.row)
? bounds.rightBottom.row + 1
: selectedCellAddress.row,
},
});
},
},
'ctrl+up|meta+up': () => {
selectionCell({ col: selectedCellAddress.col, row: max.leftTop.row });
{
code: 'ArrowDown', handler: () => {
selectionCell({ col: selectedCellAddress.col, row: selectedCellAddress.row + 1 });
},
},
'ctrl+down|meta+down': () => {
selectionCell({ col: selectedCellAddress.col, row: max.rightBottom.row });
{
code: 'ArrowUp', handler: () => {
selectionCell({ col: selectedCellAddress.col, row: selectedCellAddress.row - 1 });
},
},
'shift+right': () => {
updateSelectionRange({
leftTop: {
col: bounds.leftTop.col < selectedCellAddress.col
? bounds.leftTop.col + 1
: selectedCellAddress.col,
row: bounds.leftTop.row,
},
rightBottom: {
col: (bounds.rightBottom.col > selectedCellAddress.col || bounds.leftTop.col === selectedCellAddress.col)
? bounds.rightBottom.col + 1
: selectedCellAddress.col,
row: bounds.rightBottom.row,
},
});
{
code: 'ArrowRight', handler: () => {
selectionCell({ col: selectedCellAddress.col + 1, row: selectedCellAddress.row });
},
},
'shift+left': () => {
updateSelectionRange({
leftTop: {
col: (bounds.leftTop.col < selectedCellAddress.col || bounds.rightBottom.col === selectedCellAddress.col)
? bounds.leftTop.col - 1
: selectedCellAddress.col,
row: bounds.leftTop.row,
},
rightBottom: {
col: bounds.rightBottom.col > selectedCellAddress.col
? bounds.rightBottom.col - 1
: selectedCellAddress.col,
row: bounds.rightBottom.row,
},
});
{
code: 'ArrowLeft', handler: () => {
selectionCell({ col: selectedCellAddress.col - 1, row: selectedCellAddress.row });
},
},
'shift+up': () => {
updateSelectionRange({
leftTop: {
col: bounds.leftTop.col,
row: (bounds.leftTop.row < selectedCellAddress.row || bounds.rightBottom.row === selectedCellAddress.row)
? bounds.leftTop.row - 1
: selectedCellAddress.row,
},
rightBottom: {
col: bounds.rightBottom.col,
row: bounds.rightBottom.row > selectedCellAddress.row
? bounds.rightBottom.row - 1
: selectedCellAddress.row,
},
});
},
'shift+down': () => {
updateSelectionRange({
leftTop: {
col: bounds.leftTop.col,
row: bounds.leftTop.row < selectedCellAddress.row
? bounds.leftTop.row + 1
: selectedCellAddress.row,
},
rightBottom: {
col: bounds.rightBottom.col,
row: (bounds.rightBottom.row > selectedCellAddress.row || bounds.leftTop.row === selectedCellAddress.row)
? bounds.rightBottom.row + 1
: selectedCellAddress.row,
},
});
},
'down': () => {
selectionCell({ col: selectedCellAddress.col, row: selectedCellAddress.row + 1 });
},
'up': () => {
selectionCell({ col: selectedCellAddress.col, row: selectedCellAddress.row - 1 });
},
'right': () => {
selectionCell({ col: selectedCellAddress.col + 1, row: selectedCellAddress.row });
},
'left': () => {
selectionCell({ col: selectedCellAddress.col - 1, row: selectedCellAddress.row });
},
}, [])(ev);
]);
break;
}

View file

@ -503,7 +503,7 @@ function refreshGridItems() {
name: it.name,
host: it.host ?? '',
category: it.category ?? '',
aliases: it.aliases.join(' '),
aliases: it.aliases.join(','),
license: it.license ?? '',
isSensitive: it.isSensitive,
localOnly: it.localOnly,

View file

@ -372,6 +372,9 @@ onDeactivated(disposeBannerParallaxResizeObserver);
overflow: clip;
background-size: cover;
background-position: center;
view-timeline-name: --bannerParallax;
view-timeline-inset: var(--bannerParallaxInset, auto);
view-timeline-axis: block;
> .banner {
position: absolute;
@ -379,12 +382,13 @@ onDeactivated(disposeBannerParallaxResizeObserver);
left: 0;
width: 100%;
height: 300%;
background-size: 100% auto;
background-color: #4c5e6d;
background-repeat: repeat-y;
background-position: center;
will-change: transform;
transform: translateY(-50%);
animation: bannerParallaxKeyframes linear both;
animation-timeline: --bannerParallax;
animation-range: cover;
}
> .fade {
@ -741,26 +745,6 @@ onDeactivated(disposeBannerParallaxResizeObserver);
}
}
@supports (view-timeline-name: --name) {
.ftskorzw {
> .main {
> .profile > .main {
> .banner-container {
view-timeline-name: --bannerParallax;
view-timeline-inset: var(--bannerParallaxInset, auto);
view-timeline-axis: block;
> .banner {
animation: bannerParallaxKeyframes linear both;
animation-timeline: --bannerParallax;
animation-range: cover;
}
}
}
}
}
}
@keyframes bannerParallaxKeyframes {
from {
transform: translateY(-50%);

View file

@ -50,12 +50,12 @@ let latestHotkey: Pattern & { callback: CallbackFunction } | null = null;
//#endregion
//#region impl
export const makeHotkey = (keymap: Keymap, ignoreElements = IGNORE_ELEMENTS) => {
export const makeHotkey = (keymap: Keymap) => {
const actions = parseKeymap(keymap);
return (ev: KeyboardEvent) => {
if ('pswp' in window && window.pswp != null) return;
if (window.document.activeElement != null) {
if (ignoreElements.includes(window.document.activeElement.tagName.toLowerCase())) return;
if (IGNORE_ELEMENTS.includes(window.document.activeElement.tagName.toLowerCase())) return;
if (getHTMLElementOrNull(window.document.activeElement)?.isContentEditable) return;
}
for (const action of actions) {

View file

@ -0,0 +1,153 @@
/*
* SPDX-FileCopyrightText: syuilo and misskey-project
* SPDX-License-Identifier: AGPL-3.0-only
*/
/**
* {@link KeyboardEvent.code}
* @see https://developer.mozilla.org/en-US/docs/Web/API/UI_Events/Keyboard_event_code_values
*/
export type KeyCode = (
| 'Backspace'
| 'Tab'
| 'Enter'
| 'Shift'
| 'Control'
| 'Alt'
| 'Pause'
| 'CapsLock'
| 'Escape'
| 'Space'
| 'PageUp'
| 'PageDown'
| 'End'
| 'Home'
| 'ArrowLeft'
| 'ArrowUp'
| 'ArrowRight'
| 'ArrowDown'
| 'Insert'
| 'Delete'
| 'Digit0'
| 'Digit1'
| 'Digit2'
| 'Digit3'
| 'Digit4'
| 'Digit5'
| 'Digit6'
| 'Digit7'
| 'Digit8'
| 'Digit9'
| 'KeyA'
| 'KeyB'
| 'KeyC'
| 'KeyD'
| 'KeyE'
| 'KeyF'
| 'KeyG'
| 'KeyH'
| 'KeyI'
| 'KeyJ'
| 'KeyK'
| 'KeyL'
| 'KeyM'
| 'KeyN'
| 'KeyO'
| 'KeyP'
| 'KeyQ'
| 'KeyR'
| 'KeyS'
| 'KeyT'
| 'KeyU'
| 'KeyV'
| 'KeyW'
| 'KeyX'
| 'KeyY'
| 'KeyZ'
| 'MetaLeft'
| 'MetaRight'
| 'ContextMenu'
| 'F1'
| 'F2'
| 'F3'
| 'F4'
| 'F5'
| 'F6'
| 'F7'
| 'F8'
| 'F9'
| 'F10'
| 'F11'
| 'F12'
| 'NumLock'
| 'ScrollLock'
| 'Semicolon'
| 'Equal'
| 'Comma'
| 'Minus'
| 'Period'
| 'Slash'
| 'Backquote'
| 'BracketLeft'
| 'Backslash'
| 'BracketRight'
| 'Quote'
| 'Meta'
| 'AltGraph'
);
/**
*
*/
export type KeyModifier = (
| 'Shift'
| 'Control'
| 'Alt'
| 'Meta'
);
/**
*
*/
export type KeyState = (
| 'composing'
| 'repeat'
);
export type KeyEventHandler = {
modifiers?: KeyModifier[];
states?: KeyState[];
code: KeyCode | 'any';
handler: (event: KeyboardEvent) => void;
};
export function handleKeyEvent(event: KeyboardEvent, handlers: KeyEventHandler[]) {
function checkModifier(ev: KeyboardEvent, modifiers? : KeyModifier[]) {
if (modifiers) {
return modifiers.every(modifier => ev.getModifierState(modifier));
}
return true;
}
function checkState(ev: KeyboardEvent, states?: KeyState[]) {
if (states) {
return states.every(state => ev.getModifierState(state));
}
return true;
}
let hit = false;
for (const handler of handlers.filter(it => it.code === event.code)) {
if (checkModifier(event, handler.modifiers) && checkState(event, handler.states)) {
handler.handler(event);
hit = true;
break;
}
}
if (!hit) {
for (const handler of handlers.filter(it => it.code === 'any')) {
handler.handler(event);
}
}
}

View file

@ -11,17 +11,17 @@
"lint": "pnpm typecheck && pnpm eslint"
},
"devDependencies": {
"@types/node": "22.18.8",
"@types/node": "22.18.6",
"@types/wawoff2": "1.0.2",
"@typescript-eslint/eslint-plugin": "8.45.0",
"@typescript-eslint/parser": "8.45.0"
"@typescript-eslint/eslint-plugin": "8.44.1",
"@typescript-eslint/parser": "8.44.1"
},
"dependencies": {
"@tabler/icons-webfont": "3.35.0",
"harfbuzzjs": "0.4.13",
"harfbuzzjs": "0.4.12",
"tiny-glob": "0.2.9",
"tsx": "4.20.6",
"typescript": "5.9.3",
"typescript": "5.9.2",
"wawoff2": "2.0.1"
},
"files": [

View file

@ -23,15 +23,15 @@
},
"devDependencies": {
"@types/matter-js": "0.20.2",
"@types/node": "22.18.8",
"@types/seedrandom": "3.0.8",
"@typescript-eslint/eslint-plugin": "8.45.0",
"@typescript-eslint/parser": "8.45.0",
"esbuild": "0.25.10",
"execa": "9.6.0",
"glob": "11.0.3",
"@types/node": "22.18.6",
"@typescript-eslint/eslint-plugin": "8.44.1",
"@typescript-eslint/parser": "8.44.1",
"nodemon": "3.1.10",
"typescript": "5.9.3"
"execa": "9.6.0",
"typescript": "5.9.2",
"esbuild": "0.25.10",
"glob": "11.0.3"
},
"files": [
"built"

View file

@ -8,14 +8,14 @@
},
"devDependencies": {
"@readme/openapi-parser": "5.0.1",
"@types/node": "22.18.8",
"@typescript-eslint/eslint-plugin": "8.45.0",
"@typescript-eslint/parser": "8.45.0",
"@types/node": "22.18.6",
"@typescript-eslint/eslint-plugin": "8.44.1",
"@typescript-eslint/parser": "8.44.1",
"openapi-types": "12.1.3",
"openapi-typescript": "7.9.1",
"ts-case-convert": "2.1.0",
"tsx": "4.20.6",
"typescript": "5.9.3"
"typescript": "5.9.2"
},
"files": [
"built"

View file

@ -1,7 +1,7 @@
{
"type": "module",
"name": "misskey-js",
"version": "2025.10.1-alpha.1",
"version": "2025.10.0-rc.0",
"description": "Misskey SDK for JavaScript",
"license": "MIT",
"main": "./built/index.js",
@ -35,10 +35,10 @@
"directory": "packages/misskey-js"
},
"devDependencies": {
"@microsoft/api-extractor": "7.52.15",
"@types/node": "22.18.8",
"@typescript-eslint/eslint-plugin": "8.45.0",
"@typescript-eslint/parser": "8.45.0",
"@microsoft/api-extractor": "7.52.13",
"@types/node": "22.18.6",
"@typescript-eslint/eslint-plugin": "8.44.1",
"@typescript-eslint/parser": "8.44.1",
"@vitest/coverage-v8": "3.2.4",
"esbuild": "0.25.10",
"execa": "9.6.0",
@ -46,7 +46,7 @@
"ncp": "2.0.0",
"nodemon": "3.1.10",
"tsd": "0.33.0",
"typescript": "5.9.3",
"typescript": "5.9.2",
"vitest": "3.2.4",
"vitest-websocket-mock": "0.5.0"
},

View file

@ -22,14 +22,14 @@
"lint": "pnpm typecheck && pnpm eslint"
},
"devDependencies": {
"@types/node": "22.18.8",
"@typescript-eslint/eslint-plugin": "8.45.0",
"@typescript-eslint/parser": "8.45.0",
"esbuild": "0.25.10",
"@types/node": "22.18.6",
"@typescript-eslint/eslint-plugin": "8.44.1",
"@typescript-eslint/parser": "8.44.1",
"execa": "9.6.0",
"glob": "11.0.3",
"nodemon": "3.1.10",
"typescript": "5.9.3"
"typescript": "5.9.2",
"esbuild": "0.25.10",
"glob": "11.0.3"
},
"files": [
"built"

View file

@ -14,11 +14,11 @@
"misskey-js": "workspace:*"
},
"devDependencies": {
"@typescript-eslint/parser": "8.45.0",
"@typescript-eslint/parser": "8.44.1",
"@typescript/lib-webworker": "npm:@types/serviceworker@0.0.74",
"eslint-plugin-import": "2.32.0",
"nodemon": "3.1.10",
"typescript": "5.9.3"
"typescript": "5.9.2"
},
"type": "module"
}

4569
pnpm-lock.yaml generated

File diff suppressed because it is too large Load diff

View file

@ -9,12 +9,12 @@
"version": "1.0.0",
"devDependencies": {
"@types/mdast": "4.0.4",
"@types/node": "22.18.8",
"@types/node": "22.17.1",
"@vitest/coverage-v8": "3.2.4",
"mdast-util-to-string": "4.0.0",
"remark": "15.0.1",
"remark-parse": "11.0.0",
"typescript": "5.9.3",
"typescript": "5.9.2",
"unified": "11.0.5",
"vite": "6.3.6",
"vite-node": "3.2.4",
@ -940,12 +940,11 @@
"dev": true
},
"node_modules/@types/node": {
"version": "22.18.8",
"resolved": "https://registry.npmjs.org/@types/node/-/node-22.18.8.tgz",
"integrity": "sha512-pAZSHMiagDR7cARo/cch1f3rXy0AEXwsVsVH09FcyeJVAzCnGgmYis7P3JidtTUjyadhTeSo8TgRPswstghDaw==",
"version": "22.17.1",
"resolved": "https://registry.npmjs.org/@types/node/-/node-22.17.1.tgz",
"integrity": "sha512-y3tBaz+rjspDTylNjAX37jEC3TETEFGNJL6uQDxwF9/8GLLIjW1rvVHlynyuUKMnMr1Roq8jOv3vkopBjC4/VA==",
"dev": true,
"license": "MIT",
"peer": true,
"dependencies": {
"undici-types": "~6.21.0"
}
@ -2298,7 +2297,6 @@
"integrity": "sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg==",
"dev": true,
"license": "MIT",
"peer": true,
"engines": {
"node": ">=12"
},
@ -2714,9 +2712,9 @@
}
},
"node_modules/typescript": {
"version": "5.9.3",
"resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.3.tgz",
"integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==",
"version": "5.9.2",
"resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.2.tgz",
"integrity": "sha512-CWBzXQrc/qOkhidw1OzBTQuYRbfyxDXJMVJ1XNwUHGROVmuaeiEm3OslpZ1RV96d7SKKjZKrSJu3+t/xlw3R9A==",
"dev": true,
"license": "Apache-2.0",
"bin": {
@ -2844,7 +2842,6 @@
"integrity": "sha512-0msEVHJEScQbhkbVTb/4iHZdJ6SXp/AvxL2sjwYQFfBqleHtnCqv1J3sa9zbWz/6kW1m9Tfzn92vW+kZ1WV6QA==",
"dev": true,
"license": "MIT",
"peer": true,
"dependencies": {
"esbuild": "^0.25.0",
"fdir": "^6.4.4",
@ -2943,7 +2940,6 @@
"integrity": "sha512-LUCP5ev3GURDysTWiP47wRRUpLKMOfPh+yKTx3kVIEiu5KOMeqzpnYNsKyOoVrULivR8tLcks4+lga33Whn90A==",
"dev": true,
"license": "MIT",
"peer": true,
"dependencies": {
"@types/chai": "^5.2.2",
"@vitest/expect": "3.2.4",

View file

@ -10,12 +10,12 @@
},
"devDependencies": {
"@types/mdast": "4.0.4",
"@types/node": "22.18.8",
"@types/node": "22.17.1",
"@vitest/coverage-v8": "3.2.4",
"mdast-util-to-string": "4.0.0",
"remark": "15.0.1",
"remark-parse": "11.0.0",
"typescript": "5.9.3",
"typescript": "5.9.2",
"unified": "11.0.5",
"vite": "6.3.6",
"vite-node": "3.2.4",