From 4fa6c834150cd7fed0a539f45fdec0ea6bcbd3c0 Mon Sep 17 00:00:00 2001 From: Tulir Asokan Date: Mon, 28 Oct 2024 01:47:31 +0200 Subject: [PATCH] web/timeline: add ands to power level and pinned event diffs --- .../ui/timeline/content/PinnedEventsBody.tsx | 7 +++-- .../ui/timeline/content/PowerLevelBody.tsx | 3 +- web/src/util/join.ts | 29 +++++++++++++++++++ 3 files changed, 35 insertions(+), 4 deletions(-) create mode 100644 web/src/util/join.ts diff --git a/web/src/ui/timeline/content/PinnedEventsBody.tsx b/web/src/ui/timeline/content/PinnedEventsBody.tsx index 80ee124..da67aca 100644 --- a/web/src/ui/timeline/content/PinnedEventsBody.tsx +++ b/web/src/ui/timeline/content/PinnedEventsBody.tsx @@ -15,17 +15,18 @@ // along with this program. If not, see . import { PinnedEventsContent } from "@/api/types" import { listDiff } from "@/util/diff.ts" +import { oxfordHumanJoin } from "@/util/join.ts" import EventContentProps from "./props.ts" function renderPinChanges(content: PinnedEventsContent, prevContent?: PinnedEventsContent): string { const { added, removed } = listDiff(content.pinned ?? [], prevContent?.pinned ?? []) if (added.length) { if (removed.length) { - return `pinned ${added.join(", ")} and unpinned ${removed.join(", ")}` + return `pinned ${oxfordHumanJoin(added)} and unpinned ${oxfordHumanJoin(removed)}` } - return `pinned ${added.join(", ")}` + return `pinned ${oxfordHumanJoin(added)}` } else if (removed.length) { - return `unpinned ${removed.join(", ")}` + return `unpinned ${oxfordHumanJoin(removed)}` } else { return "sent a no-op pin event" } diff --git a/web/src/ui/timeline/content/PowerLevelBody.tsx b/web/src/ui/timeline/content/PowerLevelBody.tsx index 780b9b7..3598075 100644 --- a/web/src/ui/timeline/content/PowerLevelBody.tsx +++ b/web/src/ui/timeline/content/PowerLevelBody.tsx @@ -15,6 +15,7 @@ // along with this program. If not, see . import { PowerLevelEventContent } from "@/api/types" import { objectDiff } from "@/util/diff.ts" +import { humanJoin } from "@/util/join.ts" import EventContentProps from "./props.ts" function intDiff(messageParts: TemplateStringsArray, oldVal: number, newVal: number): string | null { @@ -67,7 +68,7 @@ const PowerLevelBody = ({ event, sender }: EventContentProps) => { const content = event.content as PowerLevelEventContent const prevContent = event.unsigned.prev_content as PowerLevelEventContent | undefined return
- {sender?.content.displayname ?? event.sender} {renderPowerLevels(content, prevContent).join(", ")} + {sender?.content.displayname ?? event.sender} {humanJoin(renderPowerLevels(content, prevContent))}
} diff --git a/web/src/util/join.ts b/web/src/util/join.ts new file mode 100644 index 0000000..0a05ea7 --- /dev/null +++ b/web/src/util/join.ts @@ -0,0 +1,29 @@ +// gomuks - A Matrix client written in Go. +// Copyright (C) 2024 Tulir Asokan +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . +export function humanJoin(arr: string[], sep: string = ", ", lastSep: string = " and "): string { + if (arr.length === 0) { + return "" + } + if (arr.length === 1) { + return arr[0] + } + if (arr.length === 2) { + return arr.join(lastSep) + } + return arr.slice(0, -1).join(sep) + lastSep + arr[arr.length - 1] +} + +export const oxfordHumanJoin = (arr: string[]) => humanJoin(arr, ", ", ", and ")