wip
This commit is contained in:
		
							parent
							
								
									e5992742d4
								
							
						
					
					
						commit
						d39c153c57
					
				
					 17 changed files with 770 additions and 468 deletions
				
			
		|  | @ -1054,6 +1054,8 @@ _profile: | ||||||
|   metadataDescription: "プロフィールに表として4つまでの追加情報を表示することができます。" |   metadataDescription: "プロフィールに表として4つまでの追加情報を表示することができます。" | ||||||
|   metadataLabel: "ラベル" |   metadataLabel: "ラベル" | ||||||
|   metadataContent: "内容" |   metadataContent: "内容" | ||||||
|  |   changeAvatar: "アバター画像を変更" | ||||||
|  |   changeBanner: "バナー画像を変更" | ||||||
| 
 | 
 | ||||||
| _exportOrImport: | _exportOrImport: | ||||||
|   allNotes: "全てのノート" |   allNotes: "全てのノート" | ||||||
|  |  | ||||||
|  | @ -1,9 +1,8 @@ | ||||||
| <template> | <template> | ||||||
| <button class="kpoogebi _button" | <button class="kpoogebi _button" | ||||||
| 	:class="{ wait, active: isFollowing || hasPendingFollowRequestFromYou, full }" | 	:class="{ wait, active: isFollowing || hasPendingFollowRequestFromYou, full, large }" | ||||||
| 	@click="onClick" | 	@click="onClick" | ||||||
| 	:disabled="wait" | 	:disabled="wait" | ||||||
| 	v-if="isFollowing != null" |  | ||||||
| > | > | ||||||
| 	<template v-if="!wait"> | 	<template v-if="!wait"> | ||||||
| 		<template v-if="hasPendingFollowRequestFromYou && user.isLocked"> | 		<template v-if="hasPendingFollowRequestFromYou && user.isLocked"> | ||||||
|  | @ -44,6 +43,11 @@ export default defineComponent({ | ||||||
| 			required: false, | 			required: false, | ||||||
| 			default: false, | 			default: false, | ||||||
| 		}, | 		}, | ||||||
|  | 		large: { | ||||||
|  | 			type: Boolean, | ||||||
|  | 			required: false, | ||||||
|  | 			default: false, | ||||||
|  | 		}, | ||||||
| 	}, | 	}, | ||||||
| 
 | 
 | ||||||
