Merge remote-tracking branch 'misskey-dev/develop' into io
This commit is contained in:
commit
c71c454103
127
.github/workflows/check-misskey-js-autogen.yml
vendored
Normal file
127
.github/workflows/check-misskey-js-autogen.yml
vendored
Normal file
|
@ -0,0 +1,127 @@
|
||||||
|
name: Check Misskey JS autogen
|
||||||
|
|
||||||
|
on:
|
||||||
|
pull_request:
|
||||||
|
branches:
|
||||||
|
- master
|
||||||
|
- develop
|
||||||
|
paths:
|
||||||
|
- packages/backend/**
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
check-misskey-js-autogen:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
permissions:
|
||||||
|
pull-requests: write
|
||||||
|
|
||||||
|
env:
|
||||||
|
api_json_names: "api-base.json api-head.json"
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: checkout
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
with:
|
||||||
|
submodules: true
|
||||||
|
|
||||||
|
- name: setup pnpm
|
||||||
|
uses: pnpm/action-setup@v2
|
||||||
|
with:
|
||||||
|
version: 8
|
||||||
|
|
||||||
|
- name: setup node
|
||||||
|
id: setup-node
|
||||||
|
uses: actions/setup-node@v4
|
||||||
|
with:
|
||||||
|
node-version-file: '.node-version'
|
||||||
|
cache: pnpm
|
||||||
|
|
||||||
|
- name: install dependencies
|
||||||
|
run: pnpm i --frozen-lockfile
|
||||||
|
|
||||||
|
- name: wait get-api-diff
|
||||||
|
uses: lewagon/wait-on-check-action@v1.3.3
|
||||||
|
with:
|
||||||
|
ref: ${{ github.event.pull_request.head.sha }}
|
||||||
|
check-regexp: get-from-misskey .+
|
||||||
|
repo-token: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
wait-interval: 30
|
||||||
|
|
||||||
|
- name: Download artifact
|
||||||
|
uses: actions/github-script@v7
|
||||||
|
with:
|
||||||
|
script: |
|
||||||
|
const fs = require('fs');
|
||||||
|
|
||||||
|
const workflows = await github.rest.actions.listWorkflowRunsForRepo({
|
||||||
|
owner: context.repo.owner,
|
||||||
|
repo: context.repo.repo,
|
||||||
|
head_sha: `${{ github.event.pull_request.head.sha }}`
|
||||||
|
}).then(x => x.data.workflow_runs);
|
||||||
|
|
||||||
|
console.log(workflows.map(x => ({name: x.name, title: x.display_title})));
|
||||||
|
|
||||||
|
const run_id = workflows.find(x => x.name.includes("Get api.json from Misskey")).id;
|
||||||
|
|
||||||
|
let allArtifacts = await github.rest.actions.listWorkflowRunArtifacts({
|
||||||
|
owner: context.repo.owner,
|
||||||
|
repo: context.repo.repo,
|
||||||
|
run_id: run_id,
|
||||||
|
});
|
||||||
|
|
||||||
|
let matchArtifacts = allArtifacts.data.artifacts.filter((artifact) => {
|
||||||
|
return artifact.name.startsWith("api-artifact-") || artifact.name == "api-artifact"
|
||||||
|
});
|
||||||
|
|
||||||
|
await Promise.all(matchArtifacts.map(async (artifact) => {
|
||||||
|
let download = await github.rest.actions.downloadArtifact({
|
||||||
|
owner: context.repo.owner,
|
||||||
|
repo: context.repo.repo,
|
||||||
|
artifact_id: artifact.id,
|
||||||
|
archive_format: 'zip',
|
||||||
|
});
|
||||||
|
await fs.promises.writeFile(`${process.env.GITHUB_WORKSPACE}/${artifact.name}.zip`, Buffer.from(download.data));
|
||||||
|
}));
|
||||||
|
|
||||||
|
- name: unzip artifacts
|
||||||
|
run: |-
|
||||||
|
find . -mindepth 1 -maxdepth 1 -type f -name '*.zip' -exec unzip {} -d . ';'
|
||||||
|
ls -la
|
||||||
|
|
||||||
|
- name: build autogen
|
||||||
|
run: |-
|
||||||
|
for name in $(echo $api_json_names)
|
||||||
|
do
|
||||||
|
checksum=$(mktemp)
|
||||||
|
mv $name packages/misskey-js/generator/api.json
|
||||||
|
|
||||||
|
cd packages/misskey-js/generator
|
||||||
|
pnpm run generate
|
||||||
|
find built -type f -exec sh -c 'echo $(sed -E "s/^\s+\*\s+generatedAt:.+$//" {} | sha256sum | cut -d" " -f 1) {}' \; > $checksum
|
||||||
|
cd ../../..
|
||||||
|
cp $checksum ${name}_checksum
|
||||||
|
done
|
||||||
|
|
||||||
|
- name: check update for type definitions
|
||||||
|
run: diff $(echo -n ${api_json_names} | awk -v RS=" " '{ printf "%s_checksum ", $0 }')
|
||||||
|
|
||||||
|
- name: send message
|
||||||
|
if: failure()
|
||||||
|
uses: thollander/actions-comment-pull-request@v2
|
||||||
|
with:
|
||||||
|
comment_tag: check-misskey-js-autogen
|
||||||
|
message: |-
|
||||||
|
Thank you for sending us a great Pull Request! 👍
|
||||||
|
Please regenerate misskey-js type definitions! 🙏
|
||||||
|
|
||||||
|
example:
|
||||||
|
```sh
|
||||||
|
pnpm run build-misskey-js-with-types
|
||||||
|
```
|
||||||
|
|
||||||
|
- name: send message
|
||||||
|
if: success()
|
||||||
|
uses: thollander/actions-comment-pull-request@v2
|
||||||
|
with:
|
||||||
|
comment_tag: check-misskey-js-autogen
|
||||||
|
mode: delete
|
||||||
|
message: "Thank you!"
|
|
@ -28,6 +28,7 @@
|
||||||
- Enhance: AiScriptを0.17.0に更新 [CHANGELOG](https://github.com/aiscript-dev/aiscript/blob/bb89d132b633a622d3cb0eff0d0cc7e476c0cfdd/CHANGELOG.md)
|
- Enhance: AiScriptを0.17.0に更新 [CHANGELOG](https://github.com/aiscript-dev/aiscript/blob/bb89d132b633a622d3cb0eff0d0cc7e476c0cfdd/CHANGELOG.md)
|
||||||
- 配列の範囲外・非整数のインデックスへの代入が完全禁止になるので注意
|
- 配列の範囲外・非整数のインデックスへの代入が完全禁止になるので注意
|
||||||
- Enhance: 絵文字ピッカー・オートコンプリートで、完全一致した絵文字を優先的に表示するように
|
- Enhance: 絵文字ピッカー・オートコンプリートで、完全一致した絵文字を優先的に表示するように
|
||||||
|
- Enhance: Playの説明欄にMFMを使えるように
|
||||||
- Fix: ネイティブモードの絵文字がモノクロにならないように
|
- Fix: ネイティブモードの絵文字がモノクロにならないように
|
||||||
- Fix: v2023.12.0で追加された「モデレーターがユーザーのアイコンもしくはバナー画像を未設定状態にできる機能」が管理画面上で正しく表示されていない問題を修正
|
- Fix: v2023.12.0で追加された「モデレーターがユーザーのアイコンもしくはバナー画像を未設定状態にできる機能」が管理画面上で正しく表示されていない問題を修正
|
||||||
- Fix: AiScriptの`readline`関数が不正な値を返すことがある問題のv2023.12.0時点での修正がPlay以外に適用されていないのを修正
|
- Fix: AiScriptの`readline`関数が不正な値を返すことがある問題のv2023.12.0時点での修正がPlay以外に適用されていないのを修正
|
||||||
|
@ -41,6 +42,7 @@
|
||||||
- Fix: `drive/files/update`でファイル名のバリデーションが機能していない問題を修正
|
- Fix: `drive/files/update`でファイル名のバリデーションが機能していない問題を修正
|
||||||
- Fix: `notes/create`で、`text`が空白文字のみで構成されているか`null`であって、かつ`text`だけであるリクエストに対するレスポンスが400になるように変更
|
- Fix: `notes/create`で、`text`が空白文字のみで構成されているか`null`であって、かつ`text`だけであるリクエストに対するレスポンスが400になるように変更
|
||||||
- Fix: `notes/create`で、`text`が空白文字のみで構成されていてかつリノート、ファイルまたは投票を含んでいるリクエストに対するレスポンスの`text`が`""`から`null`になるように変更
|
- Fix: `notes/create`で、`text`が空白文字のみで構成されていてかつリノート、ファイルまたは投票を含んでいるリクエストに対するレスポンスの`text`が`""`から`null`になるように変更
|
||||||
|
- Fix: ipv4とipv6の両方が利用可能な環境でallowedPrivateNetworksが設定されていた場合プライベートipの検証ができていなかった問題を修正
|
||||||
|
|
||||||
## 2023.12.2
|
## 2023.12.2
|
||||||
|
|
||||||
|
|
|
@ -145,7 +145,8 @@ export class DownloadService {
|
||||||
const parsedIp = ipaddr.parse(ip);
|
const parsedIp = ipaddr.parse(ip);
|
||||||
|
|
||||||
for (const net of this.config.allowedPrivateNetworks ?? []) {
|
for (const net of this.config.allowedPrivateNetworks ?? []) {
|
||||||
if (parsedIp.match(ipaddr.parseCIDR(net))) {
|
const cidr = ipaddr.parseCIDR(net);
|
||||||
|
if (cidr[0].kind() === parsedIp.kind() && parsedIp.match(ipaddr.parseCIDR(net))) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,7 +9,9 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||||
<header>
|
<header>
|
||||||
<h1 :title="flash.title">{{ flash.title }}</h1>
|
<h1 :title="flash.title">{{ flash.title }}</h1>
|
||||||
</header>
|
</header>
|
||||||
<p v-if="flash.summary" :title="flash.summary">{{ flash.summary.length > 85 ? flash.summary.slice(0, 85) + '…' : flash.summary }}</p>
|
<p v-if="flash.summary" :title="flash.summary">
|
||||||
|
<Mfm class="summaryMfm" :text="flash.summary" :plain="true" :nowrap="true"/>
|
||||||
|
</p>
|
||||||
<footer>
|
<footer>
|
||||||
<img class="icon" :src="flash.user.avatarUrl"/>
|
<img class="icon" :src="flash.user.avatarUrl"/>
|
||||||
<p>{{ userName(flash.user) }}</p>
|
<p>{{ userName(flash.user) }}</p>
|
||||||
|
@ -54,6 +56,12 @@ const props = defineProps<{
|
||||||
margin: 0;
|
margin: 0;
|
||||||
color: var(--urlPreviewText);
|
color: var(--urlPreviewText);
|
||||||
font-size: 0.8em;
|
font-size: 0.8em;
|
||||||
|
overflow: clip;
|
||||||
|
|
||||||
|
> .summaryMfm {
|
||||||
|
display: block;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
> footer {
|
> footer {
|
||||||
|
|
|
@ -11,7 +11,7 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||||
<MkInput v-model="title">
|
<MkInput v-model="title">
|
||||||
<template #label>{{ i18n.ts._play.title }}</template>
|
<template #label>{{ i18n.ts._play.title }}</template>
|
||||||
</MkInput>
|
</MkInput>
|
||||||
<MkTextarea v-model="summary">
|
<MkTextarea v-model="summary" :mfmAutocomplete="true" :mfmPreview="true">
|
||||||
<template #label>{{ i18n.ts._play.summary }}</template>
|
<template #label>{{ i18n.ts._play.summary }}</template>
|
||||||
</MkTextarea>
|
</MkTextarea>
|
||||||
<MkButton primary @click="selectPreset">{{ i18n.ts.selectFromPresets }}<i class="ti ti-chevron-down"></i></MkButton>
|
<MkButton primary @click="selectPreset">{{ i18n.ts.selectFromPresets }}<i class="ti ti-chevron-down"></i></MkButton>
|
||||||
|
|
|
@ -25,7 +25,7 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||||
<div v-else :class="$style.ready">
|
<div v-else :class="$style.ready">
|
||||||
<div class="_panel main">
|
<div class="_panel main">
|
||||||
<div class="title">{{ flash.title }}</div>
|
<div class="title">{{ flash.title }}</div>
|
||||||
<div class="summary">{{ flash.summary }}</div>
|
<div class="summary"><Mfm :text="flash.summary"/></div>
|
||||||
<MkButton class="start" gradate rounded large @click="start">Play</MkButton>
|
<MkButton class="start" gradate rounded large @click="start">Play</MkButton>
|
||||||
<div class="info">
|
<div class="info">
|
||||||
<span v-tooltip="i18n.ts.numberOfLikes"><i class="ti ti-heart"></i> {{ flash.likedCount }}</span>
|
<span v-tooltip="i18n.ts.numberOfLikes"><i class="ti ti-heart"></i> {{ flash.likedCount }}</span>
|
||||||
|
|
|
@ -207,9 +207,11 @@ SPDX-License-Identifier: AGPL-3.0-only
|
||||||
<div class="_gaps">
|
<div class="_gaps">
|
||||||
<MkFolder>
|
<MkFolder>
|
||||||
<template #label>{{ i18n.ts.additionalEmojiDictionary }}</template>
|
<template #label>{{ i18n.ts.additionalEmojiDictionary }}</template>
|
||||||
<div v-for="lang in emojiIndexLangs" class="_buttons">
|
<div class="_buttons">
|
||||||
<MkButton @click="downloadEmojiIndex(lang)"><i class="ti ti-download"></i> {{ lang }}{{ defaultStore.reactiveState.additionalUnicodeEmojiIndexes.value[lang] ? ` (${ i18n.ts.installed })` : '' }}</MkButton>
|
<template v-for="lang in emojiIndexLangs" :key="lang">
|
||||||
<MkButton v-if="defaultStore.reactiveState.additionalUnicodeEmojiIndexes.value[lang]" danger @click="removeEmojiIndex(lang)"><i class="ti ti-trash"></i> {{ i18n.ts.remove }}</MkButton>
|
<MkButton v-if="defaultStore.reactiveState.additionalUnicodeEmojiIndexes.value[lang]" danger @click="removeEmojiIndex(lang)"><i class="ti ti-trash"></i> {{ i18n.ts.remove }} ({{ getEmojiIndexLangName(lang) }})</MkButton>
|
||||||
|
<MkButton v-else @click="downloadEmojiIndex(lang)"><i class="ti ti-download"></i> {{ getEmojiIndexLangName(lang) }}{{ defaultStore.reactiveState.additionalUnicodeEmojiIndexes.value[lang] ? ` (${ i18n.ts.installed })` : '' }}</MkButton>
|
||||||
|
</template>
|
||||||
</div>
|
</div>
|
||||||
</MkFolder>
|
</MkFolder>
|
||||||
<FormLink to="/settings/deck">{{ i18n.ts.deck }}</FormLink>
|
<FormLink to="/settings/deck">{{ i18n.ts.deck }}</FormLink>
|
||||||
|
@ -341,15 +343,29 @@ watch([
|
||||||
await reloadAsk();
|
await reloadAsk();
|
||||||
});
|
});
|
||||||
|
|
||||||
const emojiIndexLangs = ['en-US'];
|
const emojiIndexLangs = ['en-US', 'ja-JP', 'ja-JP_hira'] as const;
|
||||||
|
|
||||||
function downloadEmojiIndex(lang: string) {
|
function getEmojiIndexLangName(targetLang: typeof emojiIndexLangs[number]) {
|
||||||
|
if (langs.find(x => x[0] === targetLang)) {
|
||||||
|
return langs.find(x => x[0] === targetLang)![1];
|
||||||
|
} else {
|
||||||
|
// 絵文字辞書限定の言語定義
|
||||||
|
switch (targetLang) {
|
||||||
|
case 'ja-JP_hira': return 'ひらがな';
|
||||||
|
default: return targetLang;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function downloadEmojiIndex(lang: typeof emojiIndexLangs[number]) {
|
||||||
async function main() {
|
async function main() {
|
||||||
const currentIndexes = defaultStore.state.additionalUnicodeEmojiIndexes;
|
const currentIndexes = defaultStore.state.additionalUnicodeEmojiIndexes;
|
||||||
|
|
||||||
function download() {
|
function download() {
|
||||||
switch (lang) {
|
switch (lang) {
|
||||||
case 'en-US': return import('../../unicode-emoji-indexes/en-US.json').then(x => x.default);
|
case 'en-US': return import('../../unicode-emoji-indexes/en-US.json').then(x => x.default);
|
||||||
|
case 'ja-JP': return import('../../unicode-emoji-indexes/ja-JP.json').then(x => x.default);
|
||||||
|
case 'ja-JP_hira': return import('../../unicode-emoji-indexes/ja-JP_hira.json').then(x => x.default);
|
||||||
default: throw new Error('unrecognized lang: ' + lang);
|
default: throw new Error('unrecognized lang: ' + lang);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
1865
packages/frontend/src/unicode-emoji-indexes/ja-JP.json
Normal file
1865
packages/frontend/src/unicode-emoji-indexes/ja-JP.json
Normal file
File diff suppressed because it is too large
Load diff
1865
packages/frontend/src/unicode-emoji-indexes/ja-JP_hira.json
Normal file
1865
packages/frontend/src/unicode-emoji-indexes/ja-JP_hira.json
Normal file
File diff suppressed because it is too large
Load diff
Loading…
Reference in a new issue