From 960c4df48e31483209ac0421a009686685acd82d Mon Sep 17 00:00:00 2001
From: zyoshoka <107108195+zyoshoka@users.noreply.github.com>
Date: Sun, 7 Apr 2024 21:16:37 +0900
Subject: enhance(frontend): better condition for posting and displaying Notes
 (#13670)

* enhance(frontend): better condition for posting and displaying Notes

* Update CHANGELOG.md
---
 packages/frontend/src/components/MkPostForm.vue | 8 +++++++-
 1 file changed, 7 insertions(+), 1 deletion(-)

(limited to 'packages/frontend/src/components/MkPostForm.vue')

diff --git a/packages/frontend/src/components/MkPostForm.vue b/packages/frontend/src/components/MkPostForm.vue
index e03faeaf55..014b866fbd 100644
--- a/packages/frontend/src/components/MkPostForm.vue
+++ b/packages/frontend/src/components/MkPostForm.vue
@@ -253,7 +253,13 @@ const maxTextLength = computed((): number => {
 
 const canPost = computed((): boolean => {
 	return !props.mock && !posting.value && !posted.value &&
-		(1 <= textLength.value || 1 <= files.value.length || !!poll.value || !!props.renote) &&
+		(
+			1 <= textLength.value ||
+			1 <= files.value.length ||
+			poll.value != null ||
+			props.renote != null ||
+			(props.reply != null && quoteId.value != null)
+		) &&
 		(textLength.value <= maxTextLength.value) &&
 		(!poll.value || poll.value.choices.length >= 2);
 });
-- 
cgit v1.2.3-freya


From e9e877f64e83bf34f90373a366567b852d3cce18 Mon Sep 17 00:00:00 2001
From: anatawa12 <anatawa12@icloud.com>
Date: Tue, 16 Apr 2024 13:37:14 +0900
Subject: fix: ダイレクト投稿の宛先が保存されない (#13717)
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

* fix: ダイレクト投稿の宛先が保存されない

* fix: 同じユーザーが複数回宛先に追加できる問題

* fix: 関係ないユーザーが宛先に追加される可能性がある
---
 CHANGELOG.md                                    |  1 +
 packages/frontend/src/components/MkPostForm.vue | 12 +++++++++++-
 2 files changed, 12 insertions(+), 1 deletion(-)

(limited to 'packages/frontend/src/components/MkPostForm.vue')

diff --git a/CHANGELOG.md b/CHANGELOG.md
index de18aded0c..4aad65d837 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -40,6 +40,7 @@
 - Fix: CWのみの引用リノートが詳細ページで純粋なリノートとして誤って扱われてしまう問題を修正
 - Fix: ノート詳細ページにおいてCW付き引用リノートのCWボタンのラベルに「引用」が含まれていない問題を修正
 - Fix: ダイアログの入力で字数制限に違反していてもEnterキーが押せてしまう問題を修正
+- Fix: ダイレクト投稿の宛先が保存されない問題を修正
 
 ### Server
 - Enhance: エンドポイント`antennas/update`の必須項目を`antennaId`のみに
diff --git a/packages/frontend/src/components/MkPostForm.vue b/packages/frontend/src/components/MkPostForm.vue
index 014b866fbd..d7efca9de9 100644
--- a/packages/frontend/src/components/MkPostForm.vue
+++ b/packages/frontend/src/components/MkPostForm.vue
@@ -388,7 +388,7 @@ function addMissingMention() {
 	for (const x of extractMentions(ast)) {
 		if (!visibleUsers.value.some(u => (u.username === x.username) && (u.host === x.host))) {
 			misskeyApi('users/show', { username: x.username, host: x.host }).then(user => {
-				visibleUsers.value.push(user);
+				pushVisibleUser(user);
 			});
 		}
 	}
@@ -679,6 +679,7 @@ function saveDraft() {
 			localOnly: localOnly.value,
 			files: files.value,
 			poll: poll.value,
+			visibleUserIds: visibility.value === 'specified' ? visibleUsers.value.map(x => x.id) : undefined,
 		},
 	};
 
@@ -960,6 +961,15 @@ onMounted(() => {
 				if (draft.data.poll) {
 					poll.value = draft.data.poll;
 				}
+				if (draft.data.visibleUserIds) {
+					misskeyApi('users/show', { userIds: draft.data.visibleUserIds }).then(users => {
+						for (let i = 0; i < users.length; i++) {
+							if (users[i].id === draft.data.visibleUserIds[i]) {
+								pushVisibleUser(users[i]);
+							}
+						}
+					});
+				}
 			}
 		}
 
-- 
cgit v1.2.3-freya


From 9f66f229537915f47da8e6e08e92a78be390f454 Mon Sep 17 00:00:00 2001
From: taiy <53635909+taiyme@users.noreply.github.com>
Date: Wed, 1 May 2024 15:29:38 +0900
Subject: fix(frontend): 連合なしの状態の読み書きができない問題 (#13777)
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

* fix: 連合なしの状態の読み書きができない問題

* update changelog

* fix types: https://github.com/misskey-dev/misskey/pull/13777#discussion_r1585901601
---
 CHANGELOG.md                                          | 1 +
 packages/frontend/src/components/MkPostForm.vue       | 8 ++++++--
 packages/frontend/src/components/MkPostFormDialog.vue | 6 ++++--
 packages/frontend/src/scripts/get-note-menu.ts        | 5 ++---
 packages/frontend/src/store.ts                        | 4 ++--
 5 files changed, 15 insertions(+), 9 deletions(-)

(limited to 'packages/frontend/src/components/MkPostForm.vue')

diff --git a/CHANGELOG.md b/CHANGELOG.md
index 68015596bd..4b65550daf 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -56,6 +56,7 @@
 - Fix: ページのOGP URLが間違っているのを修正
 - Fix: リバーシの対局を正しく共有できないことがある問題を修正
 - Fix: 通知をグループ化している際に、人数が正常に表示されないことがある問題を修正
+- Fix: 連合なしの状態の読み書きができない問題を修正
 
 ### Server
 - Enhance: エンドポイント`antennas/update`の必須項目を`antennaId`のみに
diff --git a/packages/frontend/src/components/MkPostForm.vue b/packages/frontend/src/components/MkPostForm.vue
index d7efca9de9..7dbc127298 100644
--- a/packages/frontend/src/components/MkPostForm.vue
+++ b/packages/frontend/src/components/MkPostForm.vue
@@ -156,6 +156,7 @@ const props = withDefaults(defineProps<{
 	initialVisibleUsers: () => [],
 	autofocus: true,
 	mock: false,
+	initialLocalOnly: undefined,
 });
 
 provide('mock', props.mock);
@@ -185,8 +186,8 @@ watch(showPreview, () => defaultStore.set('showPreview', showPreview.value));
 const showAddMfmFunction = ref(defaultStore.state.enableQuickAddMfmFunction);
 watch(showAddMfmFunction, () => defaultStore.set('enableQuickAddMfmFunction', showAddMfmFunction.value));
 const cw = ref<string | null>(props.initialCw ?? null);
-const localOnly = ref<boolean>(props.initialLocalOnly ?? defaultStore.state.rememberNoteVisibility ? defaultStore.state.localOnly : defaultStore.state.defaultNoteLocalOnly);
-const visibility = ref(props.initialVisibility ?? (defaultStore.state.rememberNoteVisibility ? defaultStore.state.visibility : defaultStore.state.defaultNoteVisibility) as typeof Misskey.noteVisibilities[number]);
+const localOnly = ref(props.initialLocalOnly ?? (defaultStore.state.rememberNoteVisibility ? defaultStore.state.localOnly : defaultStore.state.defaultNoteLocalOnly));
+const visibility = ref(props.initialVisibility ?? (defaultStore.state.rememberNoteVisibility ? defaultStore.state.visibility : defaultStore.state.defaultNoteVisibility));
 const visibleUsers = ref<Misskey.entities.UserDetailed[]>([]);
 if (props.initialVisibleUsers) {
 	props.initialVisibleUsers.forEach(pushVisibleUser);
@@ -518,6 +519,9 @@ async function toggleLocalOnly() {
 	}
 
 	localOnly.value = !localOnly.value;
+	if (defaultStore.state.rememberNoteVisibility) {
+		defaultStore.set('localOnly', localOnly.value);
+	}
 }
 
 async function toggleReactionAcceptance() {
diff --git a/packages/frontend/src/components/MkPostFormDialog.vue b/packages/frontend/src/components/MkPostFormDialog.vue
index 6331dfed29..ac37cb31bc 100644
--- a/packages/frontend/src/components/MkPostFormDialog.vue
+++ b/packages/frontend/src/components/MkPostFormDialog.vue
@@ -15,7 +15,7 @@ import * as Misskey from 'misskey-js';
 import MkModal from '@/components/MkModal.vue';
 import MkPostForm from '@/components/MkPostForm.vue';
 
-const props = defineProps<{
+const props = withDefaults(defineProps<{
 	reply?: Misskey.entities.Note;
 	renote?: Misskey.entities.Note;
 	channel?: any; // TODO
@@ -31,7 +31,9 @@ const props = defineProps<{
 	instant?: boolean;
 	fixed?: boolean;
 	autofocus?: boolean;
-}>();
+}>(), {
+	initialLocalOnly: undefined,
+});
 
 const emit = defineEmits<{
 	(ev: 'closed'): void;
diff --git a/packages/frontend/src/scripts/get-note-menu.ts b/packages/frontend/src/scripts/get-note-menu.ts
index 87921bc67f..2cd21c1edc 100644
--- a/packages/frontend/src/scripts/get-note-menu.ts
+++ b/packages/frontend/src/scripts/get-note-menu.ts
@@ -492,10 +492,9 @@ export function getNoteMenu(props: {
 	};
 }
 
-type Visibility = 'public' | 'home' | 'followers' | 'specified';
+type Visibility = (typeof Misskey.noteVisibilities)[number];
 
-// defaultStore.state.visibilityがstringなためstringも受け付けている
-function smallerVisibility(a: Visibility | string, b: Visibility | string): Visibility {
+function smallerVisibility(a: Visibility, b: Visibility): Visibility {
 	if (a === 'specified' || b === 'specified') return 'specified';
 	if (a === 'followers' || b === 'followers') return 'followers';
 	if (a === 'home' || b === 'home') return 'home';
diff --git a/packages/frontend/src/store.ts b/packages/frontend/src/store.ts
index e6a348b79f..e8eb5a1ed7 100644
--- a/packages/frontend/src/store.ts
+++ b/packages/frontend/src/store.ts
@@ -94,7 +94,7 @@ export const defaultStore = markRaw(new Storage('base', {
 	},
 	defaultNoteVisibility: {
 		where: 'account',
-		default: 'public',
+		default: 'public' as (typeof Misskey.noteVisibilities)[number],
 	},
 	defaultNoteLocalOnly: {
 		where: 'account',
@@ -150,7 +150,7 @@ export const defaultStore = markRaw(new Storage('base', {
 	},
 	visibility: {
 		where: 'deviceAccount',
-		default: 'public' as 'public' | 'home' | 'followers' | 'specified',
+		default: 'public' as (typeof Misskey.noteVisibilities)[number],
 	},
 	localOnly: {
 		where: 'deviceAccount',
-- 
cgit v1.2.3-freya


From 5836bd85df4fe511f0ab766349eb4c9d1e1e5fdf Mon Sep 17 00:00:00 2001
From: anatawa12 <anatawa12@icloud.com>
Date: Mon, 20 May 2024 19:25:50 +0900
Subject: fix:
 複数idを指定する`users/show`が関係ないユーザを返すことがある問題を修正
 (#13765)
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

* fix: 複数idを指定する`users/show`が関係ないユーザを返すことがある問題を修正

* test: fix misskey js test

* chore: user/showがnullを返さないように

* chore: pass lambda instead of pushVisibleUser
---
 CHANGELOG.md                                            |  1 +
 packages/backend/src/misc/json-schema.ts                |  2 +-
 packages/backend/src/server/api/endpoints/users/show.ts |  4 +++-
 packages/frontend/src/components/MkPostForm.vue         | 10 +++-------
 4 files changed, 8 insertions(+), 9 deletions(-)

(limited to 'packages/frontend/src/components/MkPostForm.vue')

diff --git a/CHANGELOG.md b/CHANGELOG.md
index d0b98db96a..a9944d4b5e 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -83,6 +83,7 @@
 - Fix: AP Link等は添付ファイル扱いしないようになど (#13754)
 - Fix: FTTが有効かつsinceIdのみを指定した場合に帰って来るレスポンスが逆順である問題を修正
 - Fix: `/i/notifications`に `includeTypes`か`excludeTypes`を指定しているとき、通知が存在するのに空配列を返すことがある問題を修正
+- Fix: 複数idを指定する`users/show`が関係ないユーザを返すことがある問題を修正
 
 ## 2024.3.1
 
diff --git a/packages/backend/src/misc/json-schema.ts b/packages/backend/src/misc/json-schema.ts
index a620d7c94b..41e5bfe9e4 100644
--- a/packages/backend/src/misc/json-schema.ts
+++ b/packages/backend/src/misc/json-schema.ts
@@ -228,7 +228,7 @@ export type SchemaTypeDef<p extends Schema> =
 			p['items']['allOf'] extends ReadonlyArray<Schema> ? UnionToIntersection<UnionSchemaType<NonNullable<p['items']['allOf']>>>[] :
 			never
 		) :
-		p['items'] extends NonNullable<Schema> ? SchemaTypeDef<p['items']>[] :
+		p['items'] extends NonNullable<Schema> ? SchemaType<p['items']>[] :
 		any[]
 	) :
 	p['anyOf'] extends ReadonlyArray<Schema> ? UnionSchemaType<p['anyOf']> & PartialIntersection<UnionSchemaType<p['anyOf']>> :
diff --git a/packages/backend/src/server/api/endpoints/users/show.ts b/packages/backend/src/server/api/endpoints/users/show.ts
index bd81989cb9..26cfa921c5 100644
--- a/packages/backend/src/server/api/endpoints/users/show.ts
+++ b/packages/backend/src/server/api/endpoints/users/show.ts
@@ -110,9 +110,11 @@ export default class extends Endpoint<typeof meta, typeof paramDef> { // eslint-
 				});
 
 				// リクエストされた通りに並べ替え
+				// 順番は保持されるけど数は減ってる可能性がある
 				const _users: MiUser[] = [];
 				for (const id of ps.userIds) {
-					_users.push(users.find(x => x.id === id)!);
+					const user = users.find(x => x.id === id);
+					if (user != null) _users.push(user);
 				}
 
 				return await Promise.all(_users.map(u => this.userEntityService.pack(u, me, {
diff --git a/packages/frontend/src/components/MkPostForm.vue b/packages/frontend/src/components/MkPostForm.vue
index 7dbc127298..41d603e40f 100644
--- a/packages/frontend/src/components/MkPostForm.vue
+++ b/packages/frontend/src/components/MkPostForm.vue
@@ -190,7 +190,7 @@ const localOnly = ref(props.initialLocalOnly ?? (defaultStore.state.rememberNote
 const visibility = ref(props.initialVisibility ?? (defaultStore.state.rememberNoteVisibility ? defaultStore.state.visibility : defaultStore.state.defaultNoteVisibility));
 const visibleUsers = ref<Misskey.entities.UserDetailed[]>([]);
 if (props.initialVisibleUsers) {
-	props.initialVisibleUsers.forEach(pushVisibleUser);
+	props.initialVisibleUsers.forEach(u => pushVisibleUser(u));
 }
 const reactionAcceptance = ref(defaultStore.state.reactionAcceptance);
 const autocomplete = ref(null);
@@ -336,7 +336,7 @@ if (props.reply && ['home', 'followers', 'specified'].includes(props.reply.visib
 			misskeyApi('users/show', {
 				userIds: props.reply.visibleUserIds.filter(uid => uid !== $i.id && uid !== props.reply?.userId),
 			}).then(users => {
-				users.forEach(pushVisibleUser);
+				users.forEach(u => pushVisibleUser(u));
 			});
 		}
 
@@ -967,11 +967,7 @@ onMounted(() => {
 				}
 				if (draft.data.visibleUserIds) {
 					misskeyApi('users/show', { userIds: draft.data.visibleUserIds }).then(users => {
-						for (let i = 0; i < users.length; i++) {
-							if (users[i].id === draft.data.visibleUserIds[i]) {
-								pushVisibleUser(users[i]);
-							}
-						}
+						users.forEach(u => pushVisibleUser(u));
 					});
 				}
 			}
-- 
cgit v1.2.3-freya


From aafa669cf59778ed695632b45af0408cc9c3f038 Mon Sep 17 00:00:00 2001
From: anatawa12 <anatawa12@icloud.com>
Date: Thu, 23 May 2024 13:15:22 +0900
Subject: feat(frontend):
 長いテキストをペーストした際にテキストファイルとして添付するかどうかを選択できるように
 (#13862)
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

* feat(frontend): ask if attach as file if clipboard text is very long

* docs(changelog): 長いテキストをペーストした際にテキストファイルとして添付するかどうかを選択できるように
---
 CHANGELOG.md                                    |  1 +
 locales/index.d.ts                              |  6 +++++-
 locales/ja-JP.yml                               |  1 +
 packages/frontend/src/components/MkPostForm.vue | 17 +++++++++++++++++
 4 files changed, 24 insertions(+), 1 deletion(-)

(limited to 'packages/frontend/src/components/MkPostForm.vue')

diff --git a/CHANGELOG.md b/CHANGELOG.md
index 9bdc1d135a..ce66d779a3 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -42,6 +42,7 @@
 - Enhance: `Ui:C:postForm` および `Ui:C:postFormButton` に `localOnly` と `visibility` を設定できるように
 - Enhance: AiScriptを0.18.0にバージョンアップ
 - Enhance: 通常のノートでも、お気に入りに登録したチャンネルにリノートできるように
+- Enhance: 長いテキストをペーストした際にテキストファイルとして添付するかどうかを選択できるように
 - Fix: 一部のページ内リンクが正しく動作しない問題を修正
 - Fix: 周年の実績が閏年を考慮しない問題を修正
 - Fix: ローカルURLのプレビューポップアップが左上に表示される
diff --git a/locales/index.d.ts b/locales/index.d.ts
index 70741b6460..d5d6ef0f34 100644
--- a/locales/index.d.ts
+++ b/locales/index.d.ts
@@ -917,7 +917,7 @@ export interface Locale extends ILocale {
      */
     "silencedInstances": string;
     /**
-     * サイレンスしたいサーバーのホストを改行で区切って設定します。サイレンスされたサーバーに所属するアカウントはすべて「サイレンス」として扱われ、フォローがすべてリクエストになり、フォロワーでないローカルアカウントにはメンションできなくなります。ブロックしたインスタンスには影響しません。
+     * サイレンスしたいサーバーのホストを改行で区切って設定します。サイレンスされたサーバーに所属するアカウントはすべて「サイレンス」として扱われ、フォローがすべてリクエストになります。ブロックしたインスタンスには影響しません。
      */
     "silencedInstancesDescription": string;
     /**
@@ -1900,6 +1900,10 @@ export interface Locale extends ILocale {
      * 引用として添付しますか？
      */
     "quoteQuestion": string;
+    /**
+     * クリップボードのテキストが長いです。テキストファイルとして添付しますか？
+     */
+    "attachAsFileQuestion": string;
     /**
      * まだチャットはありません
      */
diff --git a/locales/ja-JP.yml b/locales/ja-JP.yml
index 626e3f30f8..9aa1e6e6a0 100644
--- a/locales/ja-JP.yml
+++ b/locales/ja-JP.yml
@@ -471,6 +471,7 @@ retype: "再入力"
 noteOf: "{user}のノート"
 quoteAttached: "引用付き"
 quoteQuestion: "引用として添付しますか？"
+attachAsFileQuestion: "クリップボードのテキストが長いです。テキストファイルとして添付しますか？"
 noMessagesYet: "まだチャットはありません"
 newMessageExists: "新しいメッセージがあります"
 onlyOneFileCanBeAttached: "メッセージに添付できるファイルはひとつです"
diff --git a/packages/frontend/src/components/MkPostForm.vue b/packages/frontend/src/components/MkPostForm.vue
index 41d603e40f..1df9007681 100644
--- a/packages/frontend/src/components/MkPostForm.vue
+++ b/packages/frontend/src/components/MkPostForm.vue
@@ -612,6 +612,23 @@ async function onPaste(ev: ClipboardEvent) {
 			quoteId.value = paste.substring(url.length).match(/^\/notes\/(.+?)\/?$/)?.[1] ?? null;
 		});
 	}
+
+	if (paste.length > 1000) {
+		ev.preventDefault();
+		os.confirm({
+			type: 'info',
+			text: i18n.ts.attachAsFileQuestion,
+		}).then(({ canceled }) => {
+			if (canceled) {
+				insertTextAtCursor(textareaEl.value, paste);
+				return;
+			}
+
+			const fileName = formatTimeString(new Date(), defaultStore.state.pastedFileName).replace(/{{number}}/g, "0");
+			const file = new File([paste], `${fileName}.txt`, { type: "text/plain" });
+			upload(file, `${fileName}.txt`);
+		});
+	}
 }
 
 function onDragover(ev) {
-- 
cgit v1.2.3-freya

