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)).$;
 | 
			
		||||
	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
 | 
			
		||||
	const [mediaIds, mediaIdsErr] = $(params.media_ids).optional.array('id').unique().range(1, 4).$;
 | 
			
		||||
	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,
 | 
			
		||||
		app_id: app ? app._id : null,
 | 
			
		||||
		via_mobile: viaMobile,
 | 
			
		||||
		geo,
 | 
			
		||||
 | 
			
		||||
		// 以下非正規化データ
 | 
			
		||||
		_reply: reply ? { user_id: reply.user_id } : undefined,
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -32,6 +32,15 @@ export type IPost = {
 | 
			
		|||
	category: string;
 | 
			
		||||
	is_category_verified: boolean;
 | 
			
		||||
	via_mobile: boolean;
 | 
			
		||||
	geo: {
 | 
			
		||||
		latitude: number;
 | 
			
		||||
		longitude: number;
 | 
			
		||||
		altitude: number;
 | 
			
		||||
		accuracy: number;
 | 
			
		||||
		altitudeAccuracy: number;
 | 
			
		||||
		heading: number;
 | 
			
		||||
		speed: number;
 | 
			
		||||
	};
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,6 +1,7 @@
 | 
			
		|||
<template>
 | 
			
		||||
<mk-window ref="window" is-modal @closed="$destroy">
 | 
			
		||||
	<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.reply%</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"
 | 
			
		||||
		@posted="onPosted"
 | 
			
		||||
		@change-uploadings="onChangeUploadings"
 | 
			
		||||
		@change-attached-media="onChangeMedia"/>
 | 
			
		||||
		@change-attached-media="onChangeMedia"
 | 
			
		||||
		@geo-attached="onGeoAttached"/>
 | 
			
		||||
</mk-window>
 | 
			
		||||
</template>
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -24,7 +26,8 @@ export default Vue.extend({
 | 
			
		|||
	data() {
 | 
			
		||||
		return {
 | 
			
		||||
			uploadings: [],
 | 
			
		||||
			media: []
 | 
			
		||||
			media: [],
 | 
			
		||||
			geo: null
 | 
			
		||||
		};
 | 
			
		||||
	},
 | 
			
		||||
	mounted() {
 | 
			
		||||
| 
						 | 
				
			
			@ -39,6 +42,9 @@ export default Vue.extend({
 | 
			
		|||
		onChangeMedia(media) {
 | 
			
		||||
			this.media = media;
 | 
			
		||||
		},
 | 
			
		||||
		onGeoAttached(geo) {
 | 
			
		||||
			this.geo = geo;
 | 
			
		||||
		},
 | 
			
		||||
		onPosted() {
 | 
			
		||||
			(this.$refs.window as any).close();
 | 
			
		||||
		}
 | 
			
		||||
| 
						 | 
				
			
			@ -47,6 +53,9 @@ export default Vue.extend({
 | 
			
		|||
</script>
 | 
			
		||||
 | 
			
		||||
<style lang="stylus" module>
 | 
			
		||||
.icon
 | 
			
		||||
	margin-right 8px
 | 
			
		||||
 | 
			
		||||
.count
 | 
			
		||||
	margin-left 8px
 | 
			
		||||
	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="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="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>
 | 
			
		||||
	<button :class="{ posting }" class="submit" :disabled="!canPost" @click="post">
 | 
			
		||||
		{{ posting ? '%i18n:desktop.tags.mk-post-form.posting%' : submitText }}<mk-ellipsis v-if="posting"/>
 | 
			
		||||
| 
						 | 
				
			
			@ -53,6 +54,7 @@ export default Vue.extend({
 | 
			
		|||
			files: [],
 | 
			
		||||
			uploadings: [],
 | 
			
		||||
			poll: false,
 | 
			
		||||
			geo: null,
 | 
			
		||||
			autocomplete: null,
 | 
			
		||||
			draghover: false
 | 
			
		||||
		};
 | 
			
		||||
| 
						 | 
				
			
			@ -193,6 +195,21 @@ export default Vue.extend({
 | 
			
		|||
			}
 | 
			
		||||
			//#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() {
 | 
			
		||||
			this.posting = true;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -201,7 +218,8 @@ export default Vue.extend({
 | 
			
		|||
				media_ids: this.files.length > 0 ? this.files.map(f => f.id) : undefined,
 | 
			
		||||
				reply_id: this.reply ? this.reply.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 => {
 | 
			
		||||
				this.clear();
 | 
			
		||||
				this.deleteDraft();
 | 
			
		||||
| 
						 | 
				
			
			@ -459,6 +477,7 @@ export default Vue.extend({
 | 
			
		|||
	> .drive
 | 
			
		||||
	> .kao
 | 
			
		||||
	> .poll
 | 
			
		||||
	> .geo
 | 
			
		||||
		display inline-block
 | 
			
		||||
		cursor pointer
 | 
			
		||||
		padding 0
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -23,6 +23,7 @@
 | 
			
		|||
		<button class="drive" @click="chooseFileFromDrive">%fa:cloud%</button>
 | 
			
		||||
		<button class="kao" @click="kao">%fa:R smile%</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"/>
 | 
			
		||||
	</div>
 | 
			
		||||
</div>
 | 
			
		||||
| 
						 | 
				
			
			@ -44,7 +45,8 @@ export default Vue.extend({
 | 
			
		|||
			text: '',
 | 
			
		||||
			uploadings: [],
 | 
			
		||||
			files: [],
 | 
			
		||||
			poll: false
 | 
			
		||||
			poll: false,
 | 
			
		||||
			geo: null
 | 
			
		||||
		};
 | 
			
		||||
	},
 | 
			
		||||
	mounted() {
 | 
			
		||||
| 
						 | 
				
			
			@ -83,6 +85,20 @@ export default Vue.extend({
 | 
			
		|||
		onChangeUploadings(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() {
 | 
			
		||||
			this.text = '';
 | 
			
		||||
			this.files = [];
 | 
			
		||||
| 
						 | 
				
			
			@ -97,6 +113,7 @@ export default Vue.extend({
 | 
			
		|||
				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,
 | 
			
		||||
				geo: this.geo,
 | 
			
		||||
				via_mobile: viaMobile
 | 
			
		||||
			}).then(data => {
 | 
			
		||||
				this.$emit('post');
 | 
			
		||||
| 
						 | 
				
			
			@ -223,8 +240,9 @@ export default Vue.extend({
 | 
			
		|||
 | 
			
		||||
		> .upload
 | 
			
		||||
		> .drive
 | 
			
		||||
		.kao
 | 
			
		||||
		.poll
 | 
			
		||||
		> .kao
 | 
			
		||||
		> .poll
 | 
			
		||||
		> .geo
 | 
			
		||||
			display inline-block
 | 
			
		||||
			padding 0
 | 
			
		||||
			margin 0
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -128,3 +128,46 @@ props:
 | 
			
		|||
            desc:
 | 
			
		||||
              ja: "この選択肢に投票された数"
 | 
			
		||||
              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