From edb0fbc0884917dd8435336a487e02ff1ac112ec Mon Sep 17 00:00:00 2001
From: syuilo <Syuilotan@yahoo.co.jp>
Date: Sun, 25 Apr 2021 15:14:26 +0900
Subject: [PATCH] Tweak UI

---
 src/client/pages/gallery/post.vue |  14 +--
 src/client/pages/page.vue         | 199 +++++++++++++++++++++++-------
 2 files changed, 163 insertions(+), 50 deletions(-)

diff --git a/src/client/pages/gallery/post.vue b/src/client/pages/gallery/post.vue
index 86fae9988..9bd102cee 100644
--- a/src/client/pages/gallery/post.vue
+++ b/src/client/pages/gallery/post.vue
@@ -19,7 +19,7 @@
 						<MkButton class="button" @click="like()" v-else v-tooltip="$ts._gallery.like"><i class="far fa-heart"></i><span class="count" v-if="post.likedCount > 0">{{ post.likedCount }}</span></MkButton>
 					</div>
 					<div class="other">
-						<button class="_button" @click="createNote" v-tooltip="$ts.shareWithNote" v-click-anime><i class="fas fa-retweet fa-fw"></i></button>
+						<button class="_button" @click="shareWithNote" v-tooltip="$ts.shareWithNote" v-click-anime><i class="fas fa-retweet fa-fw"></i></button>
 						<button class="_button" @click="share" v-tooltip="$ts.share" v-click-anime><i class="fas fa-share-alt fa-fw"></i></button>
 					</div>
 				</div>
@@ -125,6 +125,12 @@ export default defineComponent({
 			});
 		},
 
+		shareWithNote() {
+			os.post({
+				initialText: `${this.post.title} ${url}/gallery/${this.post.id}`
+			});
+		},
+
 		like() {
 			os.apiWithDialog('gallery/posts/like', {
 				postId: this.postId,
@@ -148,12 +154,6 @@ export default defineComponent({
 				this.post.likedCount--;
 			});
 		},
-
-		createNote() {
-			os.post({
-				initialText: `${this.post.title} ${url}/gallery/${this.post.id}`
-			});
-		}
 	}
 });
 </script>
diff --git a/src/client/pages/page.vue b/src/client/pages/page.vue
index e43add7b0..6ee3ee8d2 100644
--- a/src/client/pages/page.vue
+++ b/src/client/pages/page.vue
@@ -1,35 +1,60 @@
 <template>
