parent
							
								
									f1a7ab639b
								
							
						
					
					
						commit
						ef44eda69e
					
				
					 8 changed files with 92 additions and 4 deletions
				
			
		|  | @ -804,6 +804,9 @@ common/views/components/profile-editor.vue: | |||
|   danger-zone: "危険な設定" | ||||
|   delete-account: "アカウントを削除" | ||||
|   account-deleted: "アカウントが削除されました。データが消えるまで時間がかかる場合があります。" | ||||
|   profile-metadata: "プロフィール補足情報" | ||||
|   metadata-label: "ラベル" | ||||
|   metadata-content: "内容" | ||||
| 
 | ||||
| common/views/components/user-list-editor.vue: | ||||
|   users: "ユーザー" | ||||
|  |  | |||
|  | @ -51,6 +51,26 @@ | |||
| 				<template #desc v-if="bannerUploading">{{ $t('uploading') }}<mk-ellipsis/></template> | ||||
| 			</ui-input> | ||||
| 
 | ||||
| 			<div class="fields"> | ||||
| 				<header>{{ $t('profile-metadata') }}</header> | ||||
| 				<ui-horizon-group> | ||||
| 					<ui-input v-model="fieldName0">{{ $t('metadata-label') }}</ui-input> | ||||
| 					<ui-input v-model="fieldValue0">{{ $t('metadata-content') }}</ui-input> | ||||
| 				</ui-horizon-group> | ||||
| 				<ui-horizon-group> | ||||
| 					<ui-input v-model="fieldName1">{{ $t('metadata-label') }}</ui-input> | ||||
| 					<ui-input v-model="fieldValue1">{{ $t('metadata-content') }}</ui-input> | ||||
| 				</ui-horizon-group> | ||||
| 				<ui-horizon-group> | ||||
| 					<ui-input v-model="fieldName2">{{ $t('metadata-label') }}</ui-input> | ||||
| 					<ui-input v-model="fieldValue2">{{ $t('metadata-content') }}</ui-input> | ||||
| 				</ui-horizon-group> | ||||
| 				<ui-horizon-group> | ||||
| 					<ui-input v-model="fieldName3">{{ $t('metadata-label') }}</ui-input> | ||||
| 					<ui-input v-model="fieldValue3">{{ $t('metadata-content') }}</ui-input> | ||||
| 				</ui-horizon-group> | ||||
| 			</div> | ||||
| 
 | ||||
