aboutsummaryrefslogtreecommitdiff
path: root/src/components/autocomplete_input
diff options
context:
space:
mode:
Diffstat (limited to 'src/components/autocomplete_input')
-rw-r--r--src/components/autocomplete_input/autocomplete_input.js150
-rw-r--r--src/components/autocomplete_input/autocomplete_input.vue104
2 files changed, 0 insertions, 254 deletions
diff --git a/src/components/autocomplete_input/autocomplete_input.js b/src/components/autocomplete_input/autocomplete_input.js
deleted file mode 100644
index 2a959fd1..00000000
--- a/src/components/autocomplete_input/autocomplete_input.js
+++ /dev/null
@@ -1,150 +0,0 @@
-import Completion from '../../services/completion/completion.js'
-import { take, filter, map } from 'lodash'
-
-const AutoCompleteInput = {
- props: [
- 'id',
- 'classObj',
- 'value',
- 'placeholder',
- 'autoResize',
- 'multiline',
- 'drop',
- 'dragoverPrevent',
- 'paste',
- 'keydownMetaEnter',
- 'keyupCtrlEnter'
- ],
- components: {},
- mounted () {
- this.autoResize && this.resize(this.$refs.textarea)
- const textLength = this.$refs.textarea.value.length
- this.$refs.textarea.setSelectionRange(textLength, textLength)
- },
- data () {
- return {
- caret: 0,
- highlighted: 0,
- text: this.value
- }
- },
- computed: {
- users () {
- return this.$store.state.users.users
- },
- emoji () {
- return this.$store.state.instance.emoji || []
- },
- customEmoji () {
- return this.$store.state.instance.customEmoji || []
- },
- textAtCaret () {
- return (this.wordAtCaret || {}).word || ''
- },
- wordAtCaret () {
- const word = Completion.wordAtPosition(this.text, this.caret - 1) || {}
- return word
- },
- candidates () {
- const firstchar = this.textAtCaret.charAt(0)
- if (firstchar === '@') {
- const query = this.textAtCaret.slice(1).toUpperCase()
- const matchedUsers = filter(this.users, (user) => {
- return user.screen_name.toUpperCase().startsWith(query) ||
- user.name && user.name.toUpperCase().startsWith(query)
- })
- if (matchedUsers.length <= 0) {
- return false
- }
- // eslint-disable-next-line camelcase
- return map(take(matchedUsers, 5), ({screen_name, name, profile_image_url_original}, index) => ({
- // eslint-disable-next-line camelcase
- screen_name: `@${screen_name}`,
- name: name,
- img: profile_image_url_original,
- highlighted: index === this.highlighted
- }))
- } else 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) => ({
- screen_name: `:${shortcode}:`,
- name: '',
- utf: utf || '',
- // eslint-disable-next-line camelcase
- img: utf ? '' : this.$store.state.instance.server + image_url,
- highlighted: index === this.highlighted
- }))
- } else {
- return false
- }
- }
- },
- methods: {
- setCaret ({target: {selectionStart}}) {
- this.caret = selectionStart
- },
- cycleBackward (e) {
- const len = this.candidates.length || 0
- if (len > 0) {
- e.preventDefault()
- this.highlighted -= 1
- if (this.highlighted < 0) {
- this.highlighted = this.candidates.length - 1
- }
- } else {
- this.highlighted = 0
- }
- },
- cycleForward (e) {
- const len = this.candidates.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
- }
- },
- replace (replacement) {
- this.text = Completion.replaceWord(this.text, this.wordAtCaret, replacement)
- const el = this.$el.querySelector('textarea')
- el.focus()
- this.caret = 0
- },
- replaceCandidate (e) {
- const len = this.candidates.length || 0
- if (this.textAtCaret === ':' || e.ctrlKey) { return }
- if (len > 0) {
- e.preventDefault()
- const candidate = this.candidates[this.highlighted]
- const replacement = candidate.utf || (candidate.screen_name + ' ')
- this.text = Completion.replaceWord(this.text, this.wordAtCaret, replacement)
- const el = this.$el.querySelector('textarea') || this.$el.querySelector('input')
- el.focus()
- this.caret = 0
- this.highlighted = 0
- }
- },
- resize (e) {
- const target = e.target || e
- if (!(target instanceof window.Element)) { return }
- const vertPadding = Number(window.getComputedStyle(target)['padding-top'].substr(0, 1)) +
- Number(window.getComputedStyle(target)['padding-bottom'].substr(0, 1))
- // Auto is needed to make textbox shrink when removing lines
- target.style.height = 'auto'
- target.style.height = `${target.scrollHeight - vertPadding}px`
- if (target.value === '') {
- target.style.height = null
- }
- }
- }
-}
-
-export default AutoCompleteInput
diff --git a/src/components/autocomplete_input/autocomplete_input.vue b/src/components/autocomplete_input/autocomplete_input.vue
deleted file mode 100644
index 56233535..00000000
--- a/src/components/autocomplete_input/autocomplete_input.vue
+++ /dev/null
@@ -1,104 +0,0 @@
-<template>
- <div style="display: flex; flex-direction: column;">
- <textarea
- v-if="multiline"
- ref="textarea"
- rows="1"
- :value="text" :class="classObj" :id="id" :placeholder="placeholder"
- @input="text = $event.target.value, $emit('input', $event.target.value), autoResize && resize($event)"
- @click="setCaret"
- @keyup="setCaret"
- @keydown.down="cycleForward"
- @keydown.up="cycleBackward"
- @keydown.shift.tab="cycleBackward"
- @keydown.tab="cycleForward"
- @keydown.enter="replaceCandidate"
- @drop="drop && drop()"
- @dragover.prevent="dragoverPrevent && dragoverPrevent()"
- @paste="paste && paste()"
- @keydown.meta.enter="keydownMetaEnter && keydownMetaEnter()"
- @keyup.ctrl.enter="keyupCtrlEnter && keyupCtrlEnter()">
- </textarea>
- <input
- v-else
- ref="textarea"
- :value="text" :class="classObj" :id="id" :placeholder="placeholder"
- @input="text = $event.target.value, $emit('input', $event.target.value), autoResize && resize($event)"
- @click="setCaret"
- @keyup="setCaret"
- @keydown.down="cycleForward"
- @keydown.up="cycleBackward"
- @keydown.shift.tab="cycleBackward"
- @keydown.tab="cycleForward"
- @keydown.enter="replaceCandidate"
- @drop="drop && drop()"
- @dragover.prevent="dragoverPrevent && dragoverPrevent()"
- @paste="paste && paste()"
- @keydown.meta.enter="keydownMetaEnter && keydownMetaEnter()"
- @keyup.ctrl.enter="keyupCtrlEnter && keyupCtrlEnter()"/>
- <div style="position:relative;" v-if="candidates">
- <div class="autocomplete-panel">
- <div v-for="candidate in candidates" @click="replace(candidate.utf || (candidate.screen_name + ' '))">
- <div class="autocomplete" :class="{ highlighted: candidate.highlighted }">
- <span v-if="candidate.img"><img :src="candidate.img"></img></span>
- <span v-else>{{candidate.utf}}</span>
- <span>{{candidate.screen_name}}<small>{{candidate.name}}</small></span>
- </div>
- </div>
- </div>
- </div>
- </div>
-</template>
-
-<script src="./autocomplete_input.js"></script>
-
-<style lang="scss">
-@import '../../_variables.scss';
-
-.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;
- border-radius: $fallback--avatarRadius;
- border-radius: var(--avatarRadius, $fallback--avatarRadius);
- 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);
- }
-}
-</style>