Merge branch 'develop' of https://github.com/misskey-dev/misskey into develop
This commit is contained in:
		
						commit
						b9c64053e8
					
				
					 112 changed files with 351 additions and 111 deletions
				
			
		|  | @ -18,6 +18,7 @@ You should also include the user name that made the change. | ||||||
| - Server: always remove completed tasks of job queue @Johann150 | - Server: always remove completed tasks of job queue @Johann150 | ||||||
| - Client: make emoji stand out more on reaction button @Johann150 | - Client: make emoji stand out more on reaction button @Johann150 | ||||||
| - Client: display URL of QR code for TOTP registration @tamaina | - Client: display URL of QR code for TOTP registration @tamaina | ||||||
|  | - Client: render quote renote CWs as MFM @pixeldesu | ||||||
| - API: notifications/readは配列でも受け付けるように #7667 @tamaina | - API: notifications/readは配列でも受け付けるように #7667 @tamaina | ||||||
| - API: ユーザー検索で、クエリがusernameの条件を満たす場合はusernameもLIKE検索するように @tamaina | - API: ユーザー検索で、クエリがusernameの条件を満たす場合はusernameもLIKE検索するように @tamaina | ||||||
| - MFM: Allow speed changes in all animated MFMs @Johann150 | - MFM: Allow speed changes in all animated MFMs @Johann150 | ||||||
|  |  | ||||||
|  | @ -197,7 +197,14 @@ export async function createNote(value: string | IObject, resolver?: Resolver, s | ||||||
| 	const cw = note.summary === '' ? null : note.summary; | 	const cw = note.summary === '' ? null : note.summary; | ||||||
| 
 | 
 | ||||||
| 	// テキストのパース
 | 	// テキストのパース
 | ||||||
| 	const text = typeof note._misskey_content !== 'undefined' ? note._misskey_content : (note.content ? htmlToMfm(note.content, note.tag) : null); | 	let text: string | null = null; | ||||||
|  | 	if (note.source?.mediaType === 'text/x.misskeymarkdown' && typeof note.source?.content === 'string') { | ||||||
|  | 		text = note.source.content; | ||||||
|  | 	} else if (typeof note._misskey_content === 'string') { | ||||||
|  | 		text = note._misskey_content; | ||||||
|  | 	} else if (typeof note.content === 'string') { | ||||||
|  | 		text = htmlToMfm(note.content, note.tag); | ||||||
|  | 	} | ||||||
| 
 | 
 | ||||||
| 	// vote
 | 	// vote
 | ||||||
| 	if (reply && reply.hasPoll) { | 	if (reply && reply.hasPoll) { | ||||||
|  |  | ||||||
|  | @ -138,6 +138,10 @@ export default async function renderNote(note: Note, dive = true, isTalk = false | ||||||
| 		summary, | 		summary, | ||||||
| 		content, | 		content, | ||||||
| 		_misskey_content: text, | 		_misskey_content: text, | ||||||
|  | 		source: { | ||||||
|  | 			content: text, | ||||||
|  | 			mediaType: "text/x.misskeymarkdown", | ||||||
|  | 		}, | ||||||
| 		_misskey_quote: quote, | 		_misskey_quote: quote, | ||||||
| 		quoteUrl: quote, | 		quoteUrl: quote, | ||||||
| 		published: note.createdAt.toISOString(), | 		published: note.createdAt.toISOString(), | ||||||
|  |  | ||||||
|  | @ -106,7 +106,10 @@ export const isPost = (object: IObject): object is IPost => | ||||||
| 
 | 
 | ||||||
| export interface IPost extends IObject { | export interface IPost extends IObject { | ||||||
| 	type: 'Note' | 'Question' | 'Article' | 'Audio' | 'Document' | 'Image' | 'Page' | 'Video' | 'Event'; | 	type: 'Note' | 'Question' | 'Article' | 'Audio' | 'Document' | 'Image' | 'Page' | 'Video' | 'Event'; | ||||||
| 	_misskey_content?: string; | 	source?: { | ||||||
|  | 		content: string; | ||||||
|  | 		mediaType: string; | ||||||
|  | 	}; | ||||||
| 	_misskey_quote?: string; | 	_misskey_quote?: string; | ||||||
| 	quoteUrl?: string; | 	quoteUrl?: string; | ||||||
| 	_misskey_talk: boolean; | 	_misskey_talk: boolean; | ||||||
|  | @ -114,7 +117,10 @@ export interface IPost extends IObject { | ||||||
| 
 | 
 | ||||||
| export interface IQuestion extends IObject { | export interface IQuestion extends IObject { | ||||||
| 	type: 'Note' | 'Question'; | 	type: 'Note' | 'Question'; | ||||||
| 	_misskey_content?: string; | 	source?: { | ||||||
|  | 		content: string; | ||||||
|  | 		mediaType: string; | ||||||
|  | 	}; | ||||||
| 	_misskey_quote?: string; | 	_misskey_quote?: string; | ||||||
| 	quoteUrl?: string; | 	quoteUrl?: string; | ||||||
| 	oneOf?: IQuestionChoice[]; | 	oneOf?: IQuestionChoice[]; | ||||||
|  |  | ||||||
|  | @ -9,6 +9,8 @@ export const meta = { | ||||||
| 
 | 
 | ||||||
| 	kind: 'read:drive', | 	kind: 'read:drive', | ||||||
| 
 | 
 | ||||||
|  | 	description: 'Find the notes to which the given file is attached.', | ||||||
|  | 
 | ||||||
| 	res: { | 	res: { | ||||||
| 		type: 'array', | 		type: 'array', | ||||||
| 		optional: false, nullable: false, | 		optional: false, nullable: false, | ||||||
|  |  | ||||||
|  | @ -8,6 +8,8 @@ export const meta = { | ||||||
| 
 | 
 | ||||||
| 	kind: 'read:drive', | 	kind: 'read:drive', | ||||||
| 
 | 
 | ||||||
|  | 	description: 'Check if a given file exists.', | ||||||
|  | 
 | ||||||
| 	res: { | 	res: { | ||||||
| 		type: 'boolean', | 		type: 'boolean', | ||||||
| 		optional: false, nullable: false, | 		optional: false, nullable: false, | ||||||
|  |  | ||||||
|  | @ -20,6 +20,8 @@ export const meta = { | ||||||
| 
 | 
 | ||||||
| 	kind: 'write:drive', | 	kind: 'write:drive', | ||||||
| 
 | 
 | ||||||
|  | 	description: 'Upload a new drive file.', | ||||||
|  | 
 | ||||||
| 	res: { | 	res: { | ||||||
| 		type: 'object', | 		type: 'object', | ||||||
| 		optional: false, nullable: false, | 		optional: false, nullable: false, | ||||||
|  |  | ||||||
|  | @ -11,6 +11,8 @@ export const meta = { | ||||||
| 
 | 
 | ||||||
| 	kind: 'write:drive', | 	kind: 'write:drive', | ||||||
| 
 | 
 | ||||||
|  | 	description: 'Delete an existing drive file.', | ||||||
|  | 
 | ||||||
| 	errors: { | 	errors: { | ||||||
| 		noSuchFile: { | 		noSuchFile: { | ||||||
| 			message: 'No such file.', | 			message: 'No such file.', | ||||||
|  |  | ||||||
|  | @ -8,6 +8,8 @@ export const meta = { | ||||||
| 
 | 
 | ||||||
| 	kind: 'read:drive', | 	kind: 'read:drive', | ||||||
| 
 | 
 | ||||||
|  | 	description: 'Search for a drive file by a hash of the contents.', | ||||||
|  | 
 | ||||||
| 	res: { | 	res: { | ||||||
| 		type: 'array', | 		type: 'array', | ||||||
| 		optional: false, nullable: false, | 		optional: false, nullable: false, | ||||||
|  |  | ||||||
|  | @ -9,6 +9,8 @@ export const meta = { | ||||||
| 
 | 
 | ||||||
| 	kind: 'read:drive', | 	kind: 'read:drive', | ||||||
| 
 | 
 | ||||||
|  | 	description: 'Search for a drive file by the given parameters.', | ||||||
|  | 
 | ||||||
| 	res: { | 	res: { | ||||||
| 		type: 'array', | 		type: 'array', | ||||||
| 		optional: false, nullable: false, | 		optional: false, nullable: false, | ||||||
|  |  | ||||||
|  | @ -10,6 +10,8 @@ export const meta = { | ||||||
| 
 | 
 | ||||||
| 	kind: 'read:drive', | 	kind: 'read:drive', | ||||||
| 
 | 
 | ||||||
|  | 	description: 'Show the properties of a drive file.', | ||||||
|  | 
 | ||||||
| 	res: { | 	res: { | ||||||
| 		type: 'object', | 		type: 'object', | ||||||
| 		optional: false, nullable: false, | 		optional: false, nullable: false, | ||||||
|  |  | ||||||
|  | @ -11,6 +11,8 @@ export const meta = { | ||||||
| 
 | 
 | ||||||
| 	kind: 'write:drive', | 	kind: 'write:drive', | ||||||
| 
 | 
 | ||||||
|  | 	description: 'Update the properties of a drive file.', | ||||||
|  | 
 | ||||||
| 	errors: { | 	errors: { | ||||||
| 		invalidFileName: { | 		invalidFileName: { | ||||||
| 			message: 'Invalid file name.', | 			message: 'Invalid file name.', | ||||||
|  |  | ||||||
|  | @ -13,6 +13,8 @@ export const meta = { | ||||||
| 		max: 60, | 		max: 60, | ||||||
| 	}, | 	}, | ||||||
| 
 | 
 | ||||||
|  | 	description: 'Request the server to download a new drive file from the specified URL.', | ||||||
|  | 
 | ||||||
| 	requireCredential: true, | 	requireCredential: true, | ||||||
| 
 | 
 | ||||||
| 	kind: 'write:drive', | 	kind: 'write:drive', | ||||||
|  |  | ||||||
|  | @ -10,8 +10,12 @@ import { genId } from '@/misc/gen-id.js'; | ||||||
| import { IsNull } from 'typeorm'; | import { IsNull } from 'typeorm'; | ||||||
| 
 | 
 | ||||||
| export const meta = { | export const meta = { | ||||||
|  | 	tags: ['reset password'], | ||||||
|  | 
 | ||||||
| 	requireCredential: false, | 	requireCredential: false, | ||||||
| 
 | 
 | ||||||
|  | 	description: 'Request a users password to be reset.', | ||||||
|  | 
 | ||||||
| 	limit: { | 	limit: { | ||||||
| 		duration: ms('1hour'), | 		duration: ms('1hour'), | ||||||
| 		max: 3, | 		max: 3, | ||||||
|  |  | ||||||
|  | @ -3,8 +3,12 @@ import { ApiError } from '../error.js'; | ||||||
| import { resetDb } from '@/db/postgre.js'; | import { resetDb } from '@/db/postgre.js'; | ||||||
| 
 | 
 | ||||||
| export const meta = { | export const meta = { | ||||||
|  | 	tags: ['non-productive'], | ||||||
|  | 
 | ||||||
| 	requireCredential: false, | 	requireCredential: false, | ||||||
| 
 | 
 | ||||||
|  | 	description: 'Only available when running with <code>NODE_ENV=testing</code>. Reset the database and flush Redis.', | ||||||
|  | 
 | ||||||
| 	errors: { | 	errors: { | ||||||
| 
 | 
 | ||||||
| 	}, | 	}, | ||||||
|  |  | ||||||
|  | @ -5,8 +5,12 @@ import { Users, UserProfiles, PasswordResetRequests } from '@/models/index.js'; | ||||||
| import { ApiError } from '../error.js'; | import { ApiError } from '../error.js'; | ||||||
| 
 | 
 | ||||||
| export const meta = { | export const meta = { | ||||||
|  | 	tags: ['reset password'], | ||||||
|  | 
 | ||||||
| 	requireCredential: false, | 	requireCredential: false, | ||||||
| 
 | 
 | ||||||
|  | 	description: 'Complete the password reset that was previously requested.', | ||||||
|  | 
 | ||||||
| 	errors: { | 	errors: { | ||||||
| 
 | 
 | ||||||
| 	}, | 	}, | ||||||
|  |  | ||||||
|  | @ -8,6 +8,8 @@ export const meta = { | ||||||
| 
 | 
 | ||||||
| 	requireCredential: true, | 	requireCredential: true, | ||||||
| 
 | 
 | ||||||
|  | 	description: 'Register to receive push notifications.', | ||||||
|  | 
 | ||||||
| 	res: { | 	res: { | ||||||
| 		type: 'object', | 		type: 'object', | ||||||
| 		optional: false, nullable: false, | 		optional: false, nullable: false, | ||||||
|  |  | ||||||
|  | @ -5,6 +5,8 @@ export const meta = { | ||||||
| 	tags: ['account'], | 	tags: ['account'], | ||||||
| 
 | 
 | ||||||
| 	requireCredential: true, | 	requireCredential: true, | ||||||
|  | 
 | ||||||
|  | 	description: 'Unregister from receiving push notifications.', | ||||||
| } as const; | } as const; | ||||||
| 
 | 
 | ||||||
| export const paramDef = { | export const paramDef = { | ||||||
|  |  | ||||||
|  | @ -1,6 +1,10 @@ | ||||||
| import define from '../define.js'; | import define from '../define.js'; | ||||||
| 
 | 
 | ||||||
| export const meta = { | export const meta = { | ||||||
|  | 	tags: ['non-productive'], | ||||||
|  | 
 | ||||||
|  | 	description: 'Endpoint for testing input validation.', | ||||||
|  | 
 | ||||||
| 	requireCredential: false, | 	requireCredential: false, | ||||||
| } as const; | } as const; | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -4,6 +4,18 @@ import { makePaginationQuery } from '../../common/make-pagination-query.js'; | ||||||
| 
 | 
 | ||||||
| export const meta = { | export const meta = { | ||||||
| 	tags: ['users', 'clips'], | 	tags: ['users', 'clips'], | ||||||
|  | 
 | ||||||
|  | 	description: 'Show all clips this user owns.', | ||||||
|  | 
 | ||||||
|  | 	res: { | ||||||
|  | 		type: 'array', | ||||||
|  | 		optional: false, nullable: false, | ||||||
|  | 		items: { | ||||||
|  | 			type: 'object', | ||||||
|  | 			optional: false, nullable: false, | ||||||
|  | 			ref: 'Clip', | ||||||
|  | 		}, | ||||||
|  | 	}, | ||||||
| } as const; | } as const; | ||||||
| 
 | 
 | ||||||
| export const paramDef = { | export const paramDef = { | ||||||
|  |  | ||||||
|  | @ -10,6 +10,8 @@ export const meta = { | ||||||
| 
 | 
 | ||||||
| 	requireCredential: false, | 	requireCredential: false, | ||||||
| 
 | 
 | ||||||
|  | 	description: 'Show everyone that follows this user.', | ||||||
|  | 
 | ||||||
| 	res: { | 	res: { | ||||||
| 		type: 'array', | 		type: 'array', | ||||||
| 		optional: false, nullable: false, | 		optional: false, nullable: false, | ||||||
|  |  | ||||||
|  | @ -10,6 +10,8 @@ export const meta = { | ||||||
| 
 | 
 | ||||||
| 	requireCredential: false, | 	requireCredential: false, | ||||||
| 
 | 
 | ||||||
|  | 	description: 'Show everyone that this user is following.', | ||||||
|  | 
 | ||||||
| 	res: { | 	res: { | ||||||
| 		type: 'array', | 		type: 'array', | ||||||
| 		optional: false, nullable: false, | 		optional: false, nullable: false, | ||||||
|  |  | ||||||
|  | @ -4,6 +4,18 @@ import { makePaginationQuery } from '../../../common/make-pagination-query.js'; | ||||||
| 
 | 
 | ||||||
| export const meta = { | export const meta = { | ||||||
| 	tags: ['users', 'gallery'], | 	tags: ['users', 'gallery'], | ||||||
|  | 
 | ||||||
|  | 	description: 'Show all gallery posts by the given user.', | ||||||
|  | 
 | ||||||
|  | 	res: { | ||||||
|  | 		type: 'array', | ||||||
|  | 		optional: false, nullable: false, | ||||||
|  | 		items: { | ||||||
|  | 			type: 'object', | ||||||
|  | 			optional: false, nullable: false, | ||||||
|  | 			ref: 'GalleryPost', | ||||||
|  | 		}, | ||||||
|  | 	}, | ||||||
| } as const; | } as const; | ||||||
| 
 | 
 | ||||||
| export const paramDef = { | export const paramDef = { | ||||||
|  |  | ||||||
|  | @ -10,6 +10,8 @@ export const meta = { | ||||||
| 
 | 
 | ||||||
| 	requireCredential: false, | 	requireCredential: false, | ||||||
| 
 | 
 | ||||||
|  | 	description: 'Get a list of other users that the specified user frequently replies to.', | ||||||
|  | 
 | ||||||
| 	res: { | 	res: { | ||||||
| 		type: 'array', | 		type: 'array', | ||||||
| 		optional: false, nullable: false, | 		optional: false, nullable: false, | ||||||
|  |  | ||||||
|  | @ -11,6 +11,8 @@ export const meta = { | ||||||
| 
 | 
 | ||||||
| 	kind: 'write:user-groups', | 	kind: 'write:user-groups', | ||||||
| 
 | 
 | ||||||
|  | 	description: 'Create a new group.', | ||||||
|  | 
 | ||||||
| 	res: { | 	res: { | ||||||
| 		type: 'object', | 		type: 'object', | ||||||
| 		optional: false, nullable: false, | 		optional: false, nullable: false, | ||||||
|  |  | ||||||
|  | @ -9,6 +9,8 @@ export const meta = { | ||||||
| 
 | 
 | ||||||
| 	kind: 'write:user-groups', | 	kind: 'write:user-groups', | ||||||
| 
 | 
 | ||||||
|  | 	description: 'Delete an existing group.', | ||||||
|  | 
 | ||||||
| 	errors: { | 	errors: { | ||||||
| 		noSuchGroup: { | 		noSuchGroup: { | ||||||
| 			message: 'No such group.', | 			message: 'No such group.', | ||||||
|  |  | ||||||
|  | @ -11,6 +11,8 @@ export const meta = { | ||||||
| 
 | 
 | ||||||
| 	kind: 'write:user-groups', | 	kind: 'write:user-groups', | ||||||
| 
 | 
 | ||||||
|  | 	description: 'Join a group the authenticated user has been invited to.', | ||||||
|  | 
 | ||||||
| 	errors: { | 	errors: { | ||||||
| 		noSuchInvitation: { | 		noSuchInvitation: { | ||||||
| 			message: 'No such invitation.', | 			message: 'No such invitation.', | ||||||
|  |  | ||||||
|  | @ -9,6 +9,8 @@ export const meta = { | ||||||
| 
 | 
 | ||||||
| 	kind: 'write:user-groups', | 	kind: 'write:user-groups', | ||||||
| 
 | 
 | ||||||
|  | 	description: 'Delete an existing group invitation for the authenticated user without joining the group.', | ||||||
|  | 
 | ||||||
| 	errors: { | 	errors: { | ||||||
| 		noSuchInvitation: { | 		noSuchInvitation: { | ||||||
| 			message: 'No such invitation.', | 			message: 'No such invitation.', | ||||||
|  |  | ||||||
|  | @ -13,6 +13,8 @@ export const meta = { | ||||||
| 
 | 
 | ||||||
| 	kind: 'write:user-groups', | 	kind: 'write:user-groups', | ||||||
| 
 | 
 | ||||||
|  | 	description: 'Invite a user to an existing group.', | ||||||
|  | 
 | ||||||
| 	errors: { | 	errors: { | ||||||
| 		noSuchGroup: { | 		noSuchGroup: { | ||||||
| 			message: 'No such group.', | 			message: 'No such group.', | ||||||
|  |  | ||||||
|  | @ -9,6 +9,8 @@ export const meta = { | ||||||
| 
 | 
 | ||||||
| 	kind: 'read:user-groups', | 	kind: 'read:user-groups', | ||||||
| 
 | 
 | ||||||
|  | 	description: 'List the groups that the authenticated user is a member of.', | ||||||
|  | 
 | ||||||
| 	res: { | 	res: { | ||||||
| 		type: 'array', | 		type: 'array', | ||||||
| 		optional: false, nullable: false, | 		optional: false, nullable: false, | ||||||
|  |  | ||||||
|  | @ -9,6 +9,8 @@ export const meta = { | ||||||
| 
 | 
 | ||||||
| 	kind: 'write:user-groups', | 	kind: 'write:user-groups', | ||||||
| 
 | 
 | ||||||
|  | 	description: 'Leave a group. The owner of a group can not leave. They must transfer ownership or delete the group instead.', | ||||||
|  | 
 | ||||||
| 	errors: { | 	errors: { | ||||||
| 		noSuchGroup: { | 		noSuchGroup: { | ||||||
| 			message: 'No such group.', | 			message: 'No such group.', | ||||||
|  |  | ||||||
|  | @ -8,6 +8,8 @@ export const meta = { | ||||||
| 
 | 
 | ||||||
| 	kind: 'read:user-groups', | 	kind: 'read:user-groups', | ||||||
| 
 | 
 | ||||||
|  | 	description: 'List the groups that the authenticated user is the owner of.', | ||||||
|  | 
 | ||||||
| 	res: { | 	res: { | ||||||
| 		type: 'array', | 		type: 'array', | ||||||
| 		optional: false, nullable: false, | 		optional: false, nullable: false, | ||||||
|  |  | ||||||
|  | @ -10,6 +10,8 @@ export const meta = { | ||||||
| 
 | 
 | ||||||
| 	kind: 'write:user-groups', | 	kind: 'write:user-groups', | ||||||
| 
 | 
 | ||||||
|  | 	description: 'Removes a specified user from a group. The owner can not be removed.', | ||||||
|  | 
 | ||||||
| 	errors: { | 	errors: { | ||||||
| 		noSuchGroup: { | 		noSuchGroup: { | ||||||
| 			message: 'No such group.', | 			message: 'No such group.', | ||||||
|  |  | ||||||
|  | @ -9,6 +9,8 @@ export const meta = { | ||||||
| 
 | 
 | ||||||
| 	kind: 'read:user-groups', | 	kind: 'read:user-groups', | ||||||
| 
 | 
 | ||||||
|  | 	description: 'Show the properties of a group.', | ||||||
|  | 
 | ||||||
| 	res: { | 	res: { | ||||||
| 		type: 'object', | 		type: 'object', | ||||||
| 		optional: false, nullable: false, | 		optional: false, nullable: false, | ||||||
|  |  | ||||||
|  | @ -10,6 +10,8 @@ export const meta = { | ||||||
| 
 | 
 | ||||||
| 	kind: 'write:user-groups', | 	kind: 'write:user-groups', | ||||||
| 
 | 
 | ||||||
|  | 	description: 'Transfer ownership of a group from the authenticated user to another user.', | ||||||
|  | 
 | ||||||
| 	res: { | 	res: { | ||||||
| 		type: 'object', | 		type: 'object', | ||||||
| 		optional: false, nullable: false, | 		optional: false, nullable: false, | ||||||
|  |  | ||||||
|  | @ -9,6 +9,8 @@ export const meta = { | ||||||
| 
 | 
 | ||||||
| 	kind: 'write:user-groups', | 	kind: 'write:user-groups', | ||||||
| 
 | 
 | ||||||
|  | 	description: 'Update the properties of a group.', | ||||||
|  | 
 | ||||||
| 	res: { | 	res: { | ||||||
| 		type: 'object', | 		type: 'object', | ||||||
| 		optional: false, nullable: false, | 		optional: false, nullable: false, | ||||||
|  |  | ||||||
|  | @ -10,6 +10,8 @@ export const meta = { | ||||||
| 
 | 
 | ||||||
| 	kind: 'write:account', | 	kind: 'write:account', | ||||||
| 
 | 
 | ||||||
|  | 	description: 'Create a new list of users.', | ||||||
|  | 
 | ||||||
| 	res: { | 	res: { | ||||||
| 		type: 'object', | 		type: 'object', | ||||||
| 		optional: false, nullable: false, | 		optional: false, nullable: false, | ||||||
|  |  | ||||||
|  | @ -9,6 +9,8 @@ export const meta = { | ||||||
| 
 | 
 | ||||||
| 	kind: 'write:account', | 	kind: 'write:account', | ||||||
| 
 | 
 | ||||||
|  | 	description: 'Delete an existing list of users.', | ||||||
|  | 
 | ||||||
| 	errors: { | 	errors: { | ||||||
| 		noSuchList: { | 		noSuchList: { | ||||||
| 			message: 'No such list.', | 			message: 'No such list.', | ||||||
|  |  | ||||||
|  | @ -8,6 +8,8 @@ export const meta = { | ||||||
| 
 | 
 | ||||||
| 	kind: 'read:account', | 	kind: 'read:account', | ||||||
| 
 | 
 | ||||||
|  | 	description: 'Show all lists that the authenticated user has created.', | ||||||
|  | 
 | ||||||
| 	res: { | 	res: { | ||||||
| 		type: 'array', | 		type: 'array', | ||||||
| 		optional: false, nullable: false, | 		optional: false, nullable: false, | ||||||
|  |  | ||||||
|  | @ -11,6 +11,8 @@ export const meta = { | ||||||
| 
 | 
 | ||||||
| 	kind: 'write:account', | 	kind: 'write:account', | ||||||
| 
 | 
 | ||||||
|  | 	description: 'Remove a user from a list.', | ||||||
|  | 
 | ||||||
| 	errors: { | 	errors: { | ||||||
| 		noSuchList: { | 		noSuchList: { | ||||||
| 			message: 'No such list.', | 			message: 'No such list.', | ||||||
|  |  | ||||||
|  | @ -11,6 +11,8 @@ export const meta = { | ||||||
| 
 | 
 | ||||||
| 	kind: 'write:account', | 	kind: 'write:account', | ||||||
| 
 | 
 | ||||||
|  | 	description: 'Add a user to an existing list.', | ||||||
|  | 
 | ||||||
| 	errors: { | 	errors: { | ||||||
| 		noSuchList: { | 		noSuchList: { | ||||||
| 			message: 'No such list.', | 			message: 'No such list.', | ||||||
|  |  | ||||||
|  | @ -9,6 +9,8 @@ export const meta = { | ||||||
| 
 | 
 | ||||||
| 	kind: 'read:account', | 	kind: 'read:account', | ||||||
| 
 | 
 | ||||||
|  | 	description: 'Show the properties of a list.', | ||||||
|  | 
 | ||||||
| 	res: { | 	res: { | ||||||
| 		type: 'object', | 		type: 'object', | ||||||
| 		optional: false, nullable: false, | 		optional: false, nullable: false, | ||||||
|  |  | ||||||
|  | @ -9,6 +9,8 @@ export const meta = { | ||||||
| 
 | 
 | ||||||
| 	kind: 'write:account', | 	kind: 'write:account', | ||||||
| 
 | 
 | ||||||
|  | 	description: 'Update the properties of a list.', | ||||||
|  | 
 | ||||||
| 	res: { | 	res: { | ||||||
| 		type: 'object', | 		type: 'object', | ||||||
| 		optional: false, nullable: false, | 		optional: false, nullable: false, | ||||||
|  |  | ||||||
|  | @ -12,6 +12,8 @@ import { generateMutedInstanceQuery } from '../../common/generate-muted-instance | ||||||
| export const meta = { | export const meta = { | ||||||
| 	tags: ['users', 'notes'], | 	tags: ['users', 'notes'], | ||||||
| 
 | 
 | ||||||
|  | 	description: 'Show all notes that this user created.', | ||||||
|  | 
 | ||||||
| 	res: { | 	res: { | ||||||
| 		type: 'array', | 		type: 'array', | ||||||
| 		optional: false, nullable: false, | 		optional: false, nullable: false, | ||||||
|  |  | ||||||
|  | @ -4,6 +4,18 @@ import { makePaginationQuery } from '../../common/make-pagination-query.js'; | ||||||
| 
 | 
 | ||||||
| export const meta = { | export const meta = { | ||||||
| 	tags: ['users', 'pages'], | 	tags: ['users', 'pages'], | ||||||
|  | 
 | ||||||
|  | 	description: 'Show all pages this user created.', | ||||||
|  | 
 | ||||||
|  | 	res: { | ||||||
|  | 		type: 'array', | ||||||
|  | 		optional: false, nullable: false, | ||||||
|  | 		items: { | ||||||
|  | 			type: 'object', | ||||||
|  | 			optional: false, nullable: false, | ||||||
|  | 			ref: 'Page', | ||||||
|  | 		}, | ||||||
|  | 	}, | ||||||
| } as const; | } as const; | ||||||
| 
 | 
 | ||||||
| export const paramDef = { | export const paramDef = { | ||||||
|  |  | ||||||
|  | @ -9,6 +9,8 @@ export const meta = { | ||||||
| 
 | 
 | ||||||
| 	requireCredential: false, | 	requireCredential: false, | ||||||
| 
 | 
 | ||||||
|  | 	description: 'Show all reactions this user made.', | ||||||
|  | 
 | ||||||
| 	res: { | 	res: { | ||||||
| 		type: 'array', | 		type: 'array', | ||||||
| 		optional: false, nullable: false, | 		optional: false, nullable: false, | ||||||
|  |  | ||||||
|  | @ -11,6 +11,8 @@ export const meta = { | ||||||
| 
 | 
 | ||||||
| 	kind: 'read:account', | 	kind: 'read:account', | ||||||
| 
 | 
 | ||||||
|  | 	description: 'Show users that the authenticated user might be interested to follow.', | ||||||
|  | 
 | ||||||
| 	res: { | 	res: { | ||||||
| 		type: 'array', | 		type: 'array', | ||||||
| 		optional: false, nullable: false, | 		optional: false, nullable: false, | ||||||
|  |  | ||||||
|  | @ -6,6 +6,8 @@ export const meta = { | ||||||
| 
 | 
 | ||||||
| 	requireCredential: true, | 	requireCredential: true, | ||||||
| 
 | 
 | ||||||
|  | 	description: 'Show the different kinds of relations between the authenticated user and the specified user(s).', | ||||||
|  | 
 | ||||||
| 	res: { | 	res: { | ||||||
| 		optional: false, nullable: false, | 		optional: false, nullable: false, | ||||||
| 		oneOf: [ | 		oneOf: [ | ||||||
|  |  | ||||||
|  | @ -13,6 +13,8 @@ export const meta = { | ||||||
| 
 | 
 | ||||||
| 	requireCredential: true, | 	requireCredential: true, | ||||||
| 
 | 
 | ||||||
|  | 	description: 'File a report.', | ||||||
|  | 
 | ||||||
| 	errors: { | 	errors: { | ||||||
| 		noSuchUser: { | 		noSuchUser: { | ||||||
| 			message: 'No such user.', | 			message: 'No such user.', | ||||||
|  |  | ||||||
|  | @ -9,6 +9,8 @@ export const meta = { | ||||||
| 
 | 
 | ||||||
| 	requireCredential: false, | 	requireCredential: false, | ||||||
| 
 | 
 | ||||||
|  | 	description: 'Search for a user by username and/or host.', | ||||||
|  | 
 | ||||||
| 	res: { | 	res: { | ||||||
| 		type: 'array', | 		type: 'array', | ||||||
| 		optional: false, nullable: false, | 		optional: false, nullable: false, | ||||||
|  |  | ||||||
|  | @ -8,6 +8,8 @@ export const meta = { | ||||||
| 
 | 
 | ||||||
| 	requireCredential: false, | 	requireCredential: false, | ||||||
| 
 | 
 | ||||||
|  | 	description: 'Search for users.', | ||||||
|  | 
 | ||||||
| 	res: { | 	res: { | ||||||
| 		type: 'array', | 		type: 'array', | ||||||
| 		optional: false, nullable: false, | 		optional: false, nullable: false, | ||||||
|  |  | ||||||
|  | @ -11,6 +11,8 @@ export const meta = { | ||||||
| 
 | 
 | ||||||
| 	requireCredential: false, | 	requireCredential: false, | ||||||
| 
 | 
 | ||||||
|  | 	description: 'Show the properties of a user.', | ||||||
|  | 
 | ||||||
| 	res: { | 	res: { | ||||||
| 		optional: false, nullable: false, | 		optional: false, nullable: false, | ||||||
| 		oneOf: [ | 		oneOf: [ | ||||||
|  |  | ||||||
|  | @ -8,6 +8,8 @@ export const meta = { | ||||||
| 
 | 
 | ||||||
| 	requireCredential: false, | 	requireCredential: false, | ||||||
| 
 | 
 | ||||||
|  | 	description: 'Show statistics about a user.', | ||||||
|  | 
 | ||||||
| 	errors: { | 	errors: { | ||||||
| 		noSuchUser: { | 		noSuchUser: { | ||||||
| 			message: 'No such user.', | 			message: 'No such user.', | ||||||
|  | @ -15,6 +17,94 @@ export const meta = { | ||||||
| 			id: '9e638e45-3b25-4ef7-8f95-07e8498f1819', | 			id: '9e638e45-3b25-4ef7-8f95-07e8498f1819', | ||||||
| 		}, | 		}, | ||||||
| 	}, | 	}, | ||||||
|  | 
 | ||||||
|  | 	res: { | ||||||
|  | 		type: 'object', | ||||||
|  | 		optional: false, nullable: false, | ||||||
|  | 		properties: { | ||||||
|  | 			notesCount: { | ||||||
|  | 				type: 'integer', | ||||||
|  | 				optional: false, nullable: false, | ||||||
|  | 			}, | ||||||
|  | 			repliesCount: { | ||||||
|  | 				type: 'integer', | ||||||
|  | 				optional: false, nullable: false, | ||||||
|  | 			}, | ||||||
|  | 			renotesCount: { | ||||||
|  | 				type: 'integer', | ||||||
|  | 				optional: false, nullable: false, | ||||||
|  | 			}, | ||||||
|  | 			repliedCount: { | ||||||
|  | 				type: 'integer', | ||||||
|  | 				optional: false, nullable: false, | ||||||
|  | 			}, | ||||||
|  | 			renotedCount: { | ||||||
|  | 				type: 'integer', | ||||||
|  | 				optional: false, nullable: false, | ||||||
|  | 			}, | ||||||
|  | 			pollVotesCount: { | ||||||
|  | 				type: 'integer', | ||||||
|  | 				optional: false, nullable: false, | ||||||
|  | 			}, | ||||||
|  | 			pollVotedCount: { | ||||||
|  | 				type: 'integer', | ||||||
|  | 				optional: false, nullable: false, | ||||||
|  | 			}, | ||||||
|  | 			localFollowingCount: { | ||||||
|  | 				type: 'integer', | ||||||
|  | 				optional: false, nullable: false, | ||||||
|  | 			}, | ||||||
|  | 			remoteFollowingCount: { | ||||||
|  | 				type: 'integer', | ||||||
|  | 				optional: false, nullable: false, | ||||||
|  | 			}, | ||||||
|  | 			localFollowersCount: { | ||||||
|  | 				type: 'integer', | ||||||
|  | 				optional: false, nullable: false, | ||||||
|  | 			}, | ||||||
|  | 			remoteFollowersCount: { | ||||||
|  | 				type: 'integer', | ||||||
|  | 				optional: false, nullable: false, | ||||||
|  | 			}, | ||||||
|  | 			followingCount: { | ||||||
|  | 				type: 'integer', | ||||||
|  | 				optional: false, nullable: false, | ||||||
|  | 			}, | ||||||
|  | 			followersCount: { | ||||||
|  | 				type: 'integer', | ||||||
|  | 				optional: false, nullable: false, | ||||||
|  | 			}, | ||||||
|  | 			sentReactionsCount: { | ||||||
|  | 				type: 'integer', | ||||||
|  | 				optional: false, nullable: false, | ||||||
|  | 			}, | ||||||
|  | 			receivedReactionsCount: { | ||||||
|  | 				type: 'integer', | ||||||
|  | 				optional: false, nullable: false, | ||||||
|  | 			}, | ||||||
|  | 			noteFavoritesCount: { | ||||||
|  | 				type: 'integer', | ||||||
|  | 				optional: false, nullable: false, | ||||||
|  | 			}, | ||||||
|  | 			pageLikesCount: { | ||||||
|  | 				type: 'integer', | ||||||
|  | 				optional: false, nullable: false, | ||||||
|  | 			}, | ||||||
|  | 			pageLikedCount: { | ||||||
|  | 				type: 'integer', | ||||||
|  | 				optional: false, nullable: false, | ||||||
|  | 			}, | ||||||
|  | 			driveFilesCount: { | ||||||
|  | 				type: 'integer', | ||||||
|  | 				optional: false, nullable: false, | ||||||
|  | 			}, | ||||||
|  | 			driveUsage: { | ||||||
|  | 				type: 'integer', | ||||||
|  | 				optional: false, nullable: false, | ||||||
|  | 				description: 'Drive usage in bytes', | ||||||
|  | 			}, | ||||||
|  | 		}, | ||||||
|  | 	}, | ||||||
| } as const; | } as const; | ||||||
| 
 | 
 | ||||||
| export const paramDef = { | export const paramDef = { | ||||||
|  |  | ||||||
|  | @ -15,6 +15,12 @@ module.exports = { | ||||||
| 		'plugin:vue/vue3-recommended', | 		'plugin:vue/vue3-recommended', | ||||||
| 	], | 	], | ||||||
| 	rules: { | 	rules: { | ||||||
|  | 		'@typescript-eslint/no-empty-interface': [ | ||||||
|  | 			'error', | ||||||
|  | 			{ | ||||||
|  | 				'allowSingleExtends': true, | ||||||
|  | 			}, | ||||||
|  | 		], | ||||||
| 		// window の禁止理由: グローバルスコープと衝突し、予期せぬ結果を招くため
 | 		// window の禁止理由: グローバルスコープと衝突し、予期せぬ結果を招くため
 | ||||||
| 		// data の禁止理由: 抽象的すぎるため
 | 		// data の禁止理由: 抽象的すぎるため
 | ||||||
| 		// e の禁止理由: error や event など、複数のキーワードの頭文字であり分かりにくいため
 | 		// e の禁止理由: error や event など、複数のキーワードの頭文字であり分かりにくいため
 | ||||||
|  |  | ||||||
|  | @ -27,8 +27,7 @@ type CaptchaContainer = { | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| declare global { | declare global { | ||||||
| 	interface Window extends CaptchaContainer { | 	interface Window extends CaptchaContainer { } | ||||||
| 	} |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| const props = defineProps<{ | const props = defineProps<{ | ||||||
|  |  | ||||||
|  | @ -71,7 +71,7 @@ function onMouseover() { | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| function onMouseout() { | function onMouseout() { | ||||||
| 	hover.value = false | 	hover.value = false; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| function onDragover(ev: DragEvent) { | function onDragover(ev: DragEvent) { | ||||||
|  | @ -204,7 +204,7 @@ function deleteFolder() { | ||||||
| 			defaultStore.set('uploadFolder', null); | 			defaultStore.set('uploadFolder', null); | ||||||
| 		} | 		} | ||||||
| 	}).catch(err => { | 	}).catch(err => { | ||||||
| 		switch(err.id) { | 		switch (err.id) { | ||||||
| 			case 'b0fc8a17-963c-405d-bfbc-859a487295e1': | 			case 'b0fc8a17-963c-405d-bfbc-859a487295e1': | ||||||
| 				os.alert({ | 				os.alert({ | ||||||
| 					type: 'error', | 					type: 'error', | ||||||
|  |  | ||||||
|  | @ -143,7 +143,7 @@ const fetching = ref(true); | ||||||
| 
 | 
 | ||||||
| const ilFilesObserver = new IntersectionObserver( | const ilFilesObserver = new IntersectionObserver( | ||||||
| 	(entries) => entries.some((entry) => entry.isIntersecting) && !fetching.value && moreFiles.value && fetchMoreFiles() | 	(entries) => entries.some((entry) => entry.isIntersecting) && !fetching.value && moreFiles.value && fetchMoreFiles() | ||||||
| ) | ); | ||||||
| 
 | 
 | ||||||
| watch(folder, () => emit('cd', folder.value)); | watch(folder, () => emit('cd', folder.value)); | ||||||
| 
 | 
 | ||||||
|  | @ -332,7 +332,7 @@ function deleteFolder(folderToDelete: Misskey.entities.DriveFolder) { | ||||||
| 		// 削除時に親フォルダに移動 | 		// 削除時に親フォルダに移動 | ||||||
| 		move(folderToDelete.parentId); | 		move(folderToDelete.parentId); | ||||||
| 	}).catch(err => { | 	}).catch(err => { | ||||||
| 		switch(err.id) { | 		switch (err.id) { | ||||||
| 			case 'b0fc8a17-963c-405d-bfbc-859a487295e1': | 			case 'b0fc8a17-963c-405d-bfbc-859a487295e1': | ||||||
| 				os.alert({ | 				os.alert({ | ||||||
| 					type: 'error', | 					type: 'error', | ||||||
|  | @ -607,7 +607,7 @@ function onContextmenu(ev: MouseEvent) { | ||||||
| onMounted(() => { | onMounted(() => { | ||||||
| 	if (defaultStore.state.enableInfiniteScroll && loadMoreFiles.value) { | 	if (defaultStore.state.enableInfiniteScroll && loadMoreFiles.value) { | ||||||
| 		nextTick(() => { | 		nextTick(() => { | ||||||
| 			ilFilesObserver.observe(loadMoreFiles.value?.$el) | 			ilFilesObserver.observe(loadMoreFiles.value?.$el); | ||||||
| 		}); | 		}); | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
|  | @ -628,7 +628,7 @@ onMounted(() => { | ||||||
| onActivated(() => { | onActivated(() => { | ||||||
| 	if (defaultStore.state.enableInfiniteScroll) { | 	if (defaultStore.state.enableInfiniteScroll) { | ||||||
| 		nextTick(() => { | 		nextTick(() => { | ||||||
| 			ilFilesObserver.observe(loadMoreFiles.value?.$el) | 			ilFilesObserver.observe(loadMoreFiles.value?.$el); | ||||||
| 		}); | 		}); | ||||||
| 	} | 	} | ||||||
| }); | }); | ||||||
|  |  | ||||||
|  | @ -28,7 +28,7 @@ | ||||||
| </template> | </template> | ||||||
| 
 | 
 | ||||||
| <script lang="ts" setup> | <script lang="ts" setup> | ||||||
| import { onBeforeUnmount, onMounted, ref } from 'vue'; | import { onBeforeUnmount, onMounted } from 'vue'; | ||||||
| import * as Misskey from 'misskey-js'; | import * as Misskey from 'misskey-js'; | ||||||
| import * as os from '@/os'; | import * as os from '@/os'; | ||||||
| import { stream } from '@/stream'; | import { stream } from '@/stream'; | ||||||
|  | @ -43,32 +43,30 @@ const props = withDefaults(defineProps<{ | ||||||
| 	large: false, | 	large: false, | ||||||
| }); | }); | ||||||
| 
 | 
 | ||||||
| const isFollowing = ref(props.user.isFollowing); | let isFollowing = $ref(props.user.isFollowing); | ||||||
| const hasPendingFollowRequestFromYou = ref(props.user.hasPendingFollowRequestFromYou); | let hasPendingFollowRequestFromYou = $ref(props.user.hasPendingFollowRequestFromYou); | ||||||
| const wait = ref(false); | let wait = $ref(false); | ||||||
| const connection = stream.useChannel('main'); | const connection = stream.useChannel('main'); | ||||||
| 
 | 
 | ||||||
| if (props.user.isFollowing == null) { | if (props.user.isFollowing == null) { | ||||||
| 	os.api('users/show', { | 	os.api('users/show', { | ||||||
| 		userId: props.user.id | 		userId: props.user.id | ||||||
| 	}).then(u => { | 	}) | ||||||
| 		isFollowing.value = u.isFollowing; | 	.then(onFollowChange); | ||||||
| 		hasPendingFollowRequestFromYou.value = u.hasPendingFollowRequestFromYou; |  | ||||||
| 	}); |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| function onFollowChange(user: Misskey.entities.UserDetailed) { | function onFollowChange(user: Misskey.entities.UserDetailed) { | ||||||
| 	if (user.id === props.user.id) { | 	if (user.id === props.user.id) { | ||||||
| 		isFollowing.value = user.isFollowing; | 		isFollowing = user.isFollowing; | ||||||
| 		hasPendingFollowRequestFromYou.value = user.hasPendingFollowRequestFromYou; | 		hasPendingFollowRequestFromYou = user.hasPendingFollowRequestFromYou; | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| async function onClick() { | async function onClick() { | ||||||
| 	wait.value = true; | 	wait = true; | ||||||
| 
 | 
 | ||||||
| 	try { | 	try { | ||||||
| 		if (isFollowing.value) { | 		if (isFollowing) { | ||||||
| 			const { canceled } = await os.confirm({ | 			const { canceled } = await os.confirm({ | ||||||
| 				type: 'warning', | 				type: 'warning', | ||||||
| 				text: i18n.t('unfollowConfirm', { name: props.user.name || props.user.username }), | 				text: i18n.t('unfollowConfirm', { name: props.user.name || props.user.username }), | ||||||
|  | @ -80,26 +78,22 @@ async function onClick() { | ||||||
| 				userId: props.user.id | 				userId: props.user.id | ||||||
| 			}); | 			}); | ||||||
| 		} else { | 		} else { | ||||||
| 			if (hasPendingFollowRequestFromYou.value) { | 			if (hasPendingFollowRequestFromYou) { | ||||||
| 				await os.api('following/requests/cancel', { | 				await os.api('following/requests/cancel', { | ||||||
| 					userId: props.user.id | 					userId: props.user.id | ||||||
| 				}); | 				}); | ||||||
| 			} else if (props.user.isLocked) { | 				hasPendingFollowRequestFromYou = false; | ||||||
| 				await os.api('following/create', { |  | ||||||
| 					userId: props.user.id |  | ||||||
| 				}); |  | ||||||
| 				hasPendingFollowRequestFromYou.value = true; |  | ||||||
| 			} else { | 			} else { | ||||||
| 				await os.api('following/create', { | 				await os.api('following/create', { | ||||||
| 					userId: props.user.id | 					userId: props.user.id | ||||||
| 				}); | 				}); | ||||||
| 				hasPendingFollowRequestFromYou.value = true; | 				hasPendingFollowRequestFromYou = true; | ||||||
| 			} | 			} | ||||||
| 		} | 		} | ||||||
| 	} catch (err) { | 	} catch (err) { | ||||||
| 		console.error(err); | 		console.error(err); | ||||||
| 	} finally { | 	} finally { | ||||||
| 		wait.value = false; | 		wait = false; | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -24,7 +24,7 @@ const props = withDefaults(defineProps<{ | ||||||
| 	defaultOpen: boolean; | 	defaultOpen: boolean; | ||||||
| }>(), { | }>(), { | ||||||
|   defaultOpen: false, |   defaultOpen: false, | ||||||
| }) | }); | ||||||
| 
 | 
 | ||||||
| let opened = $ref(props.defaultOpen); | let opened = $ref(props.defaultOpen); | ||||||
| let openedAtLeastOnce = $ref(props.defaultOpen); | let openedAtLeastOnce = $ref(props.defaultOpen); | ||||||
|  |  | ||||||
|  | @ -14,7 +14,7 @@ export default defineComponent({ | ||||||
| 	data() { | 	data() { | ||||||
| 		return { | 		return { | ||||||
| 			value: this.modelValue, | 			value: this.modelValue, | ||||||
| 		} | 		}; | ||||||
| 	}, | 	}, | ||||||
| 	watch: { | 	watch: { | ||||||
| 		value() { | 		value() { | ||||||
|  |  | ||||||
|  | @ -66,7 +66,7 @@ export default defineComponent({ | ||||||
| 					.then(response => response.json()) | 					.then(response => response.json()) | ||||||
| 					.then(f => { | 					.then(f => { | ||||||
| 						ok(f); | 						ok(f); | ||||||
| 					}) | 					}); | ||||||
| 				}); | 				}); | ||||||
| 			}); | 			}); | ||||||
| 			os.promiseDialog(promise); | 			os.promiseDialog(promise); | ||||||
|  |  | ||||||
|  | @ -16,7 +16,7 @@ | ||||||
| 
 | 
 | ||||||
| <script lang="ts"> | <script lang="ts"> | ||||||
| import { defineComponent, defineAsyncComponent } from 'vue'; | import { defineComponent, defineAsyncComponent } from 'vue'; | ||||||
| import MkDriveFileThumbnail from './drive-file-thumbnail.vue' | import MkDriveFileThumbnail from './drive-file-thumbnail.vue'; | ||||||
| import * as os from '@/os'; | import * as os from '@/os'; | ||||||
| 
 | 
 | ||||||
| export default defineComponent({ | export default defineComponent({ | ||||||
|  | @ -114,19 +114,19 @@ export default defineComponent({ | ||||||
| 			this.menu = os.popupMenu([{ | 			this.menu = os.popupMenu([{ | ||||||
| 				text: this.$ts.renameFile, | 				text: this.$ts.renameFile, | ||||||
| 				icon: 'fas fa-i-cursor', | 				icon: 'fas fa-i-cursor', | ||||||
| 				action: () => { this.rename(file) } | 				action: () => { this.rename(file); } | ||||||
| 			}, { | 			}, { | ||||||
| 				text: file.isSensitive ? this.$ts.unmarkAsSensitive : this.$ts.markAsSensitive, | 				text: file.isSensitive ? this.$ts.unmarkAsSensitive : this.$ts.markAsSensitive, | ||||||
| 				icon: file.isSensitive ? 'fas fa-eye-slash' : 'fas fa-eye', | 				icon: file.isSensitive ? 'fas fa-eye-slash' : 'fas fa-eye', | ||||||
| 				action: () => { this.toggleSensitive(file) } | 				action: () => { this.toggleSensitive(file); } | ||||||
| 			}, { | 			}, { | ||||||
| 				text: this.$ts.describeFile, | 				text: this.$ts.describeFile, | ||||||
| 				icon: 'fas fa-i-cursor', | 				icon: 'fas fa-i-cursor', | ||||||
| 				action: () => { this.describe(file) } | 				action: () => { this.describe(file); } | ||||||
| 			}, { | 			}, { | ||||||
| 				text: this.$ts.attachCancel, | 				text: this.$ts.attachCancel, | ||||||
| 				icon: 'fas fa-times-circle', | 				icon: 'fas fa-times-circle', | ||||||
| 				action: () => { this.detachMedia(file.id) } | 				action: () => { this.detachMedia(file.id); } | ||||||
| 			}], ev.currentTarget ?? ev.target).then(() => this.menu = null); | 			}], ev.currentTarget ?? ev.target).then(() => this.menu = null); | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|  | @ -442,7 +442,7 @@ function onCompositionEnd(ev: CompositionEvent) { | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| async function onPaste(ev: ClipboardEvent) { | async function onPaste(ev: ClipboardEvent) { | ||||||
| 	for (const { item, i } of Array.from(ev.clipboardData.items).map((item, i) => ({item, i}))) { | 	for (const { item, i } of Array.from(ev.clipboardData.items).map((item, i) => ({ item, i }))) { | ||||||
| 		if (item.kind === 'file') { | 		if (item.kind === 'file') { | ||||||
| 			const file = item.getAsFile(); | 			const file = item.getAsFile(); | ||||||
| 			const lio = file.name.lastIndexOf('.'); | 			const lio = file.name.lastIndexOf('.'); | ||||||
|  |  | ||||||
|  | @ -222,7 +222,7 @@ export default defineComponent({ | ||||||
| 
 | 
 | ||||||
| 		return { | 		return { | ||||||
| 			chartEl, | 			chartEl, | ||||||
| 		} | 		}; | ||||||
| 	}, | 	}, | ||||||
| }); | }); | ||||||
| </script> | </script> | ||||||
|  |  | ||||||
|  | @ -52,7 +52,7 @@ export default defineComponent({ | ||||||
| 			flag: true, | 			flag: true, | ||||||
| 			radio: 'misskey', | 			radio: 'misskey', | ||||||
| 			mfm: `Hello world! This is an @example mention. BTW you are @${this.$i ? this.$i.username : 'guest'}.\nAlso, here is ${config.url} and [example link](${config.url}). for more details, see https://example.com.\nAs you know #misskey is open-source software.` | 			mfm: `Hello world! This is an @example mention. BTW you are @${this.$i ? this.$i.username : 'guest'}.\nAlso, here is ${config.url} and [example link](${config.url}). for more details, see https://example.com.\nAs you know #misskey is open-source software.` | ||||||
| 		} | 		}; | ||||||
| 	}, | 	}, | ||||||
| 
 | 
 | ||||||
| 	methods: { | 	methods: { | ||||||
|  |  | ||||||
|  | @ -159,7 +159,7 @@ function queryKey() { | ||||||
| 
 | 
 | ||||||
| function onSubmit() { | function onSubmit() { | ||||||
| 	signing = true; | 	signing = true; | ||||||
| 	console.log('submit') | 	console.log('submit'); | ||||||
| 	if (!totpLogin && user && user.twoFactorEnabled) { | 	if (!totpLogin && user && user.twoFactorEnabled) { | ||||||
| 		if (window.PublicKeyCredential && user.securityKeys) { | 		if (window.PublicKeyCredential && user.securityKeys) { | ||||||
| 			os.api('signin', { | 			os.api('signin', { | ||||||
|  | @ -222,7 +222,7 @@ function loginFailed(err) { | ||||||
| 			break; | 			break; | ||||||
| 		} | 		} | ||||||
| 		default: { | 		default: { | ||||||
| 			console.log(err) | 			console.log(err); | ||||||
| 			os.alert({ | 			os.alert({ | ||||||
| 				type: 'error', | 				type: 'error', | ||||||
| 				title: i18n.ts.loginFailed, | 				title: i18n.ts.loginFailed, | ||||||
|  |  | ||||||
|  | @ -111,7 +111,7 @@ export default defineComponent({ | ||||||
| 			ToSAgreement: false, | 			ToSAgreement: false, | ||||||
| 			hCaptchaResponse: null, | 			hCaptchaResponse: null, | ||||||
| 			reCaptchaResponse: null, | 			reCaptchaResponse: null, | ||||||
| 		} | 		}; | ||||||
| 	}, | 	}, | ||||||
| 
 | 
 | ||||||
| 	computed: { | 	computed: { | ||||||
|  |  | ||||||
|  | @ -96,11 +96,11 @@ export default defineComponent({ | ||||||
| 			} | 			} | ||||||
| 
 | 
 | ||||||
| 			function calcCircleScale(boxW, boxH, circleCenterX, circleCenterY) { | 			function calcCircleScale(boxW, boxH, circleCenterX, circleCenterY) { | ||||||
| 				const origin = {x: circleCenterX, y: circleCenterY}; | 				const origin = { x: circleCenterX, y: circleCenterY }; | ||||||
| 				const dist1 = distance({x: 0, y: 0}, origin); | 				const dist1 = distance({ x: 0, y: 0 }, origin); | ||||||
| 				const dist2 = distance({x: boxW, y: 0}, origin); | 				const dist2 = distance({ x: boxW, y: 0 }, origin); | ||||||
| 				const dist3 = distance({x: 0, y: boxH}, origin); | 				const dist3 = distance({ x: 0, y: boxH }, origin); | ||||||
| 				const dist4 = distance({x: boxW, y: boxH }, origin); | 				const dist4 = distance({ x: boxW, y: boxH }, origin); | ||||||
| 				return Math.max(dist1, dist2, dist3, dist4) * 2; | 				return Math.max(dist1, dist2, dist3, dist4) * 2; | ||||||
| 			} | 			} | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -234,7 +234,7 @@ onMounted(() => { | ||||||
| 		} | 		} | ||||||
| 		fixed.value = (type.value === 'drawer') || (getFixedContainer(props.src) != null); | 		fixed.value = (type.value === 'drawer') || (getFixedContainer(props.src) != null); | ||||||
| 
 | 
 | ||||||
| 		await nextTick() | 		await nextTick(); | ||||||
| 		 | 		 | ||||||
| 		align(); | 		align(); | ||||||
| 	}, { immediate: true, }); | 	}, { immediate: true, }); | ||||||
|  |  | ||||||
|  | @ -63,7 +63,7 @@ const setPosition = () => { | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		return [left, top]; | 		return [left, top]; | ||||||
| 	} | 	}; | ||||||
| 
 | 
 | ||||||
| 	const calcPosWhenBottom = () => { | 	const calcPosWhenBottom = () => { | ||||||
| 		let left: number; | 		let left: number; | ||||||
|  | @ -84,7 +84,7 @@ const setPosition = () => { | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		return [left, top]; | 		return [left, top]; | ||||||
| 	} | 	}; | ||||||
| 
 | 
 | ||||||
| 	const calcPosWhenLeft = () => { | 	const calcPosWhenLeft = () => { | ||||||
| 		let left: number; | 		let left: number; | ||||||
|  | @ -105,7 +105,7 @@ const setPosition = () => { | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		return [left, top]; | 		return [left, top]; | ||||||
| 	} | 	}; | ||||||
| 
 | 
 | ||||||
| 	const calcPosWhenRight = () => { | 	const calcPosWhenRight = () => { | ||||||
| 		let left: number; | 		let left: number; | ||||||
|  | @ -126,7 +126,7 @@ const setPosition = () => { | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		return [left, top]; | 		return [left, top]; | ||||||
| 	} | 	}; | ||||||
| 
 | 
 | ||||||
| 	const calc = (): { | 	const calc = (): { | ||||||
| 		left: number; | 		left: number; | ||||||
|  | @ -172,7 +172,7 @@ const setPosition = () => { | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		return null as never; | 		return null as never; | ||||||
| 	} | 	}; | ||||||
| 
 | 
 | ||||||
| 	const { left, top, transformOrigin } = calc(); | 	const { left, top, transformOrigin } = calc(); | ||||||
| 	el.value.style.transformOrigin = transformOrigin; | 	el.value.style.transformOrigin = transformOrigin; | ||||||
|  |  | ||||||
|  | @ -90,7 +90,7 @@ fetch(`/url?url=${encodeURIComponent(requestUrl.href)}&lang=${requestLang}`).the | ||||||
| 		sitename = info.sitename; | 		sitename = info.sitename; | ||||||
| 		fetching = false; | 		fetching = false; | ||||||
| 		player = info.player; | 		player = info.player; | ||||||
| 	}) | 	}); | ||||||
| }); | }); | ||||||
| 
 | 
 | ||||||
| function adjustTweetHeight(message: any) { | function adjustTweetHeight(message: any) { | ||||||
|  |  | ||||||
|  | @ -9,7 +9,7 @@ export default { | ||||||
| 			} else { | 			} else { | ||||||
| 				return el.parentElement ? getBgColor(el.parentElement) : 'transparent'; | 				return el.parentElement ? getBgColor(el.parentElement) : 'transparent'; | ||||||
| 			} | 			} | ||||||
| 		} | 		}; | ||||||
| 	 | 	 | ||||||
| 		const parentBg = getBgColor(src.parentElement); | 		const parentBg = getBgColor(src.parentElement); | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -25,12 +25,12 @@ function calc(src: Element) { | ||||||
| 		return; | 		return; | ||||||
| 	} | 	} | ||||||
| 	if (info.intersection) { | 	if (info.intersection) { | ||||||
| 		info.intersection.disconnect() | 		info.intersection.disconnect(); | ||||||
| 		delete info.intersection; | 		delete info.intersection; | ||||||
| 	}; | 	} | ||||||
| 
 | 
 | ||||||
| 	info.fn(width, height); | 	info.fn(width, height); | ||||||
| }; | } | ||||||
| 
 | 
 | ||||||
| export default { | export default { | ||||||
| 	mounted(src, binding, vn) { | 	mounted(src, binding, vn) { | ||||||
|  |  | ||||||
|  | @ -9,7 +9,7 @@ export default { | ||||||
| 			} else { | 			} else { | ||||||
| 				return el.parentElement ? getBgColor(el.parentElement) : 'transparent'; | 				return el.parentElement ? getBgColor(el.parentElement) : 'transparent'; | ||||||
| 			} | 			} | ||||||
| 		} | 		}; | ||||||
| 	 | 	 | ||||||
| 		const parentBg = getBgColor(src.parentElement); | 		const parentBg = getBgColor(src.parentElement); | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -60,9 +60,9 @@ function calc(el: Element) { | ||||||
| 		return; | 		return; | ||||||
| 	} | 	} | ||||||
| 	if (info.intersection) { | 	if (info.intersection) { | ||||||
| 		info.intersection.disconnect() | 		info.intersection.disconnect(); | ||||||
| 		delete info.intersection; | 		delete info.intersection; | ||||||
| 	}; | 	} | ||||||
| 
 | 
 | ||||||
| 	mountings.set(el, Object.assign(info, { previousWidth: width })); | 	mountings.set(el, Object.assign(info, { previousWidth: width })); | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -285,7 +285,7 @@ export function inputDate(props: { | ||||||
| 	}); | 	}); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| export function select<C extends any = any>(props: { | export function select<C = any>(props: { | ||||||
| 	title?: string | null; | 	title?: string | null; | ||||||
| 	text?: string | null; | 	text?: string | null; | ||||||
| 	default?: string | null; | 	default?: string | null; | ||||||
|  |  | ||||||
|  | @ -159,7 +159,7 @@ const remoteMenu = (emoji, ev: MouseEvent) => { | ||||||
| 	}, { | 	}, { | ||||||
| 		text: i18n.ts.import, | 		text: i18n.ts.import, | ||||||
| 		icon: 'fas fa-plus', | 		icon: 'fas fa-plus', | ||||||
| 		action: () => { im(emoji) } | 		action: () => { im(emoji); } | ||||||
| 	}], ev.currentTarget ?? ev.target); | 	}], ev.currentTarget ?? ev.target); | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -132,7 +132,7 @@ export default defineComponent({ | ||||||
| 			overviewHeight: '1fr', | 			overviewHeight: '1fr', | ||||||
| 			queueHeight: '1fr', | 			queueHeight: '1fr', | ||||||
| 			paused: false, | 			paused: false, | ||||||
| 		} | 		}; | ||||||
| 	}, | 	}, | ||||||
| 
 | 
 | ||||||
| 	computed: { | 	computed: { | ||||||
|  |  | ||||||
|  | @ -20,7 +20,7 @@ import * as symbols from '@/symbols'; | ||||||
| import * as config from '@/config'; | import * as config from '@/config'; | ||||||
| import { i18n } from '@/i18n'; | import { i18n } from '@/i18n'; | ||||||
| 
 | 
 | ||||||
| const connection = markRaw(stream.useChannel('queueStats')) | const connection = markRaw(stream.useChannel('queueStats')); | ||||||
| 
 | 
 | ||||||
| function clear() { | function clear() { | ||||||
| 	os.confirm({ | 	os.confirm({ | ||||||
|  | @ -41,7 +41,7 @@ onMounted(() => { | ||||||
| 			length: 200 | 			length: 200 | ||||||
| 		}); | 		}); | ||||||
| 	}); | 	}); | ||||||
| }) | }); | ||||||
| 
 | 
 | ||||||
| onBeforeUnmount(() => { | onBeforeUnmount(() => { | ||||||
| 	connection.dispose(); | 	connection.dispose(); | ||||||
|  |  | ||||||
|  | @ -32,7 +32,7 @@ export default defineComponent({ | ||||||
| 	computed: { | 	computed: { | ||||||
| 		name(): string { | 		name(): string { | ||||||
| 			const el = document.createElement('div'); | 			const el = document.createElement('div'); | ||||||
| 			el.textContent = this.app.name | 			el.textContent = this.app.name; | ||||||
| 			return el.innerHTML; | 			return el.innerHTML; | ||||||
| 		}, | 		}, | ||||||
| 		app(): any { | 		app(): any { | ||||||
|  |  | ||||||
|  | @ -58,7 +58,7 @@ export default defineComponent({ | ||||||
| 			tags: emojiTags, | 			tags: emojiTags, | ||||||
| 			selectedTags: new Set(), | 			selectedTags: new Set(), | ||||||
| 			searchEmojis: null, | 			searchEmojis: null, | ||||||
| 		} | 		}; | ||||||
| 	}, | 	}, | ||||||
| 
 | 
 | ||||||
| 	watch: { | 	watch: { | ||||||
|  |  | ||||||
|  | @ -127,7 +127,7 @@ function getStatus(instance) { | ||||||
| 	if (instance.isSuspended) return 'suspended'; | 	if (instance.isSuspended) return 'suspended'; | ||||||
| 	if (instance.isNotResponding) return 'error'; | 	if (instance.isNotResponding) return 'error'; | ||||||
| 	return 'alive'; | 	return 'alive'; | ||||||
| }; | } | ||||||
| 
 | 
 | ||||||
| defineExpose({ | defineExpose({ | ||||||
| 	[symbols.PAGE_INFO]: { | 	[symbols.PAGE_INFO]: { | ||||||
|  |  | ||||||
|  | @ -71,7 +71,7 @@ export default defineComponent({ | ||||||
| 			description: null, | 			description: null, | ||||||
| 			title: null, | 			title: null, | ||||||
| 			isSensitive: false, | 			isSensitive: false, | ||||||
| 		} | 		}; | ||||||
| 	}, | 	}, | ||||||
| 
 | 
 | ||||||
| 	watch: { | 	watch: { | ||||||
|  |  | ||||||
|  | @ -123,11 +123,11 @@ export default defineComponent({ | ||||||
| 			os.popupMenu([{ | 			os.popupMenu([{ | ||||||
| 				text: this.$ts.messagingWithUser, | 				text: this.$ts.messagingWithUser, | ||||||
| 				icon: 'fas fa-user', | 				icon: 'fas fa-user', | ||||||
| 				action: () => { this.startUser() } | 				action: () => { this.startUser(); } | ||||||
| 			}, { | 			}, { | ||||||
| 				text: this.$ts.messagingWithGroup, | 				text: this.$ts.messagingWithGroup, | ||||||
| 				icon: 'fas fa-users', | 				icon: 'fas fa-users', | ||||||
| 				action: () => { this.startGroup() } | 				action: () => { this.startGroup(); } | ||||||
| 			}], ev.currentTarget ?? ev.target); | 			}], ev.currentTarget ?? ev.target); | ||||||
| 		}, | 		}, | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -200,7 +200,7 @@ export default defineComponent({ | ||||||
| 					text: this.text, | 					text: this.text, | ||||||
| 					file: this.file | 					file: this.file | ||||||
| 				} | 				} | ||||||
| 			} | 			}; | ||||||
| 
 | 
 | ||||||
| 			localStorage.setItem('message_drafts', JSON.stringify(drafts)); | 			localStorage.setItem('message_drafts', JSON.stringify(drafts)); | ||||||
| 		}, | 		}, | ||||||
|  |  | ||||||
|  | @ -341,7 +341,7 @@ export default defineComponent({ | ||||||
| 			preview_rainbow: `$[rainbow 🍮] $[rainbow.speed=5s 🍮]`, | 			preview_rainbow: `$[rainbow 🍮] $[rainbow.speed=5s 🍮]`, | ||||||
| 			preview_sparkle: `$[sparkle 🍮]`, | 			preview_sparkle: `$[sparkle 🍮]`, | ||||||
| 			preview_rotate: `$[rotate 🍮]`, | 			preview_rotate: `$[rotate 🍮]`, | ||||||
| 		} | 		}; | ||||||
| 	}, | 	}, | ||||||
| }); | }); | ||||||
| </script> | </script> | ||||||
|  |  | ||||||
|  | @ -32,7 +32,7 @@ defineExpose({ | ||||||
| 		icon: 'fas fa-satellite', | 		icon: 'fas fa-satellite', | ||||||
| 		bg: 'var(--bg)' | 		bg: 'var(--bg)' | ||||||
| 	} | 	} | ||||||
| }) | }); | ||||||
| </script> | </script> | ||||||
| 
 | 
 | ||||||
| <style lang="scss" scoped> | <style lang="scss" scoped> | ||||||
|  |  | ||||||
|  | @ -114,7 +114,7 @@ export default defineComponent({ | ||||||
| 			readonly: this.readonly, | 			readonly: this.readonly, | ||||||
| 			getScriptBlockList: this.getScriptBlockList, | 			getScriptBlockList: this.getScriptBlockList, | ||||||
| 			getPageBlockList: this.getPageBlockList | 			getPageBlockList: this.getPageBlockList | ||||||
| 		} | 		}; | ||||||
| 	}, | 	}, | ||||||
| 
 | 
 | ||||||
| 	props: { | 	props: { | ||||||
|  |  | ||||||
|  | @ -100,7 +100,7 @@ async function run() { | ||||||
| 			text: error.message | 			text: error.message | ||||||
| 		}); | 		}); | ||||||
| 	} | 	} | ||||||
| }; | } | ||||||
| 
 | 
 | ||||||
| function highlighter(code) { | function highlighter(code) { | ||||||
| 	return highlight(code, languages.js, 'javascript'); | 	return highlight(code, languages.js, 'javascript'); | ||||||
|  |  | ||||||
|  | @ -142,7 +142,7 @@ function registerKey() { | ||||||
| 		registration.value = null; | 		registration.value = null; | ||||||
| 		key.lastUsed = new Date(); | 		key.lastUsed = new Date(); | ||||||
| 		os.success(); | 		os.success(); | ||||||
| 	}) | 	}); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| function unregisterKey(key) { | function unregisterKey(key) { | ||||||
|  |  | ||||||
|  | @ -45,7 +45,7 @@ const init = async () => { | ||||||
| 		accounts.value = response; | 		accounts.value = response; | ||||||
| 		console.log(accounts.value); | 		console.log(accounts.value); | ||||||
| 	}); | 	}); | ||||||
| } | }; | ||||||
| 
 | 
 | ||||||
| function menu(account, ev) { | function menu(account, ev) { | ||||||
| 	os.popupMenu([{ | 	os.popupMenu([{ | ||||||
|  |  | ||||||
|  | @ -52,7 +52,7 @@ const pagination = { | ||||||
| 	params: { | 	params: { | ||||||
| 		sort: '+lastUsedAt' | 		sort: '+lastUsedAt' | ||||||
| 	} | 	} | ||||||
| } | }; | ||||||
| 
 | 
 | ||||||
| function revoke(token) { | function revoke(token) { | ||||||
| 	os.api('i/revoke-token', { tokenId: token.id }).then(() => { | 	os.api('i/revoke-token', { tokenId: token.id }).then(() => { | ||||||
|  |  | ||||||
|  | @ -120,7 +120,7 @@ const darkThemeId = computed({ | ||||||
| 		return darkTheme.value.id; | 		return darkTheme.value.id; | ||||||
| 	}, | 	}, | ||||||
| 	set(id) { | 	set(id) { | ||||||
| 		ColdDeviceStorage.set('darkTheme', themes.value.find(x => x.id === id)) | 		ColdDeviceStorage.set('darkTheme', themes.value.find(x => x.id === id)); | ||||||
| 	} | 	} | ||||||
| }); | }); | ||||||
| const lightTheme = ColdDeviceStorage.ref('lightTheme'); | const lightTheme = ColdDeviceStorage.ref('lightTheme'); | ||||||
|  | @ -129,7 +129,7 @@ const lightThemeId = computed({ | ||||||
| 		return lightTheme.value.id; | 		return lightTheme.value.id; | ||||||
| 	}, | 	}, | ||||||
| 	set(id) { | 	set(id) { | ||||||
| 		ColdDeviceStorage.set('lightTheme', themes.value.find(x => x.id === id)) | 		ColdDeviceStorage.set('lightTheme', themes.value.find(x => x.id === id)); | ||||||
| 	} | 	} | ||||||
| }); | }); | ||||||
| const darkMode = computed(defaultStore.makeGetterSetter('darkMode')); | const darkMode = computed(defaultStore.makeGetterSetter('darkMode')); | ||||||
|  |  | ||||||
|  | @ -75,7 +75,7 @@ async function save() { | ||||||
| 
 | 
 | ||||||
| 		// check each line if it is a RegExp or not | 		// check each line if it is a RegExp or not | ||||||
| 		for (let i = 0; i < lines.length; i++) { | 		for (let i = 0; i < lines.length; i++) { | ||||||
| 			const line = lines[i] | 			const line = lines[i]; | ||||||
| 			const regexp = line.match(/^\/(.+)\/(.*)$/); | 			const regexp = line.match(/^\/(.+)\/(.*)$/); | ||||||
| 			if (regexp) { | 			if (regexp) { | ||||||
| 				// check that the RegExp is valid | 				// check that the RegExp is valid | ||||||
|  |  | ||||||
|  | @ -56,7 +56,7 @@ export default defineComponent({ | ||||||
| 			localOnly: null as boolean | null, | 			localOnly: null as boolean | null, | ||||||
| 			files: [] as Misskey.entities.DriveFile[], | 			files: [] as Misskey.entities.DriveFile[], | ||||||
| 			visibleUsers: [] as Misskey.entities.User[], | 			visibleUsers: [] as Misskey.entities.User[], | ||||||
| 		} | 		}; | ||||||
| 	}, | 	}, | ||||||
| 
 | 
 | ||||||
| 	async created() { | 	async created() { | ||||||
|  |  | ||||||
|  | @ -68,7 +68,7 @@ | ||||||
| import { watch } from 'vue'; | import { watch } from 'vue'; | ||||||
| import { toUnicode } from 'punycode/'; | import { toUnicode } from 'punycode/'; | ||||||
| import tinycolor from 'tinycolor2'; | import tinycolor from 'tinycolor2'; | ||||||
| import { v4 as uuid} from 'uuid'; | import { v4 as uuid } from 'uuid'; | ||||||
| import JSON5 from 'json5'; | import JSON5 from 'json5'; | ||||||
| 
 | 
 | ||||||
| import FormButton from '@/components/ui/button.vue'; | import FormButton from '@/components/ui/button.vue'; | ||||||
|  |  | ||||||
|  | @ -20,7 +20,7 @@ | ||||||
| <script lang="ts"> | <script lang="ts"> | ||||||
| export default { | export default { | ||||||
| 	name: 'MkTimelinePage', | 	name: 'MkTimelinePage', | ||||||
| } | }; | ||||||
| </script> | </script> | ||||||
| 
 | 
 | ||||||
| <script lang="ts" setup> | <script lang="ts" setup> | ||||||
|  |  | ||||||
|  | @ -41,7 +41,7 @@ export default defineComponent({ | ||||||
| 			password: '', | 			password: '', | ||||||
| 			submitting: false, | 			submitting: false, | ||||||
| 			host, | 			host, | ||||||
| 		} | 		}; | ||||||
| 	}, | 	}, | ||||||
| 
 | 
 | ||||||
| 	methods: { | 	methods: { | ||||||
|  |  | ||||||
|  | @ -39,7 +39,7 @@ export default defineComponent({ | ||||||
| 		return { | 		return { | ||||||
| 			notes: [], | 			notes: [], | ||||||
| 			isScrolling: false, | 			isScrolling: false, | ||||||
| 		} | 		}; | ||||||
| 	}, | 	}, | ||||||
| 
 | 
 | ||||||
| 	created() { | 	created() { | ||||||
|  |  | ||||||
|  | @ -13,7 +13,7 @@ const defaultLocaleStringFormats: {[index: string]: string} = { | ||||||
| function formatLocaleString(date: Date, format: string): string { | function formatLocaleString(date: Date, format: string): string { | ||||||
| 	return format.replace(/\{\{(\w+)(:(\w+))?\}\}/g, (match: string, kind: string, unused?, option?: string) => { | 	return format.replace(/\{\{(\w+)(:(\w+))?\}\}/g, (match: string, kind: string, unused?, option?: string) => { | ||||||
| 		if (['weekday', 'era', 'year', 'month', 'day', 'hour', 'minute', 'second', 'timeZoneName'].includes(kind)) { | 		if (['weekday', 'era', 'year', 'month', 'day', 'hour', 'minute', 'second', 'timeZoneName'].includes(kind)) { | ||||||
| 			return date.toLocaleString(window.navigator.language, {[kind]: option ? option : defaultLocaleStringFormats[kind]}); | 			return date.toLocaleString(window.navigator.language, { [kind]: option ? option : defaultLocaleStringFormats[kind] }); | ||||||
| 		} else { | 		} else { | ||||||
| 			return match; | 			return match; | ||||||
| 		} | 		} | ||||||
|  | @ -24,8 +24,8 @@ export function formatDateTimeString(date: Date, format: string): string { | ||||||
| 	return format | 	return format | ||||||
| 		.replace(/yyyy/g, date.getFullYear().toString()) | 		.replace(/yyyy/g, date.getFullYear().toString()) | ||||||
| 		.replace(/yy/g, date.getFullYear().toString().slice(-2)) | 		.replace(/yy/g, date.getFullYear().toString().slice(-2)) | ||||||
| 		.replace(/MMMM/g, date.toLocaleString(window.navigator.language, { month: 'long'})) | 		.replace(/MMMM/g, date.toLocaleString(window.navigator.language, { month: 'long' })) | ||||||
| 		.replace(/MMM/g, date.toLocaleString(window.navigator.language, { month: 'short'})) | 		.replace(/MMM/g, date.toLocaleString(window.navigator.language, { month: 'short' })) | ||||||
| 		.replace(/MM/g, (`0${date.getMonth() + 1}`).slice(-2)) | 		.replace(/MM/g, (`0${date.getMonth() + 1}`).slice(-2)) | ||||||
| 		.replace(/M/g, (date.getMonth() + 1).toString()) | 		.replace(/M/g, (date.getMonth() + 1).toString()) | ||||||
| 		.replace(/dd/g, (`0${date.getDate()}`).slice(-2)) | 		.replace(/dd/g, (`0${date.getDate()}`).slice(-2)) | ||||||
|  |  | ||||||
Some files were not shown because too many files have changed in this diff Show more
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue