wip
This commit is contained in:
		
							parent
							
								
									80eefa92ce
								
							
						
					
					
						commit
						0336d640ec
					
				
					 7 changed files with 155 additions and 56 deletions
				
			
		|  | @ -1,6 +1,6 @@ | ||||||
| <template> | <template> | ||||||
| <div | <div | ||||||
| 	class="note _panel" | 	class="tkcbzcuz _panel" | ||||||
| 	v-if="!muted" | 	v-if="!muted" | ||||||
| 	v-show="!isDeleted" | 	v-show="!isDeleted" | ||||||
| 	:tabindex="!isDeleted ? '-1' : null" | 	:tabindex="!isDeleted ? '-1' : null" | ||||||
|  | @ -858,7 +858,7 @@ export default defineComponent({ | ||||||
| </script> | </script> | ||||||
| 
 | 
 | ||||||
| <style lang="scss" scoped> | <style lang="scss" scoped> | ||||||
| .note { | .tkcbzcuz { | ||||||
| 	position: relative; | 	position: relative; | ||||||
| 	transition: box-shadow 0.1s ease; | 	transition: box-shadow 0.1s ease; | ||||||
| 	overflow: hidden; | 	overflow: hidden; | ||||||
|  |  | ||||||
|  | @ -13,12 +13,10 @@ export default { | ||||||
| 			const viewHeight = container.clientHeight; | 			const viewHeight = container.clientHeight; | ||||||
| 			const height = container.scrollHeight; | 			const height = container.scrollHeight; | ||||||
| 			isBottom = (pos + viewHeight > height - 32); | 			isBottom = (pos + viewHeight > height - 32); | ||||||
| 			console.log(isBottom); |  | ||||||
| 		}, { passive: true }); | 		}, { passive: true }); | ||||||
| 		container.scrollTop = container.scrollHeight; | 		container.scrollTop = container.scrollHeight; | ||||||
| 
 | 
 | ||||||
| 		const ro = new ResizeObserver((entries, observer) => { | 		const ro = new ResizeObserver((entries, observer) => { | ||||||
| 			console.log(isBottom); |  | ||||||
| 			if (isBottom) { | 			if (isBottom) { | ||||||
| 				const height = container.scrollHeight; | 				const height = container.scrollHeight; | ||||||
| 				container.scrollTop = height; | 				container.scrollTop = height; | ||||||
|  |  | ||||||
|  | @ -120,6 +120,20 @@ export default defineComponent({ | ||||||
| .hmjzthxl { | .hmjzthxl { | ||||||
| 	> .separator { | 	> .separator { | ||||||
| 		text-align: center; | 		text-align: center; | ||||||
|  | 		position: relative; | ||||||
|  | 
 | ||||||
|  | 		&:before { | ||||||
|  | 			content: ""; | ||||||
|  | 			display: block; | ||||||
|  | 			position: absolute; | ||||||
|  | 			top: 50%; | ||||||
|  | 			left: 0; | ||||||
|  | 			right: 0; | ||||||
|  | 			margin: auto; | ||||||
|  | 			width: calc(100% - 32px); | ||||||
|  | 			height: 1px; | ||||||
|  | 			background: var(--divider); | ||||||
|  | 		} | ||||||
| 
 | 
 | ||||||
| 		> .date { | 		> .date { | ||||||
| 			display: inline-block; | 			display: inline-block; | ||||||
|  | @ -130,6 +144,7 @@ export default defineComponent({ | ||||||
| 			text-align: center; | 			text-align: center; | ||||||
| 			font-size: 12px; | 			font-size: 12px; | ||||||
| 			color: var(--dateLabelFg); | 			color: var(--dateLabelFg); | ||||||
|  | 			background: var(--panel); | ||||||
| 
 | 
 | ||||||
| 			> span { | 			> span { | ||||||
| 				&:first-child { | 				&:first-child { | ||||||
|  |  | ||||||
							
								
								
									
										44
									
								
								src/client/ui/chat/header-clock.vue
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										44
									
								
								src/client/ui/chat/header-clock.vue
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,44 @@ | ||||||
|  | <template> | ||||||
|  | <div class="_monospace"> | ||||||
|  | 	<span> | ||||||
|  | 		<span v-text="hh"></span> | ||||||
|  | 		<span :style="{ visibility: showColon ? 'visible' : 'hidden' }">:</span> | ||||||
|  | 		<span v-text="mm"></span> | ||||||
|  | 		<span :style="{ visibility: showColon ? 'visible' : 'hidden' }">:</span> | ||||||
|  | 		<span v-text="ss"></span> | ||||||
|  | 	</span> | ||||||
|  | </div> | ||||||
|  | </template> | ||||||
|  | 
 | ||||||
|  | <script lang="ts"> | ||||||
|  | import { defineComponent } from 'vue'; | ||||||
|  | import * as os from '@/os'; | ||||||
|  | 
 | ||||||
|  | export default defineComponent({ | ||||||
|  | 	data() { | ||||||
|  | 		return { | ||||||
|  | 			clock: null, | ||||||
|  | 			hh: null, | ||||||
|  | 			mm: null, | ||||||
|  | 			ss: null, | ||||||
|  | 			showColon: true, | ||||||
|  | 		}; | ||||||
|  | 	}, | ||||||
|  | 	created() { | ||||||
|  | 		this.tick(); | ||||||
|  | 		this.clock = setInterval(this.tick, 1000); | ||||||
|  | 	}, | ||||||
|  | 	beforeUnmount() { | ||||||
|  | 		clearInterval(this.clock); | ||||||
|  | 	}, | ||||||
|  | 	methods: { | ||||||
|  | 		tick() { | ||||||
|  | 			const now = new Date(); | ||||||
|  | 			this.hh = now.getHours().toString().padStart(2, '0'); | ||||||
|  | 			this.mm = now.getMinutes().toString().padStart(2, '0'); | ||||||
|  | 			this.ss = now.getSeconds().toString().padStart(2, '0'); | ||||||
|  | 			this.showColon = now.getSeconds() % 2 === 0; | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | }); | ||||||
|  | </script> | ||||||
|  | @ -62,21 +62,27 @@ | ||||||
| 
 | 
 | ||||||
| 	<main class="main" @contextmenu.stop="onContextmenu"> | 	<main class="main" @contextmenu.stop="onContextmenu"> | ||||||
| 		<header class="header" ref="header" @click="onHeaderClick"> | 		<header class="header" ref="header" @click="onHeaderClick"> | ||||||
| 			<div v-if="tl === 'home'"> | 			<div class="left"> | ||||||
| 				<Fa :icon="faHome" class="icon"/> | 				<template v-if="tl === 'home'"> | ||||||
| 				<div class="title">{{ $ts._timelines.home }}</div> | 					<Fa :icon="faHome" class="icon"/> | ||||||
|  | 					<div class="title">{{ $ts._timelines.home }}</div> | ||||||
|  | 				</template> | ||||||
|  | 				<template v-else-if="tl === 'local'"> | ||||||
|  | 					<Fa :icon="faShareAlt" class="icon"/> | ||||||
|  | 					<div class="title">{{ $ts._timelines.local }}</div> | ||||||
|  | 				</template> | ||||||
|  | 				<template v-else-if="tl === 'social'"> | ||||||
|  | 					<Fa :icon="faShareAlt" class="icon"/> | ||||||
|  | 					<div class="title">{{ $ts._timelines.social }}</div> | ||||||
|  | 				</template> | ||||||
|  | 				<template v-else-if="tl === 'global'"> | ||||||
|  | 					<Fa :icon="faShareAlt" class="icon"/> | ||||||
|  | 					<div class="title">{{ $ts._timelines.global }}</div> | ||||||
|  | 				</template> | ||||||
| 			</div> | 			</div> | ||||||
| 			<div v-else-if="tl === 'local'"> | 
 | ||||||
| 				<Fa :icon="faShareAlt" class="icon"/> | 			<div class="right"> | ||||||
| 				<div class="title">{{ $ts._timelines.local }}</div> | 				<XHeaderClock/> | ||||||
| 			</div> |  | ||||||
| 			<div v-else-if="tl === 'social'"> |  | ||||||
| 				<Fa :icon="faShareAlt" class="icon"/> |  | ||||||
| 				<div class="title">{{ $ts._timelines.social }}</div> |  | ||||||
| 			</div> |  | ||||||
| 			<div v-else-if="tl === 'global'"> |  | ||||||
| 				<Fa :icon="faShareAlt" class="icon"/> |  | ||||||
| 				<div class="title">{{ $ts._timelines.global }}</div> |  | ||||||
| 			</div> | 			</div> | ||||||
| 		</header> | 		</header> | ||||||
| 		<div class="body"> | 		<div class="body"> | ||||||
|  | @ -105,6 +111,7 @@ import XCommon from '../_common_/common.vue'; | ||||||
| import XSide from './side.vue'; | import XSide from './side.vue'; | ||||||
| import XTimeline from './timeline.vue'; | import XTimeline from './timeline.vue'; | ||||||
| import XPostForm from './post-form.vue'; | import XPostForm from './post-form.vue'; | ||||||
|  | import XHeaderClock from './header-clock.vue'; | ||||||
| import * as os from '@/os'; | import * as os from '@/os'; | ||||||
| import { sidebarDef } from '@/sidebar'; | import { sidebarDef } from '@/sidebar'; | ||||||
| 
 | 
 | ||||||
|  | @ -115,6 +122,7 @@ export default defineComponent({ | ||||||
| 		XSide, // NOTE: dynamic importするとAsyncComponentWrapperが間に入るせいでref取得できなくて面倒になる | 		XSide, // NOTE: dynamic importするとAsyncComponentWrapperが間に入るせいでref取得できなくて面倒になる | ||||||
| 		XTimeline, | 		XTimeline, | ||||||
| 		XPostForm, | 		XPostForm, | ||||||
|  | 		XHeaderClock, | ||||||
| 	}, | 	}, | ||||||
| 
 | 
 | ||||||
| 	provide() { | 	provide() { | ||||||
|  | @ -260,6 +268,29 @@ export default defineComponent({ | ||||||
| 				border-top: solid 1px var(--divider); | 				border-top: solid 1px var(--divider); | ||||||
| 			} | 			} | ||||||
| 
 | 
 | ||||||
|  | 			> .left, > .right { | ||||||
|  | 				> .item, > .menu { | ||||||
|  | 					height: ($header-height - ($padding * 2)); | ||||||
|  | 					width: ($header-height - ($padding * 2)); | ||||||
|  | 					padding: 10px; | ||||||
|  | 					box-sizing: border-box; | ||||||
|  | 					margin-right: 4px; | ||||||
|  | 					//opacity: 0.6; | ||||||
|  | 					position: relative; | ||||||
|  | 					line-height: initial; | ||||||
|  | 
 | ||||||
|  | 					> i { | ||||||
|  | 						position: absolute; | ||||||
|  | 						top: 8px; | ||||||
|  | 						right: 8px; | ||||||
|  | 						color: var(--indicator); | ||||||
|  | 						font-size: 8px; | ||||||
|  | 						line-height: 8px; | ||||||
|  | 						animation: blink 1s infinite; | ||||||
|  | 					} | ||||||
|  | 				} | ||||||
|  | 			} | ||||||
|  | 
 | ||||||
| 			> .left { | 			> .left { | ||||||
| 				> .account { | 				> .account { | ||||||
| 					display: flex; | 					display: flex; | ||||||
|  | @ -276,26 +307,6 @@ export default defineComponent({ | ||||||
| 
 | 
 | ||||||
| 			> .right { | 			> .right { | ||||||
| 				margin-left: auto; | 				margin-left: auto; | ||||||
| 
 |  | ||||||
| 				> .item { |  | ||||||
| 					height: ($header-height - ($padding * 2)); |  | ||||||
| 					width: ($header-height - ($padding * 2)); |  | ||||||
| 					padding: 10px; |  | ||||||
| 					box-sizing: border-box; |  | ||||||
| 					margin-right: 4px; |  | ||||||
| 					//opacity: 0.6; |  | ||||||
| 					position: relative; |  | ||||||
| 
 |  | ||||||
| 					> i { |  | ||||||
| 						position: absolute; |  | ||||||
| 						top: 8px; |  | ||||||
| 						right: 8px; |  | ||||||
| 						color: var(--indicator); |  | ||||||
| 						font-size: 8px; |  | ||||||
| 						line-height: 8px; |  | ||||||
| 						animation: blink 1s infinite; |  | ||||||
| 					} |  | ||||||
| 				} |  | ||||||
| 			} | 			} | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
|  | @ -358,18 +369,19 @@ export default defineComponent({ | ||||||
| 
 | 
 | ||||||
| 		> .header { | 		> .header { | ||||||
| 			$padding: 8px; | 			$padding: 8px; | ||||||
|  | 			display: flex; | ||||||
| 			z-index: 1000; | 			z-index: 1000; | ||||||
| 			height: $header-height; | 			height: $header-height; | ||||||
| 			padding: $padding; | 			padding: $padding; | ||||||
| 			box-sizing: border-box; | 			box-sizing: border-box; | ||||||
| 			line-height: ($header-height - ($padding * 2)); | 			line-height: ($header-height - ($padding * 2)); | ||||||
| 			font-weight: bold; |  | ||||||
| 			background-color: var(--panel); | 			background-color: var(--panel); | ||||||
| 			border-bottom: solid 1px var(--divider); | 			border-bottom: solid 1px var(--divider); | ||||||
| 			user-select: none; | 			user-select: none; | ||||||
| 
 | 
 | ||||||
| 			> div { | 			> .left { | ||||||
| 				display: flex; | 				display: flex; | ||||||
|  | 				font-weight: bold; | ||||||
| 
 | 
 | ||||||
| 				> .icon { | 				> .icon { | ||||||
| 					height: ($header-height - ($padding * 2)); | 					height: ($header-height - ($padding * 2)); | ||||||
|  | @ -380,10 +392,15 @@ export default defineComponent({ | ||||||
| 					opacity: 0.6; | 					opacity: 0.6; | ||||||
| 				} | 				} | ||||||
| 			} | 			} | ||||||
|  | 
 | ||||||
|  | 			> .right { | ||||||
|  | 				margin-left: auto; | ||||||
|  | 				padding: 0 8px; | ||||||
|  | 			} | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		> .footer { | 		> .footer { | ||||||
| 			padding: 16px; | 			padding: 0 16px 16px 16px; | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		> .body { | 		> .body { | ||||||
|  |  | ||||||
|  | @ -1,10 +1,10 @@ | ||||||
| <template> | <template> | ||||||
| <div | <div | ||||||
| 	class="note" | 	class="vfzoeqcg" | ||||||
| 	v-if="!muted" | 	v-if="!muted" | ||||||
| 	v-show="!isDeleted" | 	v-show="!isDeleted" | ||||||
| 	:tabindex="!isDeleted ? '-1' : null" | 	:tabindex="!isDeleted ? '-1' : null" | ||||||
| 	:class="{ renote: isRenote }" | 	:class="{ renote: isRenote, operating }" | ||||||
| 	v-hotkey="keymap" | 	v-hotkey="keymap" | ||||||
| > | > | ||||||
| 	<XSub :note="appearNote.reply" class="reply-to" v-if="appearNote.reply"/> | 	<XSub :note="appearNote.reply" class="reply-to" v-if="appearNote.reply"/> | ||||||
|  | @ -171,6 +171,7 @@ export default defineComponent({ | ||||||
| 			collapsed: false, | 			collapsed: false, | ||||||
| 			isDeleted: false, | 			isDeleted: false, | ||||||
| 			muted: false, | 			muted: false, | ||||||
|  | 			operating: false, | ||||||
| 			faEdit, faBolt, faTimes, faBullhorn, faPlus, faMinus, faRetweet, faReply, faReplyAll, faEllipsisH, faHome, faUnlock, faEnvelope, faThumbtack, faBan, faBiohazard, faPlug, faSatelliteDish | 			faEdit, faBolt, faTimes, faBullhorn, faPlus, faMinus, faRetweet, faReply, faReplyAll, faEllipsisH, faHome, faUnlock, faEnvelope, faThumbtack, faBan, faBiohazard, faPlug, faSatelliteDish | ||||||
| 		}; | 		}; | ||||||
| 	}, | 	}, | ||||||
|  | @ -439,16 +440,19 @@ export default defineComponent({ | ||||||
| 
 | 
 | ||||||
| 		reply(viaKeyboard = false) { | 		reply(viaKeyboard = false) { | ||||||
| 			pleaseLogin(); | 			pleaseLogin(); | ||||||
|  | 			this.operating = true; | ||||||
| 			os.post({ | 			os.post({ | ||||||
| 				reply: this.appearNote, | 				reply: this.appearNote, | ||||||
| 				animation: !viaKeyboard, | 				animation: !viaKeyboard, | ||||||
| 			}, () => { | 			}, () => { | ||||||
|  | 				this.operating = false; | ||||||
| 				this.focus(); | 				this.focus(); | ||||||
| 			}); | 			}); | ||||||
| 		}, | 		}, | ||||||
| 
 | 
 | ||||||
| 		renote(viaKeyboard = false) { | 		renote(viaKeyboard = false) { | ||||||
| 			pleaseLogin(); | 			pleaseLogin(); | ||||||
|  | 			this.operating = true; | ||||||
| 			this.blur(); | 			this.blur(); | ||||||
| 			os.modalMenu([{ | 			os.modalMenu([{ | ||||||
| 				text: this.$ts.renote, | 				text: this.$ts.renote, | ||||||
|  | @ -468,6 +472,8 @@ export default defineComponent({ | ||||||
| 				} | 				} | ||||||
| 			}], this.$refs.renoteButton, { | 			}], this.$refs.renoteButton, { | ||||||
| 				viaKeyboard | 				viaKeyboard | ||||||
|  | 			}).then(() => { | ||||||
|  | 				this.operating = false; | ||||||
| 			}); | 			}); | ||||||
| 		}, | 		}, | ||||||
| 
 | 
 | ||||||
|  | @ -494,10 +500,11 @@ export default defineComponent({ | ||||||
| 			}); | 			}); | ||||||
| 		}, | 		}, | ||||||
| 
 | 
 | ||||||
| 		react(viaKeyboard = false) { | 		async react(viaKeyboard = false) { | ||||||
| 			pleaseLogin(); | 			pleaseLogin(); | ||||||
|  | 			this.operating = true; | ||||||
| 			this.blur(); | 			this.blur(); | ||||||
| 			os.popup(import('@/components/emoji-picker.vue'), { | 			const { dispose } = await os.popup(import('@/components/emoji-picker.vue'), { | ||||||
| 				src: this.$refs.reactButton, | 				src: this.$refs.reactButton, | ||||||
| 				asReactionPicker: true | 				asReactionPicker: true | ||||||
| 			}, { | 			}, { | ||||||
|  | @ -508,9 +515,13 @@ export default defineComponent({ | ||||||
| 							reaction: reaction | 							reaction: reaction | ||||||
| 						}); | 						}); | ||||||
| 					} | 					} | ||||||
| 					this.focus(); |  | ||||||
| 				}, | 				}, | ||||||
| 			}, 'closed'); | 				closed: () => { | ||||||
|  | 					this.operating = false; | ||||||
|  | 					this.focus(); | ||||||
|  | 					dispose(); | ||||||
|  | 				} | ||||||
|  | 			}); | ||||||
| 		}, | 		}, | ||||||
| 
 | 
 | ||||||
| 		reactDirectly(reaction) { | 		reactDirectly(reaction) { | ||||||
|  | @ -734,9 +745,13 @@ export default defineComponent({ | ||||||
| 		}, | 		}, | ||||||
| 
 | 
 | ||||||
| 		menu(viaKeyboard = false) { | 		menu(viaKeyboard = false) { | ||||||
|  | 			this.operating = true; | ||||||
| 			os.modalMenu(this.getMenu(), this.$refs.menuButton, { | 			os.modalMenu(this.getMenu(), this.$refs.menuButton, { | ||||||
| 				viaKeyboard | 				viaKeyboard | ||||||
| 			}).then(this.focus); | 			}).then(() => { | ||||||
|  | 				this.operating = false; | ||||||
|  | 				this.focus(); | ||||||
|  | 			}); | ||||||
| 		}, | 		}, | ||||||
| 
 | 
 | ||||||
| 		showRenoteMenu(viaKeyboard = false) { | 		showRenoteMenu(viaKeyboard = false) { | ||||||
|  | @ -857,10 +872,8 @@ export default defineComponent({ | ||||||
| </script> | </script> | ||||||
| 
 | 
 | ||||||
| <style lang="scss" scoped> | <style lang="scss" scoped> | ||||||
| .note { | .vfzoeqcg { | ||||||
| 	position: relative; | 	position: relative; | ||||||
| 	transition: box-shadow 0.1s ease; |  | ||||||
| 	overflow: hidden; |  | ||||||
| 	contain: content; | 	contain: content; | ||||||
| 
 | 
 | ||||||
| 	// これらの指定はパフォーマンス向上には有効だが、ノートの高さは一定でないため、 | 	// これらの指定はパフォーマンス向上には有効だが、ノートの高さは一定でないため、 | ||||||
|  | @ -879,8 +892,10 @@ export default defineComponent({ | ||||||
| 		background: rgba(0, 0, 0, 0.05); | 		background: rgba(0, 0, 0, 0.05); | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	&:hover > .article > .main > .footer { | 	&:hover, &.operating { | ||||||
| 		display: block; | 		> .article > .main > .footer { | ||||||
|  | 			display: block; | ||||||
|  | 		} | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	&.renote { | 	&.renote { | ||||||
|  | @ -983,8 +998,8 @@ export default defineComponent({ | ||||||
| 		> .avatar { | 		> .avatar { | ||||||
| 			flex-shrink: 0; | 			flex-shrink: 0; | ||||||
| 			display: block; | 			display: block; | ||||||
| 			//position: sticky; | 			position: sticky; | ||||||
| 			//top: 72px; | 			top: 12px; | ||||||
| 			margin: 0 14px 0 0; | 			margin: 0 14px 0 0; | ||||||
| 			width: 46px; | 			width: 46px; | ||||||
| 			height: 46px; | 			height: 46px; | ||||||
|  | @ -1122,5 +1137,9 @@ export default defineComponent({ | ||||||
| .muted { | .muted { | ||||||
| 	padding: 8px 16px; | 	padding: 8px 16px; | ||||||
| 	opacity: 0.7; | 	opacity: 0.7; | ||||||
|  | 
 | ||||||
|  | 	&:hover { | ||||||
|  | 		background: rgba(0, 0, 0, 0.05); | ||||||
|  | 	} | ||||||
| } | } | ||||||
| </style> | </style> | ||||||
|  |  | ||||||
|  | @ -1,5 +1,5 @@ | ||||||
| <template> | <template> | ||||||
| <XNotes ref="tl" :pagination="pagination" @queue="$emit('queue', $event)" v-follow="pagination.reversed"/> | <XNotes class="dbiokgaf" ref="tl" :pagination="pagination" @queue="$emit('queue', $event)" v-follow="pagination.reversed"/> | ||||||
| </template> | </template> | ||||||
| 
 | 
 | ||||||
| <script lang="ts"> | <script lang="ts"> | ||||||
|  | @ -188,3 +188,9 @@ export default defineComponent({ | ||||||
| 	} | 	} | ||||||
| }); | }); | ||||||
| </script> | </script> | ||||||
|  | 
 | ||||||
|  | <style lang="scss" scoped> | ||||||
|  | .dbiokgaf { | ||||||
|  | 	padding: 16px 0; | ||||||
|  | } | ||||||
|  | </style> | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue