wip
This commit is contained in:
		
							parent
							
								
									cb0d237b6a
								
							
						
					
					
						commit
						b0c7cb8803
					
				
					 6 changed files with 117 additions and 6 deletions
				
			
		| 
						 | 
					@ -39,6 +39,18 @@ module.exports = (params, user: IUser, app) => new Promise(async (res, rej) => {
 | 
				
			||||||
	const [tags = [], tagsErr] = $(params.tags).optional.array('string').unique().eachQ(t => t.range(1, 32)).$;
 | 
						const [tags = [], tagsErr] = $(params.tags).optional.array('string').unique().eachQ(t => t.range(1, 32)).$;
 | 
				
			||||||
	if (tagsErr) return rej('invalid tags');
 | 
						if (tagsErr) return rej('invalid tags');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Get 'geo' parameter
 | 
				
			||||||
 | 
						const [geo, geoErr] = $(params.geo).optional.nullable.strict.object()
 | 
				
			||||||
 | 
							.have('latitude', $().number().range(-180, 180))
 | 
				
			||||||
 | 
							.have('longitude', $().number().range(-90, 90))
 | 
				
			||||||
 | 
							.have('altitude', $().nullable.number())
 | 
				
			||||||
 | 
							.have('accuracy', $().nullable.number())
 | 
				
			||||||
 | 
							.have('altitudeAccuracy', $().nullable.number())
 | 
				
			||||||
 | 
							.have('heading', $().nullable.number().range(0, 360))
 | 
				
			||||||
 | 
							.have('speed', $().nullable.number())
 | 
				
			||||||
 | 
							.$;
 | 
				
			||||||
 | 
						if (geoErr) return rej('invalid geo');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// Get 'media_ids' parameter
 | 
						// Get 'media_ids' parameter
 | 
				
			||||||
	const [mediaIds, mediaIdsErr] = $(params.media_ids).optional.array('id').unique().range(1, 4).$;
 | 
						const [mediaIds, mediaIdsErr] = $(params.media_ids).optional.array('id').unique().range(1, 4).$;
 | 
				
			||||||
	if (mediaIdsErr) return rej('invalid media_ids');
 | 
						if (mediaIdsErr) return rej('invalid media_ids');
 | 
				
			||||||
| 
						 | 
					@ -244,6 +256,7 @@ module.exports = (params, user: IUser, app) => new Promise(async (res, rej) => {
 | 
				
			||||||
		user_id: user._id,
 | 
							user_id: user._id,
 | 
				
			||||||
		app_id: app ? app._id : null,
 | 
							app_id: app ? app._id : null,
 | 
				
			||||||
		via_mobile: viaMobile,
 | 
							via_mobile: viaMobile,
 | 
				
			||||||
 | 
							geo,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		// 以下非正規化データ
 | 
							// 以下非正規化データ
 | 
				
			||||||
		_reply: reply ? { user_id: reply.user_id } : undefined,
 | 
							_reply: reply ? { user_id: reply.user_id } : undefined,
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -32,6 +32,15 @@ export type IPost = {
 | 
				
			||||||
	category: string;
 | 
						category: string;
 | 
				
			||||||
	is_category_verified: boolean;
 | 
						is_category_verified: boolean;
 | 
				
			||||||
	via_mobile: boolean;
 | 
						via_mobile: boolean;
 | 
				
			||||||
 | 
						geo: {
 | 
				
			||||||
 | 
							latitude: number;
 | 
				
			||||||
 | 
							longitude: number;
 | 
				
			||||||
 | 
							altitude: number;
 | 
				
			||||||
 | 
							accuracy: number;
 | 
				
			||||||
 | 
							altitudeAccuracy: number;
 | 
				
			||||||
 | 
							heading: number;
 | 
				
			||||||
 | 
							speed: number;
 | 
				
			||||||
 | 
						};
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,6 +1,7 @@
 | 
				
			||||||
<template>
 | 
					<template>
 | 
				
			||||||
<mk-window ref="window" is-modal @closed="$destroy">
 | 
					<mk-window ref="window" is-modal @closed="$destroy">
 | 
				
			||||||
	<span slot="header">
 | 
						<span slot="header">
 | 
				
			||||||
 | 
							<span :class="$style.icon" v-if="geo">%fa:map-marker-alt%</span>
 | 
				
			||||||
		<span v-if="!reply">%i18n:desktop.tags.mk-post-form-window.post%</span>
 | 
							<span v-if="!reply">%i18n:desktop.tags.mk-post-form-window.post%</span>
 | 
				
			||||||
		<span v-if="reply">%i18n:desktop.tags.mk-post-form-window.reply%</span>
 | 
							<span v-if="reply">%i18n:desktop.tags.mk-post-form-window.reply%</span>
 | 
				
			||||||
		<span :class="$style.count" v-if="media.length != 0">{{ '%i18n:desktop.tags.mk-post-form-window.attaches%'.replace('{}', media.length) }}</span>
 | 
							<span :class="$style.count" v-if="media.length != 0">{{ '%i18n:desktop.tags.mk-post-form-window.attaches%'.replace('{}', media.length) }}</span>
 | 
				
			||||||
| 
						 | 
					@ -12,7 +13,8 @@
 | 
				
			||||||
		:reply="reply"
 | 
							:reply="reply"
 | 
				
			||||||
		@posted="onPosted"
 | 
							@posted="onPosted"
 | 
				
			||||||
		@change-uploadings="onChangeUploadings"
 | 
							@change-uploadings="onChangeUploadings"
 | 
				
			||||||
		@change-attached-media="onChangeMedia"/>
 | 
							@change-attached-media="onChangeMedia"
 | 
				
			||||||
 | 
							@geo-attached="onGeoAttached"/>
 | 
				
			||||||
</mk-window>
 | 
					</mk-window>
 | 
				
			||||||
</template>
 | 
					</template>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -24,7 +26,8 @@ export default Vue.extend({
 | 
				
			||||||
	data() {
 | 
						data() {
 | 
				
			||||||
		return {
 | 
							return {
 | 
				
			||||||
			uploadings: [],
 | 
								uploadings: [],
 | 
				
			||||||
			media: []
 | 
								media: [],
 | 
				
			||||||
 | 
								geo: null
 | 
				
			||||||
		};
 | 
							};
 | 
				
			||||||
	},
 | 
						},
 | 
				
			||||||
	mounted() {
 | 
						mounted() {
 | 
				
			||||||
| 
						 | 
					@ -39,6 +42,9 @@ export default Vue.extend({
 | 
				
			||||||
		onChangeMedia(media) {
 | 
							onChangeMedia(media) {
 | 
				
			||||||
			this.media = media;
 | 
								this.media = media;
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
 | 
							onGeoAttached(geo) {
 | 
				
			||||||
 | 
								this.geo = geo;
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
		onPosted() {
 | 
							onPosted() {
 | 
				
			||||||
			(this.$refs.window as any).close();
 | 
								(this.$refs.window as any).close();
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
| 
						 | 
					@ -47,6 +53,9 @@ export default Vue.extend({
 | 
				
			||||||
</script>
 | 
					</script>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
<style lang="stylus" module>
 | 
					<style lang="stylus" module>
 | 
				
			||||||
 | 
					.icon
 | 
				
			||||||
 | 
						margin-right 8px
 | 
				
			||||||
 | 
					
 | 
				
			||||||
.count
 | 
					.count
 | 
				
			||||||
	margin-left 8px
 | 
						margin-left 8px
 | 
				
			||||||
	opacity 0.8
 | 
						opacity 0.8
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -27,6 +27,7 @@
 | 
				
			||||||
	<button class="drive" title="%i18n:desktop.tags.mk-post-form.attach-media-from-drive%" @click="chooseFileFromDrive">%fa:cloud%</button>
 | 
						<button class="drive" title="%i18n:desktop.tags.mk-post-form.attach-media-from-drive%" @click="chooseFileFromDrive">%fa:cloud%</button>
 | 
				
			||||||
	<button class="kao" title="%i18n:desktop.tags.mk-post-form.insert-a-kao%" @click="kao">%fa:R smile%</button>
 | 
						<button class="kao" title="%i18n:desktop.tags.mk-post-form.insert-a-kao%" @click="kao">%fa:R smile%</button>
 | 
				
			||||||
	<button class="poll" title="%i18n:desktop.tags.mk-post-form.create-poll%" @click="poll = true">%fa:chart-pie%</button>
 | 
						<button class="poll" title="%i18n:desktop.tags.mk-post-form.create-poll%" @click="poll = true">%fa:chart-pie%</button>
 | 
				
			||||||
 | 
						<button class="geo" title="位置情報を添付する" @click="setGeo">%fa:map-marker-alt%</button>
 | 
				
			||||||
	<p class="text-count" :class="{ over: text.length > 1000 }">{{ '%i18n:desktop.tags.mk-post-form.text-remain%'.replace('{}', 1000 - text.length) }}</p>
 | 
						<p class="text-count" :class="{ over: text.length > 1000 }">{{ '%i18n:desktop.tags.mk-post-form.text-remain%'.replace('{}', 1000 - text.length) }}</p>
 | 
				
			||||||
	<button :class="{ posting }" class="submit" :disabled="!canPost" @click="post">
 | 
						<button :class="{ posting }" class="submit" :disabled="!canPost" @click="post">
 | 
				
			||||||
		{{ posting ? '%i18n:desktop.tags.mk-post-form.posting%' : submitText }}<mk-ellipsis v-if="posting"/>
 | 
							{{ posting ? '%i18n:desktop.tags.mk-post-form.posting%' : submitText }}<mk-ellipsis v-if="posting"/>
 | 
				
			||||||
| 
						 | 
					@ -53,6 +54,7 @@ export default Vue.extend({
 | 
				
			||||||
			files: [],
 | 
								files: [],
 | 
				
			||||||
			uploadings: [],
 | 
								uploadings: [],
 | 
				
			||||||
			poll: false,
 | 
								poll: false,
 | 
				
			||||||
 | 
								geo: null,
 | 
				
			||||||
			autocomplete: null,
 | 
								autocomplete: null,
 | 
				
			||||||
			draghover: false
 | 
								draghover: false
 | 
				
			||||||
		};
 | 
							};
 | 
				
			||||||
| 
						 | 
					@ -193,6 +195,21 @@ export default Vue.extend({
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			//#endregion
 | 
								//#endregion
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
 | 
							setGeo() {
 | 
				
			||||||
 | 
								if (navigator.geolocation == null) {
 | 
				
			||||||
 | 
									alert('お使いの端末は位置情報に対応していません');
 | 
				
			||||||
 | 
									return;
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								navigator.geolocation.getCurrentPosition(pos => {
 | 
				
			||||||
 | 
									this.geo = pos.coords;
 | 
				
			||||||
 | 
									this.$emit('geo-attached', this.geo);
 | 
				
			||||||
 | 
								}, err => {
 | 
				
			||||||
 | 
									alert('エラー: ' + err.message);
 | 
				
			||||||
 | 
								}, {
 | 
				
			||||||
 | 
									enableHighAccuracy: true
 | 
				
			||||||
 | 
								});
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
		post() {
 | 
							post() {
 | 
				
			||||||
			this.posting = true;
 | 
								this.posting = true;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -201,7 +218,8 @@ export default Vue.extend({
 | 
				
			||||||
				media_ids: this.files.length > 0 ? this.files.map(f => f.id) : undefined,
 | 
									media_ids: this.files.length > 0 ? this.files.map(f => f.id) : undefined,
 | 
				
			||||||
				reply_id: this.reply ? this.reply.id : undefined,
 | 
									reply_id: this.reply ? this.reply.id : undefined,
 | 
				
			||||||
				repost_id: this.repost ? this.repost.id : undefined,
 | 
									repost_id: this.repost ? this.repost.id : undefined,
 | 
				
			||||||
				poll: this.poll ? (this.$refs.poll as any).get() : undefined
 | 
									poll: this.poll ? (this.$refs.poll as any).get() : undefined,
 | 
				
			||||||
 | 
									geo: this.geo,
 | 
				
			||||||
			}).then(data => {
 | 
								}).then(data => {
 | 
				
			||||||
				this.clear();
 | 
									this.clear();
 | 
				
			||||||
				this.deleteDraft();
 | 
									this.deleteDraft();
 | 
				
			||||||
| 
						 | 
					@ -459,6 +477,7 @@ export default Vue.extend({
 | 
				
			||||||
	> .drive
 | 
						> .drive
 | 
				
			||||||
	> .kao
 | 
						> .kao
 | 
				
			||||||
	> .poll
 | 
						> .poll
 | 
				
			||||||
 | 
						> .geo
 | 
				
			||||||
		display inline-block
 | 
							display inline-block
 | 
				
			||||||
		cursor pointer
 | 
							cursor pointer
 | 
				
			||||||
		padding 0
 | 
							padding 0
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -23,6 +23,7 @@
 | 
				
			||||||
		<button class="drive" @click="chooseFileFromDrive">%fa:cloud%</button>
 | 
							<button class="drive" @click="chooseFileFromDrive">%fa:cloud%</button>
 | 
				
			||||||
		<button class="kao" @click="kao">%fa:R smile%</button>
 | 
							<button class="kao" @click="kao">%fa:R smile%</button>
 | 
				
			||||||
		<button class="poll" @click="poll = true">%fa:chart-pie%</button>
 | 
							<button class="poll" @click="poll = true">%fa:chart-pie%</button>
 | 
				
			||||||
 | 
							<button class="geo" @click="setGeo">%fa:map-marker-alt%</button>
 | 
				
			||||||
		<input ref="file" class="file" type="file" accept="image/*" multiple="multiple" @change="onChangeFile"/>
 | 
							<input ref="file" class="file" type="file" accept="image/*" multiple="multiple" @change="onChangeFile"/>
 | 
				
			||||||
	</div>
 | 
						</div>
 | 
				
			||||||
</div>
 | 
					</div>
 | 
				
			||||||
| 
						 | 
					@ -44,7 +45,8 @@ export default Vue.extend({
 | 
				
			||||||
			text: '',
 | 
								text: '',
 | 
				
			||||||
			uploadings: [],
 | 
								uploadings: [],
 | 
				
			||||||
			files: [],
 | 
								files: [],
 | 
				
			||||||
			poll: false
 | 
								poll: false,
 | 
				
			||||||
 | 
								geo: null
 | 
				
			||||||
		};
 | 
							};
 | 
				
			||||||
	},
 | 
						},
 | 
				
			||||||
	mounted() {
 | 
						mounted() {
 | 
				
			||||||
| 
						 | 
					@ -83,6 +85,20 @@ export default Vue.extend({
 | 
				
			||||||
		onChangeUploadings(uploads) {
 | 
							onChangeUploadings(uploads) {
 | 
				
			||||||
			this.$emit('change-uploadings', uploads);
 | 
								this.$emit('change-uploadings', uploads);
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
 | 
							setGeo() {
 | 
				
			||||||
 | 
								if (navigator.geolocation == null) {
 | 
				
			||||||
 | 
									alert('お使いの端末は位置情報に対応していません');
 | 
				
			||||||
 | 
									return;
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								navigator.geolocation.getCurrentPosition(pos => {
 | 
				
			||||||
 | 
									this.geo = pos.coords;
 | 
				
			||||||
 | 
								}, err => {
 | 
				
			||||||
 | 
									alert('エラー: ' + err.message);
 | 
				
			||||||
 | 
								}, {
 | 
				
			||||||
 | 
									enableHighAccuracy: true
 | 
				
			||||||
 | 
								});
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
		clear() {
 | 
							clear() {
 | 
				
			||||||
			this.text = '';
 | 
								this.text = '';
 | 
				
			||||||
			this.files = [];
 | 
								this.files = [];
 | 
				
			||||||
| 
						 | 
					@ -97,6 +113,7 @@ export default Vue.extend({
 | 
				
			||||||
				media_ids: this.files.length > 0 ? this.files.map(f => f.id) : undefined,
 | 
									media_ids: this.files.length > 0 ? this.files.map(f => f.id) : undefined,
 | 
				
			||||||
				reply_id: this.reply ? this.reply.id : undefined,
 | 
									reply_id: this.reply ? this.reply.id : undefined,
 | 
				
			||||||
				poll: this.poll ? (this.$refs.poll as any).get() : undefined,
 | 
									poll: this.poll ? (this.$refs.poll as any).get() : undefined,
 | 
				
			||||||
 | 
									geo: this.geo,
 | 
				
			||||||
				via_mobile: viaMobile
 | 
									via_mobile: viaMobile
 | 
				
			||||||
			}).then(data => {
 | 
								}).then(data => {
 | 
				
			||||||
				this.$emit('post');
 | 
									this.$emit('post');
 | 
				
			||||||
| 
						 | 
					@ -223,8 +240,9 @@ export default Vue.extend({
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		> .upload
 | 
							> .upload
 | 
				
			||||||
		> .drive
 | 
							> .drive
 | 
				
			||||||
		.kao
 | 
							> .kao
 | 
				
			||||||
		.poll
 | 
							> .poll
 | 
				
			||||||
 | 
							> .geo
 | 
				
			||||||
			display inline-block
 | 
								display inline-block
 | 
				
			||||||
			padding 0
 | 
								padding 0
 | 
				
			||||||
			margin 0
 | 
								margin 0
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -128,3 +128,46 @@ props:
 | 
				
			||||||
            desc:
 | 
					            desc:
 | 
				
			||||||
              ja: "この選択肢に投票された数"
 | 
					              ja: "この選択肢に投票された数"
 | 
				
			||||||
              en: "The number voted for this choice"
 | 
					              en: "The number voted for this choice"
 | 
				
			||||||
 | 
					  - name: "geo"
 | 
				
			||||||
 | 
					    type: "object"
 | 
				
			||||||
 | 
					    optional: true
 | 
				
			||||||
 | 
					    desc:
 | 
				
			||||||
 | 
					      ja: "位置情報"
 | 
				
			||||||
 | 
					      en: "Geo location"
 | 
				
			||||||
 | 
					    defName: "geo"
 | 
				
			||||||
 | 
					    def:
 | 
				
			||||||
 | 
					      - name: "latitude"
 | 
				
			||||||
 | 
					        type: "number"
 | 
				
			||||||
 | 
					        optional: false
 | 
				
			||||||
 | 
					        desc:
 | 
				
			||||||
 | 
					          ja: "緯度。-180〜180で表す。"
 | 
				
			||||||
 | 
					      - name: "longitude"
 | 
				
			||||||
 | 
					        type: "number"
 | 
				
			||||||
 | 
					        optional: false
 | 
				
			||||||
 | 
					        desc:
 | 
				
			||||||
 | 
					          ja: "経度。-90〜90で表す。"
 | 
				
			||||||
 | 
					      - name: "altitude"
 | 
				
			||||||
 | 
					        type: "number"
 | 
				
			||||||
 | 
					        optional: false
 | 
				
			||||||
 | 
					        desc:
 | 
				
			||||||
 | 
					          ja: "高度。メートル単位で表す。"
 | 
				
			||||||
 | 
					      - name: "accuracy"
 | 
				
			||||||
 | 
					        type: "number"
 | 
				
			||||||
 | 
					        optional: false
 | 
				
			||||||
 | 
					        desc:
 | 
				
			||||||
 | 
					          ja: "緯度、経度の精度。メートル単位で表す。"
 | 
				
			||||||
 | 
					      - name: "altitudeAccuracy"
 | 
				
			||||||
 | 
					        type: "number"
 | 
				
			||||||
 | 
					        optional: false
 | 
				
			||||||
 | 
					        desc:
 | 
				
			||||||
 | 
					          ja: "高度の精度。メートル単位で表す。"
 | 
				
			||||||
 | 
					      - name: "heading"
 | 
				
			||||||
 | 
					        type: "number"
 | 
				
			||||||
 | 
					        optional: false
 | 
				
			||||||
 | 
					        desc:
 | 
				
			||||||
 | 
					          ja: "方角。0〜360の角度で表す。0が北、90が東、180が南、270が西。"
 | 
				
			||||||
 | 
					      - name: "speed"
 | 
				
			||||||
 | 
					        type: "number"
 | 
				
			||||||
 | 
					        optional: false
 | 
				
			||||||
 | 
					        desc:
 | 
				
			||||||
 | 
					          ja: "速度。メートル / 秒数で表す。"
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue