mirror of
https://git.joinsharkey.org/Sharkey/Sharkey.git
synced 2024-11-27 20:13:09 +02:00
parent
86fcd3a378
commit
c21caad1c5
7 changed files with 91 additions and 8 deletions
|
@ -14,7 +14,8 @@
|
||||||
</ol>
|
</ol>
|
||||||
<ol class="emojis" ref="suggests" v-if="emojis.length > 0">
|
<ol class="emojis" ref="suggests" v-if="emojis.length > 0">
|
||||||
<li v-for="emoji in emojis" @click="complete(type, emoji.emoji)" @keydown="onKeydown" tabindex="-1">
|
<li v-for="emoji in emojis" @click="complete(type, emoji.emoji)" @keydown="onKeydown" tabindex="-1">
|
||||||
<span class="emoji">{{ emoji.emoji }}</span>
|
<span class="emoji" v-if="emoji.url"><img :src="emoji.url" :alt="emoji.emoji"/></span>
|
||||||
|
<span class="emoji" v-else>{{ emoji.emoji }}</span>
|
||||||
<span class="name" v-html="emoji.name.replace(q, `<b>${q}</b>`)"></span>
|
<span class="name" v-html="emoji.name.replace(q, `<b>${q}</b>`)"></span>
|
||||||
<span class="alias" v-if="emoji.alias">({{ emoji.alias }})</span>
|
<span class="alias" v-if="emoji.alias">({{ emoji.alias }})</span>
|
||||||
</li>
|
</li>
|
||||||
|
@ -169,22 +170,45 @@ export default Vue.extend({
|
||||||
}
|
}
|
||||||
} else if (this.type == 'emoji') {
|
} else if (this.type == 'emoji') {
|
||||||
const matched = [];
|
const matched = [];
|
||||||
|
const max = 30;
|
||||||
|
|
||||||
|
const customEmojis = (this.os.getMetaSync() || { emojis: [] }).emojis;
|
||||||
|
customEmojis.some(x => {
|
||||||
|
if (x.name.startsWith(this.q)) matched.push({
|
||||||
|
name: x.name,
|
||||||
|
emoji: `:${x.name}:`,
|
||||||
|
url: x.url
|
||||||
|
});
|
||||||
|
return matched.length == max;
|
||||||
|
});
|
||||||
|
customEmojis.some(x => {
|
||||||
|
const alias = (x.aliases || []).find(a => a.startsWith(this.q));
|
||||||
|
if (alias) matched.push({
|
||||||
|
alias: x.name,
|
||||||
|
name: alias,
|
||||||
|
emoji: `:${x.name}:`,
|
||||||
|
url: x.url
|
||||||
|
});
|
||||||
|
return matched.length == max;
|
||||||
|
});
|
||||||
|
|
||||||
emjdb.some(x => {
|
emjdb.some(x => {
|
||||||
if (x.name.indexOf(this.q) == 0 && !x.alias && !matched.some(y => y.emoji == x.emoji)) matched.push(x);
|
if (x.name.indexOf(this.q) == 0 && !x.alias && !matched.some(y => y.emoji == x.emoji)) matched.push(x);
|
||||||
return matched.length == 30;
|
return matched.length == max;
|
||||||
});
|
});
|
||||||
if (matched.length < 30) {
|
if (matched.length < max) {
|
||||||
emjdb.some(x => {
|
emjdb.some(x => {
|
||||||
if (x.name.indexOf(this.q) == 0 && !matched.some(y => y.emoji == x.emoji)) matched.push(x);
|
if (x.name.indexOf(this.q) == 0 && !matched.some(y => y.emoji == x.emoji)) matched.push(x);
|
||||||
return matched.length == 30;
|
return matched.length == max;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
if (matched.length < 30) {
|
if (matched.length < max) {
|
||||||
emjdb.some(x => {
|
emjdb.some(x => {
|
||||||
if (x.name.indexOf(this.q) > -1 && !matched.some(y => y.emoji == x.emoji)) matched.push(x);
|
if (x.name.indexOf(this.q) > -1 && !matched.some(y => y.emoji == x.emoji)) matched.push(x);
|
||||||
return matched.length == 30;
|
return matched.length == max;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
this.emojis = matched;
|
this.emojis = matched;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -340,6 +364,10 @@ export default Vue.extend({
|
||||||
margin 0 4px 0 0
|
margin 0 4px 0 0
|
||||||
width 24px
|
width 24px
|
||||||
|
|
||||||
|
> img
|
||||||
|
width 24px
|
||||||
|
vertical-align bottom
|
||||||
|
|
||||||
.name
|
.name
|
||||||
color var(--autocompleteItemText)
|
color var(--autocompleteItemText)
|
||||||
|
|
||||||
|
|
|
@ -3,7 +3,6 @@ import * as emojilib from 'emojilib';
|
||||||
import { length } from 'stringz';
|
import { length } from 'stringz';
|
||||||
import parse from '../../../../../mfm/parse';
|
import parse from '../../../../../mfm/parse';
|
||||||
import getAcct from '../../../../../misc/acct/render';
|
import getAcct from '../../../../../misc/acct/render';
|
||||||
import { url } from '../../../config';
|
|
||||||
import MkUrl from './url.vue';
|
import MkUrl from './url.vue';
|
||||||
import MkGoogle from './google.vue';
|
import MkGoogle from './google.vue';
|
||||||
import { concat } from '../../../../../prelude/array';
|
import { concat } from '../../../../../prelude/array';
|
||||||
|
@ -186,6 +185,21 @@ export default Vue.component('misskey-flavored-markdown', {
|
||||||
}
|
}
|
||||||
|
|
||||||
case 'emoji': {
|
case 'emoji': {
|
||||||
|
//#region カスタム絵文字
|
||||||
|
const customEmojis = (this.os.getMetaSync() || { emojis: [] }).emojis;
|
||||||
|
const customEmoji = customEmojis.find(e => e.name == token.emoji || (e.aliases || []).includes(token.emoji));
|
||||||
|
if (customEmoji) {
|
||||||
|
return [createElement('img', {
|
||||||
|
attrs: {
|
||||||
|
src: customEmoji.url,
|
||||||
|
alt: token.emoji,
|
||||||
|
title: token.emoji,
|
||||||
|
style: 'height: 2.5em; vertical-align: middle;'
|
||||||
|
}
|
||||||
|
})];
|
||||||
|
}
|
||||||
|
//#endregion
|
||||||
|
|
||||||
const emoji = emojilib.lib[token.emoji];
|
const emoji = emojilib.lib[token.emoji];
|
||||||
return [createElement('span', emoji ? emoji.char : token.content)];
|
return [createElement('span', emoji ? emoji.char : token.content)];
|
||||||
}
|
}
|
||||||
|
|
|
@ -222,13 +222,15 @@ class Autocomplete {
|
||||||
const trimmedBefore = before.substring(0, before.lastIndexOf(':'));
|
const trimmedBefore = before.substring(0, before.lastIndexOf(':'));
|
||||||
const after = source.substr(caret);
|
const after = source.substr(caret);
|
||||||
|
|
||||||
|
if (value.startsWith(':')) value = value + ' ';
|
||||||
|
|
||||||
// 挿入
|
// 挿入
|
||||||
this.text = trimmedBefore + value + after;
|
this.text = trimmedBefore + value + after;
|
||||||
|
|
||||||
// キャレットを戻す
|
// キャレットを戻す
|
||||||
this.vm.$nextTick(() => {
|
this.vm.$nextTick(() => {
|
||||||
this.textarea.focus();
|
this.textarea.focus();
|
||||||
const pos = trimmedBefore.length + 1;
|
const pos = trimmedBefore.length + (value.startsWith(':') ? value.length : 1);
|
||||||
this.textarea.setSelectionRange(pos, pos);
|
this.textarea.setSelectionRange(pos, pos);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -510,6 +510,14 @@ export default class MiOS extends EventEmitter {
|
||||||
return promise;
|
return promise;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Misskeyのメタ情報を取得します
|
||||||
|
*/
|
||||||
|
@autobind
|
||||||
|
public getMetaSync() {
|
||||||
|
return this.meta ? this.meta.data : null;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Misskeyのメタ情報を取得します
|
* Misskeyのメタ情報を取得します
|
||||||
* @param force キャッシュを無視するか否か
|
* @param force キャッシュを無視するか否か
|
||||||
|
|
|
@ -15,4 +15,24 @@ export type IMeta = {
|
||||||
disableLocalTimeline?: boolean;
|
disableLocalTimeline?: boolean;
|
||||||
hidedTags?: string[];
|
hidedTags?: string[];
|
||||||
bannerUrl?: string;
|
bannerUrl?: string;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* カスタム絵文字定義
|
||||||
|
*/
|
||||||
|
emojis?: {
|
||||||
|
/**
|
||||||
|
* 絵文字名 (例: thinking_ai)
|
||||||
|
*/
|
||||||
|
name: string;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* エイリアス
|
||||||
|
*/
|
||||||
|
aliases?: string[];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 絵文字画像のURL
|
||||||
|
*/
|
||||||
|
url: string;
|
||||||
|
}[];
|
||||||
};
|
};
|
||||||
|
|
|
@ -17,6 +17,12 @@ export const meta = {
|
||||||
}
|
}
|
||||||
}),
|
}),
|
||||||
|
|
||||||
|
emojis: $.arr($.obj()).optional.note({
|
||||||
|
desc: {
|
||||||
|
'ja-JP': 'カスタム絵文字定義'
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
|
||||||
disableRegistration: $.bool.optional.nullable.note({
|
disableRegistration: $.bool.optional.nullable.note({
|
||||||
desc: {
|
desc: {
|
||||||
'ja-JP': '招待制か否か'
|
'ja-JP': '招待制か否か'
|
||||||
|
@ -53,6 +59,10 @@ export default (params: any) => new Promise(async (res, rej) => {
|
||||||
set.broadcasts = ps.broadcasts;
|
set.broadcasts = ps.broadcasts;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (ps.emojis) {
|
||||||
|
set.emojis = ps.emojis;
|
||||||
|
}
|
||||||
|
|
||||||
if (typeof ps.disableRegistration === 'boolean') {
|
if (typeof ps.disableRegistration === 'boolean') {
|
||||||
set.disableRegistration = ps.disableRegistration;
|
set.disableRegistration = ps.disableRegistration;
|
||||||
}
|
}
|
||||||
|
|
|
@ -50,6 +50,7 @@ export default (params: any, me: ILocalUser) => new Promise(async (res, rej) =>
|
||||||
hidedTags: (me && me.isAdmin) ? meta.hidedTags : undefined,
|
hidedTags: (me && me.isAdmin) ? meta.hidedTags : undefined,
|
||||||
bannerUrl: meta.bannerUrl,
|
bannerUrl: meta.bannerUrl,
|
||||||
maxNoteTextLength: config.maxNoteTextLength,
|
maxNoteTextLength: config.maxNoteTextLength,
|
||||||
|
emojis: meta.emojis,
|
||||||
|
|
||||||
features: {
|
features: {
|
||||||
registration: !meta.disableRegistration,
|
registration: !meta.disableRegistration,
|
||||||
|
|
Loading…
Reference in a new issue