-<div class="xcukqgmh _root" v-if="page" :key="page.id" v-size="{ max: [450] }">
-	<div class="_block main">
-		<!--
-		<div class="header">
-			<h1>{{ page.title }}</h1>
+<div class="_root">
+	<transition name="fade" mode="out-in">
+		<div v-if="page" class="xcukqgmh" :key="page.id" v-size="{ max: [450] }">
+			<div class="_block main">
+				<!--
+				<div class="header">
+					<h1>{{ page.title }}</h1>
+				</div>
+				-->
+				<div class="banner">
+					<img :src="page.eyeCatchingImage.url" v-if="page.eyeCatchingImageId"/>
+				</div>
+				<div class="content">
+					<XPage :page="page"/>
+				</div>
+				<div class="actions">
+					<div class="like">
+						<MkButton class="button" @click="unlike()" v-if="page.isLiked" v-tooltip="$ts._pages.unlike" primary><i class="fas fa-heart"></i><span class="count" v-if="page.likedCount > 0">{{ page.likedCount }}</span></MkButton>
+						<MkButton class="button" @click="like()" v-else v-tooltip="$ts._pages.like"><i class="far fa-heart"></i><span class="count" v-if="page.likedCount > 0">{{ page.likedCount }}</span></MkButton>
+					</div>
+					<div class="other">
+						<button class="_button" @click="shareWithNote" v-tooltip="$ts.shareWithNote" v-click-anime><i class="fas fa-retweet fa-fw"></i></button>
+						<button class="_button" @click="share" v-tooltip="$ts.share" v-click-anime><i class="fas fa-share-alt fa-fw"></i></button>
+					</div>
+				</div>
+				<div class="user">
+					<MkAvatar :user="page.user" class="avatar"/>
+					<div class="name">
+						<MkUserName :user="page.user" style="display: block;"/>
+						<MkAcct :user="page.user"/>
+					</div>
+					<MkFollowButton v-if="!$i || $i.id != page.user.id" :user="page.user" :inline="true" :transparent="false" :full="true" large class="koudoku"/>
+				</div>
+				<div class="links">
+					<MkA :to="`/@${username}/pages/${pageName}/view-source`" class="link">{{ $ts._pages.viewSource }}</MkA>
+					<template v-if="$i && $i.id === page.userId">
+						<MkA :to="`/pages/edit/${page.id}`" class="link">{{ $ts._pages.editThisPage }}</MkA>
+						<button v-if="$i.pinnedPageId === page.id" @click="pin(false)" class="link _textButton">{{ $ts.unpin }}</button>
+						<button v-else @click="pin(true)" class="link _textButton">{{ $ts.pin }}</button>
+					</template>
+				</div>
+			</div>
+			<div class="footer">
+				<div><i class="far fa-clock"></i> {{ $ts.createdAt }}: <MkTime :time="page.createdAt" mode="detail"/></div>
+				<div v-if="page.createdAt != page.updatedAt"><i class="far fa-clock"></i> {{ $ts.updatedAt }}: <MkTime :time="page.updatedAt" mode="detail"/></div>
+			</div>
+			<MkContainer :max-height="300" :foldable="true" class="other">
+				<template #header><i class="fas fa-clock"></i> {{ $ts.recentPosts }}</template>
+				<MkPagination :pagination="otherPostsPagination" #default="{items}">
+					<MkPagePreview v-for="page in items" :page="page" :key="page.id" class="_gap"/>
+				</MkPagination>
+			</MkContainer>
 		</div>
-		-->
-		<div class="banner">
-			<img :src="page.eyeCatchingImage.url" v-if="page.eyeCatchingImageId"/>
-		</div>
-		<div class="content">
-			<XPage :page="page"/>
-			<small style="display: block; opacity: 0.7; margin-top: 1em;">@{{ page.user.username }}</small>
-		</div>
-		<div class="like">
-			<MkButton class="button" @click="unlike()" v-if="page.isLiked" v-tooltip="$ts._pages.unlike" primary><i class="fas fa-heart"></i><span class="count" v-if="page.likedCount > 0">{{ page.likedCount }}</span></MkButton>
-			<MkButton class="button" @click="like()" v-else v-tooltip="$ts._pages.like"><i class="far fa-heart"></i><span class="count" v-if="page.likedCount > 0">{{ page.likedCount }}</span></MkButton>
-		</div>
-		<div class="links">
-			<MkA :to="`/@${username}/pages/${pageName}/view-source`" class="link">{{ $ts._pages.viewSource }}</MkA>
-			<template v-if="$i && $i.id === page.userId">
-				<MkA :to="`/pages/edit/${page.id}`" class="link">{{ $ts._pages.editThisPage }}</MkA>
-				<button v-if="$i.pinnedPageId === page.id" @click="pin(false)" class="link _textButton">{{ $ts.unpin }}</button>
-				<button v-else @click="pin(true)" class="link _textButton">{{ $ts.pin }}</button>
-			</template>
-		</div>
-	</div>
-	<div class="footer">
-		<div><i class="far fa-clock"></i> {{ $ts.createdAt }}: <MkTime :time="page.createdAt" mode="detail"/></div>
-		<div v-if="page.createdAt != page.updatedAt"><i class="far fa-clock"></i> {{ $ts.updatedAt }}: <MkTime :time="page.updatedAt" mode="detail"/></div>
-	</div>
+		<MkError v-else-if="error" @retry="fetch()"/>
+		<MkLoading v-else/>
+	</transition>
 </div>
 </template>
 
@@ -39,11 +64,20 @@ import XPage from '@client/components/page/page.vue';
 import MkButton from '@client/components/ui/button.vue';
 import * as os from '@client/os';
 import * as symbols from '@client/symbols';
