summaryrefslogtreecommitdiff
path: root/ui/routes/(app)
diff options
context:
space:
mode:
authorojacobson <ojacobson@noreply.codeberg.org>2025-07-04 05:00:21 +0200
committerojacobson <ojacobson@noreply.codeberg.org>2025-07-04 05:00:21 +0200
commitc35be3ae29e77983f013c01260dda20208175f2b (patch)
treeabf0b9d993ef03a53903aae03f375b78473952da /ui/routes/(app)
parent981cd3c0f4cf912c1d91ee5d9c39f5c1aa7afecf (diff)
parent9b38cb1a62ede4900fde4ba47a7b065db329e994 (diff)
Rename "channels" to "conversations."
The term "channel" for a conversational container has a long and storied history, but is mostly evocative of IRC and of other, ah, "nerd-centric" services. It does show up in more widespread contexts: Discord and Slack both refer to their primary conversational containers as "channels," for example. However, I think it's unnecessary jargon, and I'd like to do away with it. To that end, this change pervasively changes one term to the other wherever it appears, with the following exceptions: * A `channel` concept (unrelated to conversations) is also provided by an external library; we can't and shouldn't try to rename that. * The code to deal with the `pilcrow:channelData` and `pilcrow:lastActiveChannel` local storage properties is still present, to migrate existing data to new keys. It will be removed in a later change. This is a **breaking API change**. As we are not yet managing any API compatibility promises, this is formally not an issue, but it is something to be aware of practically. The major API changes are: * Paths beginning with `/api/channels` are now under `/api/conversations`, without other modifications. * Fields labelled with `channel…` terms are now labelled with `conversation…` terms. For example, a `message` `sent` event is now sent to a `conversation`, not a `channel`. This is also a **breaking UI change**. Specifically, any saved paths for `/ch/CHANNELID` will now lead to a 404. The corresponding paths are `/c/CONVERSATIONID`. While I've made an effort to migrate the location of stored data, I have not tried to provide adapters to fix this specific issue, because the disruption is short-lived and very easily addressed by opening a channel in the client UI. This change is obnoxiously large and difficult to review, for which I apologize. If this shows up in `git annotate`, please forgive me. These kinds of renamings are hard to carry out without a major disruption, especially when the concept ("channel" in this case) is used so pervasively throughout the system. I think it's worth making this change that pervasively so that we don't have an indefinitely-long tail of "well, it's a conversation in the docs, but the table is called `channel` for historical reasons" type issues. Merges conversations-not-channels into main.
Diffstat (limited to 'ui/routes/(app)')
-rw-r--r--ui/routes/(app)/+layout.svelte46
-rw-r--r--ui/routes/(app)/+page.svelte4
-rw-r--r--ui/routes/(app)/c/[conversation]/+page.svelte (renamed from ui/routes/(app)/ch/[channel]/+page.svelte)30
3 files changed, 46 insertions, 34 deletions
diff --git a/ui/routes/(app)/+layout.svelte b/ui/routes/(app)/+layout.svelte
index c7e1f22..658d966 100644
--- a/ui/routes/(app)/+layout.svelte
+++ b/ui/routes/(app)/+layout.svelte
@@ -7,9 +7,8 @@
import TinyGesture from 'tinygesture';
- import * as api from '$lib/apiServer.js';
- import ChannelList from '$lib/components/ChannelList.svelte';
- import CreateChannelForm from '$lib/components/CreateChannelForm.svelte';
+ import ConversationList from '$lib/components/ConversationList.svelte';
+ import CreateConversationForm from '$lib/components/CreateConversationForm.svelte';
let gesture = null;
@@ -20,9 +19,9 @@
onDestroy(session.end.bind(session));
let pageContext = getContext('page');
- let channel = $derived(page.params.channel);
+ let conversationId = $derived(page.params.conversation);
- let channels = $derived(session.channels);
+ let conversations = $derived(session.conversations);
function setUpGestures() {
if (!browser) {
@@ -46,28 +45,35 @@
}
});
- const STORE_KEY_LAST_ACTIVE = 'pilcrow:lastActiveChannel';
+ // Automatically migrate last-active-channel info now that we call them "conversations."
+ const STORE_KEY_LAST_ACTIVE = 'pilcrow:lastActiveConversation';
+ const STORE_KEY_LAST_ACTIVE_CHANNEL = 'pilcrow:lastActiveChannel';
- function getLastActiveChannel() {
- return browser && JSON.parse(localStorage.getItem(STORE_KEY_LAST_ACTIVE));
+ function getLastActiveConversation() {
+ const stored =
+ localStorage.getItem(STORE_KEY_LAST_ACTIVE) ??
+ localStorage.getItem(STORE_KEY_LAST_ACTIVE_CHANNEL);
+ return JSON.parse(stored);
}
- function setLastActiveChannel(channelId) {
- browser && localStorage.setItem(STORE_KEY_LAST_ACTIVE, JSON.stringify(channelId));
+ function setLastActiveConversation(conversationId) {
+ localStorage.setItem(STORE_KEY_LAST_ACTIVE, JSON.stringify(conversationId));
+ // Once we've saved to the new key, we no longer need the old one. Clean it up.
+ localStorage.removeItem(STORE_KEY_LAST_ACTIVE_CHANNEL);
}
afterNavigate(() => {
- const lastActiveChannel = getLastActiveChannel();
+ const conversationId = getLastActiveConversation();
const inRoot = page.url.pathname === '/';
- if (inRoot && lastActiveChannel) {
- goto(`/ch/${lastActiveChannel}`);
- } else if (channel) {
- setLastActiveChannel(channel || null);
+ if (inRoot && conversationId) {
+ goto(`/c/${conversationId}`);
+ } else if (conversationId) {
+ setLastActiveConversation(conversationId || null);
}
});
- async function createChannel(name) {
- outbox.createChannel(name);
+ async function createConversation(name) {
+ outbox.createConversation(name);
}
function onbeforeunload(event) {
@@ -114,9 +120,9 @@
<div id="interface">
<nav id="sidebar" data-expanded={pageContext.showMenu}>
- <ChannelList active={channel} {channels} />
- <div class="create-channel">
- <CreateChannelForm {createChannel} />
+ <ConversationList active={conversationId} {conversations} />
+ <div class="create-conversation">
+ <CreateConversationForm {createConversation} />
</div>
</nav>
<main>
diff --git a/ui/routes/(app)/+page.svelte b/ui/routes/(app)/+page.svelte
index 007c5c6..1db0eb2 100644
--- a/ui/routes/(app)/+page.svelte
+++ b/ui/routes/(app)/+page.svelte
@@ -1,3 +1,3 @@
-<div class="no-active-channel">
- <span class="vertical-aligner"> Please select or create a channel. </span>
+<div class="no-active-conversation">
+ <span class="vertical-aligner">Please select or create a conversation.</span>
</div>
diff --git a/ui/routes/(app)/ch/[channel]/+page.svelte b/ui/routes/(app)/c/[conversation]/+page.svelte
index 87918f7..e6cd845 100644
--- a/ui/routes/(app)/ch/[channel]/+page.svelte
+++ b/ui/routes/(app)/c/[conversation]/+page.svelte
@@ -8,12 +8,18 @@
const { data } = $props();
const { session, outbox } = data;
- let activeChannel;
+ let activeConversation;
- const channelId = $derived(page.params.channel);
- const channel = $derived(session.channels.find((channel) => channel.id === channelId));
- const messages = $derived(session.messages.filter((message) => message.channel === channelId));
- const unsent = $derived(outbox.messages.filter((message) => message.channel === channelId));
+ const conversationId = $derived(page.params.conversation);
+ const conversation = $derived(
+ session.conversations.find((conversation) => conversation.id === conversationId),
+ );
+ const messages = $derived(
+ session.messages.filter((message) => message.conversation === conversationId),
+ );
+ const unsent = $derived(
+ outbox.messages.filter((message) => message.conversation === conversationId),
+ );
const deleted = $derived(outbox.deleted.map((message) => message.messageId));
const unsentSkeletons = $derived(
unsent.map((message) => message.toSkeleton($state.snapshot(session.currentUser))),
@@ -33,12 +39,12 @@
}
function getLastVisibleMessage() {
- if (activeChannel) {
- const childElements = activeChannel.getElementsByClassName('message');
+ if (activeConversation) {
+ const childElements = activeConversation.getElementsByClassName('message');
const lastInView = Array.from(childElements)
.reverse()
.find((el) => {
- return inView(activeChannel, el);
+ return inView(activeConversation, el);
});
return lastInView;
}
@@ -46,9 +52,9 @@
function setLastRead() {
const lastInView = getLastVisibleMessage();
- const at = !!lastInView ? DateTime.fromISO(lastInView.dataset.at) : channel?.at;
+ const at = !!lastInView ? DateTime.fromISO(lastInView.dataset.at) : conversation?.at;
if (!!at) {
- session.local.updateLastReadAt(channelId, at);
+ session.local.updateLastReadAt(conversationId, at);
}
}
@@ -77,7 +83,7 @@
}
async function sendMessage(message) {
- outbox.postToChannel(channelId, message);
+ outbox.sendToConversation(conversationId, message);
}
async function deleteMessage(id) {
@@ -87,7 +93,7 @@
<svelte:window onkeydown={handleKeydown} />
-<div class="active-channel" {onscroll} bind:this={activeChannel}>
+<div class="active-conversation" {onscroll} bind:this={activeConversation}>
{#each messageRuns as { sender, ownMessage, messages }}
<MessageRun
{sender}