import { Client4 } from "@mattermost/client"; import { applyQuery, QueryProviderEvent } from "../query/engine"; import { readPage } from "@silverbulletmd/plugos-silverbullet-syscall/space"; import { parseMarkdown } from "@silverbulletmd/plugos-silverbullet-syscall/markdown"; import { extractMeta } from "../query/data"; import { niceDate } from "../core/dates"; import { Post } from "@mattermost/types/lib/posts"; import { ServerChannel } from "@mattermost/types/lib/channels"; import { UserProfile } from "@mattermost/types/lib/users"; import { Team } from "@mattermost/types/lib/teams"; type AugmentedPost = Post & { // Dates we can use to filter createdAt: string; updatedAt: string; editedAt: string; }; // https://community.mattermost.com/private-core/pl/rbp7a7jtr3f89nzsefo6ftqt3o function mattermostDesktopUrlForPost( url: string, teamName: string, postId: string ) { return `${url.replace("https://", "mattermost://")}/${teamName}/pl/${postId}`; } type MattermostConfig = { url: string; token: string; defaultTeam: string; }; async function getConfig(): Promise { let { text } = await readPage("mattermost-config"); let parsedContent = await parseMarkdown(text); let pageMeta = await extractMeta(parsedContent); return pageMeta as MattermostConfig; } function augmentPost(post: AugmentedPost) { if (post.create_at) { post.createdAt = niceDate(new Date(post.create_at)); } if (post.update_at) { post.updatedAt = niceDate(new Date(post.update_at)); } if (post.edit_at) { post.editedAt = niceDate(new Date(post.edit_at)); } } class CachingClient4 { constructor(public client: Client4) {} private channelCache = new Map(); async getChannelCached(channelId: string): Promise { let channel = this.channelCache.get(channelId); if (channel) { return channel; } channel = await this.client.getChannel(channelId); this.channelCache.set(channelId, channel!); return channel!; } private teamCache = new Map(); async getTeamCached(teamId: string): Promise { let team = this.teamCache.get(teamId); if (team) { return team; } team = await this.client.getTeam(teamId); this.teamCache.set(teamId, team!); return team!; } private userCache = new Map(); async getUserCached(userId: string): Promise { let user = this.userCache.get(userId); if (user) { return user; } user = await this.client.getUser(userId); this.userCache.set(userId, user!); return user!; } } export async function savedPostsQueryProvider({ query, }: QueryProviderEvent): Promise { let config = await getConfig(); let client = new Client4(); let cachingClient = new CachingClient4(client); client.setUrl(config.url); client.setToken(config.token); let me = await client.getMe(); let postCollection = await client.getFlaggedPosts(me.id); let savedPosts: AugmentedPost[] = []; for (let order of postCollection.order) { let post = postCollection.posts[order]; augmentPost(post); savedPosts.push(post); } let resultSavedPosts = []; savedPosts = applyQuery(query, savedPosts); for (let savedPost of savedPosts) { let channel = await cachingClient.getChannelCached(savedPost.channel_id); let teamName = config.defaultTeam; if (channel.team_id) { let team = await cachingClient.getTeamCached(channel.team_id); teamName = team.name; } resultSavedPosts.push({ ...savedPost, user: await cachingClient.getUserCached(savedPost.user_id), channel: channel, teamName: teamName, url: mattermostDesktopUrlForPost(client.url, teamName, savedPost.id), }); } return resultSavedPosts; }