diff options
| author | syuilo <syuilotan@yahoo.co.jp> | 2018-07-20 05:29:56 +0900 |
|---|---|---|
| committer | syuilo <syuilotan@yahoo.co.jp> | 2018-07-20 05:29:56 +0900 |
| commit | 8dc5375d55e9d54041ea95c960488185eaae6bd9 (patch) | |
| tree | 4a50953139d89a7350ad1861e5390780f0696d76 /src | |
| parent | Merge branch 'master' of https://github.com/syuilo/misskey (diff) | |
| download | sharkey-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.vue | 22 | ||||
| -rw-r--r-- | src/client/app/mobile/views/components/post-form.vue | 312 |
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) |