mirror of
https://github.com/styppo/hamstr.git
synced 2024-10-18 13:33:22 +00:00
Merge pull request #20 from Cameri/feature/add-mentionable-textarea
This commit is contained in:
commit
390f2241c4
@ -29,6 +29,7 @@
|
|||||||
"relative-date": "^1.1.3",
|
"relative-date": "^1.1.3",
|
||||||
"stream": "^0.0.2",
|
"stream": "^0.0.2",
|
||||||
"tailwindcss": "^3.0.1",
|
"tailwindcss": "^3.0.1",
|
||||||
|
"tributejs": "^5.1.3",
|
||||||
"vuex": "^4.0.1"
|
"vuex": "^4.0.1"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
@ -27,7 +27,11 @@ module.exports = configure(function (ctx) {
|
|||||||
boot: ['global-components'],
|
boot: ['global-components'],
|
||||||
|
|
||||||
// https://quasar.dev/quasar-cli/quasar-conf-js#Property%3A-css
|
// https://quasar.dev/quasar-cli/quasar-conf-js#Property%3A-css
|
||||||
css: ['add-tailwind.css', '../../node_modules/highlight.js/styles/base16/solarized-light.css'],
|
css: [
|
||||||
|
'add-tailwind.css',
|
||||||
|
'../../node_modules/highlight.js/styles/base16/solarized-light.css',
|
||||||
|
'../../node_modules/tributejs/tribute.css'
|
||||||
|
],
|
||||||
|
|
||||||
// https://github.com/quasarframework/quasar/tree/dev/extras
|
// https://github.com/quasarframework/quasar/tree/dev/extras
|
||||||
extras: [
|
extras: [
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
<q-card-section>
|
<q-card-section>
|
||||||
<q-form @submit="sendPost">
|
<q-form @submit="sendPost">
|
||||||
<q-input
|
<q-input
|
||||||
|
ref="input"
|
||||||
v-model="text"
|
v-model="text"
|
||||||
autogrow
|
autogrow
|
||||||
autofocus
|
autofocus
|
||||||
@ -44,9 +45,27 @@ export default {
|
|||||||
|
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
text: ''
|
text: '',
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
computed: {
|
||||||
|
textarea() {
|
||||||
|
return this.$refs.input.$el.querySelector('textarea')
|
||||||
|
},
|
||||||
|
mentions() {
|
||||||
|
return this.createMentionsProvider()
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
mounted() {
|
||||||
|
this.mentions.attach(this.textarea)
|
||||||
|
},
|
||||||
|
|
||||||
|
beforeUnmount() {
|
||||||
|
this.mentions.detach(this.textarea)
|
||||||
|
},
|
||||||
|
|
||||||
methods: {
|
methods: {
|
||||||
async sendPost() {
|
async sendPost() {
|
||||||
if (!this.text.length) {
|
if (!this.text.length) {
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
<template>
|
<template>
|
||||||
<q-form class="px-24" @submit="sendReply">
|
<q-form class="px-24" @submit="sendReply">
|
||||||
<q-input
|
<q-input
|
||||||
|
ref="input"
|
||||||
v-model="text"
|
v-model="text"
|
||||||
autogrow
|
autogrow
|
||||||
autofocus
|
autofocus
|
||||||
@ -32,6 +33,23 @@ export default {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
computed: {
|
||||||
|
textarea() {
|
||||||
|
return this.$refs.input.$el.querySelector('textarea')
|
||||||
|
},
|
||||||
|
mentions() {
|
||||||
|
return this.createMentionsProvider()
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
mounted() {
|
||||||
|
this.mentions.attach(this.textarea)
|
||||||
|
},
|
||||||
|
|
||||||
|
beforeUnmount() {
|
||||||
|
this.mentions.detach(this.textarea)
|
||||||
|
},
|
||||||
|
|
||||||
methods: {
|
methods: {
|
||||||
async sendReply() {
|
async sendReply() {
|
||||||
if (!this.text.length) {
|
if (!this.text.length) {
|
||||||
|
@ -1,5 +1,14 @@
|
|||||||
import Identicon from 'identicon.js'
|
import Identicon from 'identicon.js'
|
||||||
|
|
||||||
|
export function namedProfiles(state, getters) {
|
||||||
|
return Object.entries(state.profilesCache)
|
||||||
|
.reduce((result, [pubkey, profile]) => getters.hasName(pubkey)
|
||||||
|
? [...result, { ...profile, pubkey }] // [..., { name, pubkey, nip05, ...}, ...]
|
||||||
|
: result,
|
||||||
|
[]
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
export function hasName(state) {
|
export function hasName(state) {
|
||||||
return pubkey => {
|
return pubkey => {
|
||||||
let {name, nip05} = state.profilesCache[pubkey] || {}
|
let {name, nip05} = state.profilesCache[pubkey] || {}
|
||||||
|
@ -1,3 +1,7 @@
|
|||||||
|
export function shorten(str) {
|
||||||
|
return str ? str.slice(0, 3) + '…' + str.slice(-4) : ''
|
||||||
|
}
|
||||||
|
|
||||||
export function getElementFullHeight(element) {
|
export function getElementFullHeight(element) {
|
||||||
let styles = window.getComputedStyle(element)
|
let styles = window.getComputedStyle(element)
|
||||||
let margin =
|
let margin =
|
||||||
@ -54,7 +58,7 @@ export function processMentions(event) {
|
|||||||
match => match.groups.p
|
match => match.groups.p
|
||||||
)
|
)
|
||||||
|
|
||||||
const tags = Array.from(new Set(matches).values()).reduce(
|
const tags = matches.reduce(
|
||||||
(tags, pubkey) =>
|
(tags, pubkey) =>
|
||||||
tags.find(([t, v]) => t === 'p' && v === pubkey)
|
tags.find(([t, v]) => t === 'p' && v === pubkey)
|
||||||
? tags
|
? tags
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
import relative from 'relative-date'
|
import relative from 'relative-date'
|
||||||
import {date} from 'quasar'
|
import {date} from 'quasar'
|
||||||
|
import Tribute from 'tributejs'
|
||||||
|
import {shorten} from './helpers'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
methods: {
|
methods: {
|
||||||
@ -19,9 +21,7 @@ export default {
|
|||||||
this.$router.push('/event/' + id)
|
this.$router.push('/event/' + id)
|
||||||
},
|
},
|
||||||
|
|
||||||
shorten(str) {
|
shorten,
|
||||||
return str ? str.slice(0, 3) + '…' + str.slice(-4) : ''
|
|
||||||
},
|
|
||||||
|
|
||||||
niceDate(value) {
|
niceDate(value) {
|
||||||
if (value + 60 * 60 /* an hour */ > Date.now() / 1000) {
|
if (value + 60 * 60 /* an hour */ > Date.now() / 1000) {
|
||||||
@ -39,6 +39,47 @@ export default {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return text.replace(/\B#\[(\d+)\]\B/g, replacer)
|
return text.replace(/\B#\[(\d+)\]\B/g, replacer)
|
||||||
|
},
|
||||||
|
|
||||||
|
createMentionsProvider(options) {
|
||||||
|
const tribute = new Tribute({
|
||||||
|
spaceSelectsMatch: true,
|
||||||
|
menuShowMinLength: 1,
|
||||||
|
|
||||||
|
selectTemplate: item => `@${item.original.value.pubkey}`,
|
||||||
|
|
||||||
|
menuItemTemplate: item => {
|
||||||
|
return `
|
||||||
|
<div class="flex items-center">
|
||||||
|
<div class="inline-flex items-center">
|
||||||
|
<div class="text-secondary mr-2">${item.string}</div>
|
||||||
|
${item.original.value.nip05
|
||||||
|
? '<i class="notranslate material-icons text-accent mr-1 -ml-1" aria-hidden="true" role="presentation">verified</i>'
|
||||||
|
: ''}
|
||||||
|
</div>
|
||||||
|
<div class="text-accent font-mono text-xs">${shorten(item.original.value.pubkey)}</div>
|
||||||
|
</div>
|
||||||
|
`
|
||||||
|
},
|
||||||
|
|
||||||
|
values: (_pattern, callback) => {
|
||||||
|
callback(
|
||||||
|
this.$store.getters
|
||||||
|
.namedProfiles
|
||||||
|
.map(profile => ({
|
||||||
|
key: this.$store.getters.displayName(profile.pubkey),
|
||||||
|
value: profile,
|
||||||
|
}))
|
||||||
|
)
|
||||||
|
},
|
||||||
|
|
||||||
|
noMatchTemplate: () => undefined, // hide "No matches"
|
||||||
|
})
|
||||||
|
|
||||||
|
return {
|
||||||
|
attach: element => tribute.attach(element),
|
||||||
|
detach: element => tribute.detach(element),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -6631,6 +6631,11 @@ totalist@^1.0.0:
|
|||||||
resolved "https://registry.yarnpkg.com/totalist/-/totalist-1.1.0.tgz#a4d65a3e546517701e3e5c37a47a70ac97fe56df"
|
resolved "https://registry.yarnpkg.com/totalist/-/totalist-1.1.0.tgz#a4d65a3e546517701e3e5c37a47a70ac97fe56df"
|
||||||
integrity sha512-gduQwd1rOdDMGxFG1gEvhV88Oirdo2p+KjoYFU7k2g+i7n6AFFbDQ5kMPUsW0pNbfQsB/cwXvT1i4Bue0s9g5g==
|
integrity sha512-gduQwd1rOdDMGxFG1gEvhV88Oirdo2p+KjoYFU7k2g+i7n6AFFbDQ5kMPUsW0pNbfQsB/cwXvT1i4Bue0s9g5g==
|
||||||
|
|
||||||
|
tributejs@^5.1.3:
|
||||||
|
version "5.1.3"
|
||||||
|
resolved "https://registry.yarnpkg.com/tributejs/-/tributejs-5.1.3.tgz#980600fc72865be5868893078b4bfde721129eae"
|
||||||
|
integrity sha512-B5CXihaVzXw+1UHhNFyAwUTMDk1EfoLP5Tj1VhD9yybZ1I8DZJEv8tZ1l0RJo0t0tk9ZhR8eG5tEsaCvRigmdQ==
|
||||||
|
|
||||||
trim-left-x@^3.0.0:
|
trim-left-x@^3.0.0:
|
||||||
version "3.0.0"
|
version "3.0.0"
|
||||||
resolved "https://registry.yarnpkg.com/trim-left-x/-/trim-left-x-3.0.0.tgz#356cf055896726b9754425e841398842e90b4cdf"
|
resolved "https://registry.yarnpkg.com/trim-left-x/-/trim-left-x-3.0.0.tgz#356cf055896726b9754425e841398842e90b4cdf"
|
||||||
|
Loading…
Reference in New Issue
Block a user