diff --git a/locales/ja-JP.yml b/locales/ja-JP.yml
index eed17edb1..e3d0afcef 100644
--- a/locales/ja-JP.yml
+++ b/locales/ja-JP.yml
@@ -768,6 +768,7 @@ squareAvatars: "アイコンを四角形で表示"
sent: "送信"
received: "受信"
searchResult: "検索結果"
+hashtags: "ハッシュタグ"
_docs:
continueReading: "続きを読む"
diff --git a/src/client/components/post-form.vue b/src/client/components/post-form.vue
index 13bbb3f9e..ed2a934c2 100644
--- a/src/client/components/post-form.vue
+++ b/src/client/components/post-form.vue
@@ -37,6 +37,7 @@
{{ $ts.notSpecifiedMentionWarning }} -
+
+
@@ -67,10 +72,11 @@ import { Autocomplete } from '@client/scripts/autocomplete';
import { noteVisibilities } from '../../types';
import * as os from '@client/os';
import { selectFile } from '@client/scripts/select-file';
-import { notePostInterruptors, postFormActions } from '@client/store';
+import { defaultStore, notePostInterruptors, postFormActions } from '@client/store';
import { isMobile } from '@client/scripts/is-mobile';
import { throttle } from 'throttle-debounce';
import MkInfo from '@client/components/ui/info.vue';
+import { defaultStore } from '@client/store';
export default defineComponent({
components: {
@@ -212,7 +218,10 @@ export default defineComponent({
max(): number {
return this.$instance ? this.$instance.maxNoteTextLength : 1000;
- }
+ },
+
+ withHashtags: defaultStore.makeGetterSetter('postFormWithHashtags'),
+ hashtags: defaultStore.makeGetterSetter('postFormHashtags'),
},
watch: {
@@ -303,6 +312,7 @@ export default defineComponent({
// TODO: detach when unmount
new Autocomplete(this.$refs.text, this, { model: 'text' });
new Autocomplete(this.$refs.cw, this, { model: 'cw' });
+ new Autocomplete(this.$refs.hashtags, this, { model: 'hashtags' });
this.$nextTick(() => {
// 書きかけの投稿を復元
@@ -605,6 +615,11 @@ export default defineComponent({
viaMobile: isMobile
};
+ if (this.withHashtags) {
+ const hashtags = this.hashtags.trim().split(' ').map(x => x.startsWith('#') ? x : '#' + x).join(' ');
+ data.text = data.text ? `${data.text} ${hashtags}` : hashtags;
+ }
+
// plugin
if (notePostInterruptors.length > 0) {
for (const interruptor of notePostInterruptors) {
@@ -618,8 +633,8 @@ export default defineComponent({
this.$nextTick(() => {
this.deleteDraft();
this.$emit('posted');
- if (this.text && this.text != '') {
- const hashtags = mfm.parse(this.text).filter(x => x.type === 'hashtag').map(x => x.props.hashtag);
+ if (data.text && data.text != '') {
+ const hashtags = mfm.parse(data.text).filter(x => x.type === 'hashtag').map(x => x.props.hashtag);
const history = JSON.parse(localStorage.getItem('hashtags') || '[]') as string[];
localStorage.setItem('hashtags', JSON.stringify(unique(hashtags.concat(history))));
}
@@ -785,6 +800,7 @@ export default defineComponent({
}
> .cw,
+ > .hashtags,
> .text {
display: block;
box-sizing: border-box;
@@ -813,6 +829,13 @@ export default defineComponent({
border-bottom: solid 0.5px var(--divider);
}
+ > .hashtags {
+ z-index: 1;
+ padding-top: 8px;
+ padding-bottom: 8px;
+ border-top: solid 0.5px var(--divider);
+ }
+
> .text {
max-width: 100%;
min-width: 100%;
@@ -872,6 +895,7 @@ export default defineComponent({
}
> .cw,
+ > .hashtags,
> .text {
padding: 0 16px;
}
diff --git a/src/client/store.ts b/src/client/store.ts
index 6ca431e05..364d8afd9 100644
--- a/src/client/store.ts
+++ b/src/client/store.ts
@@ -198,6 +198,14 @@ export const defaultStore = markRaw(new Storage('base', {
where: 'device',
default: false
},
+ postFormWithHashtags: {
+ where: 'device',
+ default: false
+ },
+ postFormHashtags: {
+ where: 'device',
+ default: ''
+ },
}));
// TODO: 他のタブと永続化されたstateを同期