mirror of
https://github.com/pixelfed/pixelfed.git
synced 2024-11-10 00:34:50 +00:00
Add Autocomplete for hashtags + mentions
This commit is contained in:
parent
77e1115740
commit
de514f7d76
4 changed files with 138 additions and 55 deletions
|
@ -295,7 +295,9 @@
|
||||||
<div class="media-body">
|
<div class="media-body">
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label class="font-weight-bold text-muted small d-none">Caption</label>
|
<label class="font-weight-bold text-muted small d-none">Caption</label>
|
||||||
|
<vue-tribute :options="tributeSettings">
|
||||||
<textarea class="form-control border-0 rounded-0 no-focus" rows="3" placeholder="Write a caption..." style="" v-model="composeText" v-on:keyup="composeTextLength = composeText.length"></textarea>
|
<textarea class="form-control border-0 rounded-0 no-focus" rows="3" placeholder="Write a caption..." style="" v-model="composeText" v-on:keyup="composeTextLength = composeText.length"></textarea>
|
||||||
|
</vue-tribute>
|
||||||
<p class="help-text small text-right text-muted mb-0">{{composeTextLength}}/{{config.uploader.max_caption_length}}</p>
|
<p class="help-text small text-right text-muted mb-0">{{composeTextLength}}/{{config.uploader.max_caption_length}}</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -647,11 +649,14 @@ import VueCropper from 'vue-cropperjs';
|
||||||
import 'cropperjs/dist/cropper.css';
|
import 'cropperjs/dist/cropper.css';
|
||||||
import Autocomplete from '@trevoreyre/autocomplete-vue'
|
import Autocomplete from '@trevoreyre/autocomplete-vue'
|
||||||
import '@trevoreyre/autocomplete-vue/dist/style.css'
|
import '@trevoreyre/autocomplete-vue/dist/style.css'
|
||||||
|
import VueTribute from 'vue-tribute'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
|
|
||||||
components: {
|
components: {
|
||||||
VueCropper,
|
VueCropper,
|
||||||
Autocomplete
|
Autocomplete,
|
||||||
|
VueTribute
|
||||||
},
|
},
|
||||||
|
|
||||||
data() {
|
data() {
|
||||||
|
@ -707,7 +712,39 @@ export default {
|
||||||
cameraRollMedia: [],
|
cameraRollMedia: [],
|
||||||
taggedUsernames: [],
|
taggedUsernames: [],
|
||||||
taggedPeopleSearch: null,
|
taggedPeopleSearch: null,
|
||||||
textMode: false
|
textMode: false,
|
||||||
|
tributeSettings: {
|
||||||
|
collection: [
|
||||||
|
{
|
||||||
|
trigger: '@',
|
||||||
|
menuShowMinLength: 2,
|
||||||
|
values: (function (text, cb) {
|
||||||
|
let url = '/api/compose/v0/search/mention';
|
||||||
|
axios.get(url, { params: { q: text }})
|
||||||
|
.then(res => {
|
||||||
|
cb(res.data);
|
||||||
|
})
|
||||||
|
.catch(err => {
|
||||||
|
console.log(err);
|
||||||
|
})
|
||||||
|
})
|
||||||
|
},
|
||||||
|
{
|
||||||
|
trigger: '#',
|
||||||
|
menuShowMinLength: 2,
|
||||||
|
values: (function (text, cb) {
|
||||||
|
let url = '/api/compose/v0/search/hashtag';
|
||||||
|
axios.get(url, { params: { q: text }})
|
||||||
|
.then(res => {
|
||||||
|
cb(res.data);
|
||||||
|
})
|
||||||
|
.catch(err => {
|
||||||
|
console.log(err);
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
|
@ -643,8 +643,10 @@
|
||||||
size="md"
|
size="md"
|
||||||
body-class="p-2 rounded">
|
body-class="p-2 rounded">
|
||||||
<div>
|
<div>
|
||||||
|
<vue-tribute :options="tributeSettings">
|
||||||
<textarea class="form-control" rows="4" style="border: none; font-size: 18px; resize: none; white-space: pre-wrap;outline: none;" placeholder="Reply here ..." v-model="replyText">
|
<textarea class="form-control" rows="4" style="border: none; font-size: 18px; resize: none; white-space: pre-wrap;outline: none;" placeholder="Reply here ..." v-model="replyText">
|
||||||
</textarea>
|
</textarea>
|
||||||
|
</vue-tribute>
|
||||||
|
|
||||||
<div class="border-top border-bottom my-2">
|
<div class="border-top border-bottom my-2">
|
||||||
<ul class="nav align-items-center emoji-reactions" style="overflow-x: scroll;flex-wrap: unset;">
|
<ul class="nav align-items-center emoji-reactions" style="overflow-x: scroll;flex-wrap: unset;">
|
||||||
|
@ -757,10 +759,12 @@
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
import VueTribute from 'vue-tribute'
|
||||||
|
|
||||||
pixelfed.postComponent = {};
|
pixelfed.postComponent = {};
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
|
|
||||||
props: [
|
props: [
|
||||||
'status-id',
|
'status-id',
|
||||||
'status-username',
|
'status-username',
|
||||||
|
@ -771,6 +775,11 @@ export default {
|
||||||
'status-profile-id',
|
'status-profile-id',
|
||||||
'profile-layout'
|
'profile-layout'
|
||||||
],
|
],
|
||||||
|
|
||||||
|
components: {
|
||||||
|
VueTribute
|
||||||
|
},
|
||||||
|
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
config: window.App.config,
|
config: window.App.config,
|
||||||
|
@ -817,6 +826,38 @@ export default {
|
||||||
profileMorePosts: [],
|
profileMorePosts: [],
|
||||||
replySending: false,
|
replySending: false,
|
||||||
reactionBarLoading: true,
|
reactionBarLoading: true,
|
||||||
|
tributeSettings: {
|
||||||
|
collection: [
|
||||||
|
{
|
||||||
|
trigger: '@',
|
||||||
|
menuShowMinLength: 2,
|
||||||
|
values: (function (text, cb) {
|
||||||
|
let url = '/api/compose/v0/search/mention';
|
||||||
|
axios.get(url, { params: { q: text }})
|
||||||
|
.then(res => {
|
||||||
|
cb(res.data);
|
||||||
|
})
|
||||||
|
.catch(err => {
|
||||||
|
console.log(err);
|
||||||
|
})
|
||||||
|
})
|
||||||
|
},
|
||||||
|
{
|
||||||
|
trigger: '#',
|
||||||
|
menuShowMinLength: 2,
|
||||||
|
values: (function (text, cb) {
|
||||||
|
let url = '/api/compose/v0/search/hashtag';
|
||||||
|
axios.get(url, { params: { q: text }})
|
||||||
|
.then(res => {
|
||||||
|
cb(res.data);
|
||||||
|
})
|
||||||
|
.catch(err => {
|
||||||
|
console.log(err);
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
watch: {
|
watch: {
|
||||||
|
|
|
@ -2224,52 +2224,3 @@
|
||||||
box-shadow: none;
|
box-shadow: none;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
<style type="text/css">
|
|
||||||
.tribute-container {
|
|
||||||
position: absolute;
|
|
||||||
top: 0;
|
|
||||||
left: 0;
|
|
||||||
height: auto;
|
|
||||||
max-height: 300px;
|
|
||||||
min-width: 120px;
|
|
||||||
max-width: 100vw;
|
|
||||||
overflow: auto;
|
|
||||||
display: block;
|
|
||||||
z-index: 999999;
|
|
||||||
border: 1px solid #ccc;
|
|
||||||
border-radius: 4px;
|
|
||||||
box-shadow: 0 1px 4px rgba(#000, 0.13);
|
|
||||||
}
|
|
||||||
.tribute-container ul {
|
|
||||||
margin: 0;
|
|
||||||
margin-top: 2px;
|
|
||||||
padding: 0;
|
|
||||||
list-style: none;
|
|
||||||
background: #fff;
|
|
||||||
border-radius: 4px;
|
|
||||||
border: 1px solid rgba(#000, 0.13);
|
|
||||||
background-clip: padding-box;
|
|
||||||
overflow: hidden;
|
|
||||||
}
|
|
||||||
.tribute-container li {
|
|
||||||
color: #000;
|
|
||||||
padding: 5px 15px;
|
|
||||||
cursor: pointer;
|
|
||||||
font-size: 14px;
|
|
||||||
overflow-x: hidden !important;
|
|
||||||
}
|
|
||||||
.tribute-container li.highlight,
|
|
||||||
.tribute-container li:hover {
|
|
||||||
background: #2c78bf;
|
|
||||||
color: #fff;
|
|
||||||
}
|
|
||||||
.tribute-container li span {
|
|
||||||
font-weight: bold;
|
|
||||||
}
|
|
||||||
.tribute-container li.no-match {
|
|
||||||
cursor: default;
|
|
||||||
}
|
|
||||||
.tribute-container .menu-highlighted {
|
|
||||||
font-weight: bold;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
|
|
54
resources/assets/sass/custom.scss
vendored
54
resources/assets/sass/custom.scss
vendored
|
@ -595,3 +595,57 @@ details summary::-webkit-details-marker {
|
||||||
height: 100%;
|
height: 100%;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.tribute-container {
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
height: auto;
|
||||||
|
max-height: 300px;
|
||||||
|
min-width: 120px;
|
||||||
|
max-width: 100vw;
|
||||||
|
overflow: auto;
|
||||||
|
display: block;
|
||||||
|
z-index: 999999;
|
||||||
|
border: 1px solid #ccc;
|
||||||
|
border-radius: 4px;
|
||||||
|
box-shadow: 0 1px 4px rgba(#000, 0.13);
|
||||||
|
}
|
||||||
|
|
||||||
|
.tribute-container ul {
|
||||||
|
margin: 0;
|
||||||
|
margin-top: 2px;
|
||||||
|
padding: 0;
|
||||||
|
list-style: none;
|
||||||
|
background: #fff;
|
||||||
|
border-radius: 4px;
|
||||||
|
border: 1px solid rgba(#000, 0.13);
|
||||||
|
background-clip: padding-box;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tribute-container li {
|
||||||
|
color: #000;
|
||||||
|
padding: 5px 15px;
|
||||||
|
cursor: pointer;
|
||||||
|
font-size: 14px;
|
||||||
|
overflow-x: hidden !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tribute-container li.highlight,
|
||||||
|
.tribute-container li:hover {
|
||||||
|
background: #2c78bf;
|
||||||
|
color: #fff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tribute-container li span {
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tribute-container li.no-match {
|
||||||
|
cursor: default;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tribute-container .menu-highlighted {
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in a new issue