From 6184c88ac70b33e66a87222142344f693406bd87 Mon Sep 17 00:00:00 2001 From: Henry Jameson Date: Sun, 3 Mar 2019 15:15:41 +0200 Subject: Initial work on deprecating scopeModesEnabled in favor of minimalScopeMode --- .../post_status_form/post_status_form.js | 27 ++++++++++++---------- .../post_status_form/post_status_form.vue | 13 ++++++----- 2 files changed, 22 insertions(+), 18 deletions(-) (limited to 'src/components/post_status_form') diff --git a/src/components/post_status_form/post_status_form.js b/src/components/post_status_form/post_status_form.js index c28c51bf..b0882f70 100644 --- a/src/components/post_status_form/post_status_form.js +++ b/src/components/post_status_form/post_status_form.js @@ -1,5 +1,6 @@ import statusPoster from '../../services/status_poster/status_poster.service.js' import MediaUpload from '../media_upload/media_upload.vue' +import ScopeSelector from '../scope_selector/scope_selector.vue' import fileTypeService from '../../services/file_type/file_type.service.js' import Completion from '../../services/completion/completion.js' import { take, filter, reject, map, uniqBy } from 'lodash' @@ -28,7 +29,8 @@ const PostStatusForm = { 'subject' ], components: { - MediaUpload + MediaUpload, + ScopeSelector }, mounted () { this.resize(this.$refs.textarea) @@ -78,14 +80,6 @@ const PostStatusForm = { } }, computed: { - vis () { - return { - public: { selected: this.newStatus.visibility === 'public' }, - unlisted: { selected: this.newStatus.visibility === 'unlisted' }, - private: { selected: this.newStatus.visibility === 'private' }, - direct: { selected: this.newStatus.visibility === 'direct' } - } - }, candidates () { const firstchar = this.textAtCaret.charAt(0) if (firstchar === '@') { @@ -133,6 +127,15 @@ const PostStatusForm = { users () { return this.$store.state.users.users }, + userDefaultScope () { + return this.$store.state.users.currentUser.default_scope + }, + showAllScopes () { + const minimalScopesMode = typeof this.$store.state.config.minimalScopesMode === 'undefined' + ? this.$store.state.instance.minimalScopesMode + : this.$store.state.config.minimalScopesMode + return !minimalScopesMode + }, emoji () { return this.$store.state.instance.emoji || [] }, @@ -157,8 +160,8 @@ const PostStatusForm = { isOverLengthLimit () { return this.hasStatusLengthLimit && (this.charactersLeft < 0) }, - scopeOptionsEnabled () { - return this.$store.state.instance.scopeOptionsEnabled + scopeOptionsMinimal () { + return this.$store.state.instance.scopeOptionsMinimal }, alwaysShowSubject () { if (typeof this.$store.state.config.alwaysShowSubjectInput !== 'undefined') { @@ -166,7 +169,7 @@ const PostStatusForm = { } else if (typeof this.$store.state.instance.alwaysShowSubjectInput !== 'undefined') { return this.$store.state.instance.alwaysShowSubjectInput } else { - return this.$store.state.instance.scopeOptionsEnabled + return true } }, formattingOptionsEnabled () { diff --git a/src/components/post_status_form/post_status_form.vue b/src/components/post_status_form/post_status_form.vue index 5085570b..b3d731cd 100644 --- a/src/components/post_status_form/post_status_form.vue +++ b/src/components/post_status_form/post_status_form.vue @@ -44,12 +44,13 @@ -
- - - - -
+
-- cgit v1.2.3-70-g09d2 From b97a03383990d54573bd5e68393a1ad11e33608b Mon Sep 17 00:00:00 2001 From: jared Date: Mon, 25 Mar 2019 22:38:15 -0400 Subject: #255 - add emoji input component --- src/components/emoji-input/emoji-input.js | 106 +++++++++++++++++++++ src/components/emoji-input/emoji-input.vue | 99 +++++++++++++++++++ .../post_status_form/post_status_form.js | 4 +- .../post_status_form/post_status_form.vue | 5 +- 4 files changed, 211 insertions(+), 3 deletions(-) create mode 100644 src/components/emoji-input/emoji-input.js create mode 100644 src/components/emoji-input/emoji-input.vue (limited to 'src/components/post_status_form') diff --git a/src/components/emoji-input/emoji-input.js b/src/components/emoji-input/emoji-input.js new file mode 100644 index 00000000..56414358 --- /dev/null +++ b/src/components/emoji-input/emoji-input.js @@ -0,0 +1,106 @@ +import Completion from '../../services/completion/completion.js' +import { take, filter, map } from 'lodash' + +const EmojiInput = { + props: [ + 'value', + 'placeholder', + 'type' + ], + data () { + return { + highlighted: 0, + caret: 0 + } + }, + computed: { + suggestions () { + const firstchar = this.textAtCaret.charAt(0) + if (firstchar === ':') { + if (this.textAtCaret === ':') { return } + const matchedEmoji = filter(this.emoji.concat(this.customEmoji), (emoji) => emoji.shortcode.startsWith(this.textAtCaret.slice(1))) + if (matchedEmoji.length <= 0) { + return false + } + return map(take(matchedEmoji, 5), ({shortcode, image_url, utf}, index) => ({ + shortcode: `:${shortcode}:`, + utf: utf || '', + // eslint-disable-next-line camelcase + img: utf ? '' : this.$store.state.instance.server + image_url, + highlighted: index === this.highlighted + })) + } else { + return false + } + }, + textAtCaret () { + return (this.wordAtCaret || {}).word || '' + }, + wordAtCaret () { + const word = Completion.wordAtPosition(this.value, this.caret - 1) || {} + return word + }, + emoji () { + return this.$store.state.instance.emoji || [] + }, + customEmoji () { + return this.$store.state.instance.customEmoji || [] + } + }, + methods: { + replace (replacement) { + const newValue = Completion.replaceWord(this.value, this.wordAtCaret, replacement) + this.$emit('input', newValue) + this.caret = 0 + }, + replaceEmoji (e) { + const len = this.suggestions.length || 0 + if (this.textAtCaret === ':' || e.ctrlKey) { return } + if (len > 0) { + e.preventDefault() + const emoji = this.suggestions[this.highlighted] + const replacement = emoji.utf || (emoji.shortcode + ' ') + const newValue = Completion.replaceWord(this.value, this.wordAtCaret, replacement) + this.$emit('input', newValue) + this.caret = 0 + this.highlighted = 0 + } + }, + cycleBackward (e) { + const len = this.suggestions.length || 0 + if (len > 0) { + e.preventDefault() + this.highlighted -= 1 + if (this.highlighted < 0) { + this.highlighted = this.suggestions.length - 1 + } + } else { + this.highlighted = 0 + } + }, + cycleForward (e) { + const len = this.suggestions.length || 0 + if (len > 0) { + if (e.shiftKey) { return } + e.preventDefault() + this.highlighted += 1 + if (this.highlighted >= len) { + this.highlighted = 0 + } + } else { + this.highlighted = 0 + } + }, + onKeydown (e) { + e.stopPropagation() + }, + onInput (e) { + this.$emit('input', e.target.value) + }, + setCaret ({target: {selectionStart}}) { + this.caret = selectionStart + } + } +} + +export default EmojiInput diff --git a/src/components/emoji-input/emoji-input.vue b/src/components/emoji-input/emoji-input.vue new file mode 100644 index 00000000..95606305 --- /dev/null +++ b/src/components/emoji-input/emoji-input.vue @@ -0,0 +1,99 @@ + + + + + diff --git a/src/components/post_status_form/post_status_form.js b/src/components/post_status_form/post_status_form.js index c5f30ca6..229aefb7 100644 --- a/src/components/post_status_form/post_status_form.js +++ b/src/components/post_status_form/post_status_form.js @@ -1,5 +1,6 @@ import statusPoster from '../../services/status_poster/status_poster.service.js' import MediaUpload from '../media_upload/media_upload.vue' +import EmojiInput from '../emoji-input/emoji-input.vue' import fileTypeService from '../../services/file_type/file_type.service.js' import Completion from '../../services/completion/completion.js' import { take, filter, reject, map, uniqBy } from 'lodash' @@ -28,7 +29,8 @@ const PostStatusForm = { 'subject' ], components: { - MediaUpload + MediaUpload, + EmojiInput }, mounted () { this.resize(this.$refs.textarea) diff --git a/src/components/post_status_form/post_status_form.vue b/src/components/post_status_form/post_status_form.vue index 612f87c1..9d449b74 100644 --- a/src/components/post_status_form/post_status_form.vue +++ b/src/components/post_status_form/post_status_form.vue @@ -10,12 +10,13 @@ {{ $t('post_status.account_not_locked_warning_link') }}

{{ $t('post_status.direct_warning') }}

- + class="form-cw" + />
+

-- cgit v1.2.3-70-g09d2 From 8fe9101f0b134978212bf05ed6e73894f47c617e Mon Sep 17 00:00:00 2001 From: jared Date: Tue, 26 Mar 2019 14:53:27 -0400 Subject: #255 - clean up autocomplete form --- src/App.scss | 51 +++++++++++++++++ src/components/emoji-input/emoji-input.vue | 51 ----------------- .../post_status_form/post_status_form.vue | 65 ++++------------------ 3 files changed, 63 insertions(+), 104 deletions(-) (limited to 'src/components/post_status_form') diff --git a/src/App.scss b/src/App.scss index 244b3474..ae068e4f 100644 --- a/src/App.scss +++ b/src/App.scss @@ -767,3 +767,54 @@ nav { .btn.btn-default { min-height: 28px; } + +.autocomplete { + &-panel { + position: relative; + + &-body { + margin: 0 0.5em 0 0.5em; + border-radius: $fallback--tooltipRadius; + border-radius: var(--tooltipRadius, $fallback--tooltipRadius); + position: absolute; + z-index: 1; + box-shadow: 1px 2px 4px rgba(0, 0, 0, 0.5); + // this doesn't match original but i don't care, making it uniform. + box-shadow: var(--popupShadow); + min-width: 75%; + background: $fallback--bg; + background: var(--bg, $fallback--bg); + color: $fallback--lightText; + color: var(--lightText, $fallback--lightText); + } + } + + &-item { + cursor: pointer; + padding: 0.2em 0.4em 0.2em 0.4em; + border-bottom: 1px solid rgba(0, 0, 0, 0.4); + display: flex; + + img { + width: 24px; + height: 24px; + object-fit: contain; + } + + span { + line-height: 24px; + margin: 0 0.1em 0 0.2em; + } + + small { + margin-left: .5em; + color: $fallback--faint; + color: var(--faint, $fallback--faint); + } + + &.highlighted { + background-color: $fallback--fg; + background-color: var(--lightBg, $fallback--fg); + } + } +} \ No newline at end of file diff --git a/src/components/emoji-input/emoji-input.vue b/src/components/emoji-input/emoji-input.vue index 568bd080..338b77cd 100644 --- a/src/components/emoji-input/emoji-input.vue +++ b/src/components/emoji-input/emoji-input.vue @@ -61,55 +61,4 @@ width: 100%; } } - -.autocomplete { - &-panel { - position: relative; - - &-body { - margin: 0 0.5em 0 0.5em; - border-radius: $fallback--tooltipRadius; - border-radius: var(--tooltipRadius, $fallback--tooltipRadius); - position: absolute; - z-index: 1; - box-shadow: 1px 2px 4px rgba(0, 0, 0, 0.5); - // this doesn't match original but i don't care, making it uniform. - box-shadow: var(--popupShadow); - min-width: 75%; - background: $fallback--bg; - background: var(--bg, $fallback--bg); - color: $fallback--lightText; - color: var(--lightText, $fallback--lightText); - } - } - - &-item { - cursor: pointer; - padding: 0.2em 0.4em 0.2em 0.4em; - border-bottom: 1px solid rgba(0, 0, 0, 0.4); - display: flex; - - img { - width: 24px; - height: 24px; - object-fit: contain; - } - - span { - line-height: 24px; - margin: 0 0.1em 0 0.2em; - } - - small { - margin-left: .5em; - color: $fallback--faint; - color: var(--faint, $fallback--faint); - } - - &.highlighted { - background-color: $fallback--fg; - background-color: var(--lightBg, $fallback--fg); - } - } -} diff --git a/src/components/post_status_form/post_status_form.vue b/src/components/post_status_form/post_status_form.vue index b2a1dc58..9f9f16ba 100644 --- a/src/components/post_status_form/post_status_form.vue +++ b/src/components/post_status_form/post_status_form.vue @@ -56,14 +56,18 @@

-
-
-
-
- - {{candidate.utf}} - {{candidate.screen_name}}{{candidate.name}} -
+
+
+
+ + {{candidate.utf}} + {{candidate.screen_name}}{{candidate.name}}
@@ -262,50 +266,5 @@ cursor: pointer; z-index: 4; } - - .autocomplete-panel { - margin: 0 0.5em 0 0.5em; - border-radius: $fallback--tooltipRadius; - border-radius: var(--tooltipRadius, $fallback--tooltipRadius); - position: absolute; - z-index: 1; - box-shadow: 1px 2px 4px rgba(0, 0, 0, 0.5); - // this doesn't match original but i don't care, making it uniform. - box-shadow: var(--popupShadow); - min-width: 75%; - background: $fallback--bg; - background: var(--bg, $fallback--bg); - color: $fallback--lightText; - color: var(--lightText, $fallback--lightText); - } - - .autocomplete { - cursor: pointer; - padding: 0.2em 0.4em 0.2em 0.4em; - border-bottom: 1px solid rgba(0, 0, 0, 0.4); - display: flex; - - img { - width: 24px; - height: 24px; - object-fit: contain; - } - - span { - line-height: 24px; - margin: 0 0.1em 0 0.2em; - } - - small { - margin-left: .5em; - color: $fallback--faint; - color: var(--faint, $fallback--faint); - } - - &.highlighted { - background-color: $fallback--fg; - background-color: var(--lightBg, $fallback--fg); - } - } } -- cgit v1.2.3-70-g09d2 From bf927122df94853593a000ae873e8c840674258f Mon Sep 17 00:00:00 2001 From: Henry Jameson Date: Sat, 30 Mar 2019 12:25:23 +0200 Subject: Review --- BREAKING_CHANGES.md | 6 ++++++ src/components/post_status_form/post_status_form.vue | 1 - src/components/scope_selector/scope_selector.js | 3 +-- 3 files changed, 7 insertions(+), 3 deletions(-) create mode 100644 BREAKING_CHANGES.md (limited to 'src/components/post_status_form') diff --git a/BREAKING_CHANGES.md b/BREAKING_CHANGES.md new file mode 100644 index 00000000..915aa74c --- /dev/null +++ b/BREAKING_CHANGES.md @@ -0,0 +1,6 @@ +# v1.0 +## Removed features/radically changed behavior +* As of !633, `scopeOptions` is no longer available and instead is changed for `scopeOptionsMinimal` (default: `false`) +Reasoning is that scopeOptions option originally existed mostly as a backwards-compatibility with GNU Social which only had `public` scope available and using scope selector would''t work. Since at some point we dropped GNU Social support, this option was mostly a nuisance (being default `false`'), however some people think scopes are an annoyance to a certain degree and want as less of that feature as possible. +Solution - to only show minimal set among: *Direct*, *User default* and *Scope of post replying to*. This also makes it impossible to reply to a DM with a non-DM post from UI. +*This setting is admin-default, user-configurable. Admin can choose different default for their instance but user can override it.* diff --git a/src/components/post_status_form/post_status_form.vue b/src/components/post_status_form/post_status_form.vue index b3d731cd..8beb73a9 100644 --- a/src/components/post_status_form/post_status_form.vue +++ b/src/components/post_status_form/post_status_form.vue @@ -46,7 +46,6 @@ Date: Sat, 30 Mar 2019 12:41:42 +0200 Subject: aaaaggghh --- BREAKING_CHANGES.md | 4 ++-- src/components/features_panel/features_panel.js | 2 +- src/components/post_status_form/post_status_form.js | 4 ++-- src/components/user_settings/user_settings.js | 4 ++-- 4 files changed, 7 insertions(+), 7 deletions(-) (limited to 'src/components/post_status_form') diff --git a/BREAKING_CHANGES.md b/BREAKING_CHANGES.md index 45f7c74b..924c38da 100644 --- a/BREAKING_CHANGES.md +++ b/BREAKING_CHANGES.md @@ -1,7 +1,7 @@ # v1.0 ## Removed features/radically changed behavior -### scopeOptionsMinimal -As of !633, `scopeOptions` is no longer available and instead is changed for `scopeOptionsMinimal` (default: `false`) +### minimalScopesMode +As of !633, `scopeOptions` is no longer available and instead is changed for `minimalScopesMode` (default: `false`) Reasoning is that scopeOptions option originally existed mostly as a backwards-compatibility with GNU Social which only had `public` scope available and using scope selector would''t work. Since at some point we dropped GNU Social support, this option was mostly a nuisance (being default `false`'), however some people think scopes are an annoyance to a certain degree and want as less of that feature as possible. diff --git a/src/components/features_panel/features_panel.js b/src/components/features_panel/features_panel.js index 0a7234cc..5f0b7b25 100644 --- a/src/components/features_panel/features_panel.js +++ b/src/components/features_panel/features_panel.js @@ -6,7 +6,7 @@ const FeaturesPanel = { gopher: function () { return this.$store.state.instance.gopherAvailable }, whoToFollow: function () { return this.$store.state.instance.suggestionsEnabled }, mediaProxy: function () { return this.$store.state.instance.mediaProxyAvailable }, - scopeOptionsMinimal: function () { return this.$store.state.instance.scopeOptionsMinimal }, + minimalScopesMode: function () { return this.$store.state.instance.minimalScopesMode }, textlimit: function () { return this.$store.state.instance.textlimit } } } diff --git a/src/components/post_status_form/post_status_form.js b/src/components/post_status_form/post_status_form.js index 499cbbfb..40e2610e 100644 --- a/src/components/post_status_form/post_status_form.js +++ b/src/components/post_status_form/post_status_form.js @@ -162,8 +162,8 @@ const PostStatusForm = { isOverLengthLimit () { return this.hasStatusLengthLimit && (this.charactersLeft < 0) }, - scopeOptionsMinimal () { - return this.$store.state.instance.scopeOptionsMinimal + minimalScopesMode () { + return this.$store.state.instance.minimalScopesMode }, alwaysShowSubject () { if (typeof this.$store.state.config.alwaysShowSubjectInput !== 'undefined') { diff --git a/src/components/user_settings/user_settings.js b/src/components/user_settings/user_settings.js index 4b277b6c..b6a0479d 100644 --- a/src/components/user_settings/user_settings.js +++ b/src/components/user_settings/user_settings.js @@ -82,8 +82,8 @@ const UserSettings = { pleromaBackend () { return this.$store.state.instance.pleromaBackend }, - scopeOptionsMinimal () { - return this.$store.state.instance.scopeOptionsMinimal + minimalScopesMode () { + return this.$store.state.instance.minimalScopesMode }, vis () { return { -- cgit v1.2.3-70-g09d2