diff --git a/electron/main/backend/update-center/index.ts b/electron/main/backend/update-center/index.ts
index d41143a4..5b8a80d6 100644
--- a/electron/main/backend/update-center/index.ts
+++ b/electron/main/backend/update-center/index.ts
@@ -49,21 +49,6 @@ interface RemoteCategoryAppEntry {
const REMOTE_STORE_BASE_URL = "https://erotica.spark-app.store";
const categoryCache = new Map>();
-const isAptssAvailable = async (): Promise => {
- return await new Promise((resolve) => {
- const child = spawn("command", ["-v", "aptss"], {
- shell: false,
- env: process.env,
- });
- child.on("close", (code) => {
- resolve(code === 0);
- });
- child.on("error", () => {
- resolve(false);
- });
- });
-};
-
const APTSS_LIST_UPGRADABLE_COMMAND = {
command: "bash",
args: [
@@ -367,26 +352,23 @@ const enrichItemIcons = (items: UpdateCenterItem[]): UpdateCenterItem[] => {
export const loadUpdateCenterItems = async (
runCommand: UpdateCenterCommandRunner = runCommandCapture,
): Promise => {
- const aptssAvailable = await isAptssAvailable();
-
const [aptssResult, apmResult, aptssInstalledResult, apmInstalledResult] =
await Promise.all([
- aptssAvailable
- ? runCommand(
- APTSS_LIST_UPGRADABLE_COMMAND.command,
- APTSS_LIST_UPGRADABLE_COMMAND.args,
- )
- : Promise.resolve({ code: 0, stdout: "", stderr: "" }),
+ runCommand(
+ APTSS_LIST_UPGRADABLE_COMMAND.command,
+ APTSS_LIST_UPGRADABLE_COMMAND.args,
+ ),
runCommand("apm", ["list", "--upgradable"]),
- aptssAvailable
- ? runCommand(
- DPKG_QUERY_INSTALLED_COMMAND.command,
- DPKG_QUERY_INSTALLED_COMMAND.args,
- )
- : Promise.resolve({ code: 0, stdout: "", stderr: "" }),
+ runCommand(
+ DPKG_QUERY_INSTALLED_COMMAND.command,
+ DPKG_QUERY_INSTALLED_COMMAND.args,
+ ),
runCommand("apm", ["list", "--installed"]),
]);
+ const aptssAvailable =
+ aptssResult.code === 0 || aptssInstalledResult.code === 0;
+
const warnings = [
aptssAvailable
? getCommandError("aptss upgradable query", aptssResult)
@@ -405,10 +387,6 @@ export const loadUpdateCenterItems = async (
const apmItems =
apmResult.code === 0 ? parseApmUpgradableOutput(apmResult.stdout) : [];
- if (apmResult.code !== 0) {
- throw new Error(warnings.join("; "));
- }
-
const installedSources = buildInstalledSourceMap(
aptssAvailable && aptssInstalledResult.code === 0
? aptssInstalledResult.stdout
diff --git a/src/__tests__/unit/update-center/UpdateCenterModal.test.ts b/src/__tests__/unit/update-center/UpdateCenterModal.test.ts
index a07ad7ae..17290d8c 100644
--- a/src/__tests__/unit/update-center/UpdateCenterModal.test.ts
+++ b/src/__tests__/unit/update-center/UpdateCenterModal.test.ts
@@ -91,6 +91,34 @@ const createStore = (
};
describe("UpdateCenterModal", () => {
+ it("constrains the update list so it can scroll with a visible scrollbar", () => {
+ const store = createStore({
+ items: Array.from({ length: 20 }, (_, index) =>
+ createItem({
+ taskKey: `aptss:spark-item-${index}`,
+ packageName: `spark-item-${index}`,
+ displayName: `Spark Item ${index}`,
+ }),
+ ),
+ tasks: [],
+ warnings: [],
+ hasRunningTasks: false,
+ });
+
+ const { container } = render(UpdateCenterModal, {
+ props: {
+ show: true,
+ store,
+ },
+ });
+
+ const scrollContainer = container.querySelector(".scrollbar-muted");
+
+ expect(scrollContainer?.className).toContain("overflow-y-auto");
+ expect(scrollContainer?.className).toContain("flex-1");
+ expect(scrollContainer?.className).toContain("overscroll-contain");
+ });
+
it("renders source tags, running state, warnings, and migration marker", () => {
const store = createStore();
diff --git a/src/components/UpdateCenterModal.vue b/src/components/UpdateCenterModal.vue
index a5ef90e5..f50d1406 100644
--- a/src/components/UpdateCenterModal.vue
+++ b/src/components/UpdateCenterModal.vue
@@ -42,7 +42,7 @@
-