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…
Reference in a new issue