mirror of
https://github.com/vrtmrz/obsidian-livesync.git
synced 2026-10-08 02:12:30 +00:00
Merge current main for Setup URI dependency alignment
This commit is contained in:
@@ -10,7 +10,7 @@ import {
|
||||
import { scheduleTask } from "octagonal-wheels/concurrency/task";
|
||||
import { fireAndForget, isDirty, throttle } from "@vrtmrz/livesync-commonlib/compat/common/utils";
|
||||
import {
|
||||
collectingChunks,
|
||||
chunkFetchCounts,
|
||||
pluginScanningCount,
|
||||
hiddenFilesEventCount,
|
||||
hiddenFilesProcessingCount,
|
||||
@@ -36,7 +36,11 @@ import {
|
||||
formatRemoteActivityStatusLabel,
|
||||
getTrackedRequestCount,
|
||||
} from "./RemoteActivityStatus.ts";
|
||||
import { createMinimumVisibleActivityCount, createPaddedCounterLabel } from "./StatusBarDisplay.ts";
|
||||
import {
|
||||
createChunkFetchCounterLabel,
|
||||
createMinimumVisibleActivityCount,
|
||||
createPaddedCounterLabel,
|
||||
} from "./StatusBarDisplay.ts";
|
||||
import type { LiveSyncCore } from "@/main.ts";
|
||||
import { LiveSyncError } from "@vrtmrz/livesync-commonlib/compat/common/LSError";
|
||||
import { isValidPath } from "@/common/utils.ts";
|
||||
@@ -140,7 +144,7 @@ export class ModuleLog extends AbstractObsidianModule {
|
||||
const labelStorageCount = registerDisplay(
|
||||
createPaddedCounterLabel(this.services.replication.storageApplyingCount, `💾`)
|
||||
);
|
||||
const labelChunkCount = registerDisplay(createPaddedCounterLabel(collectingChunks, `🧩`));
|
||||
const labelChunkCount = registerDisplay(createChunkFetchCounterLabel(chunkFetchCounts));
|
||||
const labelPluginScanCount = registerDisplay(createPaddedCounterLabel(pluginScanningCount, `🔌`));
|
||||
const labelConflictProcessCount = registerDisplay(
|
||||
createPaddedCounterLabel(this.services.conflict.conflictProcessQueueCount, `🔩`)
|
||||
|
||||
@@ -131,3 +131,50 @@ export function createPaddedCounterLabel(
|
||||
source.offChanged(update);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Displays the disjoint initial and retry chunk-fetch counts with the same
|
||||
* padding and inactive linger behaviour as the other status counters.
|
||||
*/
|
||||
export function createChunkFetchCounterLabel(
|
||||
source: ReactiveValue<{ initial: number; retrying: number }>
|
||||
): DisposableReactiveValue<string> {
|
||||
const initialCount = reactiveSource(0);
|
||||
const retryingCount = reactiveSource(0);
|
||||
const initialLabel = createPaddedCounterLabel(initialCount, "🛄");
|
||||
const retryingLabel = createPaddedCounterLabel(retryingCount, "🔁");
|
||||
const formatted = reactiveSource(`${initialLabel.value}${retryingLabel.value}`);
|
||||
let updatingCounts = false;
|
||||
let disposed = false;
|
||||
|
||||
const updateLabel = () => {
|
||||
if (updatingCounts || disposed) return;
|
||||
formatted.value = `${initialLabel.value}${retryingLabel.value}`;
|
||||
};
|
||||
initialLabel.onChanged(updateLabel);
|
||||
retryingLabel.onChanged(updateLabel);
|
||||
|
||||
const updateCounts = () => {
|
||||
if (disposed) return;
|
||||
updatingCounts = true;
|
||||
try {
|
||||
initialCount.value = source.value.initial;
|
||||
retryingCount.value = source.value.retrying;
|
||||
} finally {
|
||||
updatingCounts = false;
|
||||
updateLabel();
|
||||
}
|
||||
};
|
||||
source.onChanged(updateCounts);
|
||||
updateCounts();
|
||||
|
||||
return asDisposableReactiveValue(formatted, () => {
|
||||
if (disposed) return;
|
||||
disposed = true;
|
||||
source.offChanged(updateCounts);
|
||||
initialLabel.offChanged(updateLabel);
|
||||
retryingLabel.offChanged(updateLabel);
|
||||
initialLabel.dispose();
|
||||
retryingLabel.dispose();
|
||||
});
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@ import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
|
||||
|
||||
import {
|
||||
STATUS_COUNTER_INACTIVE_LINGER_MS,
|
||||
createChunkFetchCounterLabel,
|
||||
createMinimumVisibleActivityCount,
|
||||
createPaddedCounterLabel,
|
||||
} from "./StatusBarDisplay.ts";
|
||||
@@ -137,3 +138,41 @@ describe("createPaddedCounterLabel", () => {
|
||||
expect(display.value).toBe(" 📄\u20070");
|
||||
});
|
||||
});
|
||||
|
||||
describe("createChunkFetchCounterLabel", () => {
|
||||
beforeEach(() => {
|
||||
vi.useFakeTimers();
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
vi.useRealTimers();
|
||||
});
|
||||
|
||||
it("keeps initial and retry counts separate across an unchanged-total handoff", () => {
|
||||
const counts = reactiveSource({ initial: 2, retrying: 5 });
|
||||
const display = createChunkFetchCounterLabel(counts);
|
||||
const withoutPadding = () => display.value.replace(/\u2007/g, "");
|
||||
const transitionSnapshots: string[] = [];
|
||||
const observeTransitions = () => transitionSnapshots.push(withoutPadding());
|
||||
|
||||
expect(withoutPadding()).toBe(" 🛄2 🔁5");
|
||||
|
||||
display.onChanged(observeTransitions);
|
||||
counts.value = { initial: 0, retrying: 7 };
|
||||
expect(withoutPadding()).toBe(" 🛄0 🔁7");
|
||||
expect(transitionSnapshots).toEqual([" 🛄0 🔁7"]);
|
||||
display.offChanged(observeTransitions);
|
||||
vi.advanceTimersByTime(STATUS_COUNTER_INACTIVE_LINGER_MS - 1);
|
||||
expect(withoutPadding()).toBe(" 🛄0 🔁7");
|
||||
vi.advanceTimersByTime(1);
|
||||
expect(withoutPadding()).toBe(" 🔁7");
|
||||
|
||||
counts.value = { initial: 0, retrying: 0 };
|
||||
expect(withoutPadding()).toBe(" 🔁0");
|
||||
display.dispose();
|
||||
vi.advanceTimersByTime(STATUS_COUNTER_INACTIVE_LINGER_MS);
|
||||
counts.value = { initial: 1, retrying: 0 };
|
||||
|
||||
expect(withoutPadding()).toBe(" 🔁0");
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user