Mastodon: emojis

This commit is contained in:
May B. 2019-05-28 09:35:50 +02:00
parent 539b15437c
commit 240ace2ced
4 changed files with 35 additions and 16 deletions

View File

@ -43,4 +43,12 @@ export default abstract class Lists {
}
}
static sort<T, U>(list: T[], mapper: (val: T) => U, comparer: (a: U, b: U) => number) {
return list.sort((a, b) => comparer(mapper(a), mapper(b)))
}
static stringCompare(a: string, b: string) {
return ('' + a).localeCompare(b)
}
}

View File

@ -15,9 +15,15 @@
notification(v-for="notification in notifications.get()" :key="notification.id" :notification="notification"
:showMedia="options.showMedia" @dismiss="onNotificationDismiss" @mark="onStatusMark")
.compose-toggle(@click="showCompose = !showCompose") 🖉
.emoji-list(v-show="showCompose && showEmojis")
img.emoji(v-for="emoji in emojis.get()" @click="addEmoji(emoji.shortcode)" :src="emoji.static_url" :alt="emoji.shortcode" :title="emoji.shortcode")
.compose(v-show="showCompose")
textarea.content(v-model="compose.status" placeholder="message")
.options
.emojis
button(v-if="options.showMedia" @click="showEmojis = !showEmojis")
select(v-else @change="addEmoji($event.target.value)")
option(v-for="emoji in emojis.get()" :value="emoji.shortcode") {{ emoji.shortcode }}
.sens
label.note(for="sensitive") Sensitive:&nbsp;
input(id="sensitive" v-model="compose.sensitive" type="checkbox")
@ -44,7 +50,7 @@ import AxiosLodableMore from '@/helpers/loadable/AxiosLoadableMore'
import { AUTH, getHeaders, getRest } from './Mastodon.vue'
import Notification from './Notification.vue'
import Status from './Status.vue'
import { MarkMessage, Notification as INotification, Options, Status as IStatus, StatusPost, TimelineType } from './Types'
import { Emoji, MarkMessage, Notification as INotification, Options, Status as IStatus, StatusPost, TimelineType } from './Types'
const STREAMS = {
home: 'user',
@ -55,16 +61,11 @@ const STREAMS = {
@Component({ components: { Status, Notification } })
export default class Client extends Mixins<ServiceClient<Options>>(ServiceClient) {
/*
home: timelines/home
local: timelines/public?local=true
public: timelines/public?...
*/
rest = getRest(this.auth, this.options.timeout)
statues = new AxiosLodableMore<IStatus[], object>()
notifications = new AxiosLodable<INotification[], object>()
emojis = new AxiosLodable<Emoji[], object>()
stream?: WebSocket = undefined
showCompose = false
@ -74,6 +75,7 @@ export default class Client extends Mixins<ServiceClient<Options>>(ServiceClient
sensitive: false,
spoiler_text: ''
}
showEmojis = false // MAYBE: show tabs with unicode emoticons
get hasNotifications() {
if(!this.notifications.isSuccess) {
@ -91,6 +93,7 @@ export default class Client extends Mixins<ServiceClient<Options>>(ServiceClient
created() {
this.$watch('options.timeline', this.init, { immediate: true })
this.notifications.load(this.get('/notifications'))
this.emojis.load<Emoji[]>(this.get('/custom_emojis'), res => Lists.sort(res.data, e => e.shortcode, Lists.stringCompare))
}
init() {
@ -106,6 +109,10 @@ export default class Client extends Mixins<ServiceClient<Options>>(ServiceClient
return this.catchEmit(this.rest.post(path, options))
}
addEmoji(code: string) {
this.compose.status += `:${code}:`
}
sendStatus() {
if(this.compose.status) {
const post: StatusPost = {
@ -212,15 +219,13 @@ export default class Client extends Mixins<ServiceClient<Options>>(ServiceClient
height: 100%
overflow: hidden
position: relative
.header
.header, .emoji-list
@include main-tile
.list
@include group-tile
.statues
.statues, .notifications, .emoji-list
flex: 1
overflow-y: auto
.notifications
max-width: 33%
.compose-toggle
position: absolute
bottom: .5em
@ -232,6 +237,10 @@ export default class Client extends Mixins<ServiceClient<Options>>(ServiceClient
width: 2em
text-align: center
line-height: 2em
.emoji-list
img
width: 2em
height: 2em
.compose
@include main-tile
display: flex

View File

@ -5,7 +5,7 @@
| {{ serviceName }}:
loadable-inline(:loadable="account")
template(#success)
span(v-html="parseEmojis(account.data.display_name, account.data.emojis) + '@' + server", params.showMedia)
span(v-html="parseEmojis(account.data.display_name, account.data.emojis, params.showMedia) + '@' + server", params.showMedia)
template(#settings)
setting-boolean(:id="'reconnect'" :title="'Reconnect'" :value="params.reconnect" @change="saveOptionCouple")
setting-boolean(:id="'reblog'" :title="'Show reblogs'" :value="params.reblog" @change="saveOptionCouple")

View File

@ -6,10 +6,12 @@ import { Emoji } from './Types'
export class ParseEmojisMixin extends Vue {
parseEmojis(text: string, emojis: Emoji[], show = true) {
for (const emoji of emojis) {
text = text.split(`:${emoji.shortcode}:`).join(
show ? `<img draggable="false" class="icon" alt="${emoji.shortcode}" title="${emoji.shortcode}" src="${emoji.static_url}">` : emoji.shortcode
)
if (show) {
for (const emoji of emojis) {
text = text.split(`:${emoji.shortcode}:`).join(
`<img draggable="false" class="icon" alt="${emoji.shortcode}" title="${emoji.shortcode}" src="${emoji.static_url}">`
)
}
}
return text
}