+import { url } from '@client/config';
+import MkFollowButton from '@client/components/follow-button.vue';
+import MkContainer from '@client/components/ui/container.vue';
+import MkPagination from '@client/components/ui/pagination.vue';
+import MkPagePreview from '@client/components/page-preview.vue';
 
 export default defineComponent({
 	components: {
 		XPage,
 		MkButton,
+		MkFollowButton,
+		MkContainer,
+		MkPagination,
+		MkPagePreview,
 	},
 
 	props: {
@@ -69,6 +103,14 @@ export default defineComponent({
 				},
 			} : null),
 			page: null,
+			error: null,
+			otherPostsPagination: {
+				endpoint: 'users/pages',
+				limit: 6,
+				params: () => ({
+					userId: this.page.user.id
+				})
+			},
 		};
 	},
 
@@ -90,11 +132,28 @@ export default defineComponent({
 
 	methods: {
 		fetch() {
+			this.page = null;
 			os.api('pages/show', {
 				name: this.pageName,
 				username: this.username,
 			}).then(page => {
 				this.page = page;
+			}).catch(e => {
+				this.error = e;
+			});
+		},
+
+		share() {
+			navigator.share({
+				title: this.page.title || this.page.name,
+				text: this.page.summary,
+				url: `${url}/@${this.page.user.username}/pages/${this.page.name}`
+			});
+		},
+
+		shareWithNote() {
+			os.post({
+				initialText: `${this.page.title || this.page.name} ${url}/@${this.page.user.username}/pages/${this.page.name}`
 			});
 		},
 
@@ -132,6 +191,15 @@ export default defineComponent({
 </script>
 
 <style lang="scss" scoped>
+.fade-enter-active,
+.fade-leave-active {
+	transition: opacity 0.125s ease;
+}
+.fade-enter-from,
+.fade-leave-to {
+	opacity: 0;
+}
+
 .xcukqgmh {
 	--padding: 32px;
 
@@ -140,6 +208,8 @@ export default defineComponent({
 	}
 
 	> .main {
+		padding: var(--padding);
+
 		> .header {
 			padding: 16px;
 
@@ -150,36 +220,79 @@ export default defineComponent({
 
 		> .banner {
 			> img {
+				// TODO: 良い感じのアスペクト比で表示
 				display: block;
 				width: 100%;
-				height: 120px;
+				height: 150px;
 				object-fit: cover;
 			}
 		}
 
 		> .content {
-			padding: var(--padding);
+			margin-top: 16px;
+			padding: 16px 0 0 0;
 		}
 
-		> .like {
-			padding: var(--padding);
+		> .actions {
+			display: flex;
+			align-items: center;
+			margin-top: 16px;
+			padding: 16px 0 0 0;
 			border-top: solid 0.5px var(--divider);
 
-			> .button {
-				--accent: rgb(241 97 132);
-				--X8: rgb(241 92 128);
-				--buttonBg: rgb(216 71 106 / 5%);
-				--buttonHoverBg: rgb(216 71 106 / 10%);
-				color: #ff002f;
+			> .like {
+				> .button {
+					--accent: rgb(241 97 132);
+					--X8: rgb(241 92 128);
+					--buttonBg: rgb(216 71 106 / 5%);
+					--buttonHoverBg: rgb(216 71 106 / 10%);
+					color: #ff002f;
 
-				::v-deep(.count) {
-					margin-left: 0.5em;
+					::v-deep(.count) {
+						margin-left: 0.5em;
+					}
+				}
+			}
+
+			> .other {
+				margin-left: auto;
+
+				> button {
+					padding: 8px;
+					margin: 0 8px;
+
+					&:hover {
+						color: var(--fgHighlighted);
+					}
 				}
 			}
 		}
 
+		> .user {
+			margin-top: 16px;
+			padding: 16px 0 0 0;
+			border-top: solid 0.5px var(--divider);
+			display: flex;
+			align-items: center;
+
+			> .avatar {
+				width: 52px;
+				height: 52px;
+			}
+
+			> .name {
+				margin: 0 0 0 12px;
+				font-size: 90%;
+			}
+
+			> .koudoku {
+				margin-left: auto;
+			}
+		}
+
 		> .links {
-			padding: var(--padding);
+			margin-top: 16px;
+			padding: 24px 0 0 0;
 			border-top: solid 0.5px var(--divider);
 
 			> .link {