2023-09-19 08:13:40 +02:00
|
|
|
import {z} from "zod";
|
|
|
|
|
|
|
|
import * as channel from "./channel";
|
|
|
|
import * as emoji from "./emoji";
|
|
|
|
import type {EmojiRenderingDetails} from "./emoji";
|
2024-06-21 21:13:00 +02:00
|
|
|
import type {StateData} from "./state_data";
|
2023-09-19 08:13:40 +02:00
|
|
|
import {user_settings} from "./user_settings";
|
2024-06-21 21:13:00 +02:00
|
|
|
import {user_status_schema} from "./user_status_types";
|
2023-09-19 08:13:40 +02:00
|
|
|
|
|
|
|
export type UserStatus = z.infer<typeof user_status_schema>;
|
|
|
|
export type UserStatusEmojiInfo = EmojiRenderingDetails & {
|
|
|
|
emoji_alt_code?: boolean;
|
|
|
|
};
|
|
|
|
|
2024-01-11 22:33:33 +01:00
|
|
|
const user_status_event_schema = z.intersection(
|
2023-09-19 08:13:40 +02:00
|
|
|
z.object({
|
2024-01-11 22:33:33 +01:00
|
|
|
id: z.number(),
|
|
|
|
type: z.literal("user_status"),
|
|
|
|
user_id: z.number(),
|
2023-09-19 08:13:40 +02:00
|
|
|
}),
|
2024-01-11 22:33:33 +01:00
|
|
|
user_status_schema,
|
|
|
|
);
|
|
|
|
|
|
|
|
export type UserStatusEvent = z.infer<typeof user_status_event_schema>;
|
2023-09-19 08:13:40 +02:00
|
|
|
|
|
|
|
const user_info = new Map<number, string>();
|
|
|
|
const user_status_emoji_info = new Map<number, UserStatusEmojiInfo>();
|
|
|
|
|
|
|
|
export function server_update_status(opts: {
|
|
|
|
status_text: string;
|
|
|
|
emoji_name: string;
|
|
|
|
emoji_code: string;
|
|
|
|
reaction_type?: string;
|
|
|
|
success?: () => void;
|
|
|
|
}): void {
|
|
|
|
void channel.post({
|
|
|
|
url: "/json/users/me/status",
|
|
|
|
data: {
|
|
|
|
status_text: opts.status_text,
|
|
|
|
emoji_name: opts.emoji_name,
|
|
|
|
emoji_code: opts.emoji_code,
|
|
|
|
reaction_type: opts.reaction_type,
|
|
|
|
},
|
|
|
|
success() {
|
|
|
|
if (opts.success) {
|
|
|
|
opts.success();
|
|
|
|
}
|
|
|
|
},
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
export function server_invisible_mode_on(): void {
|
|
|
|
void channel.patch({
|
|
|
|
url: "/json/settings",
|
|
|
|
data: {
|
|
|
|
presence_enabled: false,
|
|
|
|
},
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
export function server_invisible_mode_off(): void {
|
|
|
|
void channel.patch({
|
|
|
|
url: "/json/settings",
|
|
|
|
data: {
|
|
|
|
presence_enabled: true,
|
|
|
|
},
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
export function get_status_text(user_id: number): string | undefined {
|
|
|
|
return user_info.get(user_id);
|
|
|
|
}
|
|
|
|
|
|
|
|
export function set_status_text(opts: {user_id: number; status_text: string}): void {
|
|
|
|
if (!opts.status_text) {
|
|
|
|
user_info.delete(opts.user_id);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
user_info.set(opts.user_id, opts.status_text);
|
|
|
|
}
|
|
|
|
|
|
|
|
export function get_status_emoji(user_id: number): UserStatusEmojiInfo | undefined {
|
|
|
|
return user_status_emoji_info.get(user_id);
|
|
|
|
}
|
|
|
|
|
|
|
|
export function set_status_emoji(event: UserStatusEvent): void {
|
2024-06-21 21:13:00 +02:00
|
|
|
// TODO/typescript: Move validation to the caller when
|
|
|
|
// server_events_dispatch.js is converted to TypeScript.
|
2023-09-19 08:13:40 +02:00
|
|
|
const opts = user_status_event_schema.parse(event);
|
|
|
|
|
|
|
|
if (!opts.emoji_name) {
|
|
|
|
user_status_emoji_info.delete(opts.user_id);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
user_status_emoji_info.set(opts.user_id, {
|
|
|
|
emoji_alt_code: user_settings.emojiset === "text",
|
|
|
|
...emoji.get_emoji_details_for_rendering({
|
|
|
|
emoji_name: opts.emoji_name,
|
|
|
|
emoji_code: opts.emoji_code,
|
|
|
|
reaction_type: opts.reaction_type,
|
|
|
|
}),
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2024-06-21 21:13:00 +02:00
|
|
|
export function initialize(params: StateData["user_status"]): void {
|
2023-09-19 08:13:40 +02:00
|
|
|
user_info.clear();
|
|
|
|
|
2024-06-21 21:13:00 +02:00
|
|
|
for (const [str_user_id, dct] of Object.entries(params.user_status)) {
|
2023-09-19 08:13:40 +02:00
|
|
|
// JSON does not allow integer keys, so we
|
|
|
|
// convert them here.
|
|
|
|
const user_id = Number.parseInt(str_user_id, 10);
|
|
|
|
|
|
|
|
if (dct.status_text) {
|
|
|
|
user_info.set(user_id, dct.status_text);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (dct.emoji_name) {
|
|
|
|
user_status_emoji_info.set(user_id, {
|
|
|
|
...emoji.get_emoji_details_for_rendering(dct),
|
|
|
|
});
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|