wip
This commit is contained in:
		
							parent
							
								
									f5637205cb
								
							
						
					
					
						commit
						7a97924d01
					
				|  | @ -18,6 +18,7 @@ import messaging from './messaging.vue'; | |||
| import messagingRoom from './messaging-room.vue'; | ||||
| import urlPreview from './url-preview.vue'; | ||||
| import twitterSetting from './twitter-setting.vue'; | ||||
| import fileTypeIcon from './file-type-icon.vue'; | ||||
| 
 | ||||
| Vue.component('mk-signin', signin); | ||||
| Vue.component('mk-signup', signup); | ||||
|  | @ -37,3 +38,4 @@ Vue.component('mk-messaging', messaging); | |||
| Vue.component('mk-messaging-room', messagingRoom); | ||||
| Vue.component('mk-url-preview', urlPreview); | ||||
| Vue.component('mk-twitter-setting', twitterSetting); | ||||
| Vue.component('mk-file-type-icon', fileTypeIcon); | ||||
|  |  | |||
|  | @ -15,7 +15,7 @@ | |||
| 		</template> | ||||
| 	</div> | ||||
| 	<footer> | ||||
| 		<div ref="notifications"></div> | ||||
| 		<div ref="notifications" class="notifications"></div> | ||||
| 		<div class="grippie" title="%i18n:common.tags.mk-messaging-room.resize-form%"></div> | ||||
| 		<x-form :user="user"/> | ||||
| 	</footer> | ||||
|  | @ -278,7 +278,7 @@ export default Vue.extend({ | |||
| 		background rgba(255, 255, 255, 0.95) | ||||
| 		background-clip content-box | ||||
| 
 | ||||
| 		> [ref='notifications'] | ||||
| 		> .notifications | ||||
| 			position absolute | ||||
| 			top -48px | ||||
| 			width 100% | ||||
|  |  | |||
|  | @ -1,8 +1,8 @@ | |||
| <template> | ||||
| <div class="mk-post-menu"> | ||||
| 	<div class="backdrop" ref="backdrop" @click="close"></div> | ||||
| 	<div class="popover { compact: opts.compact }" ref="popover"> | ||||
| 		<button v-if="post.user_id === I.id" @click="pin">%i18n:common.tags.mk-post-menu.pin%</button> | ||||
| 	<div class="popover" :class="{ compact }" ref="popover"> | ||||
| 		<button v-if="post.user_id == os.i.id" @click="pin">%i18n:common.tags.mk-post-menu.pin%</button> | ||||
| 	</div> | ||||
| </div> | ||||
| </template> | ||||
|  | @ -14,36 +14,38 @@ import * as anime from 'animejs'; | |||
| export default Vue.extend({ | ||||
| 	props: ['post', 'source', 'compact'], | ||||
| 	mounted() { | ||||
| 		const popover = this.$refs.popover as any; | ||||
| 		this.$nextTick(() => { | ||||
| 			const popover = this.$refs.popover as any; | ||||
| 
 | ||||
| 		const rect = this.source.getBoundingClientRect(); | ||||
| 		const width = popover.offsetWidth; | ||||
| 		const height = popover.offsetHeight; | ||||
| 			const rect = this.source.getBoundingClientRect(); | ||||
| 			const width = popover.offsetWidth; | ||||
| 			const height = popover.offsetHeight; | ||||
| 
 | ||||
| 		if (this.compact) { | ||||
| 			const x = rect.left + window.pageXOffset + (this.source.offsetWidth / 2); | ||||
| 			const y = rect.top + window.pageYOffset + (this.source.offsetHeight / 2); | ||||
| 			popover.style.left = (x - (width / 2)) + 'px'; | ||||
| 			popover.style.top = (y - (height / 2)) + 'px'; | ||||
| 		} else { | ||||
| 			const x = rect.left + window.pageXOffset + (this.source.offsetWidth / 2); | ||||
| 			const y = rect.top + window.pageYOffset + this.source.offsetHeight; | ||||
| 			popover.style.left = (x - (width / 2)) + 'px'; | ||||
| 			popover.style.top = y + 'px'; | ||||
| 		} | ||||
| 			if (this.compact) { | ||||
| 				const x = rect.left + window.pageXOffset + (this.source.offsetWidth / 2); | ||||
| 				const y = rect.top + window.pageYOffset + (this.source.offsetHeight / 2); | ||||
| 				popover.style.left = (x - (width / 2)) + 'px'; | ||||
| 				popover.style.top = (y - (height / 2)) + 'px'; | ||||
| 			} else { | ||||
| 				const x = rect.left + window.pageXOffset + (this.source.offsetWidth / 2); | ||||
| 				const y = rect.top + window.pageYOffset + this.source.offsetHeight; | ||||
| 				popover.style.left = (x - (width / 2)) + 'px'; | ||||
| 				popover.style.top = y + 'px'; | ||||
| 			} | ||||
| 
 | ||||
| 		anime({ | ||||
| 			targets: this.$refs.backdrop, | ||||
| 			opacity: 1, | ||||
| 			duration: 100, | ||||
| 			easing: 'linear' | ||||
| 		}); | ||||
| 			anime({ | ||||
| 				targets: this.$refs.backdrop, | ||||
| 				opacity: 1, | ||||
| 				duration: 100, | ||||
| 				easing: 'linear' | ||||
| 			}); | ||||
| 
 | ||||
| 		anime({ | ||||
| 			targets: this.$refs.popover, | ||||
| 			opacity: 1, | ||||
| 			scale: [0.5, 1], | ||||
| 			duration: 500 | ||||
| 			anime({ | ||||
| 				targets: this.$refs.popover, | ||||
| 				opacity: 1, | ||||
| 				scale: [0.5, 1], | ||||
| 				duration: 500 | ||||
| 			}); | ||||
| 		}); | ||||
| 	}, | ||||
| 	methods: { | ||||
|  | @ -134,5 +136,6 @@ $border-color = rgba(27, 31, 35, 0.15) | |||
| 
 | ||||
| 		> button | ||||
| 			display block | ||||
| 			padding 16px | ||||
| 
 | ||||
| </style> | ||||
|  |  | |||
|  | @ -8,7 +8,10 @@ | |||
| 			<router-link class="avatar-anchor" :to="`/${post.user.username}`" v-user-preview="post.user_id"> | ||||
| 				<img class="avatar" :src="`${post.user.avatar_url}?thumbnail&size=32`" alt="avatar"/> | ||||
| 			</router-link> | ||||
| 			%fa:retweet%{{'%i18n:desktop.tags.mk-timeline-post.reposted-by%'.substr(0, '%i18n:desktop.tags.mk-timeline-post.reposted-by%'.indexOf('{'))}}<a class="name" :href="`/${post.user.username}`" v-user-preview="post.user_id">{{ post.user.name }}</a>{{'%i18n:desktop.tags.mk-timeline-post.reposted-by%'.substr('%i18n:desktop.tags.mk-timeline-post.reposted-by%'.indexOf('}') + 1)}} | ||||
| 			%fa:retweet% | ||||
| 			{{ '%i18n:desktop.tags.mk-timeline-post.reposted-by%'.substr(0, '%i18n:desktop.tags.mk-timeline-post.reposted-by%'.indexOf('{')) }} | ||||
| 			<a class="name" :href="`/${post.user.username}`" v-user-preview="post.user_id">{{ post.user.name }}</a> | ||||
| 			{{ '%i18n:desktop.tags.mk-timeline-post.reposted-by%'.substr('%i18n:desktop.tags.mk-timeline-post.reposted-by%'.indexOf('}') + 1) }} | ||||
| 		</p> | ||||
| 		<mk-time :time="post.created_at"/> | ||||
| 	</div> | ||||
|  |  | |||
|  | @ -4,10 +4,10 @@ | |||
| 		<header> | ||||
| 			<h1>%i18n:mobile.tags.mk-drive-selector.select-file%<span class="count" v-if="files.length > 0">({{ files.length }})</span></h1> | ||||
| 			<button class="close" @click="cancel">%fa:times%</button> | ||||
| 			<button v-if="opts.multiple" class="ok" @click="ok">%fa:check%</button> | ||||
| 			<button v-if="multiple" class="ok" @click="ok">%fa:check%</button> | ||||
| 		</header> | ||||
| 		<mk-drive ref="browser" | ||||
| 			select-file | ||||
| 			:select-file="true" | ||||
| 			:multiple="multiple" | ||||
| 			@change-selection="onChangeSelection" | ||||
| 			@selected="onSelected" | ||||
|  |  | |||
|  | @ -1,5 +1,5 @@ | |||
| <template> | ||||
| <a class="folder" @click.prevent="onClick" :href="`/i/drive/folder/${ folder.id }`"> | ||||
| <a class="root folder" @click.prevent="onClick" :href="`/i/drive/folder/${ folder.id }`"> | ||||
| 	<div class="container"> | ||||
| 		<p class="name">%fa:folder%{{ folder.name }}</p>%fa:angle-right% | ||||
| 	</div> | ||||
|  | @ -24,7 +24,7 @@ export default Vue.extend({ | |||
| </script> | ||||
| 
 | ||||
| <style lang="stylus" scoped> | ||||
| .folder | ||||
| .root.folder | ||||
| 	display block | ||||
| 	color #777 | ||||
| 	text-decoration none !important | ||||
|  |  | |||
|  | @ -26,11 +26,11 @@ | |||
| 			</p> | ||||
| 		</div> | ||||
| 		<div class="folders" v-if="folders.length > 0"> | ||||
| 			<mk-drive-folder v-for="folder in folders" :key="folder.id" :folder="folder"/> | ||||
| 			<x-folder v-for="folder in folders" :key="folder.id" :folder="folder"/> | ||||
| 			<p v-if="moreFolders">%i18n:mobile.tags.mk-drive.load-more%</p> | ||||
| 		</div> | ||||
| 		<div class="files" v-if="files.length > 0"> | ||||
| 			<mk-drive-file v-for="file in files" :key="file.id" :file="file"/> | ||||
| 			<x-file v-for="file in files" :key="file.id" :file="file"/> | ||||
| 			<button class="more" v-if="moreFiles" @click="fetchMoreFiles"> | ||||
| 				{{ fetchingMoreFiles ? '%i18n:common.loading%' : '%i18n:mobile.tags.mk-drive.load-more%' }} | ||||
| 			</button> | ||||
|  | @ -46,15 +46,23 @@ | |||
| 			<div class="dot2"></div> | ||||
| 		</div> | ||||
| 	</div> | ||||
| 	<input ref="file" type="file" multiple="multiple" @change="onChangeLocalFile"/> | ||||
| 	<mk-drive-file-detail v-if="file != null" :file="file"/> | ||||
| 	<input ref="file" class="file" type="file" multiple="multiple" @change="onChangeLocalFile"/> | ||||
| 	<x-file-detail v-if="file != null" :file="file"/> | ||||
| </div> | ||||
| </template> | ||||
| 
 | ||||
| <script lang="ts"> | ||||
| import Vue from 'vue'; | ||||
| import XFolder from './drive.folder.vue'; | ||||
| import XFile from './drive.file.vue'; | ||||
| import XFileDetail from './drive.file-detail.vue'; | ||||
| 
 | ||||
| export default Vue.extend({ | ||||
| 	components: { | ||||
| 		XFolder, | ||||
| 		XFile, | ||||
| 		XFileDetail | ||||
| 	}, | ||||
| 	props: ['initFolder', 'initFile', 'selectFile', 'multiple', 'isNaked', 'top'], | ||||
| 	data() { | ||||
| 		return { | ||||
|  | @ -423,8 +431,7 @@ export default Vue.extend({ | |||
| 				alert('現在いる場所はルートで、フォルダではないため移動はできません。移動したいフォルダに移動してからやってください。'); | ||||
| 				return; | ||||
| 			} | ||||
| 			const dialog = riot.mount(document.body.appendChild(document.createElement('mk-drive-folder-selector')))[0]; | ||||
| 			dialog.one('selected', folder => { | ||||
| 			(this as any).apis.chooseDriveFolder().then(folder => { | ||||
| 				(this as any).api('drive/folders/update', { | ||||
| 					parent_id: folder ? folder.id : null, | ||||
| 					folder_id: this.folder.id | ||||
|  | @ -510,11 +517,11 @@ export default Vue.extend({ | |||
| 				color #777 | ||||
| 
 | ||||
| 		> .folders | ||||
| 			> .mk-drive-folder | ||||
| 			> .folder | ||||
| 				border-bottom solid 1px #eee | ||||
| 
 | ||||
| 		> .files | ||||
| 			> .mk-drive-file | ||||
| 			> .file | ||||
| 				border-bottom solid 1px #eee | ||||
| 
 | ||||
| 			> .more | ||||
|  | @ -568,7 +575,7 @@ export default Vue.extend({ | |||
| 			} | ||||
| 		} | ||||
| 
 | ||||
| 	> [ref='file'] | ||||
| 	> .file | ||||
| 		display none | ||||
| 
 | ||||
| </style> | ||||
|  |  | |||
|  | @ -5,9 +5,11 @@ import home from './home.vue'; | |||
| import timeline from './timeline.vue'; | ||||
| import posts from './posts.vue'; | ||||
| import imagesImage from './images-image.vue'; | ||||
| import drive from './drive.vue'; | ||||
| 
 | ||||
| Vue.component('mk-ui', ui); | ||||
| Vue.component('mk-home', home); | ||||
| Vue.component('mk-timeline', timeline); | ||||
| Vue.component('mk-posts', posts); | ||||
| Vue.component('mk-images-image', imagesImage); | ||||
| Vue.component('mk-drive', drive); | ||||
|  |  | |||
|  | @ -3,37 +3,40 @@ | |||
| 	<header> | ||||
| 		<button class="cancel" @click="cancel">%fa:times%</button> | ||||
| 		<div> | ||||
| 			<span v-if="refs.text" class="text-count" :class="{ over: refs.text.value.length > 1000 }">{{ 1000 - refs.text.value.length }}</span> | ||||
| 			<button class="submit" @click="post">%i18n:mobile.tags.mk-post-form.submit%</button> | ||||
| 			<span class="text-count" :class="{ over: text.length > 1000 }">{{ 1000 - text.length }}</span> | ||||
| 			<button class="submit" :disabled="posting" @click="post">%i18n:mobile.tags.mk-post-form.submit%</button> | ||||
| 		</div> | ||||
| 	</header> | ||||
| 	<div class="form"> | ||||
| 		<mk-post-preview v-if="reply" :post="reply"/> | ||||
| 		<textarea v-model="text" :disabled="wait" :placeholder="reply ? '%i18n:mobile.tags.mk-post-form.reply-placeholder%' : '%i18n:mobile.tags.mk-post-form.post-placeholder%'"></textarea> | ||||
| 		<textarea v-model="text" ref="text" :disabled="posting" :placeholder="reply ? '%i18n:mobile.tags.mk-post-form.reply-placeholder%' : '%i18n:mobile.tags.mk-post-form.post-placeholder%'"></textarea> | ||||
| 		<div class="attaches" v-show="files.length != 0"> | ||||
| 			<ul class="files" ref="attaches"> | ||||
| 				<li class="file" v-for="file in files"> | ||||
| 					<div class="img" :style="`background-image: url(${file.url}?thumbnail&size=128)`" @click="removeFile(file)"></div> | ||||
| 				</li> | ||||
| 			</ul> | ||||
| 			<x-draggable class="files" :list="files" :options="{ animation: 150 }"> | ||||
| 				<div class="file" v-for="file in files" :key="file.id"> | ||||
| 					<div class="img" :style="`background-image: url(${file.url}?thumbnail&size=128)`" @click="detachMedia(file)"></div> | ||||
| 				</div> | ||||
| 			</x-draggable> | ||||
| 		</div> | ||||
| 		<mk-poll-editor v-if="poll" ref="poll"/> | ||||
| 		<mk-uploader @uploaded="attachMedia" @change="onChangeUploadings"/> | ||||
| 		<button ref="upload" @click="selectFile">%fa:upload%</button> | ||||
| 		<button ref="drive" @click="selectFileFromDrive">%fa:cloud%</button> | ||||
| 		<mk-uploader ref="uploader" @uploaded="attachMedia" @change="onChangeUploadings"/> | ||||
| 		<button class="upload" @click="chooseFile">%fa:upload%</button> | ||||
| 		<button class="drive" @click="chooseFileFromDrive">%fa:cloud%</button> | ||||
| 		<button class="kao" @click="kao">%fa:R smile%</button> | ||||
| 		<button class="poll" @click="addPoll">%fa:chart-pie%</button> | ||||
| 		<input ref="file" type="file" accept="image/*" multiple="multiple" @change="onChangeFile"/> | ||||
| 		<button class="poll" @click="poll = true">%fa:chart-pie%</button> | ||||
| 		<input ref="file" class="file" type="file" accept="image/*" multiple="multiple" @change="onChangeFile"/> | ||||
| 	</div> | ||||
| </div> | ||||
| </template> | ||||
| 
 | ||||
| <script lang="ts"> | ||||
| import Vue from 'vue'; | ||||
| import Sortable from 'sortablejs'; | ||||
| import * as XDraggable from 'vuedraggable'; | ||||
| import getKao from '../../../common/scripts/get-kao'; | ||||
| 
 | ||||
| export default Vue.extend({ | ||||
| 	components: { | ||||
| 		XDraggable | ||||
| 	}, | ||||
| 	props: ['reply'], | ||||
| 	data() { | ||||
| 		return { | ||||
|  | @ -45,19 +48,27 @@ export default Vue.extend({ | |||
| 		}; | ||||
| 	}, | ||||
| 	mounted() { | ||||
| 		(this.$refs.text as any).focus(); | ||||
| 
 | ||||
| 		new Sortable(this.$refs.attaches, { | ||||
| 			animation: 150 | ||||
| 		this.$nextTick(() => { | ||||
| 			(this.$refs.text as any).focus(); | ||||
| 		}); | ||||
| 	}, | ||||
| 	methods: { | ||||
| 		chooseFile() { | ||||
| 			(this.$refs.file as any).click(); | ||||
| 		}, | ||||
| 		chooseFileFromDrive() { | ||||
| 			(this as any).apis.chooseDriveFile({ | ||||
| 				multiple: true | ||||
| 			}).then(files => { | ||||
| 				files.forEach(this.attachMedia); | ||||
| 			}); | ||||
| 		}, | ||||
| 		attachMedia(driveFile) { | ||||
| 			this.files.push(driveFile); | ||||
| 			this.$emit('change-attached-media', this.files); | ||||
| 		}, | ||||
| 		detachMedia(id) { | ||||
| 			this.files = this.files.filter(x => x.id != id); | ||||
| 		detachMedia(file) { | ||||
| 			this.files = this.files.filter(x => x.id != file.id); | ||||
| 			this.$emit('change-attached-media', this.files); | ||||
| 		}, | ||||
| 		onChangeFile() { | ||||
|  | @ -75,6 +86,20 @@ export default Vue.extend({ | |||
| 			this.poll = false; | ||||
| 			this.$emit('change-attached-media'); | ||||
| 		}, | ||||
| 		post() { | ||||
| 			this.posting = true; | ||||
| 			(this as any).api('posts/create', { | ||||
| 				text: this.text == '' ? undefined : this.text, | ||||
| 				media_ids: this.files.length > 0 ? this.files.map(f => f.id) : undefined, | ||||
| 				reply_id: this.reply ? this.reply.id : undefined, | ||||
| 				poll: this.poll ? (this.$refs.poll as any).get() : undefined | ||||
| 			}).then(data => { | ||||
| 				this.$emit('post'); | ||||
| 				this.$destroy(); | ||||
| 			}).catch(err => { | ||||
| 				this.posting = false; | ||||
| 			}); | ||||
| 		}, | ||||
| 		cancel() { | ||||
| 			this.$emit('cancel'); | ||||
| 			this.$destroy(); | ||||
|  | @ -167,10 +192,10 @@ export default Vue.extend({ | |||
| 			margin 8px 0 0 0 | ||||
| 			padding 8px | ||||
| 
 | ||||
| 		> [ref='file'] | ||||
| 		> .file | ||||
| 			display none | ||||
| 
 | ||||
| 		> [ref='text'] | ||||
| 		> textarea | ||||
| 			display block | ||||
| 			padding 12px | ||||
| 			margin 0 | ||||
|  | @ -187,8 +212,8 @@ export default Vue.extend({ | |||
| 			&:disabled | ||||
| 				opacity 0.5 | ||||
| 
 | ||||
| 		> [ref='upload'] | ||||
| 		> [ref='drive'] | ||||
| 		> .upload | ||||
| 		> .drive | ||||
| 		.kao | ||||
| 		.poll | ||||
| 			display inline-block | ||||
|  |  | |||
|  | @ -1,117 +0,0 @@ | |||
| <template> | ||||
| <div class="mk-posts-post-sub"> | ||||
| 	<article> | ||||
| 		<a class="avatar-anchor" href={ '/' + post.user.username }> | ||||
| 			<img class="avatar" src={ post.user.avatar_url + '?thumbnail&size=96' } alt="avatar"/> | ||||
| 		</a> | ||||
| 		<div class="main"> | ||||
| 			<header> | ||||
| 				<a class="name" href={ '/' + post.user.username }>{ post.user.name }</a> | ||||
| 				<span class="username">@{ post.user.username }</span> | ||||
| 				<a class="created-at" href={ '/' + post.user.username + '/' + post.id }> | ||||
| 					<mk-time time={ post.created_at }/> | ||||
| 				</a> | ||||
| 			</header> | ||||
| 			<div class="body"> | ||||
| 				<mk-sub-post-content class="text" post={ post }/> | ||||
| 			</div> | ||||
| 		</div> | ||||
| 	</article> | ||||
| </div> | ||||
| </template> | ||||
| 
 | ||||
| <script lang="ts"> | ||||
| import Vue from 'vue'; | ||||
| export default Vue.extend({ | ||||
| 	props: ['post'] | ||||
| }); | ||||
| </script> | ||||
| 
 | ||||
| 
 | ||||
| <style lang="stylus" scoped> | ||||
| .mk-posts-post-sub | ||||
| 	font-size 0.9em | ||||
| 
 | ||||
| 	> article | ||||
| 		padding 16px | ||||
| 
 | ||||
| 		&:after | ||||
| 			content "" | ||||
| 			display block | ||||
| 			clear both | ||||
| 
 | ||||
| 		&:hover | ||||
| 			> .main > footer > button | ||||
| 				color #888 | ||||
| 
 | ||||
| 		> .avatar-anchor | ||||
| 			display block | ||||
| 			float left | ||||
| 			margin 0 10px 0 0 | ||||
| 
 | ||||
| 			@media (min-width 500px) | ||||
| 				margin-right 16px | ||||
| 
 | ||||
| 			> .avatar | ||||
| 				display block | ||||
| 				width 44px | ||||
| 				height 44px | ||||
| 				margin 0 | ||||
| 				border-radius 8px | ||||
| 				vertical-align bottom | ||||
| 
 | ||||
| 				@media (min-width 500px) | ||||
| 					width 52px | ||||
| 					height 52px | ||||
| 
 | ||||
| 		> .main | ||||
| 			float left | ||||
| 			width calc(100% - 54px) | ||||
| 
 | ||||
| 			@media (min-width 500px) | ||||
| 				width calc(100% - 68px) | ||||
| 
 | ||||
| 			> header | ||||
| 				display flex | ||||
| 				margin-bottom 2px | ||||
| 				white-space nowrap | ||||
| 
 | ||||
| 				> .name | ||||
| 					display block | ||||
| 					margin 0 0.5em 0 0 | ||||
| 					padding 0 | ||||
| 					overflow hidden | ||||
| 					color #607073 | ||||
| 					font-size 1em | ||||
| 					font-weight 700 | ||||
| 					text-align left | ||||
| 					text-decoration none | ||||
| 					text-overflow ellipsis | ||||
| 
 | ||||
| 					&:hover | ||||
| 						text-decoration underline | ||||
| 
 | ||||
| 				> .username | ||||
| 					text-align left | ||||
| 					margin 0 | ||||
| 					color #d1d8da | ||||
| 
 | ||||
| 				> .created-at | ||||
| 					margin-left auto | ||||
| 					color #b2b8bb | ||||
| 
 | ||||
| 			> .body | ||||
| 
 | ||||
| 				> .text | ||||
| 					cursor default | ||||
| 					margin 0 | ||||
| 					padding 0 | ||||
| 					font-size 1.1em | ||||
| 					color #717171 | ||||
| 
 | ||||
| 					pre | ||||
| 						max-height 120px | ||||
| 						font-size 80% | ||||
| 
 | ||||
| </style> | ||||
| 
 | ||||
|  | @ -0,0 +1,108 @@ | |||
| <template> | ||||
| <div class="sub"> | ||||
| 	<router-link class="avatar-anchor" :to="`/${post.user.username}`"> | ||||
| 		<img class="avatar" :src="`${post.user.avatar_url}?thumbnail&size=96`" alt="avatar"/> | ||||
| 	</router-link> | ||||
| 	<div class="main"> | ||||
| 		<header> | ||||
| 			<router-link class="name" :to="`/${post.user.username}`">{{ post.user.name }}</router-link> | ||||
| 			<span class="username">@{{ post.user.username }}</span> | ||||
| 			<router-link class="created-at" :href="`/${post.user.username}/${post.id}`"> | ||||
| 				<mk-time :time="post.created_at"/> | ||||
| 			</router-link> | ||||
| 		</header> | ||||
| 		<div class="body"> | ||||
| 			<mk-sub-post-content class="text" :post="post"/> | ||||
| 		</div> | ||||
| 	</div> | ||||
| </div> | ||||
| </template> | ||||
| 
 | ||||
| <script lang="ts"> | ||||
| import Vue from 'vue'; | ||||
| export default Vue.extend({ | ||||
| 	props: ['post'] | ||||
| }); | ||||
| </script> | ||||
| 
 | ||||
| <style lang="stylus" scoped> | ||||
| .sub | ||||
| 	font-size 0.9em | ||||
| 	padding 16px | ||||
| 
 | ||||
| 	&:after | ||||
| 		content "" | ||||
| 		display block | ||||
| 		clear both | ||||
| 
 | ||||
| 	> .avatar-anchor | ||||
| 		display block | ||||
| 		float left | ||||
| 		margin 0 10px 0 0 | ||||
| 
 | ||||
| 		@media (min-width 500px) | ||||
| 			margin-right 16px | ||||
| 
 | ||||
| 		> .avatar | ||||
| 			display block | ||||
| 			width 44px | ||||
| 			height 44px | ||||
| 			margin 0 | ||||
| 			border-radius 8px | ||||
| 			vertical-align bottom | ||||
| 
 | ||||
| 			@media (min-width 500px) | ||||
| 				width 52px | ||||
| 				height 52px | ||||
| 
 | ||||
| 	> .main | ||||
| 		float left | ||||
| 		width calc(100% - 54px) | ||||
| 
 | ||||
| 		@media (min-width 500px) | ||||
| 			width calc(100% - 68px) | ||||
| 
 | ||||
| 		> header | ||||
| 			display flex | ||||
| 			margin-bottom 2px | ||||
| 			white-space nowrap | ||||
| 
 | ||||
| 			> .name | ||||
| 				display block | ||||
| 				margin 0 0.5em 0 0 | ||||
| 				padding 0 | ||||
| 				overflow hidden | ||||
| 				color #607073 | ||||
| 				font-size 1em | ||||
| 				font-weight 700 | ||||
| 				text-align left | ||||
| 				text-decoration none | ||||
| 				text-overflow ellipsis | ||||
| 
 | ||||
| 				&:hover | ||||
| 					text-decoration underline | ||||
| 
 | ||||
| 			> .username | ||||
| 				text-align left | ||||
| 				margin 0 | ||||
| 				color #d1d8da | ||||
| 
 | ||||
| 			> .created-at | ||||
| 				margin-left auto | ||||
| 				color #b2b8bb | ||||
| 
 | ||||
| 		> .body | ||||
| 
 | ||||
| 			> .text | ||||
| 				cursor default | ||||
| 				margin 0 | ||||
| 				padding 0 | ||||
| 				font-size 1.1em | ||||
| 				color #717171 | ||||
| 
 | ||||
| 				pre | ||||
| 					max-height 120px | ||||
| 					font-size 80% | ||||
| 
 | ||||
| </style> | ||||
| 
 | ||||
|  | @ -69,8 +69,14 @@ | |||
| 
 | ||||
| <script lang="ts"> | ||||
| import Vue from 'vue'; | ||||
| import MkPostMenu from '../../../common/views/components/post-menu.vue'; | ||||
| import MkReactionPicker from '../../../common/views/components/reaction-picker.vue'; | ||||
| import XSub from './posts.post.sub.vue'; | ||||
| 
 | ||||
| export default Vue.extend({ | ||||
| 	components: { | ||||
| 		XSub | ||||
| 	}, | ||||
| 	props: ['post'], | ||||
| 	data() { | ||||
| 		return { | ||||
|  | @ -152,6 +158,34 @@ export default Vue.extend({ | |||
| 				this.$emit('update:post', post); | ||||
| 			} | ||||
| 		}, | ||||
| 		reply() { | ||||
| 			(this as any).apis.post({ | ||||
| 				reply: this.p | ||||
| 			}); | ||||
| 		}, | ||||
| 		repost() { | ||||
| 			(this as any).apis.post({ | ||||
| 				repost: this.p | ||||
| 			}); | ||||
| 		}, | ||||
| 		react() { | ||||
| 			document.body.appendChild(new MkReactionPicker({ | ||||
| 				propsData: { | ||||
| 					source: this.$refs.reactButton, | ||||
| 					post: this.p, | ||||
| 					compact: true | ||||
| 				} | ||||
| 			}).$mount().$el); | ||||
| 		}, | ||||
| 		menu() { | ||||
| 			document.body.appendChild(new MkPostMenu({ | ||||
| 				propsData: { | ||||
| 					source: this.$refs.menuButton, | ||||
| 					post: this.p, | ||||
| 					compact: true | ||||
| 				} | ||||
| 			}).$mount().$el); | ||||
| 		} | ||||
| 	} | ||||
| }); | ||||
| </script> | ||||
|  |  | |||
|  | @ -9,7 +9,7 @@ | |||
| 			%fa:R comments% | ||||
| 			%i18n:mobile.tags.mk-home-timeline.empty-timeline% | ||||
| 		</div> | ||||
| 		<button v-if="canFetchMore" @click="more" :disabled="fetching" slot="tail"> | ||||
| 		<button @click="more" :disabled="fetching" slot="tail"> | ||||
| 			<span v-if="!fetching">%i18n:mobile.tags.mk-timeline.load-more%</span> | ||||
| 			<span v-if="fetching">%i18n:common.loading%<mk-ellipsis/></span> | ||||
| 		</button> | ||||
|  |  | |||
|  | @ -24,7 +24,6 @@ export default Vue.extend({ | |||
| 	props: ['func'], | ||||
| 	data() { | ||||
| 		return { | ||||
| 			func: null, | ||||
| 			hasUnreadNotifications: false, | ||||
| 			hasUnreadMessagingMessages: false, | ||||
| 			connection: null, | ||||
|  |  | |||
|  | @ -1,6 +1,6 @@ | |||
| <template> | ||||
| <div class="nav" :style="{ display: isOpen ? 'block' : 'none' }"> | ||||
| 	<div class="backdrop" @click="parent.toggleDrawer"></div> | ||||
| 	<div class="backdrop" @click="$parent.isDrawerOpening = false"></div> | ||||
| 	<div class="body"> | ||||
| 		<router-link class="me" v-if="os.isSignedIn" :to="`/${os.i.username}`"> | ||||
| 			<img class="avatar" :src="`${os.i.avatar_url}?thumbnail&size=128`" alt="avatar"/> | ||||
|  | @ -8,36 +8,40 @@ | |||
| 		</router-link> | ||||
| 		<div class="links"> | ||||
| 			<ul> | ||||
| 				<li><router-link href="/">%fa:home%%i18n:mobile.tags.mk-ui-nav.home%%fa:angle-right%</router-link></li> | ||||
| 				<li><router-link href="/i/notifications">%fa:R bell%%i18n:mobile.tags.mk-ui-nav.notifications%<template v-if="hasUnreadNotifications">%fa:circle%</template>%fa:angle-right%</router-link></li> | ||||
| 				<li><router-link href="/i/messaging">%fa:R comments%%i18n:mobile.tags.mk-ui-nav.messaging%<template v-if="hasUnreadMessagingMessages">%fa:circle%</template>%fa:angle-right%</router-link></li> | ||||
| 				<li><router-link to="/">%fa:home%%i18n:mobile.tags.mk-ui-nav.home%%fa:angle-right%</router-link></li> | ||||
| 				<li><router-link to="/i/notifications">%fa:R bell%%i18n:mobile.tags.mk-ui-nav.notifications%<template v-if="hasUnreadNotifications">%fa:circle%</template>%fa:angle-right%</router-link></li> | ||||
| 				<li><router-link to="/i/messaging">%fa:R comments%%i18n:mobile.tags.mk-ui-nav.messaging%<template v-if="hasUnreadMessagingMessages">%fa:circle%</template>%fa:angle-right%</router-link></li> | ||||
| 			</ul> | ||||
| 			<ul> | ||||
| 				<li><a :href="chUrl" target="_blank">%fa:tv%%i18n:mobile.tags.mk-ui-nav.ch%%fa:angle-right%</a></li> | ||||
| 				<li><router-link href="/i/drive">%fa:cloud%%i18n:mobile.tags.mk-ui-nav.drive%%fa:angle-right%</router-link></li> | ||||
| 				<li><router-link to="/i/drive">%fa:cloud%%i18n:mobile.tags.mk-ui-nav.drive%%fa:angle-right%</router-link></li> | ||||
| 			</ul> | ||||
| 			<ul> | ||||
| 				<li><a @click="search">%fa:search%%i18n:mobile.tags.mk-ui-nav.search%%fa:angle-right%</a></li> | ||||
| 			</ul> | ||||
| 			<ul> | ||||
| 				<li><router-link href="/i/settings">%fa:cog%%i18n:mobile.tags.mk-ui-nav.settings%%fa:angle-right%</router-link></li> | ||||
| 				<li><router-link to="/i/settings">%fa:cog%%i18n:mobile.tags.mk-ui-nav.settings%%fa:angle-right%</router-link></li> | ||||
| 			</ul> | ||||
| 		</div> | ||||
| 		<a :href="aboutUrl"><p class="about">%i18n:mobile.tags.mk-ui-nav.about%</p></a> | ||||
| 		<a :href="docsUrl"><p class="about">%i18n:mobile.tags.mk-ui-nav.about%</p></a> | ||||
| 	</div> | ||||
| </div> | ||||
| </template> | ||||
| 
 | ||||
| <script lang="ts"> | ||||
| import Vue from 'vue'; | ||||
| import { docsUrl, chUrl } from '../../../config'; | ||||
| 
 | ||||
| export default Vue.extend({ | ||||
| 	props: ['isOpen'], | ||||
| 	data() { | ||||
| 		return { | ||||
| 			hasUnreadNotifications: false, | ||||
| 			hasUnreadMessagingMessages: false, | ||||
| 			connection: null, | ||||
| 			connectionId: null | ||||
| 			connectionId: null, | ||||
| 			docsUrl, | ||||
| 			chUrl | ||||
| 		}; | ||||
| 	}, | ||||
| 	mounted() { | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue