diff --git a/src/renderer/src/app.css b/src/renderer/src/app.css
index c7d0f9d..689c2b5 100644
--- a/src/renderer/src/app.css
+++ b/src/renderer/src/app.css
@@ -5078,6 +5078,13 @@ video.lightbox-media {
border-radius: var(--corner-radius-small);
background: var(--surface-container-high);
color: var(--surface-variant-text);
+ /* One line, and not the thing that gives way: the stream title beside it
+ is what shrinks into an ellipsis. */
+ white-space: nowrap;
+ flex: none;
+}
+
+.channel-modes.letters {
font-family: var(--font-mono, monospace);
letter-spacing: 0.04em;
}
@@ -8396,3 +8403,13 @@ video.lightbox-media {
.composer-watching .button {
margin-left: auto;
}
+
+/* Removing an account, asked in place of the button that asked for it. */
+.remove-confirm {
+ display: flex;
+ flex-direction: column;
+ gap: var(--spacing-s);
+ padding: var(--spacing-s) var(--spacing-m);
+ border: 1px solid #c9403c;
+ border-radius: var(--corner-radius-small);
+}
diff --git a/src/renderer/src/assets/matrix-mark.svg b/src/renderer/src/assets/matrix-mark.svg
new file mode 100644
index 0000000..3a5961a
--- /dev/null
+++ b/src/renderer/src/assets/matrix-mark.svg
@@ -0,0 +1,5 @@
+
diff --git a/src/renderer/src/components/AccountsPanel.tsx b/src/renderer/src/components/AccountsPanel.tsx
index e871899..b009acd 100644
--- a/src/renderer/src/components/AccountsPanel.tsx
+++ b/src/renderer/src/components/AccountsPanel.tsx
@@ -300,6 +300,7 @@ function AccountRow({ account }: { account: Account }): JSX.Element {
const media = useMediaUrl(account.id)
const store = useStore()
const [expanded, setExpanded] = useState(false)
+ const [confirmingRemove, setConfirmingRemove] = useState(false)
const icon = serviceIcon(account.service)
const connected = account.state === 'connected'
/**
@@ -459,22 +460,44 @@ function AccountRow({ account }: { account: Account }): JSX.Element {
on and never find again. */}
This homeserver is not accepting new accounts.
+ {/* A server that hands its accounts to an account service is closed to + the registration API and open on that service's site - matrix.org + is. Said as "not accepting new accounts", a new user's first look at + Matrix told them sign-up was impossible. */} + {signUpSite ? ( ++ This server signs people up on its own website, {new URL(signUpSite).host}. Make the + account there, then come back and use Sign in with a code. +
+ ) : ( + registration?.open === false && ( +This homeserver is not accepting new accounts.
+ ) )} {/* While a code sign-in is waiting. The code is the whole of what somebody needs, so it is the largest thing here and selectable - @@ -1827,6 +1871,16 @@ function MatrixForm(): JSX.Element { server wants a captcha, an email or its terms agreed to, the daemon says which and says to sign up on the server's own page, because those need a person somewhere this window is not. */} + {signUpSite ? ( + + ) : ( + )} {status &&{status}
}
diff --git a/src/renderer/src/components/ConversationTools.tsx b/src/renderer/src/components/ConversationTools.tsx
index 2068570..59e0098 100644
--- a/src/renderer/src/components/ConversationTools.tsx
+++ b/src/renderer/src/components/ConversationTools.tsx
@@ -835,7 +835,13 @@ export function ConversationTools({ buffer }: { buffer: BufferEntry }): JSX.Elem
with the long form, since the letters are only obvious to people who
already knew. */}
{buffer.channelModes && (
-
+
{buffer.channelModes}
)}
diff --git a/src/renderer/src/components/UserFooter.tsx b/src/renderer/src/components/UserFooter.tsx
index 1303026..154402f 100644
--- a/src/renderer/src/components/UserFooter.tsx
+++ b/src/renderer/src/components/UserFooter.tsx
@@ -55,6 +55,7 @@ export function UserFooter({ account }: { account?: Account }): JSX.Element {
const store = useStore()
const { menu, open, close } = useContextMenu()
const voice = useChat((s) => s.voicePrefs)
+ const inACall = useChat((s) => s.voiceSessions.length > 0 || !!s.activeCall)
const details = useChat((s) => s.connectionDetail)
// With no account selected there is nobody to show, but the footer still
@@ -64,6 +65,13 @@ export function UserFooter({ account }: { account?: Account }): JSX.Element {
const status = effectiveStatus(account)
const name = account.displayName || account.id
const detail = details[account.id]
+ // A signed-out Kick account is a reader: it has no presence to show, and
+ // "Online" claimed one.
+ const watching = account.service === 'kick' && !account.hasPassword && status !== 'connecting' && status !== 'offline'
+ // Mute and deafen are the whole client's, for whatever call is up - so
+ // shown on a service that has calls, or anywhere while one is running,
+ // and not beside an IRC or Kick account with nothing to apply them to.
+ const showVoice = account.service === 'discord' || account.service === 'matrix' || inACall
return (
<>
@@ -77,10 +85,12 @@ export function UserFooter({ account }: { account?: Account }): JSX.Element {