mirror of
https://github.com/MathMan05/Fermi.git
synced 2026-07-28 07:49:23 +00:00
Restore emoji textures in nicknames, mentions and roles
This commit is contained in:
@@ -5,6 +5,7 @@ import {Guild} from "./guild.js";
|
||||
import {I18n} from "./i18n.js";
|
||||
import {Dialog} from "./settings.js";
|
||||
import {Contextmenu} from "./contextmenu.js";
|
||||
import {setTextWithWrappedEmoji} from "./utils/utils.js";
|
||||
const linkMenu = new Contextmenu<string, void>("copyLink", true);
|
||||
linkMenu.addButton(
|
||||
() => I18n.copyRegLink(),
|
||||
@@ -629,6 +630,7 @@ class MarkDown {
|
||||
mention.classList.add("mentionMD");
|
||||
mention.contentEditable = "false";
|
||||
mention.textContent = everyone ? "@everyone" : "@here";
|
||||
setTextWithWrappedEmoji(mention, mention.textContent || "");
|
||||
appendcurrent();
|
||||
span.appendChild(mention);
|
||||
mention.setAttribute("real", everyone ? `@everyone` : "@here");
|
||||
@@ -670,17 +672,21 @@ class MarkDown {
|
||||
const role = this.channel.guild.roleids.get(id);
|
||||
if (role) {
|
||||
mention.textContent = `@${role.name}`;
|
||||
setTextWithWrappedEmoji(mention, mention.textContent || "");
|
||||
mention.style.color = `var(--role-${role.id})`;
|
||||
} else {
|
||||
mention.textContent = I18n.guild.unknownRole();
|
||||
setTextWithWrappedEmoji(mention, mention.textContent || "");
|
||||
}
|
||||
}
|
||||
} else {
|
||||
(async () => {
|
||||
mention.textContent = I18n.userping.resolving();
|
||||
setTextWithWrappedEmoji(mention, mention.textContent || "");
|
||||
const user = await this.localuser?.getUser(id);
|
||||
if (user) {
|
||||
mention.textContent = `@${user.name}`;
|
||||
setTextWithWrappedEmoji(mention, mention.textContent || "");
|
||||
let guild: null | Guild = null;
|
||||
if (this.channel) {
|
||||
guild = this.channel.guild;
|
||||
@@ -692,11 +698,13 @@ class MarkDown {
|
||||
guild.resolveMember(user).then((member) => {
|
||||
if (member) {
|
||||
mention.textContent = `@${member.name}`;
|
||||
setTextWithWrappedEmoji(mention, mention.textContent || "");
|
||||
}
|
||||
});
|
||||
}
|
||||
} else {
|
||||
mention.textContent = I18n.userping.unknown();
|
||||
setTextWithWrappedEmoji(mention, mention.textContent || "");
|
||||
}
|
||||
})();
|
||||
}
|
||||
@@ -705,6 +713,7 @@ class MarkDown {
|
||||
const channel = this.localuser.channelids.get(id);
|
||||
if (channel) {
|
||||
mention.textContent = `#${channel.name}`;
|
||||
setTextWithWrappedEmoji(mention, mention.textContent || "");
|
||||
if (!keep && !stdsize) {
|
||||
mention.onclick = (_) => {
|
||||
if (!this.localuser) return;
|
||||
@@ -713,6 +722,7 @@ class MarkDown {
|
||||
}
|
||||
} else {
|
||||
mention.textContent = "#unknown";
|
||||
setTextWithWrappedEmoji(mention, mention.textContent || "");
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -6,6 +6,7 @@ import {highMemberJSON, memberjson, presencejson} from "./jsontypes.js";
|
||||
import {I18n} from "./i18n.js";
|
||||
import {Dialog, Options, Settings} from "./settings.js";
|
||||
import {CDNParams} from "./utils/cdnParams.js";
|
||||
import {setTextWithWrappedEmoji} from "./utils/utils.js";
|
||||
|
||||
class Member extends SnowFlake {
|
||||
static already = {};
|
||||
@@ -34,6 +35,7 @@ class Member extends SnowFlake {
|
||||
elms = new Set<WeakRef<HTMLElement>>();
|
||||
subName(elm: HTMLElement) {
|
||||
this.elms.add(new WeakRef(elm));
|
||||
setTextWithWrappedEmoji(elm, this.name);
|
||||
}
|
||||
nameChange() {
|
||||
for (const ref of this.elms) {
|
||||
@@ -42,7 +44,7 @@ class Member extends SnowFlake {
|
||||
this.elms.delete(ref);
|
||||
continue;
|
||||
}
|
||||
elm.textContent = this.name;
|
||||
setTextWithWrappedEmoji(elm, this.name);
|
||||
}
|
||||
}
|
||||
commuicationDisabledLeft() {
|
||||
|
||||
+2
-1
@@ -8,6 +8,7 @@ import {OptionsElement, Buttons, Dialog, ColorInput} from "./settings.js";
|
||||
import {Contextmenu} from "./contextmenu.js";
|
||||
import {Channel} from "./channel.js";
|
||||
import {I18n} from "./i18n.js";
|
||||
import {setTextWithWrappedEmoji} from "./utils/utils.js";
|
||||
|
||||
class Role extends SnowFlake {
|
||||
permissions: Permissions;
|
||||
@@ -647,7 +648,7 @@ class RoleList extends Buttons {
|
||||
this.buttonMap.set(thing[0], button);
|
||||
button.classList.add("SettingsButton");
|
||||
const span = document.createElement("span");
|
||||
span.textContent = thing[0];
|
||||
setTextWithWrappedEmoji(span, thing[0]);
|
||||
button.append(span);
|
||||
span.classList.add("roleButtonStyle");
|
||||
const role = this.guild.roleids.get(thing[1]) || this.guild.localuser.userMap.get(thing[1]);
|
||||
|
||||
@@ -2646,6 +2646,9 @@ span.instanceStatus {
|
||||
object-fit: contain;
|
||||
align-self: center;
|
||||
}
|
||||
span.emoji {
|
||||
color: initial;
|
||||
}
|
||||
.userwrap {
|
||||
display: flex;
|
||||
align-items: baseline;
|
||||
|
||||
+3
-2
@@ -17,7 +17,7 @@ import {Search} from "./search.js";
|
||||
import {I18n} from "./i18n.js";
|
||||
import {Hover} from "./hover.js";
|
||||
import {Dialog, Float, Options} from "./settings.js";
|
||||
import {createImg, removeAni, safeImg} from "./utils/utils.js";
|
||||
import {createImg, removeAni, safeImg, setTextWithWrappedEmoji} from "./utils/utils.js";
|
||||
import {Direct} from "./direct.js";
|
||||
import {Permissions} from "./permissions.js";
|
||||
import {Channel} from "./channel.js";
|
||||
@@ -682,6 +682,7 @@ class User extends SnowFlake {
|
||||
elms = new Set<WeakRef<HTMLElement>>();
|
||||
subName(elm: HTMLElement) {
|
||||
this.elms.add(new WeakRef(elm));
|
||||
setTextWithWrappedEmoji(elm, this.name);
|
||||
}
|
||||
nameChange() {
|
||||
this.getMembersSync().forEach((memb) => {
|
||||
@@ -694,7 +695,7 @@ class User extends SnowFlake {
|
||||
this.elms.delete(ref);
|
||||
continue;
|
||||
}
|
||||
elm.textContent = this.name;
|
||||
setTextWithWrappedEmoji(elm, this.name);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -31,6 +31,35 @@ let instances:
|
||||
}[]
|
||||
| null = null;
|
||||
await setTheme();
|
||||
const emojiGraphemeRegex = /^(?:[0-9#*]\uFE0F?\u20E3|\p{Regional_Indicator}{2}|\p{Extended_Pictographic}(?:\uFE0F|\uFE0E)?[\u{1F3FB}-\u{1F3FF}]?(?:\u200D\p{Extended_Pictographic}(?:\uFE0F|\uFE0E)?[\u{1F3FB}-\u{1F3FF}]?)*?)$/u;
|
||||
export function setTextWithWrappedEmoji(target: HTMLElement, name: string) {
|
||||
target.textContent = "";
|
||||
|
||||
if (!("Segmenter" in Intl)) {
|
||||
target.textContent = name;
|
||||
return;
|
||||
}
|
||||
|
||||
const segmenter = new Intl.Segmenter("und", {granularity: "grapheme"});
|
||||
let textBuffer = "";
|
||||
const flushTextBuffer = () => {
|
||||
if (!textBuffer) return;
|
||||
target.append(textBuffer);
|
||||
textBuffer = "";
|
||||
};
|
||||
for (const {segment} of segmenter.segment(name)) {
|
||||
if (emojiGraphemeRegex.test(segment)) {
|
||||
flushTextBuffer();
|
||||
const emoji = document.createElement("span");
|
||||
emoji.classList.add("emoji");
|
||||
emoji.textContent = segment;
|
||||
target.append(emoji);
|
||||
} else {
|
||||
textBuffer += segment;
|
||||
}
|
||||
}
|
||||
flushTextBuffer();
|
||||
}
|
||||
export async function setTheme(theme?: string) {
|
||||
const prefs = await getPreferences();
|
||||
document.body.className = (theme || prefs.theme) + "-theme";
|
||||
|
||||
Reference in New Issue
Block a user