Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
dd99dd6d7b | ||
|
|
e93e9ed839 | ||
|
|
dd23de7aaa | ||
|
|
f1602f67d4 |
No files matched your search
@@ -6,7 +6,7 @@
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=24.18.0",
|
||||
"pnpm": ">=11.11.0"
|
||||
"pnpm": ">=11.13.1"
|
||||
},
|
||||
"packageManager": "pnpm@11.11.0"
|
||||
"packageManager": "pnpm@11.13.1"
|
||||
}
|
||||
+2
-2
@@ -69,7 +69,7 @@
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=24.18.0",
|
||||
"pnpm": ">=11.11.0"
|
||||
"pnpm": ">=11.13.1"
|
||||
},
|
||||
"packageManager": "pnpm@11.11.0"
|
||||
"packageManager": "pnpm@11.13.1"
|
||||
}
|
||||
@@ -271,6 +271,7 @@ export const onboardRouter = createTRPCRouter({
|
||||
setupIntegrations: onboardingProcedure.requiresStep("integrations").mutation(async ({ ctx }) => {
|
||||
const db = ctx.db;
|
||||
|
||||
const allIntegrations = await db.query.integrations.findMany();
|
||||
const allApps = await db.query.apps.findMany();
|
||||
|
||||
const board = await db.query.boards.findFirst({
|
||||
@@ -315,6 +316,7 @@ export const onboardRouter = createTRPCRouter({
|
||||
layoutId: layout.id,
|
||||
columnCount: layout.columnCount,
|
||||
},
|
||||
allIntegrations,
|
||||
allApps,
|
||||
);
|
||||
}
|
||||
|
||||
@@ -698,11 +698,13 @@ const seedBoardWidgetsAsync = async (db: Database) => {
|
||||
const layout = board.layouts[0];
|
||||
if (!section || !layout) return;
|
||||
|
||||
const allIntegrations = await db.query.integrations.findMany();
|
||||
const allApps = await db.query.apps.findMany();
|
||||
|
||||
const count = await placeAllWidgetsAsync(
|
||||
db,
|
||||
{ boardId: board.id, sectionId: section.id, layoutId: layout.id, columnCount: layout.columnCount },
|
||||
allIntegrations,
|
||||
allApps,
|
||||
);
|
||||
|
||||
|
||||
@@ -1,11 +1,19 @@
|
||||
import { stringify } from "superjson";
|
||||
import superjson from "superjson";
|
||||
|
||||
import { createId } from "@homarr/common";
|
||||
import { defaultBookmarkApps, defaultWidgetConfigs, emptySuperJSON } from "@homarr/definitions";
|
||||
import {
|
||||
defaultBookmarkApps,
|
||||
defaultWidgetConfigs,
|
||||
emptySuperJSON,
|
||||
getWidgetKindsForIntegration,
|
||||
} from "@homarr/definitions";
|
||||
import type { WidgetKind } from "@homarr/definitions";
|
||||
|
||||
import type { Database } from "..";
|
||||
import { integrationItems, itemLayouts, items } from "../schema";
|
||||
import type { Integration } from "../schema";
|
||||
|
||||
const widgetConfigMap = new Map(defaultWidgetConfigs.map((config) => [config.kind, config]));
|
||||
|
||||
interface BoardTarget {
|
||||
boardId: string;
|
||||
@@ -69,7 +77,12 @@ interface App {
|
||||
name: string;
|
||||
}
|
||||
|
||||
export const placeAllWidgetsAsync = async (db: Database, target: BoardTarget, allApps: App[]) => {
|
||||
export const placeAllWidgetsAsync = async (
|
||||
db: Database,
|
||||
target: BoardTarget,
|
||||
allIntegrations: Integration[],
|
||||
allApps: App[],
|
||||
) => {
|
||||
const ctx: PlacementContext = {
|
||||
...target,
|
||||
xOffset: 0,
|
||||
@@ -79,11 +92,38 @@ export const placeAllWidgetsAsync = async (db: Database, target: BoardTarget, al
|
||||
|
||||
const placedWidgets = new Set<WidgetKind>();
|
||||
|
||||
for (const integration of allIntegrations) {
|
||||
for (const widgetKind of getWidgetKindsForIntegration(integration.kind)) {
|
||||
if (placedWidgets.has(widgetKind)) continue;
|
||||
const config = widgetConfigMap.get(widgetKind);
|
||||
if (config?.skip) continue;
|
||||
placedWidgets.add(widgetKind);
|
||||
|
||||
const matchingIds = allIntegrations
|
||||
.filter((row) => getWidgetKindsForIntegration(row.kind).includes(widgetKind))
|
||||
.map((row) => row.id);
|
||||
|
||||
const options = config?.options ? superjson.stringify(config.options) : undefined;
|
||||
await placeWidgetAsync(
|
||||
db,
|
||||
ctx,
|
||||
widgetKind,
|
||||
matchingIds,
|
||||
options,
|
||||
config && { width: config.width, height: config.height },
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
for (const app of allApps) {
|
||||
await placeWidgetAsync(db, ctx, "app", [], stringify({ appId: app.id, openInNewTab: true, showTitle: true }), {
|
||||
width: 1,
|
||||
height: 1,
|
||||
});
|
||||
await placeWidgetAsync(
|
||||
db,
|
||||
ctx,
|
||||
"app",
|
||||
[],
|
||||
superjson.stringify({ appId: app.id, openInNewTab: true, showTitle: true }),
|
||||
{ width: 1, height: 1 },
|
||||
);
|
||||
}
|
||||
|
||||
const bookmarkAppNames = new Set(defaultBookmarkApps.map((bookmark) => bookmark.name));
|
||||
@@ -98,7 +138,7 @@ export const placeAllWidgetsAsync = async (db: Database, target: BoardTarget, al
|
||||
options = { ...options, items: bookmarkAppIds };
|
||||
}
|
||||
|
||||
await placeWidgetAsync(db, ctx, config.kind, [], options ? stringify(options) : undefined, {
|
||||
await placeWidgetAsync(db, ctx, config.kind, [], options ? superjson.stringify(options) : undefined, {
|
||||
width: config.width,
|
||||
height: config.height,
|
||||
});
|
||||
|
||||
@@ -66,16 +66,20 @@ export default function MediaServerWidget({ options, integrationIds }: WidgetCom
|
||||
const currentlyPlaying = row.original.currentlyPlaying;
|
||||
if (!currentlyPlaying) return null;
|
||||
|
||||
const isPaused = currentlyPlaying.playback.state === "paused";
|
||||
const playback = currentlyPlaying.playback;
|
||||
const isPaused = playback?.state === "paused";
|
||||
const Icon = isPaused ? IconPlayerPause : mediaTypeIconMap[currentlyPlaying.type];
|
||||
|
||||
const { positionMs, durationMs } = currentlyPlaying.playback;
|
||||
const positionMs = playback?.positionMs ?? null;
|
||||
const durationMs = playback?.durationMs ?? null;
|
||||
const progressPercent =
|
||||
positionMs !== null && durationMs !== null && durationMs > 0
|
||||
? Math.min(100, Math.round((positionMs / durationMs) * 100))
|
||||
: null;
|
||||
const remainingMinutes =
|
||||
positionMs !== null && durationMs !== null ? Math.max(0, Math.round((durationMs - positionMs) / 60_000)) : null;
|
||||
positionMs !== null && durationMs !== null
|
||||
? Math.max(0, Math.round((durationMs - positionMs) / 60_000))
|
||||
: null;
|
||||
|
||||
return (
|
||||
<Stack gap={4} style={{ minWidth: 0 }}>
|
||||
@@ -122,8 +126,8 @@ export default function MediaServerWidget({ options, integrationIds }: WidgetCom
|
||||
|
||||
const isTranscoding = Boolean(
|
||||
currentlyPlaying.metadata?.transcoding.target.videoCodec ??
|
||||
currentlyPlaying.metadata?.transcoding.target.audioCodec ??
|
||||
currentlyPlaying.metadata?.transcoding.container,
|
||||
currentlyPlaying.metadata?.transcoding.target.audioCodec ??
|
||||
currentlyPlaying.metadata?.transcoding.container,
|
||||
);
|
||||
|
||||
return (
|
||||
|
||||
Reference in new issue
Block a user