* fix(frontend): #13089 を修正 * fix * 正規表現を強化 * fix
This commit is contained in:
		
							parent
							
								
									09d30fef5b
								
							
						
					
					
						commit
						722acf5986
					
				
					 7 changed files with 56 additions and 28 deletions
				
			
		
							
								
								
									
										2
									
								
								locales/index.d.ts
									
										
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								locales/index.d.ts
									
										
									
									
										vendored
									
									
								
							| 
						 | 
				
			
			@ -5004,7 +5004,7 @@ export interface Locale extends ILocale {
 | 
			
		|||
     * お問い合わせ
 | 
			
		||||
     */
 | 
			
		||||
    "inquiry": string;
 | 
			
		||||
     /**
 | 
			
		||||
    /**
 | 
			
		||||
     * もう一度お試しください。
 | 
			
		||||
     */
 | 
			
		||||
    "tryAgain": string;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -174,7 +174,7 @@ import MkPoll from '@/components/MkPoll.vue';
 | 
			
		|||
import MkUsersTooltip from '@/components/MkUsersTooltip.vue';
 | 
			
		||||
import MkUrlPreview from '@/components/MkUrlPreview.vue';
 | 
			
		||||
import MkInstanceTicker from '@/components/MkInstanceTicker.vue';
 | 
			
		||||
import { pleaseLogin } from '@/scripts/please-login.js';
 | 
			
		||||
import { pleaseLogin, type OpenOnRemoteOptions } from '@/scripts/please-login.js';
 | 
			
		||||
import { checkWordMute } from '@/scripts/check-word-mute.js';
 | 
			
		||||
import { userPage } from '@/filters/user.js';
 | 
			
		||||
import number from '@/filters/number.js';
 | 
			
		||||
| 
						 | 
				
			
			@ -279,10 +279,10 @@ const renoteCollapsed = ref(
 | 
			
		|||
	),
 | 
			
		||||
);
 | 
			
		||||
 | 
			
		||||
const pleaseLoginContext = {
 | 
			
		||||
const pleaseLoginContext = computed<OpenOnRemoteOptions>(() => ({
 | 
			
		||||
	type: 'lookup',
 | 
			
		||||
	path: `https://${host}/notes/${appearNote.value.id}`,
 | 
			
		||||
} as const;
 | 
			
		||||
	url: `https://${host}/notes/${appearNote.value.id}`,
 | 
			
		||||
}));
 | 
			
		||||
 | 
			
		||||
/* Overload FunctionにLintが対応していないのでコメントアウト
 | 
			
		||||
function checkMute(noteToCheck: Misskey.entities.Note, mutedWords: Array<string | string[]> | undefined | null, checkOnly: true): boolean;
 | 
			
		||||
| 
						 | 
				
			
			@ -417,7 +417,7 @@ if (!props.mock) {
 | 
			
		|||
}
 | 
			
		||||
 | 
			
		||||
function renote(viaKeyboard = false) {
 | 
			
		||||
	pleaseLogin(undefined, pleaseLoginContext);
 | 
			
		||||
	pleaseLogin(undefined, pleaseLoginContext.value);
 | 
			
		||||
	showMovedDialog();
 | 
			
		||||
 | 
			
		||||
	const { menu } = getRenoteMenu({ note: note.value, renoteButton, mock: props.mock });
 | 
			
		||||
| 
						 | 
				
			
			@ -427,7 +427,7 @@ function renote(viaKeyboard = false) {
 | 
			
		|||
}
 | 
			
		||||
 | 
			
		||||
function reply(): void {
 | 
			
		||||
	pleaseLogin(undefined, pleaseLoginContext);
 | 
			
		||||
	pleaseLogin(undefined, pleaseLoginContext.value);
 | 
			
		||||
	if (props.mock) {
 | 
			
		||||
		return;
 | 
			
		||||
	}
 | 
			
		||||
| 
						 | 
				
			
			@ -440,7 +440,7 @@ function reply(): void {
 | 
			
		|||
}
 | 
			
		||||
 | 
			
		||||
function react(): void {
 | 
			
		||||
	pleaseLogin(undefined, pleaseLoginContext);
 | 
			
		||||
	pleaseLogin(undefined, pleaseLoginContext.value);
 | 
			
		||||
	showMovedDialog();
 | 
			
		||||
	if (appearNote.value.reactionAcceptance === 'likeOnly') {
 | 
			
		||||
		sound.playMisskeySfx('reaction');
 | 
			
		||||
| 
						 | 
				
			
			@ -571,7 +571,7 @@ function showRenoteMenu(): void {
 | 
			
		|||
	}
 | 
			
		||||
 | 
			
		||||
	if (isMyRenote) {
 | 
			
		||||
		pleaseLogin(undefined, pleaseLoginContext);
 | 
			
		||||
		pleaseLogin(undefined, pleaseLoginContext.value);
 | 
			
		||||
		os.popupMenu([
 | 
			
		||||
			getCopyNoteLinkMenu(note.value, i18n.ts.copyLinkRenote),
 | 
			
		||||
			{ type: 'divider' },
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -209,7 +209,7 @@ import MkPoll from '@/components/MkPoll.vue';
 | 
			
		|||
import MkUsersTooltip from '@/components/MkUsersTooltip.vue';
 | 
			
		||||
import MkUrlPreview from '@/components/MkUrlPreview.vue';
 | 
			
		||||
import MkInstanceTicker from '@/components/MkInstanceTicker.vue';
 | 
			
		||||
import { pleaseLogin } from '@/scripts/please-login.js';
 | 
			
		||||
import { pleaseLogin, type OpenOnRemoteOptions } from '@/scripts/please-login.js';
 | 
			
		||||
import { checkWordMute } from '@/scripts/check-word-mute.js';
 | 
			
		||||
import { userPage } from '@/filters/user.js';
 | 
			
		||||
import { notePage } from '@/filters/note.js';
 | 
			
		||||
| 
						 | 
				
			
			@ -297,10 +297,10 @@ const conversation = ref<Misskey.entities.Note[]>([]);
 | 
			
		|||
const replies = ref<Misskey.entities.Note[]>([]);
 | 
			
		||||
const canRenote = computed(() => ['public', 'home'].includes(appearNote.value.visibility) || appearNote.value.userId === $i?.id);
 | 
			
		||||
 | 
			
		||||
const pleaseLoginContext = {
 | 
			
		||||
const pleaseLoginContext = computed<OpenOnRemoteOptions>(() => ({
 | 
			
		||||
	type: 'lookup',
 | 
			
		||||
	path: `https://${host}/notes/${appearNote.value.id}`,
 | 
			
		||||
} as const;
 | 
			
		||||
	url: `https://${host}/notes/${appearNote.value.id}`,
 | 
			
		||||
}));
 | 
			
		||||
 | 
			
		||||
const keymap = {
 | 
			
		||||
	'r': () => reply(),
 | 
			
		||||
| 
						 | 
				
			
			@ -402,7 +402,7 @@ if (appearNote.value.reactionAcceptance === 'likeOnly') {
 | 
			
		|||
}
 | 
			
		||||
 | 
			
		||||
function renote() {
 | 
			
		||||
	pleaseLogin(undefined, pleaseLoginContext);
 | 
			
		||||
	pleaseLogin(undefined, pleaseLoginContext.value);
 | 
			
		||||
	showMovedDialog();
 | 
			
		||||
 | 
			
		||||
	const { menu } = getRenoteMenu({ note: note.value, renoteButton });
 | 
			
		||||
| 
						 | 
				
			
			@ -410,7 +410,7 @@ function renote() {
 | 
			
		|||
}
 | 
			
		||||
 | 
			
		||||
function reply(): void {
 | 
			
		||||
	pleaseLogin(undefined, pleaseLoginContext);
 | 
			
		||||
	pleaseLogin(undefined, pleaseLoginContext.value);
 | 
			
		||||
	showMovedDialog();
 | 
			
		||||
	os.post({
 | 
			
		||||
		reply: appearNote.value,
 | 
			
		||||
| 
						 | 
				
			
			@ -421,7 +421,7 @@ function reply(): void {
 | 
			
		|||
}
 | 
			
		||||
 | 
			
		||||
function react(): void {
 | 
			
		||||
	pleaseLogin(undefined, pleaseLoginContext);
 | 
			
		||||
	pleaseLogin(undefined, pleaseLoginContext.value);
 | 
			
		||||
	showMovedDialog();
 | 
			
		||||
	if (appearNote.value.reactionAcceptance === 'likeOnly') {
 | 
			
		||||
		sound.playMisskeySfx('reaction');
 | 
			
		||||
| 
						 | 
				
			
			@ -505,7 +505,7 @@ async function clip(): Promise<void> {
 | 
			
		|||
 | 
			
		||||
function showRenoteMenu(): void {
 | 
			
		||||
	if (!isMyRenote) return;
 | 
			
		||||
	pleaseLogin(undefined, pleaseLoginContext);
 | 
			
		||||
	pleaseLogin(undefined, pleaseLoginContext.value);
 | 
			
		||||
	os.popupMenu([{
 | 
			
		||||
		text: i18n.ts.unrenote,
 | 
			
		||||
		icon: 'ti ti-trash',
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -36,6 +36,7 @@ import { misskeyApi } from '@/scripts/misskey-api.js';
 | 
			
		|||
import { i18n } from '@/i18n.js';
 | 
			
		||||
import { host } from '@/config.js';
 | 
			
		||||
import { useInterval } from '@/scripts/use-interval.js';
 | 
			
		||||
import type { OpenOnRemoteOptions } from '@/scripts/please-login.js';
 | 
			
		||||
 | 
			
		||||
const props = defineProps<{
 | 
			
		||||
	noteId: string;
 | 
			
		||||
| 
						 | 
				
			
			@ -61,10 +62,10 @@ const timer = computed(() => i18n.tsx._poll[
 | 
			
		|||
 | 
			
		||||
const showResult = ref(props.readOnly || isVoted.value);
 | 
			
		||||
 | 
			
		||||
const pleaseLoginContext = {
 | 
			
		||||
const pleaseLoginContext = computed<OpenOnRemoteOptions>(() => ({
 | 
			
		||||
	type: 'lookup',
 | 
			
		||||
	path: `https://${host}/notes/${props.note.id}`,
 | 
			
		||||
} as const;
 | 
			
		||||
	url: `https://${host}/notes/${props.noteId}`,
 | 
			
		||||
}));
 | 
			
		||||
 | 
			
		||||
// 期限付きアンケート
 | 
			
		||||
if (props.poll.expiresAt) {
 | 
			
		||||
| 
						 | 
				
			
			@ -82,7 +83,7 @@ if (props.poll.expiresAt) {
 | 
			
		|||
}
 | 
			
		||||
 | 
			
		||||
const vote = async (id) => {
 | 
			
		||||
	pleaseLogin(undefined, pleaseLoginContext);
 | 
			
		||||
	pleaseLogin(undefined, pleaseLoginContext.value);
 | 
			
		||||
 | 
			
		||||
	if (props.readOnly || closed.value || isVoted.value) return;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -236,12 +236,14 @@ function openRemote(options: OpenOnRemoteOptions, targetHost?: string): void {
 | 
			
		|||
	switch (options.type) {
 | 
			
		||||
		case 'web':
 | 
			
		||||
		case 'lookup': {
 | 
			
		||||
			let _path = options.path;
 | 
			
		||||
			let _path: string;
 | 
			
		||||
 | 
			
		||||
			if (options.type === 'lookup') {
 | 
			
		||||
				// TODO: v2024.2.0以降が浸透してきたら正式なURLに変更する▼
 | 
			
		||||
				// TODO: v2024.7.0以降が浸透してきたら正式なURLに変更する▼
 | 
			
		||||
				// _path = `/lookup?uri=${encodeURIComponent(_path)}`;
 | 
			
		||||
				_path = `/authorize-follow?acct=${encodeURIComponent(_path)}`;
 | 
			
		||||
				_path = `/authorize-follow?acct=${encodeURIComponent(options.url)}`;
 | 
			
		||||
			} else {
 | 
			
		||||
				_path = options.path;
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			if (targetHost) {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -9,13 +9,38 @@ import { i18n } from '@/i18n.js';
 | 
			
		|||
import { popup } from '@/os.js';
 | 
			
		||||
 | 
			
		||||
export type OpenOnRemoteOptions = {
 | 
			
		||||
	/**
 | 
			
		||||
	 * 外部のMisskey Webで特定のパスを開く
 | 
			
		||||
	 */
 | 
			
		||||
	type: 'web';
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * 内部パス(例: `/settings`)
 | 
			
		||||
	 */
 | 
			
		||||
	path: string;
 | 
			
		||||
} | {
 | 
			
		||||
	/**
 | 
			
		||||
	 * 外部のMisskey Webで照会する
 | 
			
		||||
	 */
 | 
			
		||||
	type: 'lookup';
 | 
			
		||||
	path: string;	
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * 照会したいエンティティのURL
 | 
			
		||||
	 *
 | 
			
		||||
	 * (例: `https://misskey.example.com/notes/abcdexxxxyz`)
 | 
			
		||||
	 */
 | 
			
		||||
	url: string;
 | 
			
		||||
} | {
 | 
			
		||||
	/**
 | 
			
		||||
	 * 外部のMisskeyでノートする
 | 
			
		||||
	 */
 | 
			
		||||
	type: 'share';
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * `/share` ページに渡すクエリストリング
 | 
			
		||||
	 *
 | 
			
		||||
	 * @see https://go.misskey-hub.net/spec/share/
 | 
			
		||||
	 */
 | 
			
		||||
	params: Record<string, string>;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -23,6 +23,6 @@ export function appendQuery(url: string, query: string): string {
 | 
			
		|||
}
 | 
			
		||||
 | 
			
		||||
export function extractDomain(url: string) {
 | 
			
		||||
	const match = url.match(/^(https)?:?\/{0,2}([^\/]+)/);
 | 
			
		||||
	return match ? match[2] : null;
 | 
			
		||||
	const match = url.match(/^(?:https?:)?(?:\/\/)?(?:[^@\n]+@)?([^:\/\n]+)/im);
 | 
			
		||||
	return match ? match[1] : null;
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue