[Init] Initial commit - NetMesh terminal manager
Some checks failed
build-packages / resolve bundled mosh-client (push) Has been cancelled
build-packages / resolve bundled et-client (push) Has been cancelled
build-packages / build-macos (push) Has been cancelled
build-packages / build-windows (push) Has been cancelled
build-packages / build-linux-x64 (push) Has been cancelled
build-packages / build-linux-arm64 (push) Has been cancelled
build-packages / release (push) Has been cancelled
build-packages / update Nix release metadata (push) Has been cancelled
build-packages / bump homebrew tap (push) Has been cancelled
test / lint-and-test (push) Has been cancelled
AI automation / Route event (push) Has been cancelled
AI automation / Hand reopened issue to maintainers (push) Has been cancelled
AI automation / Clean source issue state (push) Has been cancelled
AI automation / Reconcile handoffs (push) Has been cancelled
AI automation / Classify issue (push) Has been cancelled
AI automation / Claude Code smoke (push) Has been cancelled
AI automation / Review issue follow-up (push) Has been cancelled
AI automation / Publish issue follow-up (push) Has been cancelled
AI automation / Implement with Claude Code (push) Has been cancelled
AI automation / Publish implement PR (push) Has been cancelled
AI automation / Continue queued issue comments (push) Has been cancelled
AI automation / Codex review loop (push) Has been cancelled
AI automation / Publish Codex fix (push) Has been cancelled
AI automation / Clear Codex dispatch marker (push) Has been cancelled
AI automation / Own PR re-request Codex (push) Has been cancelled
AI automation / External PR re-request Codex (push) Has been cancelled
AI automation / Poll Codex reaction / retry (push) Has been cancelled
build-et-binaries / build-linux-x64 (push) Has been cancelled
build-et-binaries / build-linux-arm64 (push) Has been cancelled
build-et-binaries / build-macos-universal (push) Has been cancelled
build-et-binaries / build-windows-x64 (push) Has been cancelled
build-et-binaries / release (push) Has been cancelled
Some checks failed
build-packages / resolve bundled mosh-client (push) Has been cancelled
build-packages / resolve bundled et-client (push) Has been cancelled
build-packages / build-macos (push) Has been cancelled
build-packages / build-windows (push) Has been cancelled
build-packages / build-linux-x64 (push) Has been cancelled
build-packages / build-linux-arm64 (push) Has been cancelled
build-packages / release (push) Has been cancelled
build-packages / update Nix release metadata (push) Has been cancelled
build-packages / bump homebrew tap (push) Has been cancelled
test / lint-and-test (push) Has been cancelled
AI automation / Route event (push) Has been cancelled
AI automation / Hand reopened issue to maintainers (push) Has been cancelled
AI automation / Clean source issue state (push) Has been cancelled
AI automation / Reconcile handoffs (push) Has been cancelled
AI automation / Classify issue (push) Has been cancelled
AI automation / Claude Code smoke (push) Has been cancelled
AI automation / Review issue follow-up (push) Has been cancelled
AI automation / Publish issue follow-up (push) Has been cancelled
AI automation / Implement with Claude Code (push) Has been cancelled
AI automation / Publish implement PR (push) Has been cancelled
AI automation / Continue queued issue comments (push) Has been cancelled
AI automation / Codex review loop (push) Has been cancelled
AI automation / Publish Codex fix (push) Has been cancelled
AI automation / Clear Codex dispatch marker (push) Has been cancelled
AI automation / Own PR re-request Codex (push) Has been cancelled
AI automation / External PR re-request Codex (push) Has been cancelled
AI automation / Poll Codex reaction / retry (push) Has been cancelled
build-et-binaries / build-linux-x64 (push) Has been cancelled
build-et-binaries / build-linux-arm64 (push) Has been cancelled
build-et-binaries / build-macos-universal (push) Has been cancelled
build-et-binaries / build-windows-x64 (push) Has been cancelled
build-et-binaries / release (push) Has been cancelled
This commit is contained in:
91
application/state/useAppLockRuntime.ts
Normal file
91
application/state/useAppLockRuntime.ts
Normal file
@@ -0,0 +1,91 @@
|
||||
import { useCallback, useEffect, useState } from 'react';
|
||||
|
||||
export type RuntimeAppLockReason = 'startup' | 'idle' | 'manual' | 'background' | null;
|
||||
|
||||
export interface RuntimeAppLockState {
|
||||
initialized: boolean;
|
||||
locked: boolean;
|
||||
reason: RuntimeAppLockReason;
|
||||
version: number;
|
||||
lastLockedAt: number | null;
|
||||
lastUnlockedAt: number | null;
|
||||
lastActivityAt: number | null;
|
||||
}
|
||||
|
||||
export function normalizeRuntimeAppLockState(input: unknown): RuntimeAppLockState {
|
||||
const record = input && typeof input === 'object' ? input as Record<string, unknown> : null;
|
||||
const reason = record?.reason;
|
||||
|
||||
return {
|
||||
initialized: record?.initialized === true,
|
||||
locked: record?.locked === true,
|
||||
reason:
|
||||
reason === 'startup' ||
|
||||
reason === 'idle' ||
|
||||
reason === 'manual' ||
|
||||
reason === 'background'
|
||||
? reason
|
||||
: null,
|
||||
version: typeof record?.version === 'number' && Number.isFinite(record.version) ? record.version : 0,
|
||||
lastLockedAt: typeof record?.lastLockedAt === 'number' && Number.isFinite(record.lastLockedAt) ? record.lastLockedAt : null,
|
||||
lastUnlockedAt: typeof record?.lastUnlockedAt === 'number' && Number.isFinite(record.lastUnlockedAt) ? record.lastUnlockedAt : null,
|
||||
lastActivityAt: typeof record?.lastActivityAt === 'number' && Number.isFinite(record.lastActivityAt) ? record.lastActivityAt : null,
|
||||
};
|
||||
}
|
||||
|
||||
const DEFAULT_RUNTIME_APP_LOCK_STATE: RuntimeAppLockState = normalizeRuntimeAppLockState(null);
|
||||
|
||||
export function selectPreferredRuntimeAppLockState(
|
||||
current: RuntimeAppLockState,
|
||||
incoming: RuntimeAppLockState,
|
||||
): RuntimeAppLockState {
|
||||
if (incoming.version > current.version) return incoming;
|
||||
if (incoming.version < current.version) return current;
|
||||
if (incoming.initialized && !current.initialized) return incoming;
|
||||
if (!incoming.initialized && current.initialized) return current;
|
||||
return incoming;
|
||||
}
|
||||
|
||||
export function useAppLockRuntime(
|
||||
bridge: Pick<
|
||||
NonNullable<NetcattyBridge>,
|
||||
'getAppLockRuntimeState' | 'onAppLockRuntimeStateChanged'
|
||||
> | null | undefined,
|
||||
) {
|
||||
const [runtimeState, setRuntimeState] = useState<RuntimeAppLockState>(DEFAULT_RUNTIME_APP_LOCK_STATE);
|
||||
const refreshRuntimeState = useCallback(async () => {
|
||||
const nextState = await bridge?.getAppLockRuntimeState?.();
|
||||
const normalized = normalizeRuntimeAppLockState(nextState);
|
||||
setRuntimeState((current) => selectPreferredRuntimeAppLockState(current, normalized));
|
||||
return normalized;
|
||||
}, [bridge]);
|
||||
|
||||
useEffect(() => {
|
||||
let cancelled = false;
|
||||
|
||||
const unsubscribe = bridge?.onAppLockRuntimeStateChanged?.((nextState) => {
|
||||
if (cancelled) return;
|
||||
const normalized = normalizeRuntimeAppLockState(nextState);
|
||||
setRuntimeState((current) => selectPreferredRuntimeAppLockState(current, normalized));
|
||||
}) ?? (() => {});
|
||||
|
||||
void refreshRuntimeState().catch(() => {
|
||||
if (cancelled) return;
|
||||
setRuntimeState((current) => selectPreferredRuntimeAppLockState(
|
||||
current,
|
||||
DEFAULT_RUNTIME_APP_LOCK_STATE,
|
||||
));
|
||||
});
|
||||
|
||||
return () => {
|
||||
cancelled = true;
|
||||
unsubscribe();
|
||||
};
|
||||
}, [bridge, refreshRuntimeState]);
|
||||
|
||||
return {
|
||||
runtimeState,
|
||||
setRuntimeState,
|
||||
refreshRuntimeState,
|
||||
};
|
||||
}
|
||||
Reference in New Issue
Block a user