summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorsyuilo <syuilotan@yahoo.co.jp>2018-03-05 08:44:37 +0900
committersyuilo <syuilotan@yahoo.co.jp>2018-03-05 08:44:37 +0900
commitb0c7cb88035b5ca723de2a5a08cd2840214d9b97 (patch)
treee17702b4c64a4860ed3e3e17cee92c21a8040c9c /src
parent#1183 (diff)
downloadsharkey-b0c7cb88035b5ca723de2a5a08cd2840214d9b97.tar.gz
sharkey-b0c7cb88035b5ca723de2a5a08cd2840214d9b97.tar.bz2
sharkey-b0c7cb88035b5ca723de2a5a08cd2840214d9b97.zip
wip
Diffstat (limited to 'src')
-rw-r--r--src/api/endpoints/posts/create.ts13
-rw-r--r--src/api/models/post.ts9
-rw-r--r--src/web/app/desktop/views/components/post-form-window.vue13
-rw-r--r--src/web/app/desktop/views/components/post-form.vue21
-rw-r--r--src/web/app/mobile/views/components/post-form.vue24
-rw-r--r--src/web/docs/api/entities/post.yaml43
6 files changed, 117 insertions, 6 deletions
diff --git a/src/api/endpoints/posts/create.ts b/src/api/endpoints/posts/create.ts
index a9d52fd128..15cbc4845c 100644
--- a/src/api/endpoints/posts/create.ts
+++ b/src/api/endpoints/posts/create.ts
@@ -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,
diff --git a/src/api/models/post.ts b/src/api/models/post.ts
index edb69e0c15..c37c8371c0 100644
--- a/src/api/models/post.ts
+++ b/src/api/models/post.ts
@@ -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;
+ };
};
/**
diff --git a/src/web/app/desktop/views/components/post-form-window.vue b/src/web/app/desktop/views/components/post-form-window.vue
index 4427f59829..31a07a890e 100644
--- a/src/web/app/desktop/views/components/post-form-window.vue
+++ b/src/web/app/desktop/views/components/post-form-window.vue
@@ -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
diff --git a/src/web/app/desktop/views/components/post-form.vue b/src/web/app/desktop/views/components/post-form.vue
index 5cf5cffc6a..6e334e7ca8 100644
--- a/src/web/app/desktop/views/components/post-form.vue
+++ b/src/web/app/desktop/views/components/post-form.vue
@@ -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
diff --git a/src/web/app/mobile/views/components/post-form.vue b/src/web/app/mobile/views/components/post-form.vue
index d16d5d358b..559a6c1c4b 100644
--- a/src/web/app/mobile/views/components/post-form.vue
+++ b/src/web/app/mobile/views/components/post-form.vue
@@ -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
diff --git a/src/web/docs/api/entities/post.yaml b/src/web/docs/api/entities/post.yaml
index e4359ffd0c..451d2579d9 100644
--- a/src/web/docs/api/entities/post.yaml
+++ b/src/web/docs/api/entities/post.yaml
@@ -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: "速度。メートル / 秒数で表す。"