| 			<ui-button @click="save(true)"><fa :icon="faSave"/> {{ $t('save') }}</ui-button> | ||||
| 		</ui-form> | ||||
| 	</section> | ||||
|  | @ -189,6 +209,17 @@ export default Vue.extend({ | |||
| 		this.isLocked = this.$store.state.i.isLocked; | ||||
| 		this.carefulBot = this.$store.state.i.carefulBot; | ||||
| 		this.autoAcceptFollowed = this.$store.state.i.autoAcceptFollowed; | ||||
| 
 | ||||
| 		if (this.$store.state.i.fields) { | ||||
| 			this.fieldName0 = this.$store.state.i.fields[0].name; | ||||
| 			this.fieldValue0 = this.$store.state.i.fields[0].value; | ||||
| 			this.fieldName1 = this.$store.state.i.fields[1].name; | ||||
| 			this.fieldValue1 = this.$store.state.i.fields[1].value; | ||||
| 			this.fieldName2 = this.$store.state.i.fields[2].name; | ||||
| 			this.fieldValue2 = this.$store.state.i.fields[2].value; | ||||
| 			this.fieldName3 = this.$store.state.i.fields[3].name; | ||||
| 			this.fieldValue3 = this.$store.state.i.fields[3].value; | ||||
| 		} | ||||
| 	}, | ||||
| 
 | ||||
| 	methods: { | ||||
|  | @ -237,6 +268,13 @@ export default Vue.extend({ | |||
| 		}, | ||||
| 
 | ||||
| 		save(notify) { | ||||
| 			const fields = [ | ||||
| 				{ name: this.fieldName0, value: this.fieldValue0 }, | ||||
| 				{ name: this.fieldName1, value: this.fieldValue1 }, | ||||
| 				{ name: this.fieldName2, value: this.fieldValue2 }, | ||||
| 				{ name: this.fieldName3, value: this.fieldValue3 }, | ||||
| 			]; | ||||
| 
 | ||||
| 			this.saving = true; | ||||
| 
 | ||||
| 			this.$root.api('i/update', { | ||||
|  | @ -247,6 +285,7 @@ export default Vue.extend({ | |||
| 				birthday: this.birthday || null, | ||||
| 				avatarId: this.avatarId || undefined, | ||||
| 				bannerId: this.bannerId || undefined, | ||||
| 				fields, | ||||
| 				isCat: !!this.isCat, | ||||
| 				isBot: !!this.isBot, | ||||
| 				isLocked: !!this.isLocked, | ||||
|  | @ -389,4 +428,11 @@ export default Vue.extend({ | |||
| 			height 72px | ||||
| 			margin auto | ||||
| 
 | ||||
| .fields | ||||
| 	> header | ||||
| 		padding 8px 0px | ||||
| 		font-weight bold | ||||
| 	> div | ||||
| 		padding-left 16px | ||||
| 
 | ||||
| </style> | ||||
|  |  | |||
|  | @ -148,6 +148,7 @@ export class UserRepository extends Repository<User> { | |||
| 				description: profile!.description, | ||||
| 				location: profile!.location, | ||||
| 				birthday: profile!.birthday, | ||||
| 				fields: profile!.fields, | ||||
| 				followersCount: user.followersCount, | ||||
| 				followingCount: user.followingCount, | ||||
| 				notesCount: user.notesCount, | ||||
|  |  | |||
|  | @ -21,13 +21,24 @@ export async function renderPerson(user: ILocalUser) { | |||
| 	]); | ||||
| 
 | ||||
| 	const attachment: { | ||||
| 		type: string, | ||||
| 		type: 'PropertyValue', | ||||
| 		name: string, | ||||
| 		value: string, | ||||
| 		verified_at?: string, | ||||
| 		identifier?: IIdentifier | ||||
| 	}[] = []; | ||||
| 
 | ||||
| 	if (profile.fields) { | ||||
| 		for (const field of profile.fields) { | ||||
| 			attachment.push({ | ||||
| 				type: 'PropertyValue', | ||||
| 				name: field.name, | ||||
| 				value: (field.value != null && field.value.match(/^https?:/)) | ||||
| 					? `<a href="${new URL(field.value).href}" rel="me nofollow noopener" target="_blank">${new URL(field.value).href}</a>` | ||||
| 					: field.value | ||||
| 			}); | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	if (profile.twitter) { | ||||
| 		attachment.push({ | ||||
| 			type: 'PropertyValue', | ||||
|  |  | |||
|  | @ -77,6 +77,13 @@ export const meta = { | |||
| 			} | ||||
| 		}, | ||||
| 
 | ||||
| 		fields: { | ||||
| 			validator: $.optional.arr($.object()).range(1, 4), | ||||
| 			desc: { | ||||
| 				'ja-JP': 'プロフィール補足情報' | ||||
| 			} | ||||
| 		}, | ||||
| 
 | ||||
| 		isLocked: { | ||||
| 			validator: $.optional.bool, | ||||
| 			desc: { | ||||
|  | @ -226,6 +233,14 @@ export default define(meta, async (ps, user, app) => { | |||
| 		profileUpdates.pinnedPageId = null; | ||||
| 	} | ||||
| 
 | ||||
| 	if (ps.fields) { | ||||
| 		profileUpdates.fields = ps.fields | ||||
| 			.filter(x => typeof x.name === 'string' && x.name !== '' && typeof x.value === 'string' && x.value !== '') | ||||
| 			.map(x => { | ||||
| 				return { name: x.name, value: x.value }; | ||||
| 			}); | ||||
| 	} | ||||
| 
 | ||||
| 	//#region emojis/tags
 | ||||
| 
 | ||||
| 	let emojis = [] as string[]; | ||||
|  |  | |||
|  | @ -156,11 +156,17 @@ router.get('/@:user', async (ctx, next) => { | |||
| 	if (user != null) { | ||||
| 		const profile = await UserProfiles.findOne(user.id).then(ensure); | ||||
| 		const meta = await fetchMeta(); | ||||
| 		const me = profile.fields | ||||
| 			? profile.fields | ||||
| 				.filter(filed => filed.value != null && filed.value.match(/^https?:/)) | ||||
| 				.map(field => field.value) | ||||
| 			: []; | ||||
| 
 | ||||
| 		await ctx.render('user', { | ||||
| 			user, profile, | ||||
| 			user, profile, me, | ||||
| 			instanceName: meta.name || 'Misskey' | ||||
| 		}); | ||||
| 		ctx.set('Cache-Control', 'public, max-age=180'); | ||||
| 		ctx.set('Cache-Control', 'public, max-age=30'); | ||||
| 	} else { | ||||
| 		// リモートユーザーなので
 | ||||
| 		await next(); | ||||
|  |  | |||
|  | @ -44,3 +44,4 @@ html | |||
| 			<svg viewBox="0 0 50 50"> | ||||
| 				<path fill=#fb4e4e d="M25.251,6.461c-10.318,0-18.683,8.365-18.683,18.683h4.068c0-8.071,6.543-14.615,14.615-14.615V6.461z" /> | ||||
| 			</svg> | ||||
| 		block content | ||||
|  |  | |||
|  | @ -36,3 +36,8 @@ block meta | |||
| 		link(rel='alternate' href=user.uri type='application/activity+json') | ||||
| 	if profile.url | ||||
| 		link(rel='alternate' href=profile.url type='text/html') | ||||
| 
 | ||||
| block content | ||||
| 	div#me | ||||
| 		each m in me | ||||
| 			a(rel='me' href=`${m}`) #{m} | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue