summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorsyuilo <syuilotan@yahoo.co.jp>2018-07-20 05:29:56 +0900
committersyuilo <syuilotan@yahoo.co.jp>2018-07-20 05:29:56 +0900
commit8dc5375d55e9d54041ea95c960488185eaae6bd9 (patch)
tree4a50953139d89a7350ad1861e5390780f0696d76 /src
parentMerge branch 'master' of https://github.com/syuilo/misskey (diff)
downloadsharkey-8dc5375d55e9d54041ea95c960488185eaae6bd9.tar.gz
sharkey-8dc5375d55e9d54041ea95c960488185eaae6bd9.tar.bz2
sharkey-8dc5375d55e9d54041ea95c960488185eaae6bd9.zip
最近使ったハッシュタグを表示するようにするなど
Diffstat (limited to 'src')
-rw-r--r--src/client/app/desktop/views/components/post-form.vue22
-rw-r--r--src/client/app/mobile/views/components/post-form.vue312
2 files changed, 191 insertions, 143 deletions
diff --git a/src/client/app/desktop/views/components/post-form.vue b/src/client/app/desktop/views/components/post-form.vue
index 3832e5b38c..5efa1eacca 100644
--- a/src/client/app/desktop/views/components/post-form.vue
+++ b/src/client/app/desktop/views/components/post-form.vue
@@ -10,6 +10,9 @@
<span v-for="u in visibleUsers">{{ u | userName }}<a @click="removeVisibleUser(u)">[x]</a></span>
<a @click="addVisibleUser">+ユーザーを追加</a>
</div>
+ <div class="hashtags" v-if="recentHashtags.length > 0">
+ <a v-for="tag in recentHashtags" @click="addTag(tag)">#{{ tag }}</a>
+ </div>
<input v-show="useCw" v-model="cw" placeholder="内容への注釈 (オプション)">
<textarea :class="{ with: (files.length != 0 || poll) }"
ref="text" v-model="text" :disabled="posting"
@@ -46,6 +49,7 @@
<script lang="ts">
import Vue from 'vue';
+import insertTextAtCursor from 'insert-text-at-cursor';
import * as XDraggable from 'vuedraggable';
import getKao from '../../../common/scripts/get-kao';
import MkVisibilityChooser from '../../../common/views/components/visibility-chooser.vue';
@@ -91,7 +95,8 @@ export default Vue.extend({
visibility: 'public',
visibleUsers: [],
autocomplete: null,
- draghover: false
+ draghover: false,
+ recentHashtags: JSON.parse(localStorage.getItem('hashtags') || '[]')
};
},
@@ -183,6 +188,10 @@ export default Vue.extend({
},
methods: {
+ addTag(tag: string) {
+ insertTextAtCursor(this.$refs.text, ` #${tag} `);
+ },
+
watch() {
this.$watch('text', () => this.saveDraft());
this.$watch('poll', () => this.saveDraft());
@@ -370,6 +379,13 @@ export default Vue.extend({
}).then(() => {
this.posting = false;
});
+
+ if (this.text && this.text != '') {
+ const hashtags = parse(this.text).filter(x => x.type == 'hashtag').map(x => x.hashtag);
+ let history = JSON.parse(localStorage.getItem('hashtags') || '[]') as string[];
+ history = history.filter(x => !hashtags.includes(x));
+ localStorage.setItem('hashtags', JSON.stringify(hashtags.concat(history)));
+ }
},
saveDraft() {
@@ -478,6 +494,10 @@ root(isDark)
margin-right 16px
color isDark ? #fff : #666
+ > .hashtags
+ > *
+ margin-right 8px
+
> .medias
margin 0
padding 0
diff --git a/src/client/app/mobile/views/components/post-form.vue b/src/client/app/mobile/views/components/post-form.vue
index 52ba95e87a..05e8b09865 100644
--- a/src/client/app/mobile/views/components/post-form.vue
+++ b/src/client/app/mobile/views/components/post-form.vue
@@ -1,47 +1,53 @@
<template>
<div class="mk-post-form">
- <header>
- <button class="cancel" @click="cancel">%fa:times%</button>
- <div>
- <span class="text-count" :class="{ over: text.length > 1000 }">{{ 1000 - text.length }}</span>
- <span class="geo" v-if="geo">%fa:map-marker-alt%</span>
- <button class="submit" :disabled="!canPost" @click="post">{{ submitText }}</button>
- </div>
- </header>
<div class="form">
- <mk-note-preview v-if="reply" :note="reply"/>
- <mk-note-preview v-if="renote" :note="renote"/>
- <div v-if="visibility == 'specified'" class="visibleUsers">
- <span v-for="u in visibleUsers">{{ u | userName }}<a @click="removeVisibleUser(u)">[x]</a></span>
- <a @click="addVisibleUser">+%i18n:@add-visible-user%</a>
- </div>
- <input v-show="useCw" v-model="cw" placeholder="%i18n:@cw-placeholder%">
- <textarea v-model="text" ref="text" :disabled="posting" :placeholder="placeholder" v-autocomplete="'text'"></textarea>
- <div class="attaches" v-show="files.length != 0">
- <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>
+ <header>
+ <button class="cancel" @click="cancel">%fa:times%</button>
+ <div>
+ <span class="text-count" :class="{ over: text.length > 1000 }">{{ 1000 - text.length }}</span>
+ <span class="geo" v-if="geo">%fa:map-marker-alt%</span>
+ <button class="submit" :disabled="!canPost" @click="post">{{ submitText }}</button>
+ </div>
+ </header>
+ <div class="form">
+ <mk-note-preview v-if="reply" :note="reply"/>
+ <mk-note-preview v-if="renote" :note="renote"/>
+ <div v-if="visibility == 'specified'" class="visibleUsers">
+ <span v-for="u in visibleUsers">{{ u | userName }}<a @click="removeVisibleUser(u)">[x]</a></span>
+ <a @click="addVisibleUser">+%i18n:@add-visible-user%</a>
+ </div>
+ <input v-show="useCw" v-model="cw" placeholder="%i18n:@cw-placeholder%">
+ <textarea v-model="text" ref="text" :disabled="posting" :placeholder="placeholder" v-autocomplete="'text'"></textarea>
+ <div class="attaches" v-show="files.length != 0">
+ <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" @destroyed="poll = false"/>
+ <mk-uploader ref="uploader" @uploaded="attachMedia" @change="onChangeUploadings"/>
+ <footer>
+ <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="poll = true">%fa:chart-pie%</button>
+ <button class="poll" @click="useCw = !useCw">%fa:eye-slash%</button>
+ <button class="geo" @click="geo ? removeGeo() : setGeo()">%fa:map-marker-alt%</button>
+ <button class="visibility" @click="setVisibility" ref="visibilityButton">%fa:lock%</button>
+ </footer>
+ <input ref="file" class="file" type="file" accept="image/*" multiple="multiple" @change="onChangeFile"/>
</div>
- <mk-poll-editor v-if="poll" ref="poll" @destroyed="poll = false"/>
- <mk-uploader ref="uploader" @uploaded="attachMedia" @change="onChangeUploadings"/>
- <footer>
- <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="poll = true">%fa:chart-pie%</button>
- <button class="poll" @click="useCw = !useCw">%fa:eye-slash%</button>
- <button class="geo" @click="geo ? removeGeo() : setGeo()">%fa:map-marker-alt%</button>
- <button class="visibility" @click="setVisibility" ref="visibilityButton">%fa:lock%</button>
- </footer>
- <input ref="file" class="file" type="file" accept="image/*" multiple="multiple" @change="onChangeFile"/>
+ </div>
+ <div class="hashtags" v-if="recentHashtags.length > 0">
+ <a v-for="tag in recentHashtags" @click="addTag(tag)">#{{ tag }}</a>
</div>
</div>
</template>
<script lang="ts">
import Vue from 'vue';
+import insertTextAtCursor from 'insert-text-at-cursor';
import * as XDraggable from 'vuedraggable';
import MkVisibilityChooser from '../../../common/views/components/visibility-chooser.vue';
import getKao from '../../../common/scripts/get-kao';
@@ -85,7 +91,8 @@ export default Vue.extend({
visibility: 'public',
visibleUsers: [],
useCw: false,
- cw: null
+ cw: null,
+ recentHashtags: JSON.parse(localStorage.getItem('hashtags') || '[]')
};
},
@@ -161,6 +168,10 @@ export default Vue.extend({
},
methods: {
+ addTag(tag: string) {
+ insertTextAtCursor(this.$refs.text, ` #${tag} `);
+ },
+
focus() {
(this.$refs.text as any).focus();
},
@@ -281,6 +292,13 @@ export default Vue.extend({
}).catch(err => {
this.posting = false;
});
+
+ if (this.text && this.text != '') {
+ const hashtags = parse(this.text).filter(x => x.type == 'hashtag').map(x => x.hashtag);
+ let history = JSON.parse(localStorage.getItem('hashtags') || '[]') as string[];
+ history = history.filter(x => !hashtags.includes(x));
+ localStorage.setItem('hashtags', JSON.stringify(hashtags.concat(history)));
+ }
},
cancel() {
@@ -302,146 +320,156 @@ root(isDark)
max-width 500px
width calc(100% - 16px)
margin 8px auto
- background isDark ? #282C37 : #fff
- border-radius 8px
- box-shadow 0 0 2px rgba(#000, 0.1)
@media (min-width 500px)
margin 16px auto
width calc(100% - 32px)
- box-shadow 0 8px 32px rgba(#000, 0.1)
+
+ > .form
+ box-shadow 0 8px 32px rgba(#000, 0.1)
@media (min-width 600px)
margin 32px auto
- > header
- z-index 1000
- height 50px
- box-shadow 0 1px 0 0 isDark ? rgba(#000, 0.2) : rgba(#000, 0.1)
-
- > .cancel
- padding 0
- width 50px
- line-height 50px
- font-size 24px
- color isDark ? #9baec8 : #555
-
- > div
- position absolute
- top 0
- right 0
- color #657786
+ > .form
+ background isDark ? #282C37 : #fff
+ border-radius 8px
+ box-shadow 0 0 2px rgba(#000, 0.1)
- > .text-count
- line-height 50px
+ > header
+ z-index 1000
+ height 50px
+ box-shadow 0 1px 0 0 isDark ? rgba(#000, 0.2) : rgba(#000, 0.1)
- > .geo
- margin 0 8px
+ > .cancel
+ padding 0
+ width 50px
line-height 50px
+ font-size 24px
+ color isDark ? #9baec8 : #555
- > .submit
- margin 8px
- padding 0 16px
- line-height 34px
- vertical-align bottom
- color $theme-color-foreground
- background $theme-color
- border-radius 4px
-
- &:disabled
- opacity 0.7
+ > div
+ position absolute
+ top 0
+ right 0
+ color #657786
- > .form
- max-width 500px
- margin 0 auto
+ > .text-count
+ line-height 50px
- > .mk-note-preview
- padding 16px
+ > .geo
+ margin 0 8px
+ line-height 50px
- > .visibleUsers
- margin-bottom 8px
- font-size 14px
+ > .submit
+ margin 8px
+ padding 0 16px
+ line-height 34px
+ vertical-align bottom
+ color $theme-color-foreground
+ background $theme-color
+ border-radius 4px
- > span
- margin-right 16px
- color isDark ? #fff : #666
+ &:disabled
+ opacity 0.7
- > input
- z-index 1
+ > .form
+ max-width 500px
+ margin 0 auto
- > input
- > textarea
- display block
- padding 12px
- margin 0
- width 100%
- font-size 16px
- color isDark ? #fff : #333
- background isDark ? #191d23 : #fff
- border none
- border-radius 0
- box-shadow 0 1px 0 0 isDark ? rgba(#000, 0.2) : rgba(#000, 0.1)
+ > .mk-note-preview
+ padding 16px
- &:disabled
- opacity 0.5
+ > .visibleUsers
+ margin-bottom 8px
+ font-size 14px
- > textarea
- max-width 100%
- min-width 100%
- min-height 80px
+ > span
+ margin-right 16px
+ color isDark ? #fff : #666
- > .attaches
+ > input
+ z-index 1
- > .files
+ > input
+ > textarea
display block
+ padding 12px
margin 0
- padding 4px
- list-style none
+ width 100%
+ font-size 16px
+ color isDark ? #fff : #333
+ background isDark ? #191d23 : #fff
+ border none
+ border-radius 0
+ box-shadow 0 1px 0 0 isDark ? rgba(#000, 0.2) : rgba(#000, 0.1)
- &:after
- content ""
- display block
- clear both
+ &:disabled
+ opacity 0.5
+
+ > textarea
+ max-width 100%
+ min-width 100%
+ min-height 80px
- > .file
+ > .attaches
+
+ > .files
display block
- float left
margin 0
- padding 0
- border solid 4px transparent
+ padding 4px
+ list-style none
- > .img
- width 64px
- height 64px
- background-size cover
- background-position center center
+ &:after
+ content ""
+ display block
+ clear both
- > .mk-uploader
- margin 8px 0 0 0
- padding 8px
+ > .file
+ display block
+ float left
+ margin 0
+ padding 0
+ border solid 4px transparent
- > .file
- display none
+ > .img
+ width 64px
+ height 64px
+ background-size cover
+ background-position center center
- > footer
- white-space nowrap
- overflow auto
- -webkit-overflow-scrolling touch
- overflow-scrolling touch
+ > .mk-uploader
+ margin 8px 0 0 0
+ padding 8px
- > *
- display inline-block
- padding 0
- margin 0
- width 48px
- height 48px
- font-size 20px
- color #657786
- background transparent
- outline none
- border none
- border-radius 0
- box-shadow none
+ > .file
+ display none
+
+ > footer
+ white-space nowrap
+ overflow auto
+ -webkit-overflow-scrolling touch
+ overflow-scrolling touch
+
+ > *
+ display inline-block
+ padding 0
+ margin 0
+ width 48px
+ height 48px
+ font-size 20px
+ color #657786
+ background transparent
+ outline none
+ border none
+ border-radius 0
+ box-shadow none
+
+ > .hashtags
+ margin 8px
+
+ > *
+ margin-right 8px
.mk-post-form[data-darkmode]
root(true)