Skip to content

Commit

Permalink
FE - mention @everyone (#4419)
Browse files Browse the repository at this point in the history
  • Loading branch information
megrogan authored Sep 21, 2023
1 parent 6e1908a commit 30f146e
Show file tree
Hide file tree
Showing 10 changed files with 71 additions and 33 deletions.
10 changes: 6 additions & 4 deletions frontend/app/src/components/UserPill.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,15 @@
export let userOrGroup: UserOrUserGroup;
$: avatarUrl =
userOrGroup.kind === "user_group" ? undefined : client.userAvatarUrl(userOrGroup);
$: userId = userOrGroup.kind === "user_group" ? undefined : userOrGroup.userId;
userOrGroup.kind === "user_group" || userOrGroup.kind === "everyone"
? undefined
: client.userAvatarUrl(userOrGroup);
$: userId = client.userOrUserGroupId(userOrGroup);
$: communityMembers = client.currentCommunityMembers;
$: name = userOrGroup.kind === "user_group" ? userOrGroup.name : userOrGroup.username;
$: name = client.userOrUserGroupName(userOrGroup);
$: displayName =
userOrGroup.kind === "user_group"
userOrGroup.kind === "user_group" || userOrGroup.kind === "everyone"
? undefined
: client.getDisplayName(userOrGroup, $communityMembers);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -114,8 +114,7 @@
let expandedText = text.replace(/@([\w\d_]*)/g, (match, p1) => {
const userOrGroup = client.lookupUserForMention(p1, true);
if (userOrGroup !== undefined) {
if (userOrGroup.kind === "user_group") return "";
mentionedSet.add(userOrGroup.userId);
mentionedSet.add(client.userOrUserGroupId(userOrGroup) ?? "");
return "";
} else {
console.log(
Expand Down Expand Up @@ -224,8 +223,7 @@
function mention(ev: CustomEvent<UserOrUserGroup>): void {
const userOrGroup = ev.detail;
const username =
userOrGroup.kind === "user_group" ? userOrGroup.name : userOrGroup.username;
const username = client.userOrUserGroupName(userOrGroup);
const userLabel = `@${username}`;
replaceTextWith(userLabel);
Expand Down
9 changes: 8 additions & 1 deletion frontend/app/src/components/home/Markdown.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -44,14 +44,21 @@
});
}
function replaceEveryone(text: string): string {
if (!text.includes("@everyone")) return text;
return text.replace(/(^|[\s(){}\[\]])(@everyone)($|[\s(){}\[\]])/gm, "$1**$2**$3");
}
function replaceDatetimes(text: string): string {
return text.replace(/@DateTime\((\d+)\)/g, (_, p1) => {
return client.toDatetimeString(new Date(Number(p1)));
});
}
$: {
let parsed = replaceUserGroupIds(replaceUserIds(replaceDatetimes(text)), $userGroups);
let parsed = replaceEveryone(
replaceUserGroupIds(replaceUserIds(replaceDatetimes(text)), $userGroups)
);
try {
if (inline) {
parsed = marked.parseInline(parsed, options) as string;
Expand Down
11 changes: 9 additions & 2 deletions frontend/app/src/components/home/MentionPicker.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,9 @@
prefixLower === undefined ||
(supportsUserGroups && userOrGroup.name.toLowerCase().startsWith(prefixLower))
);
case "everyone": {
return prefixLower === undefined || userOrGroup.kind.startsWith(prefixLower);
}
default:
return (
(mentionSelf || userOrGroup.userId !== currentUser.userId) &&
Expand All @@ -62,7 +65,7 @@
onMount(() => {
usersAndGroups = Object.values(client.getUserLookupForMentions()).sort(
(a: UserOrUserGroup, b: UserOrUserGroup) => {
const order = { user_group: 1, user: 2, bot: 3 };
const order = { everyone: 1, user_group: 2, user: 3, bot: 4 };
return order[a.kind] - order[b.kind];
}
);
Expand Down Expand Up @@ -113,7 +116,7 @@
<VirtualList keyFn={(p) => p.userId} items={filtered} let:item let:itemIndex>
<MenuItem selected={itemIndex === index} on:click={() => mention(item)}>
<div class="avatar" slot="icon">
{#if item.kind === "user_group"}
{#if item.kind === "user_group" || item.kind === "everyone"}
<div class="group-icon">
<AccountMultiple color={"var(--menu-disabled-txt)"} size={$iconSize} />
</div>
Expand All @@ -129,6 +132,10 @@
<span class="display-name">
{item.name}
</span>
{:else if item.kind === "everyone"}
<span class="display-name">
{"everyone"}
</span>
{:else}
<span class="display-name">
{client.getDisplayName(item, $communityMembers)}
Expand Down
5 changes: 3 additions & 2 deletions frontend/app/src/components/home/MessageEntry.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -260,6 +260,8 @@
switch (userOrGroup.kind) {
case "user_group":
return `@UserGroup(${userOrGroup.id})`;
case "everyone":
return "@everyone";
default:
mentionedMap.set(userOrGroup.userId, userOrGroup);
return `@UserId(${userOrGroup.userId})`;
Expand Down Expand Up @@ -432,8 +434,7 @@
function mention(ev: CustomEvent<UserOrUserGroup>): void {
const userOrGroup = ev.detail;
const username =
userOrGroup.kind === "user_group" ? userOrGroup.name : userOrGroup.username;
const username = client.userOrUserGroupName(userOrGroup);
const userLabel = `@${username}`;
replaceTextWith(userLabel);
Expand Down
13 changes: 8 additions & 5 deletions frontend/openchat-client/src/openchat.ts
Original file line number Diff line number Diff line change
Expand Up @@ -349,6 +349,9 @@ import {
toTitleCase,
CommonResponses,
defaultChatRules,
userOrUserGroupName,
userOrUserGroupId,
extractUserIdsFromMentions,
} from "openchat-shared";
import { failedMessagesStore } from "./stores/failedMessages";
import {
Expand Down Expand Up @@ -1203,6 +1206,9 @@ export class OpenChat extends OpenChatAgentWorker {
formatMessageDate = formatMessageDate;
userIdsFromEvents = userIdsFromEvents;
missingUserIds = missingUserIds;
userOrUserGroupName = userOrUserGroupName;
userOrUserGroupId = userOrUserGroupId;
extractUserIdsFromMentions = extractUserIdsFromMentions;
toRecord2 = toRecord2;
toDatetimeString = toDatetimeString;
groupBySender = groupBySender;
Expand Down Expand Up @@ -4306,11 +4312,6 @@ export class OpenChat extends OpenChatAgentWorker {
}
}

// FIXME - this is duplicated
private extractUserIdsFromMentions(text: string): string[] {
return [...text.matchAll(/@UserId\(([\d\w-]+)\)/g)].map((m) => m[1]);
}

private userIdsFromChatSummaries(chats: ChatSummary[]): Set<string> {
const userIds = new Set<string>();
chats.forEach((chat) => {
Expand Down Expand Up @@ -4852,6 +4853,7 @@ export class OpenChat extends OpenChatAgentWorker {
const userGroups = [...this._liveState.selectedCommunity.userGroups.values()];
userGroups.forEach((ug) => (lookup[ug.name.toLowerCase()] = ug));
}
lookup["everyone"] = { kind: "everyone" };
this._userLookupForMentions = lookup;
}
return this._userLookupForMentions;
Expand All @@ -4865,6 +4867,7 @@ export class OpenChat extends OpenChatAgentWorker {

switch (userOrGroup.kind) {
case "user_group":
case "everyone":
return userOrGroup;
default:
return includeSelf || userOrGroup.userId !== this.user.userId
Expand Down
2 changes: 1 addition & 1 deletion frontend/openchat-shared/src/domain/user/index.ts
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
export * from "./user";
export { extractUserIdsFromMentions, missingUserIds, userStatus } from "./user.utils";
export { extractUserIdsFromMentions, missingUserIds, userStatus, userOrUserGroupName, userOrUserGroupId } from "./user.utils";
26 changes: 15 additions & 11 deletions frontend/openchat-shared/src/domain/user/user.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,16 @@
import type { DataContent } from "../data/data";

export type UserOrUserGroup = UserSummary | UserGroupSummary;
export type UserOrUserGroup = UserSummary | UserGroupSummary | MentionEveryone;

export type UserSummary = DataContent & {
kind: "user" | "bot";
userId: string;
username: string;
displayName: string | undefined;
updated: bigint;
suspended: boolean;
diamond: boolean;
};

export type UserGroupSummary = {
kind: "user_group";
Expand All @@ -9,6 +19,10 @@ export type UserGroupSummary = {
id: number;
};

export type MentionEveryone = {
kind: "everyone";
}

export type UserGroupDetails = {
kind: "user_group";
members: Set<string>;
Expand All @@ -25,16 +39,6 @@ export type IdentityState =
| "upgrading_user"
| "upgrade_user";

export type UserSummary = DataContent & {
kind: "user" | "bot";
userId: string;
username: string;
displayName: string | undefined;
updated: bigint;
suspended: boolean;
diamond: boolean;
};

export type UserLookup = Record<string, UserSummary>;

export type User = {
Expand Down
19 changes: 18 additions & 1 deletion frontend/openchat-shared/src/domain/user/user.utils.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { ONLINE_THRESHOLD } from "../../constants";
import type { UserLookup } from "./user";
import type { UserLookup, UserOrUserGroup } from "./user";
import { UserStatus } from "./user";

export function userStatus(lastOnline: number | undefined, now: number): UserStatus {
Expand All @@ -22,4 +22,21 @@ const mentionRegex = /@UserId\(([\d\w-]+)\)/g;

export function extractUserIdsFromMentions(text: string): string[] {
return [...text.matchAll(mentionRegex)].map((m) => m[1]);
}

export function userOrUserGroupName(u: UserOrUserGroup): string {
switch (u.kind) {
case "user_group": return u.name;
case "everyone": return u.kind;
default: return u.username;
}
}

export function userOrUserGroupId(u: UserOrUserGroup): string | undefined {
switch (u.kind) {
case "user":
case "bot":
return u.username;
default: return undefined;
}
}
3 changes: 1 addition & 2 deletions frontend/openchat-shared/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,2 @@
export * from "./domain";
export * from "./utils";
export { missingUserIds } from "./domain/user/user.utils";
export * from "./utils";

0 comments on commit 30f146e

Please sign in to comment.