mirror of
https://github.com/YuzuZensai/Discord-Presence-Relay.git
synced 2026-09-13 10:49:02 +00:00
✨ feat: Implement waiting state
This commit is contained in:
+7
-3
@@ -150,15 +150,19 @@ function updateTrayMenu(status: RelayStatus): void {
|
|||||||
|
|
||||||
const menu = Menu.buildFromTemplate([
|
const menu = Menu.buildFromTemplate([
|
||||||
{
|
{
|
||||||
label: status.running ? 'Relay: Running' : 'Relay: Stopped',
|
label: status.running
|
||||||
|
? 'Relay: Running'
|
||||||
|
: status.waiting
|
||||||
|
? 'Relay: Waiting for Discord…'
|
||||||
|
: 'Relay: Stopped',
|
||||||
enabled: false
|
enabled: false
|
||||||
},
|
},
|
||||||
{ type: 'separator' },
|
{ type: 'separator' },
|
||||||
{
|
{
|
||||||
label: status.running ? 'Stop Relay' : 'Start Relay',
|
label: status.running || status.waiting ? 'Stop Relay' : 'Start Relay',
|
||||||
click: async () => {
|
click: async () => {
|
||||||
try {
|
try {
|
||||||
if (status.running) {
|
if (status.running || status.waiting) {
|
||||||
await relay.stop()
|
await relay.stop()
|
||||||
} else {
|
} else {
|
||||||
await relay.start()
|
await relay.start()
|
||||||
|
|||||||
+39
-4
@@ -7,6 +7,7 @@ import { platform, type ClaimedSocket, type ProcessInfo } from './platform'
|
|||||||
|
|
||||||
const MAX_SOCKETS = 10
|
const MAX_SOCKETS = 10
|
||||||
const DISCOVERY_INTERVAL_MS = 3000
|
const DISCOVERY_INTERVAL_MS = 3000
|
||||||
|
const WAITING_RETRY_INTERVAL_MS = 3000
|
||||||
|
|
||||||
interface AppAsset {
|
interface AppAsset {
|
||||||
id: string
|
id: string
|
||||||
@@ -101,6 +102,7 @@ export interface LastActivity {
|
|||||||
|
|
||||||
export interface RelayStatus {
|
export interface RelayStatus {
|
||||||
running: boolean
|
running: boolean
|
||||||
|
waiting: boolean
|
||||||
unsupported: boolean
|
unsupported: boolean
|
||||||
instances: RelayInstance[]
|
instances: RelayInstance[]
|
||||||
connectedClients: ConnectedClient[]
|
connectedClients: ConnectedClient[]
|
||||||
@@ -120,8 +122,10 @@ export class RpcRelay extends EventEmitter {
|
|||||||
private connectedClients = new Map<number, ConnectedClient>()
|
private connectedClients = new Map<number, ConnectedClient>()
|
||||||
private nextClientId = 1
|
private nextClientId = 1
|
||||||
private discoveryTimer: NodeJS.Timeout | null = null
|
private discoveryTimer: NodeJS.Timeout | null = null
|
||||||
|
private waitingTimer: NodeJS.Timeout | null = null
|
||||||
private lastActivity: LastActivity | null = null
|
private lastActivity: LastActivity | null = null
|
||||||
private running = false
|
private running = false
|
||||||
|
private waiting = false
|
||||||
private lastError: string | null = null
|
private lastError: string | null = null
|
||||||
private restarting = false
|
private restarting = false
|
||||||
private mirrors = new Map<number, MirrorConnection>()
|
private mirrors = new Map<number, MirrorConnection>()
|
||||||
@@ -138,6 +142,7 @@ export class RpcRelay extends EventEmitter {
|
|||||||
|
|
||||||
return {
|
return {
|
||||||
running: this.running,
|
running: this.running,
|
||||||
|
waiting: this.waiting,
|
||||||
unsupported: !platform.isSupported,
|
unsupported: !platform.isSupported,
|
||||||
instances,
|
instances,
|
||||||
connectedClients: [...this.connectedClients.values()],
|
connectedClients: [...this.connectedClients.values()],
|
||||||
@@ -181,11 +186,13 @@ export class RpcRelay extends EventEmitter {
|
|||||||
this.claimed = platform.discoverAndClaim()
|
this.claimed = platform.discoverAndClaim()
|
||||||
|
|
||||||
if (this.claimed.length === 0) {
|
if (this.claimed.length === 0) {
|
||||||
this.lastError = 'No running Discord clients found (no discord-ipc-N sockets)'
|
this.waitForDiscord()
|
||||||
this.emitStatus()
|
return
|
||||||
throw new Error(this.lastError)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this.waiting = false
|
||||||
|
this.stopWaitingTimer()
|
||||||
|
|
||||||
const fake = platform.fakeSocketPath()
|
const fake = platform.fakeSocketPath()
|
||||||
platform.removeFakeSocket(fake)
|
platform.removeFakeSocket(fake)
|
||||||
|
|
||||||
@@ -211,7 +218,13 @@ export class RpcRelay extends EventEmitter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async stop(): Promise<void> {
|
async stop(): Promise<void> {
|
||||||
if (!this.running) return
|
this.stopWaitingTimer()
|
||||||
|
this.waiting = false
|
||||||
|
|
||||||
|
if (!this.running) {
|
||||||
|
this.emitStatus()
|
||||||
|
return
|
||||||
|
}
|
||||||
this.running = false
|
this.running = false
|
||||||
this.stopDiscoveryTimer()
|
this.stopDiscoveryTimer()
|
||||||
|
|
||||||
@@ -236,6 +249,28 @@ export class RpcRelay extends EventEmitter {
|
|||||||
return this.claimed[0]?.index
|
return this.claimed[0]?.index
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private waitForDiscord(): void {
|
||||||
|
this.waiting = true
|
||||||
|
this.lastError = null
|
||||||
|
this.emitStatus()
|
||||||
|
|
||||||
|
if (this.waitingTimer) return
|
||||||
|
this.waitingTimer = setInterval(() => {
|
||||||
|
if (!this.waiting) return
|
||||||
|
void this.start().catch((err) => {
|
||||||
|
this.lastError = err instanceof Error ? err.message : String(err)
|
||||||
|
this.emitStatus()
|
||||||
|
})
|
||||||
|
}, WAITING_RETRY_INTERVAL_MS)
|
||||||
|
}
|
||||||
|
|
||||||
|
private stopWaitingTimer(): void {
|
||||||
|
if (this.waitingTimer) {
|
||||||
|
clearInterval(this.waitingTimer)
|
||||||
|
this.waitingTimer = null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private startDiscoveryTimer(): void {
|
private startDiscoveryTimer(): void {
|
||||||
this.stopDiscoveryTimer()
|
this.stopDiscoveryTimer()
|
||||||
this.discoveryTimer = setInterval(() => this.discoverNewInstances(), DISCOVERY_INTERVAL_MS)
|
this.discoveryTimer = setInterval(() => this.discoverNewInstances(), DISCOVERY_INTERVAL_MS)
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ import { Button, LinkButton } from './components/Button'
|
|||||||
|
|
||||||
const EMPTY_STATUS: RelayStatus = {
|
const EMPTY_STATUS: RelayStatus = {
|
||||||
running: false,
|
running: false,
|
||||||
|
waiting: false,
|
||||||
unsupported: false,
|
unsupported: false,
|
||||||
instances: [],
|
instances: [],
|
||||||
connectedClients: [],
|
connectedClients: [],
|
||||||
@@ -120,7 +121,7 @@ export function App(): React.JSX.Element {
|
|||||||
const toggleRelay = async (): Promise<void> => {
|
const toggleRelay = async (): Promise<void> => {
|
||||||
setLoading(true)
|
setLoading(true)
|
||||||
try {
|
try {
|
||||||
if (status.running) {
|
if (status.running || status.waiting) {
|
||||||
await window.api.stop()
|
await window.api.stop()
|
||||||
} else {
|
} else {
|
||||||
await window.api.start()
|
await window.api.start()
|
||||||
@@ -227,11 +228,23 @@ export function App(): React.JSX.Element {
|
|||||||
<section className="rounded-xl bg-zinc-800/60 border border-zinc-700 p-4 flex items-center justify-between">
|
<section className="rounded-xl bg-zinc-800/60 border border-zinc-700 p-4 flex items-center justify-between">
|
||||||
<div className="flex flex-col">
|
<div className="flex flex-col">
|
||||||
<span className="text-sm">Relay</span>
|
<span className="text-sm">Relay</span>
|
||||||
<span className={`text-xs ${status.running ? 'text-emerald-400' : 'text-zinc-500'}`}>
|
<span
|
||||||
{status.running ? 'Running' : 'Stopped'}
|
className={`text-xs ${
|
||||||
|
status.running
|
||||||
|
? 'text-emerald-400'
|
||||||
|
: status.waiting
|
||||||
|
? 'text-amber-400'
|
||||||
|
: 'text-zinc-500'
|
||||||
|
}`}
|
||||||
|
>
|
||||||
|
{status.running ? 'Running' : status.waiting ? 'Waiting for Discord…' : 'Stopped'}
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<Toggle checked={status.running} onChange={() => toggleRelay()} disabled={loading} />
|
<Toggle
|
||||||
|
checked={status.running || status.waiting}
|
||||||
|
onChange={() => toggleRelay()}
|
||||||
|
disabled={loading}
|
||||||
|
/>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
<section className="rounded-xl bg-zinc-800/60 border border-zinc-700 p-4 flex flex-col gap-2">
|
<section className="rounded-xl bg-zinc-800/60 border border-zinc-700 p-4 flex flex-col gap-2">
|
||||||
|
|||||||
Reference in New Issue
Block a user