Merge remote-branch 'misskey/develop'

This commit is contained in:
NoriDev 2023-12-05 17:36:02 +09:00
commit 16ec2754ab
18 changed files with 1914 additions and 1989 deletions

View file

@ -58,6 +58,7 @@
- Fix: Social/Local/Home Timelineにてインスタンスミュートが効かない問題
- Fix: ユーザのノート一覧にてインスタンスミュートが効かない問題
- Fix: チャンネルのノート一覧にてインスタンスミュートが効かない問題
- Fix: 「みつける」が年越し時に壊れる問題を修正
## 2023.11.1

View file

@ -1,7 +1,7 @@
{
"name": "cherrypick",
"version": "4.6.0-beta.1",
"basedMisskeyVersion": "2023.12.0-beta.1",
"basedMisskeyVersion": "2023.12.0-beta.2",
"codename": "nasubi",
"repository": {
"type": "git",
@ -52,16 +52,16 @@
"execa": "8.0.1",
"cssnano": "6.0.1",
"js-yaml": "4.1.0",
"postcss": "8.4.31",
"postcss": "8.4.32",
"terser": "5.24.0",
"typescript": "5.3.2"
},
"devDependencies": {
"@typescript-eslint/eslint-plugin": "6.12.0",
"@typescript-eslint/parser": "6.12.0",
"@typescript-eslint/eslint-plugin": "6.13.1",
"@typescript-eslint/parser": "6.13.1",
"cross-env": "7.0.3",
"cypress": "13.6.0",
"eslint": "8.54.0",
"eslint": "8.55.0",
"start-server-and-test": "2.0.3",
"ncp": "2.0.0"
},

View file

@ -61,9 +61,9 @@
"dependencies": {
"@aws-sdk/client-s3": "3.412.0",
"@aws-sdk/lib-storage": "3.412.0",
"@bull-board/api": "5.9.2",
"@bull-board/fastify": "5.9.2",
"@bull-board/ui": "5.9.2",
"@bull-board/api": "5.10.1",
"@bull-board/fastify": "5.10.1",
"@bull-board/ui": "5.10.1",
"@discordapp/twemoji": "14.1.2",
"@fastify/accepts": "4.2.0",
"@fastify/cookie": "9.2.0",
@ -83,7 +83,7 @@
"@sinonjs/fake-timers": "11.2.2",
"@smithy/node-http-handler": "2.1.10",
"@swc/cli": "0.1.63",
"@swc/core": "1.3.99",
"@swc/core": "1.3.100",
"@vitalets/google-translate-api": "9.2.0",
"accepts": "1.3.8",
"ajv": "8.12.0",
@ -92,7 +92,7 @@
"bcryptjs": "2.4.3",
"blurhash": "2.0.5",
"body-parser": "1.20.2",
"bullmq": "4.14.2",
"bullmq": "4.14.4",
"cacheable-lookup": "7.0.0",
"cbor": "9.0.1",
"chalk": "5.3.0",
@ -120,7 +120,7 @@
"ipaddr.js": "2.1.0",
"is-svg": "5.0.0",
"js-yaml": "4.1.0",
"jsdom": "23.0.0",
"jsdom": "23.0.1",
"json5": "2.2.3",
"jsonld": "8.3.1",
"jsrsasign": "10.9.0",
@ -128,7 +128,7 @@
"microformats-parser": "1.5.2",
"mime-types": "2.1.35",
"ms": "3.0.0-canary.1",
"nanoid": "5.0.3",
"nanoid": "5.0.4",
"nested-property": "4.0.0",
"node-fetch": "3.3.2",
"nodemailer": "6.9.7",
@ -164,7 +164,7 @@
"stringz": "2.1.0",
"strip-ansi": "^7.1.0",
"summaly": "github:misskey-dev/summaly",
"systeminformation": "5.21.18",
"systeminformation": "5.21.20",
"tinycolor2": "1.6.0",
"tmp": "0.2.1",
"tsc-alias": "1.8.8",
@ -198,7 +198,7 @@
"@types/jsrsasign": "10.5.12",
"@types/mime-types": "2.1.4",
"@types/ms": "0.7.34",
"@types/node": "20.10.0",
"@types/node": "20.10.3",
"@types/node-fetch": "3.0.3",
"@types/nodemailer": "6.4.14",
"@types/oauth": "0.9.4",
@ -221,11 +221,11 @@
"@types/vary": "1.1.3",
"@types/web-push": "3.6.3",
"@types/ws": "8.5.10",
"@typescript-eslint/eslint-plugin": "6.12.0",
"@typescript-eslint/parser": "6.12.0",
"@typescript-eslint/eslint-plugin": "6.13.1",
"@typescript-eslint/parser": "6.13.1",
"aws-sdk-client-mock": "3.0.0",
"cross-env": "7.0.3",
"eslint": "8.54.0",
"eslint": "8.55.0",
"eslint-plugin-import": "2.29.0",
"execa": "8.0.1",
"jest": "29.7.0",

View file

@ -18,6 +18,7 @@ export type FanoutTimelineName =
| `localTimeline` // replies are not included
| `localTimelineWithFiles` // only non-reply notes with files are included
| `localTimelineWithReplies` // only replies are included
| `localTimelineWithReplyTo:${string}` // Only replies to specific local user are included. Parameter is reply user id.
| `localTimelineWithCats` // only notes with cats are included
// antenna

View file

@ -14,6 +14,8 @@ export const GALLERY_POSTS_RANKING_WINDOW = 1000 * 60 * 60 * 24 * 3; // 3日ご
const PER_USER_NOTES_RANKING_WINDOW = 1000 * 60 * 60 * 24 * 7; // 1週間ごと
const HASHTAG_RANKING_WINDOW = 1000 * 60 * 60; // 1時間ごと
const featuredEpoc = new Date('2023-01-01T00:00:00Z').getTime();
@Injectable()
export class FeaturedService {
constructor(
@ -24,7 +26,7 @@ export class FeaturedService {
@bindThis
private getCurrentWindow(windowRange: number): number {
const passed = new Date().getTime() - new Date(new Date().getFullYear(), 0, 1).getTime();
const passed = new Date().getTime() - featuredEpoc;
return Math.floor(passed / windowRange);
}

View file

@ -957,6 +957,9 @@ export class NoteCreateService implements OnApplicationShutdown {
if (note.visibility === 'public' && note.userHost == null) {
this.fanoutTimelineService.push('localTimelineWithReplies', note.id, 300, r);
if (note.replyUserHost == null) {
this.fanoutTimelineService.push(`localTimelineWithReplyTo:${note.replyUserId}`, note.id, 300 / 10, r);
}
}
} else {
this.fanoutTimelineService.push(`userTimeline:${user.id}`, note.id, note.userHost == null ? meta.perLocalUserUserTimelineCacheMax : meta.perRemoteUserUserTimelineCacheMax, r);

View file

@ -3,6 +3,18 @@
* SPDX-License-Identifier: AGPL-3.0-only
*/
const notificationRecieveConfig = {
type: 'object',
nullable: false, optional: true,
properties: {
type: {
type: 'string',
nullable: false, optional: false,
enum: ['all', 'following', 'follower', 'mutualFollow', 'list', 'never'],
},
},
} as const;
export const packedUserLiteSchema = {
type: 'object',
properties: {
@ -414,6 +426,7 @@ export const packedUserDetailedNotMeOnlySchema = {
notify: {
type: 'string',
nullable: false, optional: true,
enum: ['normal', 'none'],
},
withReplies: {
type: 'boolean',
@ -573,6 +586,20 @@ export const packedMeDetailedOnlySchema = {
notificationRecieveConfig: {
type: 'object',
nullable: false, optional: false,
properties: {
app: notificationRecieveConfig,
quote: notificationRecieveConfig,
reply: notificationRecieveConfig,
follow: notificationRecieveConfig,
renote: notificationRecieveConfig,
mention: notificationRecieveConfig,
reaction: notificationRecieveConfig,
pollEnded: notificationRecieveConfig,
achievementEarned: notificationRecieveConfig,
receiveFollowRequest: notificationRecieveConfig,
followRequestAccepted: notificationRecieveConfig,
groupInvited: notificationRecieveConfig,
},
},
emailNotificationTypes: {
type: 'array',
@ -717,6 +744,23 @@ export const packedMeDetailedOnlySchema = {
items: {
type: 'object',
nullable: false, optional: false,
properties: {
id: {
type: 'string',
nullable: false, optional: false,
format: 'id',
example: 'xxxxxxxxxx',
},
name: {
type: 'string',
nullable: false, optional: false,
},
lastUsed: {
type: 'string',
nullable: false, optional: false,
format: 'date-time',
},
},
},
},
//#endregion

View file

@ -42,7 +42,7 @@ export const meta = {
bothWithRepliesAndWithFiles: {
message: 'Specifying both withReplies and withFiles is not supported',
code: 'BOTH_WITH_REPLIES_AND_WITH_FILES',
id: 'dd9c8400-1cb5-4eef-8a31-200c5f933793'
id: 'dd9c8400-1cb5-4eef-8a31-200c5f933793',
},
},
} as const;
@ -118,9 +118,12 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
allowPartial: ps.allowPartial,
me,
useDbFallback: serverSettings.enableFanoutTimelineDbFallback,
redisTimelines: ps.withFiles ? ['localTimelineWithFiles'] : ['localTimeline', 'localTimelineWithReplies'],
redisTimelines:
ps.withFiles ? ['localTimelineWithFiles']
: ps.withReplies ? ['localTimeline', 'localTimelineWithReplies']
: me ? ['localTimeline', `localTimelineWithReplyTo:${me.id}`]
: ['localTimeline'],
alwaysIncludeMyNotes: true,
excludeReplies: !ps.withReplies,
excludePureRenotes: !ps.withRenotes,
dbFallback: async (untilId, sinceId, limit) => await this.getFromDb({
untilId,

View file

@ -24,10 +24,10 @@
"@microsoft/api-extractor": "7.38.3",
"@swc/jest": "0.2.29",
"@types/jest": "29.5.10",
"@types/node": "20.10.0",
"@typescript-eslint/eslint-plugin": "6.12.0",
"@typescript-eslint/parser": "6.12.0",
"eslint": "8.54.0",
"@types/node": "20.10.3",
"@typescript-eslint/eslint-plugin": "6.13.1",
"@typescript-eslint/parser": "6.13.1",
"eslint": "8.55.0",
"jest": "29.7.0",
"jest-fetch-mock": "3.0.3",
"jest-websocket-mock": "2.5.0",
@ -41,7 +41,7 @@
],
"dependencies": {
"@swc/cli": "0.1.63",
"@swc/core": "1.3.99",
"@swc/core": "1.3.100",
"eventemitter3": "5.0.1",
"reconnecting-websocket": "4.4.0"
}

View file

@ -1,6 +1,6 @@
/*
* version: 4.6.0-beta.1
* generatedAt: 2023-12-05T08:05:02.075Z
* generatedAt: 2023-12-05T08:31:06.220Z
*/
import type {

View file

@ -1,6 +1,6 @@
/*
* version: 4.6.0-beta.1
* generatedAt: 2023-12-05T08:05:02.073Z
* generatedAt: 2023-12-05T08:31:06.218Z
*/
import { operations } from './types.js';

View file

@ -1,6 +1,6 @@
/*
* version: 4.6.0-beta.1
* generatedAt: 2023-12-05T08:05:02.072Z
* generatedAt: 2023-12-05T08:31:06.217Z
*/
import { components } from './types.js';

View file

@ -3,7 +3,7 @@
/*
* version: 4.6.0-beta.1
* generatedAt: 2023-12-05T08:05:01.998Z
* generatedAt: 2023-12-05T08:31:06.141Z
*/
/**
@ -3492,7 +3492,8 @@ export type components = {
isBlocked?: boolean;
isMuted?: boolean;
isRenoteMuted?: boolean;
notify?: string;
/** @enum {string} */
notify?: 'normal' | 'none';
withReplies?: boolean;
};
MeDetailedOnly: {
@ -3528,7 +3529,56 @@ export type components = {
mutedWords: string[][];
hardMutedWords: string[][];
mutedInstances: string[] | null;
notificationRecieveConfig: Record<string, never>;
notificationRecieveConfig: {
app?: {
/** @enum {string} */
type: 'all' | 'following' | 'follower' | 'mutualFollow' | 'list' | 'never';
};
quote?: {
/** @enum {string} */
type: 'all' | 'following' | 'follower' | 'mutualFollow' | 'list' | 'never';
};
reply?: {
/** @enum {string} */
type: 'all' | 'following' | 'follower' | 'mutualFollow' | 'list' | 'never';
};
follow?: {
/** @enum {string} */
type: 'all' | 'following' | 'follower' | 'mutualFollow' | 'list' | 'never';
};
renote?: {
/** @enum {string} */
type: 'all' | 'following' | 'follower' | 'mutualFollow' | 'list' | 'never';
};
mention?: {
/** @enum {string} */
type: 'all' | 'following' | 'follower' | 'mutualFollow' | 'list' | 'never';
};
reaction?: {
/** @enum {string} */
type: 'all' | 'following' | 'follower' | 'mutualFollow' | 'list' | 'never';
};
pollEnded?: {
/** @enum {string} */
type: 'all' | 'following' | 'follower' | 'mutualFollow' | 'list' | 'never';
};
achievementEarned?: {
/** @enum {string} */
type: 'all' | 'following' | 'follower' | 'mutualFollow' | 'list' | 'never';
};
receiveFollowRequest?: {
/** @enum {string} */
type: 'all' | 'following' | 'follower' | 'mutualFollow' | 'list' | 'never';
};
followRequestAccepted?: {
/** @enum {string} */
type: 'all' | 'following' | 'follower' | 'mutualFollow' | 'list' | 'never';
};
groupInvited?: {
/** @enum {string} */
type: 'all' | 'following' | 'follower' | 'mutualFollow' | 'list' | 'never';
};
};
emailNotificationTypes: string[];
achievements: {
name: string;
@ -3562,7 +3612,16 @@ export type components = {
};
email?: string | null;
emailVerified?: boolean | null;
securityKeysList?: Record<string, never>[];
securityKeysList?: {
/**
* Format: id
* @example xxxxxxxxxx
*/
id: string;
name: string;
/** Format: date-time */
lastUsed: string;
}[];
};
UserDetailedNotMe: components['schemas']['UserLite'] & components['schemas']['UserDetailedNotMeOnly'];
MeDetailed: components['schemas']['UserLite'] & components['schemas']['UserDetailedNotMeOnly'] & components['schemas']['MeDetailedOnly'];

View file

@ -25,7 +25,7 @@
"@rollup/pluginutils": "5.0.5",
"@syuilo/aiscript": "0.16.0",
"@tabler/icons-webfont": "2.37.0",
"@vitejs/plugin-vue": "4.5.0",
"@vitejs/plugin-vue": "4.5.1",
"@vue-macros/reactivity-transform": "0.4.0",
"@vue/compiler-sfc": "3.3.9",
"astring": "1.8.6",
@ -49,26 +49,26 @@
"escape-regexp": "0.0.1",
"estree-walker": "3.0.3",
"eventemitter3": "5.0.1",
"gsap": "3.12.2",
"gsap": "3.12.3",
"idb-keyval": "6.2.1",
"insert-text-at-cursor": "0.3.0",
"is-file-animated": "1.0.2",
"json5": "2.2.3",
"matter-js": "0.19.0",
"photoswipe": "5.4.2",
"photoswipe": "5.4.3",
"pretendard": "^1.3.8",
"pretendard-jp": "^1.3.8",
"prismjs": "1.29.0",
"punycode": "2.3.1",
"querystring": "0.2.1",
"rollup": "4.6.0",
"rollup": "4.6.1",
"sanitize-html": "2.11.0",
"shiki": "^0.14.5",
"sass": "1.69.5",
"strict-event-emitter-types": "2.0.0",
"temml": "0.10.13",
"textarea-caret": "3.1.0",
"three": "0.158.0",
"three": "0.159.0",
"throttle-debounce": "5.0.0",
"tinycolor2": "1.6.0",
"tinyld": "^1.3.4",
@ -79,37 +79,37 @@
"uuid": "9.0.1",
"v-code-diff": "1.7.2",
"vanilla-tilt": "1.8.1",
"vite": "5.0.2",
"vite": "5.0.5",
"vue": "3.3.9",
"vue-prism-editor": "2.0.0-alpha.2",
"vuedraggable": "next"
},
"devDependencies": {
"@storybook/addon-actions": "7.5.3",
"@storybook/addon-essentials": "7.5.3",
"@storybook/addon-interactions": "7.5.3",
"@storybook/addon-links": "7.5.3",
"@storybook/addon-storysource": "7.5.3",
"@storybook/addons": "7.5.3",
"@storybook/blocks": "7.5.3",
"@storybook/core-events": "7.5.3",
"@storybook/addon-actions": "7.6.3",
"@storybook/addon-essentials": "7.6.3",
"@storybook/addon-interactions": "7.6.3",
"@storybook/addon-links": "7.6.3",
"@storybook/addon-storysource": "7.6.3",
"@storybook/addons": "7.6.3",
"@storybook/blocks": "7.6.3",
"@storybook/core-events": "7.6.3",
"@storybook/jest": "0.2.3",
"@storybook/manager-api": "7.5.3",
"@storybook/preview-api": "7.5.3",
"@storybook/react": "7.5.3",
"@storybook/react-vite": "7.5.3",
"@storybook/manager-api": "7.6.3",
"@storybook/preview-api": "7.6.3",
"@storybook/react": "7.6.3",
"@storybook/react-vite": "7.6.3",
"@storybook/testing-library": "0.2.2",
"@storybook/theming": "7.5.3",
"@storybook/types": "7.5.3",
"@storybook/vue3": "7.5.3",
"@storybook/vue3-vite": "7.5.3",
"@storybook/theming": "7.6.3",
"@storybook/types": "7.6.3",
"@storybook/vue3": "7.6.3",
"@storybook/vue3-vite": "7.6.3",
"@testing-library/vue": "8.0.1",
"@types/autosize": "^4.0.1",
"@types/escape-regexp": "0.0.3",
"@types/estree": "1.0.5",
"@types/matter-js": "0.19.5",
"@types/micromatch": "4.0.6",
"@types/node": "20.10.0",
"@types/node": "20.10.3",
"@types/prismjs": "^1.26.0",
"@types/punycode": "2.1.3",
"@types/sanitize-html": "2.9.5",
@ -118,34 +118,34 @@
"@types/uuid": "9.0.7",
"@types/websocket": "1.0.10",
"@types/ws": "8.5.10",
"@typescript-eslint/eslint-plugin": "6.12.0",
"@typescript-eslint/parser": "6.12.0",
"@typescript-eslint/eslint-plugin": "6.13.1",
"@typescript-eslint/parser": "6.13.1",
"@vitest/coverage-v8": "0.34.6",
"@vue/runtime-core": "3.3.9",
"acorn": "8.11.2",
"cross-env": "7.0.3",
"cypress": "13.6.0",
"eslint": "8.54.0",
"eslint": "8.55.0",
"eslint-plugin-import": "2.29.0",
"eslint-plugin-storybook": "^0.6.13",
"eslint-plugin-vue": "9.18.1",
"eslint-plugin-vue": "9.19.2",
"fast-glob": "3.3.2",
"happy-dom": "10.0.3",
"micromatch": "4.0.5",
"msw": "1.3.2",
"msw-storybook-addon": "1.10.0",
"nodemon": "3.0.1",
"nodemon": "3.0.2",
"prettier": "3.1.0",
"react": "18.2.0",
"react-dom": "18.2.0",
"start-server-and-test": "2.0.3",
"storybook": "7.5.3",
"storybook": "7.6.3",
"storybook-addon-misskey-theme": "github:misskey-dev/storybook-addon-misskey-theme",
"summaly": "github:misskey-dev/summaly",
"vite-plugin-turbosnap": "1.0.3",
"vitest": "0.34.6",
"vitest-fetch-mock": "0.2.2",
"vue-eslint-parser": "9.3.2",
"vue-tsc": "1.8.22"
"vue-tsc": "1.8.24"
}
}

View file

@ -69,7 +69,7 @@ SPDX-License-Identifier: AGPL-3.0-only
<MkInfo v-if="hasNotSpecifiedMentions" warn :class="$style.hasNotSpecifiedMentions">{{ i18n.ts.notSpecifiedMentionWarning }} - <button class="_textButton" @click="addMissingMention()">{{ i18n.ts.add }}</button></MkInfo>
<input v-show="useCw" ref="cwInputEl" v-model="cw" :class="$style.cw" :placeholder="i18n.ts.annotation" @keydown="onKeydown">
<div :class="[$style.textOuter, { [$style.withCw]: useCw }]">
<textarea ref="textareaEl" v-model="text" :class="[$style.text]" :disabled="posting || posted" :placeholder="placeholder" data-cy-post-form-text @keydown="onKeydown" @paste="onPaste" @compositionupdate="onCompositionUpdate" @compositionend="onCompositionEnd"/>
<textarea ref="textareaEl" v-model="text" :class="[$style.text]" :disabled="posting || posted" :readonly="textAreaReadOnly" :placeholder="placeholder" data-cy-post-form-text @keydown="onKeydown" @paste="onPaste" @compositionupdate="onCompositionUpdate" @compositionend="onCompositionEnd"/>
<div v-if="maxTextLength - textLength < 100" :class="['_acrylic', $style.textCount, { [$style.textOver]: textLength > maxTextLength }]">{{ maxTextLength - textLength }}</div>
</div>
<input v-show="withHashtags" ref="hashtagsInputEl" v-model="hashtags" :class="$style.hashtags" :placeholder="i18n.ts.hashtags" list="hashtags">
@ -102,7 +102,7 @@ SPDX-License-Identifier: AGPL-3.0-only
</template>
<script lang="ts" setup>
import { inject, watch, nextTick, onMounted, defineAsyncComponent, provide } from 'vue';
import { inject, watch, nextTick, onMounted, defineAsyncComponent, provide, ref } from 'vue';
import * as mfm from 'cherrypick-mfm-js';
import * as Misskey from 'cherrypick-js';
import insertTextAtCursor from 'insert-text-at-cursor';
@ -212,6 +212,7 @@ let recentHashtags = $ref(JSON.parse(miLocalStorage.getItem('hashtags') ?? '[]')
let imeText = $ref('');
let showingOptions = $ref(false);
let disableRightClick = $ref(false);
const textAreaReadOnly = ref(false);
const draftKey = $computed((): string => {
let key = props.channel ? `channel:${props.channel.id}` : '';
@ -912,12 +913,15 @@ function insertMention() {
}
async function insertEmoji(ev: MouseEvent) {
textAreaReadOnly.value = true;
emojiPicker.show(
ev.currentTarget ?? ev.target,
emoji => {
insertTextAtCursor(textareaEl, emoji);
},
() => {
textAreaReadOnly.value = false;
focus();
},
);

View file

@ -74,7 +74,7 @@ SPDX-License-Identifier: AGPL-3.0-only
<MkInfo v-if="hasNotSpecifiedMentions && showForm" warn :class="$style.hasNotSpecifiedMentions">{{ i18n.ts.notSpecifiedMentionWarning }} - <button class="_textButton" @click="addMissingMention()">{{ i18n.ts.add }}</button></MkInfo>
<input v-show="useCw && showForm" ref="cwInputEl" v-model="cw" :class="$style.cw" :placeholder="i18n.ts.annotation" @keydown="onKeydown">
<div :class="[$style.textOuter, { [$style.withCw]: useCw, [$style.showForm]: !showForm }]">
<textarea ref="textareaEl" v-model="text" :class="[$style.text]" :disabled="posting || posted || !$i" :placeholder="placeholder" data-cy-post-form-text @click="formClick" @keydown="onKeydown" @paste="onPaste" @compositionupdate="onCompositionUpdate" @compositionend="onCompositionEnd"/>
<textarea ref="textareaEl" v-model="text" :class="[$style.text]" :disabled="posting || posted" :readonly="textAreaReadOnly" :placeholder="placeholder" data-cy-post-form-text @keydown="onKeydown" @paste="onPaste" @compositionupdate="onCompositionUpdate" @compositionend="onCompositionEnd"/>
<div v-if="maxTextLength - textLength < 100" :class="['_acrylic', $style.textCount, { [$style.textOver]: textLength > maxTextLength }]">{{ maxTextLength - textLength }}</div>
<button v-if="!showForm" v-click-anime class="_button" :class="$style.submit" style="position: absolute; bottom: 0; right: 12px;" :disabled="!canPost && $i" data-cy-open-post-form-submit @click="$i ? post : signin()">
<div :class="$style.submitInner">
@ -122,7 +122,7 @@ SPDX-License-Identifier: AGPL-3.0-only
</template>
<script lang="ts" setup>
import { inject, watch, nextTick, onMounted, defineAsyncComponent, provide } from 'vue';
import { inject, watch, nextTick, onMounted, defineAsyncComponent, provide, ref } from 'vue';
import * as mfm from 'cherrypick-mfm-js';
import * as Misskey from 'cherrypick-js';
import insertTextAtCursor from 'insert-text-at-cursor';
@ -235,6 +235,7 @@ let recentHashtags = $ref(JSON.parse(miLocalStorage.getItem('hashtags') ?? '[]')
let imeText = $ref('');
let showingOptions = $ref(false);
let disableRightClick = $ref(false);
const textAreaReadOnly = ref(false);
const draftKey = $computed((): string => {
let key = props.channel ? `channel:${props.channel.id}` : '';
@ -933,12 +934,15 @@ function insertMention() {
}
async function insertEmoji(ev: MouseEvent) {
textAreaReadOnly.value = true;
emojiPicker.show(
ev.currentTarget ?? ev.target,
emoji => {
insertTextAtCursor(textareaEl, emoji);
},
() => {
textAreaReadOnly.value = false;
focus();
},
);

View file

@ -14,9 +14,9 @@
"cherrypick-js": "workspace:*"
},
"devDependencies": {
"@typescript-eslint/parser": "6.12.0",
"@typescript-eslint/parser": "6.13.1",
"@typescript/lib-webworker": "npm:@types/serviceworker@0.0.67",
"eslint": "8.54.0",
"eslint": "8.55.0",
"eslint-plugin-import": "2.29.0",
"typescript": "5.3.2"
},

File diff suppressed because it is too large Load diff