| 	data() { | 	data() { | ||||||
|  | @ -149,6 +153,12 @@ export default defineComponent({ | ||||||
| 		font-size: 14px; | 		font-size: 14px; | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
|  | 	&.large { | ||||||
|  | 		font-size: 16px; | ||||||
|  | 		height: 38px; | ||||||
|  | 		padding: 0 12px 0 16px; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
| 	&:not(.full) { | 	&:not(.full) { | ||||||
| 		width: 31px; | 		width: 31px; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|  | @ -7,7 +7,7 @@ | ||||||
| 			<div style="opacity: 0.5;">v{{ version }}</div> | 			<div style="opacity: 0.5;">v{{ version }}</div> | ||||||
| 		</div> | 		</div> | ||||||
| 	</section> | 	</section> | ||||||
| 	<section class="_formItem" style="text-align: center;"> | 	<section class="_formItem" style="text-align: center; padding: 0 16px;"> | ||||||
| 		{{ $t('_aboutMisskey.about') }} | 		{{ $t('_aboutMisskey.about') }} | ||||||
| 	</section> | 	</section> | ||||||
| 	<FormGroup> | 	<FormGroup> | ||||||
|  |  | ||||||
|  | @ -20,7 +20,7 @@ | ||||||
| 		</div> | 		</div> | ||||||
| 	</div> | 	</div> | ||||||
| 
 | 
 | ||||||
| 	<XPostForm :channel="channel" class="post-form _content _panel _vMargin" fixed v-if="this.$store.getters.isSignedIn"/> | 	<XPostForm :channel="channel" class="post-form _content _panel _vMargin" fixed v-if="$store.getters.isSignedIn"/> | ||||||
| 
 | 
 | ||||||
| 	<XTimeline class="_content _vMargin" src="channel" :channel="channelId" @before="before" @after="after"/> | 	<XTimeline class="_content _vMargin" src="channel" :channel="channelId" @before="before" @after="after"/> | ||||||
| </div> | </div> | ||||||
|  |  | ||||||
|  | @ -1,6 +1,6 @@ | ||||||
| <template> | <template> | ||||||
| <div> | <div> | ||||||
| 	<div class="_section" style="padding: 0;" v-if="this.$store.getters.isSignedIn"> | 	<div class="_section" style="padding: 0;" v-if="$store.getters.isSignedIn"> | ||||||
| 		<MkTab class="_content" v-model:value="tab"> | 		<MkTab class="_content" v-model:value="tab"> | ||||||
| 			<option value="featured"><Fa :icon="faFireAlt"/> {{ $t('_channel.featured') }}</option> | 			<option value="featured"><Fa :icon="faFireAlt"/> {{ $t('_channel.featured') }}</option> | ||||||
| 			<option value="following"><Fa :icon="faHeart"/> {{ $t('_channel.following') }}</option> | 			<option value="following"><Fa :icon="faHeart"/> {{ $t('_channel.following') }}</option> | ||||||
|  |  | ||||||
|  | @ -1,5 +1,5 @@ | ||||||
| <template> | <template> | ||||||
| <div> | <div class="lznhrdub"> | ||||||
| 	<div class="_section"> | 	<div class="_section"> | ||||||
| 		<MkInput v-model:value="query" :debounce="true" type="search"><template #icon><Fa :icon="faSearch"/></template><span>{{ $t('searchUser') }}</span></MkInput> | 		<MkInput v-model:value="query" :debounce="true" type="search"><template #icon><Fa :icon="faSearch"/></template><span>{{ $t('searchUser') }}</span></MkInput> | ||||||
| 
 | 
 | ||||||
|  | @ -186,6 +186,11 @@ export default defineComponent({ | ||||||
| </script> | </script> | ||||||
| 
 | 
 | ||||||
| <style lang="scss" scoped> | <style lang="scss" scoped> | ||||||
|  | .lznhrdub { | ||||||
|  | 	max-width: 1400px; | ||||||
|  | 	margin: 0 auto; | ||||||
|  | } | ||||||
|  | 
 | ||||||
| .localfedi7 { | .localfedi7 { | ||||||
| 	color: #fff; | 	color: #fff; | ||||||
| 	padding: 16px; | 	padding: 16px; | ||||||
|  |  | ||||||
|  | @ -1,6 +1,6 @@ | ||||||
| <template> | <template> | ||||||
| <div> | <div> | ||||||
| 	<MkTab v-model:value="tab" v-if="this.$store.getters.isSignedIn"> | 	<MkTab v-model:value="tab" v-if="$store.getters.isSignedIn"> | ||||||
| 		<option value="featured"><Fa :icon="faFireAlt"/> {{ $t('_pages.featured') }}</option> | 		<option value="featured"><Fa :icon="faFireAlt"/> {{ $t('_pages.featured') }}</option> | ||||||
| 		<option value="my"><Fa :icon="faEdit"/> {{ $t('_pages.my') }}</option> | 		<option value="my"><Fa :icon="faEdit"/> {{ $t('_pages.my') }}</option> | ||||||
| 		<option value="liked"><Fa :icon="faHeart"/> {{ $t('_pages.liked') }}</option> | 		<option value="liked"><Fa :icon="faHeart"/> {{ $t('_pages.liked') }}</option> | ||||||
|  |  | ||||||
|  | @ -1,8 +1,12 @@ | ||||||
| <template> | <template> | ||||||
| <FormBase class="llvierxe"> | <FormBase> | ||||||
| 	<div class="header _formItem" :style="{ backgroundImage: $store.state.i.bannerUrl ? `url(${ $store.state.i.bannerUrl })` : null }" @click="changeBanner"> | 	<FormGroup> | ||||||
| 		<MkAvatar class="avatar" :user="$store.state.i" :disable-preview="true" :disable-link="true" @click.stop="changeAvatar"/> | 		<div class="_formItem _formPanel llvierxe" :style="{ backgroundImage: $store.state.i.bannerUrl ? `url(${ $store.state.i.bannerUrl })` : null }"> | ||||||
| 	</div> | 			<MkAvatar class="avatar" :user="$store.state.i"/> | ||||||
|  | 		</div> | ||||||
|  | 		<FormButton @click="changeAvatar" primary>{{ $t('_profile.changeAvatar') }}</FormButton> | ||||||
|  | 		<FormButton @click="changeBanner" primary>{{ $t('_profile.changeBanner') }}</FormButton> | ||||||
|  | 	</FormGroup> | ||||||
| 
 | 
 | ||||||
| 	<FormInput v-model:value="name" :max="30"> | 	<FormInput v-model:value="name" :max="30"> | ||||||
| 		<span>{{ $t('_profile.name') }}</span> | 		<span>{{ $t('_profile.name') }}</span> | ||||||
|  | @ -245,30 +249,26 @@ export default defineComponent({ | ||||||
| 
 | 
 | ||||||
| <style lang="scss" scoped> | <style lang="scss" scoped> | ||||||
| .llvierxe { | .llvierxe { | ||||||
| 	> .header { | 	position: relative; | ||||||
| 		position: relative; | 	height: 150px; | ||||||
| 		height: 150px; | 	background-size: cover; | ||||||
| 		overflow: hidden; | 	background-position: center; | ||||||
| 		background-size: cover; |  | ||||||
| 		background-position: center; |  | ||||||
| 		border-radius: 5px; |  | ||||||
| 		border: solid 1px var(--divider); |  | ||||||
| 		box-sizing: border-box; |  | ||||||
| 		cursor: pointer; |  | ||||||
| 
 | 
 | ||||||
| 		> .avatar { | 	> * { | ||||||
| 			position: absolute; | 		pointer-events: none; | ||||||
| 			top: 0; | 	} | ||||||
| 			bottom: 0; | 
 | ||||||
| 			left: 0; | 	> .avatar { | ||||||
| 			right: 0; | 		position: absolute; | ||||||
| 			display: block; | 		top: 0; | ||||||
| 			width: 72px; | 		bottom: 0; | ||||||
| 			height: 72px; | 		left: 0; | ||||||
| 			margin: auto; | 		right: 0; | ||||||
| 			cursor: pointer; | 		display: block; | ||||||
| 			box-shadow: 0 0 0 6px rgba(0, 0, 0, 0.5); | 		width: 72px; | ||||||
| 		} | 		height: 72px; | ||||||
|  | 		margin: auto; | ||||||
|  | 		box-shadow: 0 0 0 6px rgba(0, 0, 0, 0.5); | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
| </style> | </style> | ||||||
|  |  | ||||||
|  | @ -1,22 +1,24 @@ | ||||||
| <template> | <template> | ||||||
| <div class="kjeftjfm" v-size="{ max: [500] }"> | <div> | ||||||
| 	<div class="with"> | 	<MkTab v-model:value="with_" class="_vMargin"> | ||||||
| 		<button class="_button" @click="with_ = null" :class="{ active: with_ === null }">{{ $t('notes') }}</button> | 		<option :value="null">{{ $t('notes') }}</option> | ||||||
| 		<button class="_button" @click="with_ = 'replies'" :class="{ active: with_ === 'replies' }">{{ $t('notesAndReplies') }}</button> | 		<option value="replies">{{ $t('notesAndReplies') }}</option> | ||||||
| 		<button class="_button" @click="with_ = 'files'" :class="{ active: with_ === 'files' }">{{ $t('withFiles') }}</button> | 		<option value="files">{{ $t('withFiles') }}</option> | ||||||
| 	</div> | 	</MkTab> | ||||||
| 	<XNotes ref="timeline" :pagination="pagination" @before="$emit('before')" @after="e => $emit('after', e)"/> | 	<XNotes ref="timeline" class="_vMargin" :pagination="pagination" @before="$emit('before')" @after="e => $emit('after', e)"/> | ||||||
| </div> | </div> | ||||||
| </template> | </template> | ||||||
| 
 | 
 | ||||||
| <script lang="ts"> | <script lang="ts"> | ||||||
| import { defineComponent } from 'vue'; | import { defineComponent } from 'vue'; | ||||||
| import XNotes from '@/components/notes.vue'; | import XNotes from '@/components/notes.vue'; | ||||||
|  | import MkTab from '@/components/tab.vue'; | ||||||
| import * as os from '@/os'; | import * as os from '@/os'; | ||||||
| 
 | 
 | ||||||
| export default defineComponent({ | export default defineComponent({ | ||||||
| 	components: { | 	components: { | ||||||
| 		XNotes | 		XNotes, | ||||||
|  | 		MkTab, | ||||||
| 	}, | 	}, | ||||||
| 
 | 
 | ||||||
| 	props: { | 	props: { | ||||||
|  | @ -54,29 +56,3 @@ export default defineComponent({ | ||||||
| 	}, | 	}, | ||||||
| }); | }); | ||||||
| </script> | </script> | ||||||
| 
 |  | ||||||
| <style lang="scss" scoped> |  | ||||||
| .kjeftjfm { |  | ||||||
| 	> .with { |  | ||||||
| 		display: flex; |  | ||||||
| 		margin-bottom: var(--margin); |  | ||||||
| 
 |  | ||||||
| 		> button { |  | ||||||
| 			flex: 1; |  | ||||||
| 			padding: 11px 8px 8px 8px; |  | ||||||
| 			border-bottom: solid 3px transparent; |  | ||||||
| 
 |  | ||||||
| 			&.active { |  | ||||||
| 				color: var(--accent); |  | ||||||
| 				border-bottom-color: var(--accent); |  | ||||||
| 			} |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	&.max-width_500px { |  | ||||||
| 		> .with { |  | ||||||
| 			font-size: 80%; |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
| } |  | ||||||
| </style> |  | ||||||
|  |  | ||||||
|  | @ -1,113 +1,191 @@ | ||||||
| <template> | <template> | ||||||
| <div> | <div class="ftskorzw wide _section" v-if="user && narrow === false"> | ||||||
| 	<div class="mk-user-page" v-if="user" v-size="{ max: [500] }" :class="{ _section: narrow === false }"> | 	<div class="banner-container" :style="style"> | ||||||
| 		<!-- TODO --> | 		<div class="banner" ref="banner" :style="style"></div> | ||||||
| 		<!-- <div class="punished" v-if="user.isSuspended"><Fa :icon="faExclamationTriangle" style="margin-right: 8px;"/> {{ $t('userSuspended') }}</div> --> | 	</div> | ||||||
| 		<!-- <div class="punished" v-if="user.isSilenced"><Fa :icon="faExclamationTriangle" style="margin-right: 8px;"/> {{ $t('userSilenced') }}</div> --> | 	<div class="contents"> | ||||||
| 
 | 		<div class="side _forceContainerFull_"> | ||||||
|  | 			<MkAvatar class="avatar" :user="user" :disable-preview="true"/> | ||||||
|  | 			<div class="name"> | ||||||
|  | 				<MkUserName :user="user" :nowrap="false" class="name"/> | ||||||
|  | 				<MkAcct :user="user" :detail="true" class="acct"/> | ||||||
|  | 			</div> | ||||||
|  | 			<div class="followed" v-if="$store.getters.isSignedIn && $store.state.i.id != user.id && user.isFollowed"><span>{{ $t('followsYou') }}</span></div> | ||||||
|  | 			<div class="status"> | ||||||
|  | 				<MkA :to="userPage(user)" :class="{ active: page === 'index' }"> | ||||||
|  | 					<b>{{ number(user.notesCount) }}</b> | ||||||
|  | 					<span>{{ $t('notes') }}</span> | ||||||
|  | 				</MkA> | ||||||
|  | 				<MkA :to="userPage(user, 'following')" :class="{ active: page === 'following' }"> | ||||||
|  | 					<b>{{ number(user.followingCount) }}</b> | ||||||
|  | 					<span>{{ $t('following') }}</span> | ||||||
|  | 				</MkA> | ||||||
|  | 				<MkA :to="userPage(user, 'followers')" :class="{ active: page === 'followers' }"> | ||||||
|  | 					<b>{{ number(user.followersCount) }}</b> | ||||||
|  | 					<span>{{ $t('followers') }}</span> | ||||||
|  | 				</MkA> | ||||||
|  | 			</div> | ||||||
|  | 			<div class="description"> | ||||||
|  | 				<Mfm v-if="user.description" :text="user.description" :is-note="false" :author="user" :i="$store.state.i" :custom-emojis="user.emojis"/> | ||||||
|  | 				<p v-else class="empty">{{ $t('noAccountDescription') }}</p> | ||||||
|  | 			</div> | ||||||
|  | 			<div class="fields system"> | ||||||
|  | 				<dl class="field" v-if="user.location"> | ||||||
|  | 					<dt class="name"><Fa :icon="faMapMarker" fixed-width/> {{ $t('location') }}</dt> | ||||||
|  | 					<dd class="value">{{ user.location }}</dd> | ||||||
|  | 				</dl> | ||||||
|  | 				<dl class="field" v-if="user.birthday"> | ||||||
|  | 					<dt class="name"><Fa :icon="faBirthdayCake" fixed-width/> {{ $t('birthday') }}</dt> | ||||||
|  | 					<dd class="value">{{ user.birthday.replace('-', '/').replace('-', '/') }} ({{ $t('yearsOld', { age }) }})</dd> | ||||||
|  | 				</dl> | ||||||
|  | 				<dl class="field"> | ||||||
|  | 					<dt class="name"><Fa :icon="faCalendarAlt" fixed-width/> {{ $t('registeredDate') }}</dt> | ||||||
|  | 					<dd class="value">{{ new Date(user.createdAt).toLocaleString() }} (<MkTime :time="user.createdAt"/>)</dd> | ||||||
|  | 				</dl> | ||||||
|  | 			</div> | ||||||
|  | 			<div class="fields" v-if="user.fields.length > 0"> | ||||||
|  | 				<dl class="field" v-for="(field, i) in user.fields" :key="i"> | ||||||
|  | 					<dt class="name"> | ||||||
|  | 						<Mfm :text="field.name" :plain="true" :custom-emojis="user.emojis" :colored="false"/> | ||||||
|  | 					</dt> | ||||||
|  | 					<dd class="value"> | ||||||
|  | 						<Mfm :text="field.value" :author="user" :i="$store.state.i" :custom-emojis="user.emojis" :colored="false"/> | ||||||
|  | 					</dd> | ||||||
|  | 				</dl> | ||||||
|  | 			</div> | ||||||
|  | 			<XActivity :user="user" :key="user.id" class="_vMargin"/> | ||||||
|  | 			<XPhotos :user="user" :key="user.id" class="_vMargin"/> | ||||||
|  | 		</div> | ||||||
| 		<div class="main"> | 		<div class="main"> | ||||||
| 			<div class="profile _vMargin" :class="{ _section: narrow === true }"> | 			<div class="nav _vMargin"> | ||||||
| 				<MkRemoteCaution v-if="user.host != null" :href="user.url" class="_content _vMargin"/> | 				<MkA :to="userPage(user)" :class="{ active: page === 'index' }" class="link"> | ||||||
| 
 | 					<span>{{ $t('notes') }}</span> | ||||||
| 				<div class="_content _panel _vMargin" :key="user.id"> | 				</MkA> | ||||||
| 					<div class="banner-container" :style="style"> | 				<MkA :to="userPage(user, 'clips')" :class="{ active: page === 'clips' }" class="link"> | ||||||
| 						<div class="banner" ref="banner" :style="style"></div> | 					<span>{{ $t('clips') }}</span> | ||||||
| 						<div class="fade"></div> | 				</MkA> | ||||||
| 						<div class="title"> | 				<MkA :to="userPage(user, 'pages')" :class="{ active: page === 'pages' }" class="link"> | ||||||
| 							<MkUserName class="name" :user="user" :nowrap="true"/> | 					<span>{{ $t('pages') }}</span> | ||||||
| 							<div class="bottom"> | 				</MkA> | ||||||
| 								<span class="username"><MkAcct :user="user" :detail="true" /></span> | 				<div class="actions"> | ||||||
| 								<span v-if="user.isAdmin" :title="$t('isAdmin')" style="color: var(--badge);"><Fa :icon="faBookmark"/></span> | 					<button @click="menu" class="menu _button"><Fa :icon="faEllipsisH"/></button> | ||||||
| 								<span v-if="!user.isAdmin && user.isModerator" :title="$t('isModerator')" style="color: var(--badge);"><Fa :icon="farBookmark"/></span> | 					<MkFollowButton v-if="!$store.getters.isSignedIn || $store.state.i.id != user.id" :user="user" :inline="true" :transparent="false" :full="true" large class="koudoku"/> | ||||||
| 								<span v-if="user.isLocked" :title="$t('isLocked')"><Fa :icon="faLock"/></span> |  | ||||||
| 								<span v-if="user.isBot" :title="$t('isBot')"><Fa :icon="faRobot"/></span> |  | ||||||
| 							</div> |  | ||||||
| 						</div> |  | ||||||
| 						<span class="followed" v-if="$store.getters.isSignedIn && $store.state.i.id != user.id && user.isFollowed">{{ $t('followsYou') }}</span> |  | ||||||
| 						<div class="actions" v-if="$store.getters.isSignedIn"> |  | ||||||
| 							<button @click="menu" class="menu _button"><Fa :icon="faEllipsisH"/></button> |  | ||||||
| 							<MkFollowButton v-if="$store.state.i.id != user.id" :user="user" :inline="true" :transparent="false" :full="true" class="koudoku"/> |  | ||||||
| 						</div> |  | ||||||
| 					</div> |  | ||||||
| 					<MkAvatar class="avatar" :user="user" :disable-preview="true"/> |  | ||||||
| 					<div class="title"> |  | ||||||
| 						<MkUserName :user="user" :nowrap="false" class="name"/> |  | ||||||
| 						<div class="bottom"> |  | ||||||
| 							<span class="username"><MkAcct :user="user" :detail="true" /></span> |  | ||||||
| 							<span v-if="user.isAdmin" :title="$t('isAdmin')" style="color: var(--badge);"><Fa :icon="faBookmark"/></span> |  | ||||||
| 							<span v-if="!user.isAdmin && user.isModerator" :title="$t('isModerator')" style="color: var(--badge);"><Fa :icon="farBookmark"/></span> |  | ||||||
| 							<span v-if="user.isLocked" :title="$t('isLocked')"><Fa :icon="faLock"/></span> |  | ||||||
| 							<span v-if="user.isBot" :title="$t('isBot')"><Fa :icon="faRobot"/></span> |  | ||||||
| 						</div> |  | ||||||
| 					</div> |  | ||||||
| 					<div class="description"> |  | ||||||
| 						<Mfm v-if="user.description" :text="user.description" :is-note="false" :author="user" :i="$store.state.i" :custom-emojis="user.emojis"/> |  | ||||||
| 						<p v-else class="empty">{{ $t('noAccountDescription') }}</p> |  | ||||||
| 					</div> |  | ||||||
| 					<div class="fields system"> |  | ||||||
| 						<dl class="field" v-if="user.location"> |  | ||||||
| 							<dt class="name"><Fa :icon="faMapMarker" fixed-width/> {{ $t('location') }}</dt> |  | ||||||
| 							<dd class="value">{{ user.location }}</dd> |  | ||||||
| 						</dl> |  | ||||||
| 						<dl class="field" v-if="user.birthday"> |  | ||||||
| 							<dt class="name"><Fa :icon="faBirthdayCake" fixed-width/> {{ $t('birthday') }}</dt> |  | ||||||
| 							<dd class="value">{{ user.birthday.replace('-', '/').replace('-', '/') }} ({{ $t('yearsOld', { age }) }})</dd> |  | ||||||
| 						</dl> |  | ||||||
| 						<dl class="field"> |  | ||||||
| 							<dt class="name"><Fa :icon="faCalendarAlt" fixed-width/> {{ $t('registeredDate') }}</dt> |  | ||||||
| 							<dd class="value">{{ new Date(user.createdAt).toLocaleString() }} (<MkTime :time="user.createdAt"/>)</dd> |  | ||||||
| 						</dl> |  | ||||||
| 					</div> |  | ||||||
| 					<div class="fields" v-if="user.fields.length > 0"> |  | ||||||
| 						<dl class="field" v-for="(field, i) in user.fields" :key="i"> |  | ||||||
| 							<dt class="name"> |  | ||||||
| 								<Mfm :text="field.name" :plain="true" :custom-emojis="user.emojis" :colored="false"/> |  | ||||||
| 							</dt> |  | ||||||
| 							<dd class="value"> |  | ||||||
| 								<Mfm :text="field.value" :author="user" :i="$store.state.i" :custom-emojis="user.emojis" :colored="false"/> |  | ||||||
| 							</dd> |  | ||||||
| 						</dl> |  | ||||||
| 					</div> |  | ||||||
| 					<div class="status"> |  | ||||||
| 						<MkA :to="userPage(user)" :class="{ active: page === 'index' }"> |  | ||||||
| 							<b>{{ number(user.notesCount) }}</b> |  | ||||||
| 							<span>{{ $t('notes') }}</span> |  | ||||||
| 						</MkA> |  | ||||||
| 						<MkA :to="userPage(user, 'following')" :class="{ active: page === 'following' }"> |  | ||||||
| 							<b>{{ number(user.followingCount) }}</b> |  | ||||||
| 							<span>{{ $t('following') }}</span> |  | ||||||
| 						</MkA> |  | ||||||
| 						<MkA :to="userPage(user, 'followers')" :class="{ active: page === 'followers' }"> |  | ||||||
| 							<b>{{ number(user.followersCount) }}</b> |  | ||||||
| 							<span>{{ $t('followers') }}</span> |  | ||||||
| 						</MkA> |  | ||||||
| 					</div> |  | ||||||
| 				</div> | 				</div> | ||||||
| 			</div> | 			</div> | ||||||
| 
 |  | ||||||
| 			<template v-if="page === 'index'"> | 			<template v-if="page === 'index'"> | ||||||
| 				<div v-if="user.pinnedNotes.length > 0" :class="{ _section: narrow === true, _vMargin: narrow === false }"> | 				<div v-if="user.pinnedNotes.length > 0" class="_vMargin"> | ||||||
| 					<XNote v-for="note in user.pinnedNotes" class="note _content _vMargin" :note="note" @update:note="pinnedNoteUpdated(note, $event)" :key="note.id" :detail="true" :pinned="true"/> | 					<XNote v-for="note in user.pinnedNotes" class="note _vMargin" :note="note" @update:note="pinnedNoteUpdated(note, $event)" :key="note.id" :detail="true" :pinned="true"/> | ||||||
| 				</div> | 				</div> | ||||||
| 				<div v-if="narrow === true" class="_section"> | 				<div class="_vMargin"> | ||||||
| 					<XPhotos class="_content _vMargin" :user="user" :key="user.id"/> | 					<XUserTimeline :user="user"/> | ||||||
| 					<XActivity class="_content _vMargin" :user="user" :key="user.id"/> |  | ||||||
| 				</div> |  | ||||||
| 				<div :class="{ _section: narrow === true, _vMargin: narrow === false }"> |  | ||||||
| 					<XUserTimeline :user="user" class="_content"/> |  | ||||||
| 				</div> | 				</div> | ||||||
| 			</template> | 			</template> | ||||||
| 			<XFollowList v-else-if="page === 'following'" :class="{ _section: narrow === true, _vMargin: narrow === false }" type="following" :user="user"/> | 			<XFollowList v-else-if="page === 'following'" type="following" :user="user" class="_vMargin"/> | ||||||
| 			<XFollowList v-else-if="page === 'followers'" :class="{ _section: narrow === true, _vMargin: narrow === false }" type="followers" :user="user"/> | 			<XFollowList v-else-if="page === 'followers'" type="followers" :user="user" class="_vMargin"/> | ||||||
| 		</div> |  | ||||||
| 		<div class="side" v-if="narrow === false"> |  | ||||||
| 			<XPhotos class="_vMargin" :user="user" :key="user.id"/> |  | ||||||
| 			<XActivity class="_vMargin" :user="user" :key="user.id"/> |  | ||||||
| 		</div> | 		</div> | ||||||
| 	</div> | 	</div> | ||||||
| 	<div v-else-if="error"> | </div> | ||||||
| 		<MkError @retry="fetch()"/> | <div class="ftskorzw narrow _section" v-else-if="user && narrow === true" v-size="{ max: [500] }"> | ||||||
|  | 	<!-- TODO --> | ||||||
|  | 	<!-- <div class="punished" v-if="user.isSuspended"><Fa :icon="faExclamationTriangle" style="margin-right: 8px;"/> {{ $t('userSuspended') }}</div> --> | ||||||
|  | 	<!-- <div class="punished" v-if="user.isSilenced"><Fa :icon="faExclamationTriangle" style="margin-right: 8px;"/> {{ $t('userSilenced') }}</div> --> | ||||||
|  | 
 | ||||||
|  | 	<div class="profile _content _vMargin"> | ||||||
|  | 		<MkRemoteCaution v-if="user.host != null" :href="user.url" class="_vMargin"/> | ||||||
|  | 
 | ||||||
|  | 		<div class="_vMargin _panel main" :key="user.id"> | ||||||
|  | 			<div class="banner-container" :style="style"> | ||||||
|  | 				<div class="banner" ref="banner" :style="style"></div> | ||||||
|  | 				<div class="fade"></div> | ||||||
|  | 				<div class="title"> | ||||||
|  | 					<MkUserName class="name" :user="user" :nowrap="true"/> | ||||||
|  | 					<div class="bottom"> | ||||||
|  | 						<span class="username"><MkAcct :user="user" :detail="true" /></span> | ||||||
|  | 						<span v-if="user.isAdmin" :title="$t('isAdmin')" style="color: var(--badge);"><Fa :icon="faBookmark"/></span> | ||||||
|  | 						<span v-if="!user.isAdmin && user.isModerator" :title="$t('isModerator')" style="color: var(--badge);"><Fa :icon="farBookmark"/></span> | ||||||
|  | 						<span v-if="user.isLocked" :title="$t('isLocked')"><Fa :icon="faLock"/></span> | ||||||
|  | 						<span v-if="user.isBot" :title="$t('isBot')"><Fa :icon="faRobot"/></span> | ||||||
|  | 					</div> | ||||||
|  | 				</div> | ||||||
|  | 				<span class="followed" v-if="$store.getters.isSignedIn && $store.state.i.id != user.id && user.isFollowed">{{ $t('followsYou') }}</span> | ||||||
|  | 				<div class="actions" v-if="$store.getters.isSignedIn"> | ||||||
|  | 					<button @click="menu" class="menu _button"><Fa :icon="faEllipsisH"/></button> | ||||||
|  | 					<MkFollowButton v-if="$store.state.i.id != user.id" :user="user" :inline="true" :transparent="false" :full="true" class="koudoku"/> | ||||||
|  | 				</div> | ||||||
|  | 			</div> | ||||||
|  | 			<MkAvatar class="avatar" :user="user" :disable-preview="true"/> | ||||||
|  | 			<div class="title"> | ||||||
|  | 				<MkUserName :user="user" :nowrap="false" class="name"/> | ||||||
|  | 				<div class="bottom"> | ||||||
|  | 					<span class="username"><MkAcct :user="user" :detail="true" /></span> | ||||||
|  | 					<span v-if="user.isAdmin" :title="$t('isAdmin')" style="color: var(--badge);"><Fa :icon="faBookmark"/></span> | ||||||
|  | 					<span v-if="!user.isAdmin && user.isModerator" :title="$t('isModerator')" style="color: var(--badge);"><Fa :icon="farBookmark"/></span> | ||||||
|  | 					<span v-if="user.isLocked" :title="$t('isLocked')"><Fa :icon="faLock"/></span> | ||||||
|  | 					<span v-if="user.isBot" :title="$t('isBot')"><Fa :icon="faRobot"/></span> | ||||||
|  | 				</div> | ||||||
|  | 			</div> | ||||||
|  | 			<div class="description"> | ||||||
|  | 				<Mfm v-if="user.description" :text="user.description" :is-note="false" :author="user" :i="$store.state.i" :custom-emojis="user.emojis"/> | ||||||
|  | 				<p v-else class="empty">{{ $t('noAccountDescription') }}</p> | ||||||
|  | 			</div> | ||||||
|  | 			<div class="fields system"> | ||||||
|  | 				<dl class="field" v-if="user.location"> | ||||||
|  | 					<dt class="name"><Fa :icon="faMapMarker" fixed-width/> {{ $t('location') }}</dt> | ||||||
|  | 					<dd class="value">{{ user.location }}</dd> | ||||||
|  | 				</dl> | ||||||
|  | 				<dl class="field" v-if="user.birthday"> | ||||||
|  | 					<dt class="name"><Fa :icon="faBirthdayCake" fixed-width/> {{ $t('birthday') }}</dt> | ||||||
|  | 					<dd class="value">{{ user.birthday.replace('-', '/').replace('-', '/') }} ({{ $t('yearsOld', { age }) }})</dd> | ||||||
|  | 				</dl> | ||||||
|  | 				<dl class="field"> | ||||||
|  | 					<dt class="name"><Fa :icon="faCalendarAlt" fixed-width/> {{ $t('registeredDate') }}</dt> | ||||||
|  | 					<dd class="value">{{ new Date(user.createdAt).toLocaleString() }} (<MkTime :time="user.createdAt"/>)</dd> | ||||||
|  | 				</dl> | ||||||
|  | 			</div> | ||||||
|  | 			<div class="fields" v-if="user.fields.length > 0"> | ||||||
|  | 				<dl class="field" v-for="(field, i) in user.fields" :key="i"> | ||||||
|  | 					<dt class="name"> | ||||||
|  | 						<Mfm :text="field.name" :plain="true" :custom-emojis="user.emojis" :colored="false"/> | ||||||
|  | 					</dt> | ||||||
|  | 					<dd class="value"> | ||||||
|  | 						<Mfm :text="field.value" :author="user" :i="$store.state.i" :custom-emojis="user.emojis" :colored="false"/> | ||||||
|  | 					</dd> | ||||||
|  | 				</dl> | ||||||
|  | 			</div> | ||||||
|  | 			<div class="status"> | ||||||
|  | 				<MkA :to="userPage(user)" :class="{ active: page === 'index' }"> | ||||||
|  | 					<b>{{ number(user.notesCount) }}</b> | ||||||
|  | 					<span>{{ $t('notes') }}</span> | ||||||
|  | 				</MkA> | ||||||
|  | 				<MkA :to="userPage(user, 'following')" :class="{ active: page === 'following' }"> | ||||||
|  | 					<b>{{ number(user.followingCount) }}</b> | ||||||
|  | 					<span>{{ $t('following') }}</span> | ||||||
|  | 				</MkA> | ||||||
|  | 				<MkA :to="userPage(user, 'followers')" :class="{ active: page === 'followers' }"> | ||||||
|  | 					<b>{{ number(user.followersCount) }}</b> | ||||||
|  | 					<span>{{ $t('followers') }}</span> | ||||||
|  | 				</MkA> | ||||||
|  | 			</div> | ||||||
|  | 		</div> | ||||||
| 	</div> | 	</div> | ||||||
|  | 
 | ||||||
|  | 	<template v-if="page === 'index'"> | ||||||
|  | 		<div class="_content _vMargin"> | ||||||
|  | 			<div v-if="user.pinnedNotes.length > 0"> | ||||||
|  | 				<XNote v-for="note in user.pinnedNotes" class="note _vMargin" :note="note" @update:note="pinnedNoteUpdated(note, $event)" :key="note.id" :detail="true" :pinned="true"/> | ||||||
|  | 			</div> | ||||||
|  | 			<XPhotos :user="user" :key="user.id"/> | ||||||
|  | 			<XActivity :user="user" :key="user.id"/> | ||||||
|  | 		</div> | ||||||
|  | 		<div class="_content _vMargin"> | ||||||
|  | 			<XUserTimeline :user="user" class="_content"/> | ||||||
|  | 		</div> | ||||||
|  | 	</template> | ||||||
|  | 	<XFollowList v-else-if="page === 'following'" type="following" :user="user" class="_content _vMargin"/> | ||||||
|  | 	<XFollowList v-else-if="page === 'followers'" type="followers" :user="user" class="_content _vMargin"/> | ||||||
|  | </div> | ||||||
|  | <div v-else-if="error"> | ||||||
|  | 	<MkError @retry="fetch()"/> | ||||||
| </div> | </div> | ||||||
| </template> | </template> | ||||||
| 
 | 
 | ||||||
|  | @ -122,6 +200,7 @@ import MkFollowButton from '@/components/follow-button.vue'; | ||||||
| import MkContainer from '@/components/ui/container.vue'; | import MkContainer from '@/components/ui/container.vue'; | ||||||
| import MkFolder from '@/components/ui/folder.vue'; | import MkFolder from '@/components/ui/folder.vue'; | ||||||
| import MkRemoteCaution from '@/components/remote-caution.vue'; | import MkRemoteCaution from '@/components/remote-caution.vue'; | ||||||
|  | import MkTab from '@/components/tab.vue'; | ||||||
| import Progress from '@/scripts/loading'; | import Progress from '@/scripts/loading'; | ||||||
| import parseAcct from '../../../misc/acct/parse'; | import parseAcct from '../../../misc/acct/parse'; | ||||||
| import { getScrollPosition } from '@/scripts/scroll'; | import { getScrollPosition } from '@/scripts/scroll'; | ||||||
|  | @ -138,6 +217,7 @@ export default defineComponent({ | ||||||
| 		MkContainer, | 		MkContainer, | ||||||
| 		MkRemoteCaution, | 		MkRemoteCaution, | ||||||
| 		MkFolder, | 		MkFolder, | ||||||
|  | 		MkTab, | ||||||
| 		XFollowList: defineAsyncComponent(() => import('./follow-list.vue')), | 		XFollowList: defineAsyncComponent(() => import('./follow-list.vue')), | ||||||
| 		XPhotos: defineAsyncComponent(() => import('./index.photos.vue')), | 		XPhotos: defineAsyncComponent(() => import('./index.photos.vue')), | ||||||
| 		XActivity: defineAsyncComponent(() => import('./index.activity.vue')), | 		XActivity: defineAsyncComponent(() => import('./index.activity.vue')), | ||||||
|  | @ -253,235 +333,392 @@ export default defineComponent({ | ||||||
| </script> | </script> | ||||||
| 
 | 
 | ||||||
| <style lang="scss" scoped> | <style lang="scss" scoped> | ||||||
| .mk-user-page { | .ftskorzw.wide { | ||||||
| 	display: flex; | 	max-width: 1150px; | ||||||
| 	max-width: 1050px; |  | ||||||
| 	margin: 0 auto; | 	margin: 0 auto; | ||||||
| 	 |  | ||||||
| 	> .main { |  | ||||||
| 		flex: 1; |  | ||||||
| 
 | 
 | ||||||
| 		> .punished { | 	> .banner-container { | ||||||
| 			font-size: 0.8em; | 		position: relative; | ||||||
| 			padding: 16px; | 		height: 450px; | ||||||
|  | 		border-radius: 16px; | ||||||
|  | 		overflow: hidden; | ||||||
|  | 		background-size: cover; | ||||||
|  | 		background-position: center; | ||||||
|  | 
 | ||||||
|  | 		> .banner { | ||||||
|  | 			height: 100%; | ||||||
|  | 			background-color: #4c5e6d; | ||||||
|  | 			background-size: cover; | ||||||
|  | 			background-position: center; | ||||||
|  | 			box-shadow: 0 0 128px rgba(0, 0, 0, 0.5) inset; | ||||||
|  | 			will-change: background-position; | ||||||
| 		} | 		} | ||||||
|  | 	} | ||||||
| 
 | 
 | ||||||
| 		> .profile { | 	> .contents { | ||||||
| 			> ._content { | 		display: flex; | ||||||
| 				position: relative; |  | ||||||
| 				overflow: hidden; |  | ||||||
| 
 | 
 | ||||||
| 				> .banner-container { | 		> .side { | ||||||
| 					position: relative; | 			width: 360px; | ||||||
| 					height: 250px; |  | ||||||
| 					overflow: hidden; |  | ||||||
| 					background-size: cover; |  | ||||||
| 					background-position: center; |  | ||||||
| 
 | 
 | ||||||
| 					> .banner { | 			> .avatar { | ||||||
| 						height: 100%; | 				display: block; | ||||||
| 						background-color: #4c5e6d; | 				width: 190px; | ||||||
| 						background-size: cover; | 				height: 190px; | ||||||
| 						background-position: center; | 				margin: -140px auto 0 auto; | ||||||
| 						box-shadow: 0 0 128px rgba(0, 0, 0, 0.5) inset; | 			} | ||||||
| 						will-change: background-position; |  | ||||||
| 					} |  | ||||||
| 
 | 
 | ||||||
| 					> .fade { | 			> .name { | ||||||
| 						position: absolute; | 				padding: 16px 0px 20px 0; | ||||||
| 						bottom: 0; | 				text-align: center; | ||||||
| 						left: 0; |  | ||||||
| 						width: 100%; |  | ||||||
| 						height: 78px; |  | ||||||
| 						background: linear-gradient(transparent, rgba(#000, 0.7)); |  | ||||||
| 					} |  | ||||||
| 
 | 
 | ||||||
| 					> .followed { | 				> .name { | ||||||
| 						position: absolute; |  | ||||||
| 						top: 12px; |  | ||||||
| 						left: 12px; |  | ||||||
| 						padding: 4px 8px; |  | ||||||
| 						color: #fff; |  | ||||||
| 						background: rgba(0, 0, 0, 0.7); |  | ||||||
| 						font-size: 0.7em; |  | ||||||
| 						border-radius: 6px; |  | ||||||
| 					} |  | ||||||
| 
 |  | ||||||
| 					> .actions { |  | ||||||
| 						position: absolute; |  | ||||||
| 						top: 12px; |  | ||||||
| 						right: 12px; |  | ||||||
| 						-webkit-backdrop-filter: blur(8px); |  | ||||||
| 						backdrop-filter: blur(8px); |  | ||||||
| 						background: rgba(0, 0, 0, 0.2); |  | ||||||
| 						padding: 8px; |  | ||||||
| 						border-radius: 24px; |  | ||||||
| 
 |  | ||||||
| 						> .menu { |  | ||||||
| 							vertical-align: bottom; |  | ||||||
| 							height: 31px; |  | ||||||
| 							width: 31px; |  | ||||||
| 							color: #fff; |  | ||||||
| 							text-shadow: 0 0 8px #000; |  | ||||||
| 							font-size: 16px; |  | ||||||
| 						} |  | ||||||
| 
 |  | ||||||
| 						> .koudoku { |  | ||||||
| 							margin-left: 4px; |  | ||||||
| 							vertical-align: bottom; |  | ||||||
| 						} |  | ||||||
| 					} |  | ||||||
| 
 |  | ||||||
| 					> .title { |  | ||||||
| 						position: absolute; |  | ||||||
| 						bottom: 0; |  | ||||||
| 						left: 0; |  | ||||||
| 						width: 100%; |  | ||||||
| 						padding: 0 0 8px 154px; |  | ||||||
| 						box-sizing: border-box; |  | ||||||
| 						color: #fff; |  | ||||||
| 
 |  | ||||||
| 						> .name { |  | ||||||
| 							display: block; |  | ||||||
| 							margin: 0; |  | ||||||
| 							line-height: 32px; |  | ||||||
| 							font-weight: bold; |  | ||||||
| 							font-size: 1.8em; |  | ||||||
| 							text-shadow: 0 0 8px #000; |  | ||||||
| 						} |  | ||||||
| 
 |  | ||||||
| 						> .bottom { |  | ||||||
| 							> * { |  | ||||||
| 								display: inline-block; |  | ||||||
| 								margin-right: 16px; |  | ||||||
| 								line-height: 20px; |  | ||||||
| 								opacity: 0.8; |  | ||||||
| 
 |  | ||||||
| 								&.username { |  | ||||||
| 									font-weight: bold; |  | ||||||
| 								} |  | ||||||
| 							} |  | ||||||
| 						} |  | ||||||
| 					} |  | ||||||
| 				} |  | ||||||
| 
 |  | ||||||
| 				> .title { |  | ||||||
| 					display: none; |  | ||||||
| 					text-align: center; |  | ||||||
| 					padding: 50px 8px 16px 8px; |  | ||||||
| 					font-weight: bold; |  | ||||||
| 					border-bottom: solid 1px var(--divider); |  | ||||||
| 
 |  | ||||||
| 					> .bottom { |  | ||||||
| 						> * { |  | ||||||
| 							display: inline-block; |  | ||||||
| 							margin-right: 8px; |  | ||||||
| 							opacity: 0.8; |  | ||||||
| 						} |  | ||||||
| 					} |  | ||||||
| 				} |  | ||||||
| 
 |  | ||||||
| 				> .avatar { |  | ||||||
| 					display: block; | 					display: block; | ||||||
| 					position: absolute; | 					font-size: 2em; | ||||||
| 					top: 170px; | 					font-weight: bold; | ||||||
| 					left: 16px; |  | ||||||
| 					z-index: 2; |  | ||||||
| 					width: 120px; |  | ||||||
| 					height: 120px; |  | ||||||
| 					box-shadow: 1px 1px 3px rgba(#000, 0.2); |  | ||||||
| 				} | 				} | ||||||
|  | 			} | ||||||
| 
 | 
 | ||||||
| 				> .description { | 			> .followed { | ||||||
| 					padding: 24px 24px 24px 154px; | 				text-align: center; | ||||||
| 					font-size: 0.95em; |  | ||||||
| 
 | 
 | ||||||
| 					> .empty { | 				> span { | ||||||
| 						margin: 0; | 					display: inline-block; | ||||||
| 						opacity: 0.5; | 					font-size: 80%; | ||||||
| 					} | 					padding: 8px 12px; | ||||||
|  | 					margin-bottom: 20px; | ||||||
|  | 					border: solid 1px var(--divider); | ||||||
|  | 					border-radius: 999px; | ||||||
| 				} | 				} | ||||||
|  | 			} | ||||||
| 
 | 
 | ||||||
| 				> .fields { | 			> .status { | ||||||
| 					padding: 24px; | 				display: flex; | ||||||
| 					font-size: 0.9em; | 				padding: 20px 16px; | ||||||
| 					border-top: solid 1px var(--divider); | 				border-top: solid 1px var(--divider); | ||||||
|  | 				font-size: 90%; | ||||||
| 
 | 
 | ||||||
| 					> .field { | 				> a { | ||||||
| 						display: flex; | 					flex: 1; | ||||||
| 						padding: 0; | 					text-align: center; | ||||||
| 						margin: 0; |  | ||||||
| 						align-items: center; |  | ||||||
| 
 | 
 | ||||||
| 						&:not(:last-child) { | 					&.active { | ||||||
| 							margin-bottom: 8px; | 						color: var(--accent); | ||||||
| 						} |  | ||||||
| 
 |  | ||||||
| 						> .name { |  | ||||||
| 							width: 30%; |  | ||||||
| 							overflow: hidden; |  | ||||||
| 							white-space: nowrap; |  | ||||||
| 							text-overflow: ellipsis; |  | ||||||
| 							font-weight: bold; |  | ||||||
| 							text-align: center; |  | ||||||
| 						} |  | ||||||
| 
 |  | ||||||
| 						> .value { |  | ||||||
| 							width: 70%; |  | ||||||
| 							overflow: hidden; |  | ||||||
| 							white-space: nowrap; |  | ||||||
| 							text-overflow: ellipsis; |  | ||||||
| 						} |  | ||||||
| 					} | 					} | ||||||
| 
 | 
 | ||||||
| 					&.system > .field > .name { | 					&:hover { | ||||||
|  | 						text-decoration: none; | ||||||
|  | 					} | ||||||
|  | 
 | ||||||
|  | 					> b { | ||||||
|  | 						display: block; | ||||||
|  | 						line-height: 16px; | ||||||
|  | 					} | ||||||
|  | 
 | ||||||
|  | 					> span { | ||||||
|  | 						font-size: 75%; | ||||||
| 					} | 					} | ||||||
| 				} | 				} | ||||||
|  | 			} | ||||||
| 
 | 
 | ||||||
| 				> .status { | 			> .description { | ||||||
|  | 				padding: 20px 16px; | ||||||
|  | 				border-top: solid 1px var(--divider); | ||||||
|  | 				font-size: 90%; | ||||||
|  | 			} | ||||||
|  | 
 | ||||||
|  | 			> .fields { | ||||||
|  | 				padding: 20px 16px; | ||||||
|  | 				border-top: solid 1px var(--divider); | ||||||
|  | 				font-size: 90%; | ||||||
|  | 
 | ||||||
|  | 				> .field { | ||||||
| 					display: flex; | 					display: flex; | ||||||
| 					padding: 24px; | 					padding: 0; | ||||||
| 					border-top: solid 1px var(--divider); | 					margin: 0; | ||||||
|  | 					align-items: center; | ||||||
| 
 | 
 | ||||||
| 					> a { | 					&:not(:last-child) { | ||||||
| 						flex: 1; | 						margin-bottom: 8px; | ||||||
| 						text-align: center; | 					} | ||||||
| 
 | 
 | ||||||
| 						&.active { | 					> .name { | ||||||
| 							color: var(--accent); | 						width: 30%; | ||||||
| 						} | 						overflow: hidden; | ||||||
|  | 						white-space: nowrap; | ||||||
|  | 						text-overflow: ellipsis; | ||||||
|  | 						font-weight: bold; | ||||||
|  | 					} | ||||||
| 
 | 
 | ||||||
| 						&:hover { | 					> .value { | ||||||
| 							text-decoration: none; | 						width: 70%; | ||||||
| 						} | 						overflow: hidden; | ||||||
| 
 | 						white-space: nowrap; | ||||||
| 						> b { | 						text-overflow: ellipsis; | ||||||
| 							display: block; | 						margin: 0; | ||||||
| 							line-height: 16px; |  | ||||||
| 						} |  | ||||||
| 
 |  | ||||||
| 						> span { |  | ||||||
| 							font-size: 70%; |  | ||||||
| 						} |  | ||||||
| 					} | 					} | ||||||
| 				} | 				} | ||||||
| 			} | 			} | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		> .content { | 		> .main { | ||||||
| 			margin-bottom: var(--margin); | 			flex: 1; | ||||||
|  | 			margin-left: var(--margin); | ||||||
|  | 
 | ||||||
|  | 			> .nav { | ||||||
|  | 				display: flex; | ||||||
|  | 				align-items: center; | ||||||
|  | 				margin-top: var(--margin); | ||||||
|  | 				font-size: 120%; | ||||||
|  | 
 | ||||||
|  | 				> .link { | ||||||
|  | 					display: inline-block; | ||||||
|  | 					padding: 15px 24px 12px 24px; | ||||||
|  | 					text-align: center; | ||||||
|  | 					border-bottom: solid 3px transparent; | ||||||
|  | 
 | ||||||
|  | 					&.active { | ||||||
|  | 						color: var(--accent); | ||||||
|  | 						border-bottom-color: var(--accent); | ||||||
|  | 					} | ||||||
|  | 
 | ||||||
|  | 					&:not(.active):hover { | ||||||
|  | 						color: var(--fgHighlighted); | ||||||
|  | 					} | ||||||
|  | 
 | ||||||
|  | 					> .icon { | ||||||
|  | 						margin-right: 6px; | ||||||
|  | 					} | ||||||
|  | 				} | ||||||
|  | 
 | ||||||
|  | 				> .actions { | ||||||
|  | 					display: flex; | ||||||
|  | 					align-items: center; | ||||||
|  | 					margin-left: auto; | ||||||
|  | 
 | ||||||
|  | 					> .menu { | ||||||
|  | 						padding: 12px 16px; | ||||||
|  | 					} | ||||||
|  | 				} | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | .ftskorzw.narrow { | ||||||
|  | 	> .punished { | ||||||
|  | 		font-size: 0.8em; | ||||||
|  | 		padding: 16px; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	> .profile { | ||||||
|  | 		> .main { | ||||||
|  | 			position: relative; | ||||||
|  | 			overflow: hidden; | ||||||
|  | 
 | ||||||
|  | 			> .banner-container { | ||||||
|  | 				position: relative; | ||||||
|  | 				height: 250px; | ||||||
|  | 				overflow: hidden; | ||||||
|  | 				background-size: cover; | ||||||
|  | 				background-position: center; | ||||||
|  | 
 | ||||||
|  | 				> .banner { | ||||||
|  | 					height: 100%; | ||||||
|  | 					background-color: #4c5e6d; | ||||||
|  | 					background-size: cover; | ||||||
|  | 					background-position: center; | ||||||
|  | 					box-shadow: 0 0 128px rgba(0, 0, 0, 0.5) inset; | ||||||
|  | 					will-change: background-position; | ||||||
|  | 				} | ||||||
|  | 
 | ||||||
|  | 				> .fade { | ||||||
|  | 					position: absolute; | ||||||
|  | 					bottom: 0; | ||||||
|  | 					left: 0; | ||||||
|  | 					width: 100%; | ||||||
|  | 					height: 78px; | ||||||
|  | 					background: linear-gradient(transparent, rgba(#000, 0.7)); | ||||||
|  | 				} | ||||||
|  | 
 | ||||||
|  | 				> .followed { | ||||||
|  | 					position: absolute; | ||||||
|  | 					top: 12px; | ||||||
|  | 					left: 12px; | ||||||
|  | 					padding: 4px 8px; | ||||||
|  | 					color: #fff; | ||||||
|  | 					background: rgba(0, 0, 0, 0.7); | ||||||
|  | 					font-size: 0.7em; | ||||||
|  | 					border-radius: 6px; | ||||||
|  | 				} | ||||||
|  | 
 | ||||||
|  | 				> .actions { | ||||||
|  | 					position: absolute; | ||||||
|  | 					top: 12px; | ||||||
|  | 					right: 12px; | ||||||
|  | 					-webkit-backdrop-filter: blur(8px); | ||||||
|  | 					backdrop-filter: blur(8px); | ||||||
|  | 					background: rgba(0, 0, 0, 0.2); | ||||||
|  | 					padding: 8px; | ||||||
|  | 					border-radius: 24px; | ||||||
|  | 
 | ||||||
|  | 					> .menu { | ||||||
|  | 						vertical-align: bottom; | ||||||
|  | 						height: 31px; | ||||||
|  | 						width: 31px; | ||||||
|  | 						color: #fff; | ||||||
|  | 						text-shadow: 0 0 8px #000; | ||||||
|  | 						font-size: 16px; | ||||||
|  | 					} | ||||||
|  | 
 | ||||||
|  | 					> .koudoku { | ||||||
|  | 						margin-left: 4px; | ||||||
|  | 						vertical-align: bottom; | ||||||
|  | 					} | ||||||
|  | 				} | ||||||
|  | 
 | ||||||
|  | 				> .title { | ||||||
|  | 					position: absolute; | ||||||
|  | 					bottom: 0; | ||||||
|  | 					left: 0; | ||||||
|  | 					width: 100%; | ||||||
|  | 					padding: 0 0 8px 154px; | ||||||
|  | 					box-sizing: border-box; | ||||||
|  | 					color: #fff; | ||||||
|  | 
 | ||||||
|  | 					> .name { | ||||||
|  | 						display: block; | ||||||
|  | 						margin: 0; | ||||||
|  | 						line-height: 32px; | ||||||
|  | 						font-weight: bold; | ||||||
|  | 						font-size: 1.8em; | ||||||
|  | 						text-shadow: 0 0 8px #000; | ||||||
|  | 					} | ||||||
|  | 
 | ||||||
|  | 					> .bottom { | ||||||
|  | 						> * { | ||||||
|  | 							display: inline-block; | ||||||
|  | 							margin-right: 16px; | ||||||
|  | 							line-height: 20px; | ||||||
|  | 							opacity: 0.8; | ||||||
|  | 
 | ||||||
|  | 							&.username { | ||||||
|  | 								font-weight: bold; | ||||||
|  | 							} | ||||||
|  | 						} | ||||||
|  | 					} | ||||||
|  | 				} | ||||||
|  | 			} | ||||||
|  | 
 | ||||||
|  | 			> .title { | ||||||
|  | 				display: none; | ||||||
|  | 				text-align: center; | ||||||
|  | 				padding: 50px 8px 16px 8px; | ||||||
|  | 				font-weight: bold; | ||||||
|  | 				border-bottom: solid 1px var(--divider); | ||||||
|  | 
 | ||||||
|  | 				> .bottom { | ||||||
|  | 					> * { | ||||||
|  | 						display: inline-block; | ||||||
|  | 						margin-right: 8px; | ||||||
|  | 						opacity: 0.8; | ||||||
|  | 					} | ||||||
|  | 				} | ||||||
|  | 			} | ||||||
|  | 
 | ||||||
|  | 			> .avatar { | ||||||
|  | 				display: block; | ||||||
|  | 				position: absolute; | ||||||
|  | 				top: 170px; | ||||||
|  | 				left: 16px; | ||||||
|  | 				z-index: 2; | ||||||
|  | 				width: 120px; | ||||||
|  | 				height: 120px; | ||||||
|  | 				box-shadow: 1px 1px 3px rgba(#000, 0.2); | ||||||
|  | 			} | ||||||
|  | 
 | ||||||
|  | 			> .description { | ||||||
|  | 				padding: 24px 24px 24px 154px; | ||||||
|  | 				font-size: 0.95em; | ||||||
|  | 
 | ||||||
|  | 				> .empty { | ||||||
|  | 					margin: 0; | ||||||
|  | 					opacity: 0.5; | ||||||
|  | 				} | ||||||
|  | 			} | ||||||
|  | 
 | ||||||
|  | 			> .fields { | ||||||
|  | 				padding: 24px; | ||||||
|  | 				font-size: 0.9em; | ||||||
|  | 				border-top: solid 1px var(--divider); | ||||||
|  | 
 | ||||||
|  | 				> .field { | ||||||
|  | 					display: flex; | ||||||
|  | 					padding: 0; | ||||||
|  | 					margin: 0; | ||||||
|  | 					align-items: center; | ||||||
|  | 
 | ||||||
|  | 					&:not(:last-child) { | ||||||
|  | 						margin-bottom: 8px; | ||||||
|  | 					} | ||||||
|  | 
 | ||||||
|  | 					> .name { | ||||||
|  | 						width: 30%; | ||||||
|  | 						overflow: hidden; | ||||||
|  | 						white-space: nowrap; | ||||||
|  | 						text-overflow: ellipsis; | ||||||
|  | 						font-weight: bold; | ||||||
|  | 						text-align: center; | ||||||
|  | 					} | ||||||
|  | 
 | ||||||
|  | 					> .value { | ||||||
|  | 						width: 70%; | ||||||
|  | 						overflow: hidden; | ||||||
|  | 						white-space: nowrap; | ||||||
|  | 						text-overflow: ellipsis; | ||||||
|  | 					} | ||||||
|  | 				} | ||||||
|  | 
 | ||||||
|  | 				&.system > .field > .name { | ||||||
|  | 				} | ||||||
|  | 			} | ||||||
|  | 
 | ||||||
|  | 			> .status { | ||||||
|  | 				display: flex; | ||||||
|  | 				padding: 24px; | ||||||
|  | 				border-top: solid 1px var(--divider); | ||||||
|  | 
 | ||||||
|  | 				> a { | ||||||
|  | 					flex: 1; | ||||||
|  | 					text-align: center; | ||||||
|  | 
 | ||||||
|  | 					&.active { | ||||||
|  | 						color: var(--accent); | ||||||
|  | 					} | ||||||
|  | 
 | ||||||
|  | 					&:hover { | ||||||
|  | 						text-decoration: none; | ||||||
|  | 					} | ||||||
|  | 
 | ||||||
|  | 					> b { | ||||||
|  | 						display: block; | ||||||
|  | 						line-height: 16px; | ||||||
|  | 					} | ||||||
|  | 
 | ||||||
|  | 					> span { | ||||||
|  | 						font-size: 70%; | ||||||
|  | 					} | ||||||
|  | 				} | ||||||
|  | 			} | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	> .side { | 	> .content { | ||||||
| 		flex-basis: 300px; | 		margin-bottom: var(--margin); | ||||||
| 		margin-left: var(--margin); |  | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	&.max-width_500px { | 	&.max-width_500px { | ||||||
| 		display: block; | 		> .profile > ._content { | ||||||
| 
 |  | ||||||
| 		> .main > .profile > ._content { |  | ||||||
| 			> .banner-container { | 			> .banner-container { | ||||||
| 				height: 140px; | 				height: 140px; | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -241,7 +241,7 @@ hr { | ||||||
| 	background: var(--panel); | 	background: var(--panel); | ||||||
| 	border-radius: var(--radius); | 	border-radius: var(--radius); | ||||||
| 	//border: var(--panelBorder); | 	//border: var(--panelBorder); | ||||||
| 	box-shadow: var(--panelShadow); | 	//box-shadow: var(--panelShadow); | ||||||
| 	overflow: hidden; | 	overflow: hidden; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -8,7 +8,7 @@ | ||||||
| 
 | 
 | ||||||
| 	props: { | 	props: { | ||||||
| 		divider: '#2d2d2d', | 		divider: '#2d2d2d', | ||||||
| 		panel: '#0a0a0a', | 		panel: '#111111', | ||||||
| 		panelHeaderBg: '@panel', | 		panelHeaderBg: '@panel', | ||||||
| 		panelHeaderDivider: '@divider', | 		panelHeaderDivider: '@divider', | ||||||
| 		panelShadow: '" 0 8px 24px rgb(0 0 0 / 25%)', | 		panelShadow: '" 0 8px 24px rgb(0 0 0 / 25%)', | ||||||
|  |  | ||||||
|  | @ -294,7 +294,7 @@ export default defineComponent({ | ||||||
| 			-webkit-backdrop-filter: blur(32px); | 			-webkit-backdrop-filter: blur(32px); | ||||||
| 			backdrop-filter: blur(32px); | 			backdrop-filter: blur(32px); | ||||||
| 			background-color: var(--header); | 			background-color: var(--header); | ||||||
| 			border-bottom: solid 1px var(--divider); | 			//border-bottom: solid 1px var(--divider); | ||||||
| 			user-select: none; | 			user-select: none; | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -1,5 +1,5 @@ | ||||||
| <template> | <template> | ||||||
| <DesignA/> | <DesignB/> | ||||||
| <XCommon/> | <XCommon/> | ||||||
| </template> | </template> | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -2,12 +2,6 @@ | ||||||
| <div class="mk-app"> | <div class="mk-app"> | ||||||
| 	<div class="banner" v-if="$route.path === '/'" :style="{ backgroundImage: `url(${ $store.state.instance.meta.bannerUrl })` }"> | 	<div class="banner" v-if="$route.path === '/'" :style="{ backgroundImage: `url(${ $store.state.instance.meta.bannerUrl })` }"> | ||||||
| 		<div> | 		<div> | ||||||
| 			<header> |  | ||||||
| 				<MkA class="link" to="/">{{ $t('home') }}</MkA> |  | ||||||
| 				<MkA class="link" to="/announcements">{{ $t('announcements') }}</MkA> |  | ||||||
| 				<MkA class="link" to="/channels">{{ $t('channel') }}</MkA> |  | ||||||
| 				<MkA class="link" to="/about">{{ $t('aboutX', { x: instanceName }) }}</MkA> |  | ||||||
| 			</header> |  | ||||||
| 			<h1 v-if="meta"><img class="logo" v-if="meta.logoImageUrl" :src="meta.logoImageUrl"><span v-else class="text">{{ instanceName }}</span></h1> | 			<h1 v-if="meta"><img class="logo" v-if="meta.logoImageUrl" :src="meta.logoImageUrl"><span v-else class="text">{{ instanceName }}</span></h1> | ||||||
| 			<div class="about" v-if="meta"> | 			<div class="about" v-if="meta"> | ||||||
| 				<div class="desc" v-html="meta.description || $t('introMisskey')"></div> | 				<div class="desc" v-html="meta.description || $t('introMisskey')"></div> | ||||||
|  | @ -20,16 +14,6 @@ | ||||||
| 	</div> | 	</div> | ||||||
| 	<div class="banner-mini" v-else :style="{ backgroundImage: `url(${ $store.state.instance.meta.bannerUrl })` }"> | 	<div class="banner-mini" v-else :style="{ backgroundImage: `url(${ $store.state.instance.meta.bannerUrl })` }"> | ||||||
| 		<div> | 		<div> | ||||||
| 			<header> |  | ||||||
| 				<MkA class="link" to="/">{{ $t('home') }}</MkA> |  | ||||||
| 				<MkA class="link" to="/announcements">{{ $t('announcements') }}</MkA> |  | ||||||
| 				<MkA class="link" to="/channels">{{ $t('channel') }}</MkA> |  | ||||||
| 				<MkA class="link" to="/about">{{ $t('aboutX', { x: instanceName }) }}</MkA> |  | ||||||
| 				<div class="action"> |  | ||||||
| 					<button class="_button primary" @click="signup()">{{ $t('signup') }}</button> |  | ||||||
| 					<button class="_button" @click="signin()">{{ $t('login') }}</button> |  | ||||||
| 				</div> |  | ||||||
| 			</header> |  | ||||||
| 			<h1 v-if="meta"><img class="logo" v-if="meta.logoImageUrl" :src="meta.logoImageUrl"><span v-else class="text">{{ instanceName }}</span></h1> | 			<h1 v-if="meta"><img class="logo" v-if="meta.logoImageUrl" :src="meta.logoImageUrl"><span v-else class="text">{{ instanceName }}</span></h1> | ||||||
| 		</div> | 		</div> | ||||||
| 	</div> | 	</div> | ||||||
|  | @ -62,10 +46,8 @@ import { host, instanceName } from '@/config'; | ||||||
| import { search } from '@/scripts/search'; | import { search } from '@/scripts/search'; | ||||||
| import * as os from '@/os'; | import * as os from '@/os'; | ||||||
| import MkPagination from '@/components/ui/pagination.vue'; | import MkPagination from '@/components/ui/pagination.vue'; | ||||||
| import XSigninDialog from '@/components/signin-dialog.vue'; |  | ||||||
| import XSignupDialog from '@/components/signup-dialog.vue'; |  | ||||||
| import MkButton from '@/components/ui/button.vue'; | import MkButton from '@/components/ui/button.vue'; | ||||||
| import XHeader from '../_common_/header.vue'; | import XHeader from './header.vue'; | ||||||
| 
 | 
 | ||||||
| const DESKTOP_THRESHOLD = 1100; | const DESKTOP_THRESHOLD = 1100; | ||||||
| 
 | 
 | ||||||
|  | @ -150,18 +132,6 @@ export default defineComponent({ | ||||||
| 		onTransition() { | 		onTransition() { | ||||||
| 			if (window._scroll) window._scroll(); | 			if (window._scroll) window._scroll(); | ||||||
| 		}, | 		}, | ||||||
| 
 |  | ||||||
| 		signin() { |  | ||||||
| 			os.popup(XSigninDialog, { |  | ||||||
| 				autoSet: true |  | ||||||
| 			}, {}, 'closed'); |  | ||||||
| 		}, |  | ||||||
| 
 |  | ||||||
| 		signup() { |  | ||||||
| 			os.popup(XSignupDialog, { |  | ||||||
| 				autoSet: true |  | ||||||
| 			}, {}, 'closed'); |  | ||||||
| 		} |  | ||||||
| 	} | 	} | ||||||
| }); | }); | ||||||
| </script> | </script> | ||||||
|  | @ -264,59 +234,6 @@ export default defineComponent({ | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	> .main { | 	> .main { | ||||||
| 		> header { |  | ||||||
| 			position: relative; |  | ||||||
| 			z-index: 1; |  | ||||||
| 			background: var(--panel); |  | ||||||
| 			padding: 0 32px; |  | ||||||
| 			text-align: left; |  | ||||||
| 			overflow: auto; |  | ||||||
| 			white-space: nowrap; |  | ||||||
| 
 |  | ||||||
| 			> .link { |  | ||||||
| 				display: inline-block; |  | ||||||
| 				line-height: 60px; |  | ||||||
| 				padding: 0 0.7em; |  | ||||||
| 
 |  | ||||||
| 				&.MkA-active { |  | ||||||
| 					box-shadow: 0 -2px 0 0 var(--accent) inset; |  | ||||||
| 				} |  | ||||||
| 			} |  | ||||||
| 		} |  | ||||||
| 
 |  | ||||||
| 		> .banner { |  | ||||||
| 			position: relative; |  | ||||||
| 			width: 100%; |  | ||||||
| 			height: 200px; |  | ||||||
| 			background-size: cover; |  | ||||||
| 			background-position: center; |  | ||||||
| 
 |  | ||||||
| 			&.asBg { |  | ||||||
| 				position: absolute; |  | ||||||
| 				left: 0; |  | ||||||
| 				height: 320px; |  | ||||||
| 			} |  | ||||||
| 
 |  | ||||||
| 			&:after { |  | ||||||
| 				content: ""; |  | ||||||
| 				display: block; |  | ||||||
| 				position: absolute; |  | ||||||
| 				bottom: 0; |  | ||||||
| 				left: 0; |  | ||||||
| 				width: 100%; |  | ||||||
| 				height: 64px; |  | ||||||
| 				background: linear-gradient(transparent, var(--bg)); |  | ||||||
| 			} |  | ||||||
| 
 |  | ||||||
| 			> h1 { |  | ||||||
| 				margin: 0; |  | ||||||
| 				text-align: center; |  | ||||||
| 				color: #fff; |  | ||||||
| 				text-shadow: 0 0 8px #000; |  | ||||||
| 				line-height: 200px; |  | ||||||
| 			} |  | ||||||
| 		} |  | ||||||
| 
 |  | ||||||
| 		> .contents { | 		> .contents { | ||||||
| 			position: relative; | 			position: relative; | ||||||
| 			z-index: 1; | 			z-index: 1; | ||||||
|  | @ -326,14 +243,6 @@ export default defineComponent({ | ||||||
| 				top: 0; | 				top: 0; | ||||||
| 				left: 0; | 				left: 0; | ||||||
| 				z-index: 1000; | 				z-index: 1000; | ||||||
| 				height: 60px; |  | ||||||
| 				width: 100%; |  | ||||||
| 				line-height: 60px; |  | ||||||
| 				text-align: center; |  | ||||||
| 				-webkit-backdrop-filter: blur(32px); |  | ||||||
| 				backdrop-filter: blur(32px); |  | ||||||
| 				background-color: var(--header); |  | ||||||
| 				border-bottom: 1px solid var(--divider); |  | ||||||
| 			} | 			} | ||||||
| 
 | 
 | ||||||
| 			> .powered-by { | 			> .powered-by { | ||||||
|  |  | ||||||
|  | @ -8,7 +8,7 @@ | ||||||
| 				<div class="desc" v-html="meta.description || $t('introMisskey')"></div> | 				<div class="desc" v-html="meta.description || $t('introMisskey')"></div> | ||||||
| 			</div> | 			</div> | ||||||
| 			<div class="action"> | 			<div class="action"> | ||||||
| 				<button class="_button primary" @click="signup()">{{ $t('signup') }}</button> | 				<button class="_buttonPrimary" @click="signup()">{{ $t('signup') }}</button> | ||||||
| 				<button class="_button" @click="signin()">{{ $t('login') }}</button> | 				<button class="_button" @click="signin()">{{ $t('login') }}</button> | ||||||
| 			</div> | 			</div> | ||||||
| 			<div class="announcements panel"> | 			<div class="announcements panel"> | ||||||
|  | @ -27,13 +27,6 @@ | ||||||
| 	</div> | 	</div> | ||||||
| 
 | 
 | ||||||
| 	<div class="main"> | 	<div class="main"> | ||||||
| 		<header> |  | ||||||
| 			<MkA class="link" to="/">{{ $t('home') }}</MkA> |  | ||||||
| 			<MkA class="link" to="/announcements">{{ $t('announcements') }}</MkA> |  | ||||||
| 			<MkA class="link" to="/channels">{{ $t('channel') }}</MkA> |  | ||||||
| 			<MkA class="link" to="/about">{{ $t('aboutX', { x: instanceName }) }}</MkA> |  | ||||||
| 		</header> |  | ||||||
| 
 |  | ||||||
| 		<div v-if="narrow" class="banner" :style="{ backgroundImage: `url(${ $store.state.instance.meta.bannerUrl })` }"> | 		<div v-if="narrow" class="banner" :style="{ backgroundImage: `url(${ $store.state.instance.meta.bannerUrl })` }"> | ||||||
| 			<h1 v-if="meta"><img class="logo" v-if="meta.logoImageUrl" :src="meta.logoImageUrl"><span v-else class="text">{{ instanceName }}</span></h1> | 			<h1 v-if="meta"><img class="logo" v-if="meta.logoImageUrl" :src="meta.logoImageUrl"><span v-else class="text">{{ instanceName }}</span></h1> | ||||||
| 		</div> | 		</div> | ||||||
|  | @ -181,6 +174,7 @@ export default defineComponent({ | ||||||
| 			left: 0; | 			left: 0; | ||||||
| 			width: 500px; | 			width: 500px; | ||||||
| 			height: 100vh; | 			height: 100vh; | ||||||
|  | 			overflow: auto; | ||||||
| 			background-position: center; | 			background-position: center; | ||||||
| 			background-size: cover; | 			background-size: cover; | ||||||
| 
 | 
 | ||||||
|  | @ -235,11 +229,9 @@ export default defineComponent({ | ||||||
| 					box-sizing: border-box; | 					box-sizing: border-box; | ||||||
| 					text-align: center; | 					text-align: center; | ||||||
| 					border-radius: 999px; | 					border-radius: 999px; | ||||||
| 					background: var(--panel); |  | ||||||
| 
 | 
 | ||||||
| 					&.primary { | 					&._button { | ||||||
| 						background: var(--accent); | 						background: var(--panel); | ||||||
| 						color: #fff; |  | ||||||
| 					} | 					} | ||||||
| 
 | 
 | ||||||
| 					&:first-child { | 					&:first-child { | ||||||
|  |  | ||||||
							
								
								
									
										171
									
								
								src/client/ui/visitor/header.vue
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										171
									
								
								src/client/ui/visitor/header.vue
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,171 @@ | ||||||
|  | <template> | ||||||
|  | <div class="sqxihjet"> | ||||||
|  | 	<div class="content"> | ||||||
|  | 		<MkA to="/" class="link" active-class="active">{{ $t('home') }}</MkA> | ||||||
|  | 		<MkA to="/explore" class="link" active-class="active">{{ $t('explore') }}</MkA> | ||||||
|  | 		<MkA to="/featured" class="link" active-class="active">{{ $t('featured') }}</MkA> | ||||||
|  | 		<MkA to="/channels" class="link" active-class="active">{{ $t('channel') }}</MkA> | ||||||
|  | 		<div class="page link" v-if="info"> | ||||||
|  | 			<div class="title"> | ||||||
|  | 				<Fa v-if="info.icon" :icon="info.icon" :key="info.icon" class="icon"/> | ||||||
|  | 				<MkAvatar v-else-if="info.avatar" class="avatar" :user="info.avatar" :disable-preview="true"/> | ||||||
|  | 				<span v-if="info.title" class="text">{{ info.title }}</span> | ||||||
|  | 				<MkUserName v-else-if="info.userName" :user="info.userName" :nowrap="false" class="text"/> | ||||||
|  | 			</div> | ||||||
|  | 			<button class="_button action" v-if="info.action" @click.stop="info.action.handler"><Fa :icon="info.action.icon" :key="info.action.icon"/></button> | ||||||
|  | 		</div> | ||||||
|  | 		<div class="right"> | ||||||
|  | 			<button class="_button search" @click="search()"><Fa :icon="faSearch" class="icon"/><span>{{ $t('search') }}</span></button> | ||||||
|  | 			<button class="_buttonPrimary signup" @click="signup()">{{ $t('signup') }}</button> | ||||||
|  | 			<button class="_button login" @click="signin()">{{ $t('login') }}</button> | ||||||
|  | 		</div> | ||||||
|  | 	</div> | ||||||
|  | </div> | ||||||
|  | </template> | ||||||
|  | 
 | ||||||
|  | <script lang="ts"> | ||||||
|  | import { defineComponent } from 'vue'; | ||||||
|  | import { faSearch } from '@fortawesome/free-solid-svg-icons'; | ||||||
|  | import XSigninDialog from '@/components/signin-dialog.vue'; | ||||||
|  | import XSignupDialog from '@/components/signup-dialog.vue'; | ||||||
|  | import * as os from '@/os'; | ||||||
|  | import { search } from '@/scripts/search'; | ||||||
|  | 
 | ||||||
|  | export default defineComponent({ | ||||||
|  | 	props: { | ||||||
|  | 		info: { | ||||||
|  | 			required: true | ||||||
|  | 		}, | ||||||
|  | 	}, | ||||||
|  | 
 | ||||||
|  | 	data() { | ||||||
|  | 		return { | ||||||
|  | 			faSearch | ||||||
|  | 		}; | ||||||
|  | 	}, | ||||||
|  | 
 | ||||||
|  | 	methods: { | ||||||
|  | 		signin() { | ||||||
|  | 			os.popup(XSigninDialog, { | ||||||
|  | 				autoSet: true | ||||||
|  | 			}, {}, 'closed'); | ||||||
|  | 		}, | ||||||
|  | 
 | ||||||
|  | 		signup() { | ||||||
|  | 			os.popup(XSignupDialog, { | ||||||
|  | 				autoSet: true | ||||||
|  | 			}, {}, 'closed'); | ||||||
|  | 		}, | ||||||
|  | 
 | ||||||
|  | 		search | ||||||
|  | 	} | ||||||
|  | }); | ||||||
|  | </script> | ||||||
|  | 
 | ||||||
|  | <style lang="scss" scoped> | ||||||
|  | .sqxihjet { | ||||||
|  | 	$height: 60px; | ||||||
|  | 	line-height: $height; | ||||||
|  | 	background: var(--panel); | ||||||
|  | 
 | ||||||
|  | 	> .content { | ||||||
|  | 		max-width: 1400px; | ||||||
|  | 		margin: 0 auto; | ||||||
|  | 		display: flex; | ||||||
|  | 		align-items: center; | ||||||
|  | 
 | ||||||
|  | 		> .link { | ||||||
|  | 			display: inline-block; | ||||||
|  | 			padding: 0 16px; | ||||||
|  | 			line-height: $height - 4px; | ||||||
|  | 			border-top: solid 2px transparent; | ||||||
|  | 			border-bottom: solid 2px transparent; | ||||||
|  | 
 | ||||||
|  | 			&.page { | ||||||
|  | 				border-bottom-color: var(--accent); | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		> .page { | ||||||
|  | 			> .title { | ||||||
|  | 				display: inline-block; | ||||||
|  | 				vertical-align: bottom; | ||||||
|  | 				white-space: nowrap; | ||||||
|  | 				overflow: hidden; | ||||||
|  | 				text-overflow: ellipsis; | ||||||
|  | 				position: relative; | ||||||
|  | 
 | ||||||
|  | 				> .indicator { | ||||||
|  | 					position: absolute; | ||||||
|  | 					top: initial; | ||||||
|  | 					right: 8px; | ||||||
|  | 					top: 8px; | ||||||
|  | 					color: var(--indicator); | ||||||
|  | 					font-size: 12px; | ||||||
|  | 					animation: blink 1s infinite; | ||||||
|  | 				} | ||||||
|  | 
 | ||||||
|  | 				> .icon + .text { | ||||||
|  | 					margin-left: 8px; | ||||||
|  | 				} | ||||||
|  | 
 | ||||||
|  | 				> .avatar { | ||||||
|  | 					$size: 32px; | ||||||
|  | 					display: inline-block; | ||||||
|  | 					width: $size; | ||||||
|  | 					height: $size; | ||||||
|  | 					vertical-align: middle; | ||||||
|  | 					margin-right: 8px; | ||||||
|  | 					pointer-events: none; | ||||||
|  | 				} | ||||||
|  | 
 | ||||||
|  | 				&._button { | ||||||
|  | 					&:hover { | ||||||
|  | 						color: var(--fgHighlighted); | ||||||
|  | 					} | ||||||
|  | 				} | ||||||
|  | 
 | ||||||
|  | 				&.selected { | ||||||
|  | 					box-shadow: 0 -2px 0 0 var(--accent) inset; | ||||||
|  | 					color: var(--fgHighlighted); | ||||||
|  | 				} | ||||||
|  | 			} | ||||||
|  | 
 | ||||||
|  | 			> .action { | ||||||
|  | 				padding: 0 0 0 16px; | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		> .right { | ||||||
|  | 			margin-left: auto; | ||||||
|  | 
 | ||||||
|  | 			> .search { | ||||||
|  | 				background: var(--bg); | ||||||
|  | 				border-radius: 999px; | ||||||
|  | 				width: 230px; | ||||||
|  | 				line-height: $height - 20px; | ||||||
|  | 				margin-right: 16px; | ||||||
|  | 				text-align: left; | ||||||
|  | 
 | ||||||
|  | 				> * { | ||||||
|  | 					opacity: 0.7; | ||||||
|  | 				} | ||||||
|  | 
 | ||||||
|  | 				> .icon { | ||||||
|  | 					padding: 0 16px; | ||||||
|  | 				} | ||||||
|  | 			} | ||||||
|  | 
 | ||||||
|  | 			> .signup { | ||||||
|  | 				border-radius: 999px; | ||||||
|  | 				padding: 0 24px; | ||||||
|  | 				line-height: $height - 20px; | ||||||
|  | 			} | ||||||
|  | 
 | ||||||
|  | 			> .login { | ||||||
|  | 				padding: 0 16px; | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | </style> | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue