diff --git a/.gitignore b/.gitignore index ab8f822..1243e29 100644 --- a/.gitignore +++ b/.gitignore @@ -6,6 +6,8 @@ node_modules/ /out/ /dist/ +# npm pack output - a build artifact, regenerable with `npm pack` +*.tgz *.log *.tsbuildinfo diff --git a/nobilis b/nobilis index 94e801f..e6b8244 160000 --- a/nobilis +++ b/nobilis @@ -1 +1 @@ -Subproject commit 94e801f0247e1821eefdb305e40050eb80b14295 +Subproject commit e6b824462734ef40211d65dd1f067a45f7692905 diff --git a/src/main/index.ts b/src/main/index.ts index ad457b4..aef0620 100644 --- a/src/main/index.ts +++ b/src/main/index.ts @@ -221,15 +221,7 @@ function applyHotkey(accelerator: string): void { function wireIpc(): void { ipcMain.handle(IPC.rpc, async (_e, method: string, params: Record) => { try { - const result = await client.request(method, params) - // Main needs each account's status to enforce Do Not Disturb, and the - // renderer already asks for the account list whenever it changes - - // watching the answer keeps the two in step without a second channel or - // a poll of its own. - if (method === 'listAccounts' && Array.isArray(result)) { - notifier.trackAccounts(result as { id: string; status?: string }[]) - } - return { ok: true, result } + return { ok: true, result: await client.request(method, params) } } catch (err) { // Surfaced as a value rather than a rejection so the renderer sees // nobilis's own error text (which is often the actionable part - "account diff --git a/src/main/notifications.ts b/src/main/notifications.ts index e969395..0441c86 100644 --- a/src/main/notifications.ts +++ b/src/main/notifications.ts @@ -35,8 +35,6 @@ export class Notifier { /** Source path -> transcoded PNG, so a repeat sender is converted once. */ private transcoded = new Map() - /** Accounts currently set to Do Not Disturb. */ - private dndAccounts = new Set() constructor( private prefs: Prefs, @@ -46,11 +44,6 @@ export class Notifier { private renderer: () => WebContents | null = () => null ) {} - /** Mirrors each account's status, so DND can be enforced here. */ - trackAccounts(accounts: { id: string; status?: string }[]): void { - this.dndAccounts = new Set(accounts.filter((a) => a.status === 'dnd').map((a) => a.id)) - } - trackBuffer(buffer: ChatBuffer, removed: boolean): void { if (removed) this.buffers.delete(buffer.id) else this.buffers.set(buffer.id, buffer) @@ -67,12 +60,6 @@ export class Notifier { * all; see isMuted for why. */ private isMuted(accountId: string, bufferId: string): boolean { - // Do Not Disturb is a statement about the person rather than any one - // connection, so it silences every account regardless of which one it was - // set from. Held in main so it keeps working with the window closed, - // which is the whole point of the setting. - if (this.dndAccounts.size > 0) return true - const muted = this.prefs.get('mutedBuffers', []) if (muted.includes(bufferId)) return true diff --git a/src/renderer/src/components/UserFooter.tsx b/src/renderer/src/components/UserFooter.tsx index ea4d957..c43397a 100644 --- a/src/renderer/src/components/UserFooter.tsx +++ b/src/renderer/src/components/UserFooter.tsx @@ -1,6 +1,6 @@ import { ContextMenu, useContextMenu } from './ContextMenu' import { Icon, MaskIcon } from './Icon' -import { useChat, useStore } from '../state/hooks' +import { useStore } from '../state/hooks' import { nickColor, resolveMediaUrl, serviceIcon } from '../lib/util' import type { Account } from '../../../shared/wire' @@ -9,33 +9,22 @@ import type { Account } from '../../../shared/wire' * channel list - and the way to change how you are presenting. * * Per account rather than global because that is what the underlying status - * is: each protocol carries its own, and only Do Not Disturb reaches across - * all of them (by silencing notifications, which is this app's own doing - * rather than anything a server is told). + * is: each protocol carries its own. */ -export type Status = 'online' | 'idle' | 'dnd' +export type Status = 'online' | 'idle' -const STATUSES: { id: Status; label: string; glyph: string; note?: string }[] = [ +const STATUSES: { id: Status; label: string; glyph: string }[] = [ { id: 'online', label: 'Online', glyph: 'circle' }, - { id: 'idle', label: 'Idle', glyph: 'dark_mode' }, - { - id: 'dnd', - label: 'Do Not Disturb', - glyph: 'do_not_disturb_on', - note: 'Silences notifications everywhere' - } + { id: 'idle', label: 'Idle', glyph: 'dark_mode' } ] export function statusColor(status: string): string { - if (status === 'idle') return 'var(--warning)' - if (status === 'dnd') return 'var(--error)' - return 'var(--success)' + return status === 'idle' ? 'var(--warning)' : 'var(--success)' } export function UserFooter({ account }: { account?: Account }): JSX.Element { const store = useStore() - const accounts = useChat((s) => s.accounts) const { menu, open, close } = useContextMenu() // With no account selected there is nobody to show, but the footer still @@ -46,13 +35,7 @@ export function UserFooter({ account }: { account?: Account }): JSX.Element { const service = serviceIcon(account.service) const name = account.displayName || account.id - const setStatus = (next: Status): void => { - // DND is a statement about the person, not the connection, so it goes to - // every account at once. The others are per-account, matching where the - // user set them from. - const targets = next === 'dnd' || status === 'dnd' ? accounts : [account] - for (const a of targets) void store.setAccountStatus(a.id, next) - } + const setStatus = (next: Status): void => void store.setAccountStatus(account.id, next) return ( <> diff --git a/src/renderer/src/state/store.ts b/src/renderer/src/state/store.ts index 7f57a15..8ddfed9 100644 --- a/src/renderer/src/state/store.ts +++ b/src/renderer/src/state/store.ts @@ -256,7 +256,7 @@ export class ChatStore { * disconnected account or a protocol with no presence concept the answer is * no - showing it as set anyway would be a lie. */ - async setAccountStatus(accountId: string, status: 'online' | 'idle' | 'dnd'): Promise { + async setAccountStatus(accountId: string, status: 'online' | 'idle'): Promise { try { await window.moho.rpc('setAccountStatus', { accountId, status }) await this.refreshAccounts() diff --git a/src/shared/wire.ts b/src/shared/wire.ts index d0ac63f..8e861ab 100644 --- a/src/shared/wire.ts +++ b/src/shared/wire.ts @@ -6,7 +6,7 @@ export interface Account { service: 'irc' | 'discord' | 'sockchat' | 'matrix' | 'jabber' | 'slack' displayName: string /** - * How the user is presenting: "online" | "idle" | "dnd". Distinct from + * How the user is presenting: "online" | "idle". Distinct from * `state`, which is whether the connection is up. */ status?: string