Compare commits
11
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
cc32c167fb | ||
|
|
edb56f3fcd | ||
|
|
fcc5130068 | ||
|
|
c7751e293d | ||
|
|
9b5b79525f | ||
|
|
426929556f | ||
|
|
ade640dcea | ||
|
|
61128ddcc8 | ||
|
|
6a3cee8107 | ||
|
|
06d9c07d22 | ||
|
|
49d0f1a141 |
No files matched your search
@@ -1,3 +1,5 @@
|
||||
## [1.73.0](https://github.com/homarr-labs/homarr/compare/v1.72.0...v1.73.0) (2026-07-31)
|
||||
|
||||
## [1.72.0](https://github.com/homarr-labs/homarr/compare/v1.71.0...v1.72.0) (2026-07-24)
|
||||
|
||||
## [1.71.0](https://github.com/homarr-labs/homarr/compare/v1.70.0...v1.71.0) (2026-07-17)
|
||||
|
||||
@@ -55,9 +55,9 @@ A random secret can be generated by using the following command: `openssl rand -
|
||||
|
||||
| Environment Variable | Description | Possible values | Default |
|
||||
| ------------------------ | ----------- | --------------- | ------- |
|
||||
| ``DOCKER_HOSTNAMES`` | Comma seperated list of hostnames to connect to | For example `localhost,docker.example.com` | - |
|
||||
| ``DOCKER_PORTS`` | Comma seperated list of ports to connect to | For example `2375,2376` | - |
|
||||
| ``DOCKER_SOCKET_PATHS`` | Comma seperated list of paths to sockets | For example `/var/run/docker.sock,/run/user/1000/podman/podman.sock` | - |
|
||||
| ``DOCKER_HOSTNAMES`` | Comma-separated list of hostnames to connect to | For example `localhost,docker.example.com` | - |
|
||||
| ``DOCKER_PORTS`` | Comma-separated list of ports to connect to | For example `2375,2376` | - |
|
||||
| ``DOCKER_SOCKET_PATHS`` | Comma-separated list of mounted Docker-compatible socket paths. See the [Docker and Podman integration guide](/docs/integrations/docker) | For example `/var/run/docker.sock,/var/run/podman.sock` | - |
|
||||
|
||||
## Database
|
||||
| Environment Variable | Description | Possible values | Default |
|
||||
|
||||
@@ -31,4 +31,4 @@ Icons that are high quality and printable ([SVG](https://wikipedia.org/wiki/Scal
|
||||
|
||||
### Using external icons
|
||||
If you don't find the icon you're looking for on Dashboard Icons or wish to use a different source, you can simply enter a URL that points to an icon.
|
||||
It is important that the URL directly points to the file without any advertisements or elements around it.
|
||||
Direct HTTP(S) image URLs are used as entered instead of being searched in the built-in repositories. It is important that the URL directly points to the file without any advertisements or elements around it.
|
||||
@@ -55,6 +55,74 @@ services:
|
||||
With docker run, add this parameter: `-v /var/run/docker.sock:/var/run/docker.sock`.
|
||||
In Windows, you'll need to adjust the slashes: `-v //var/run/docker.sock:/var/run/docker.sock`
|
||||
|
||||
### Using Podman
|
||||
|
||||
On Linux, Homarr can connect to Podman's [Docker-compatible API](https://docs.podman.io/en/latest/markdown/podman-system-service.1.html).
|
||||
The Podman API socket must be running and mounted into the Homarr container.
|
||||
The socket grants full access to Podman, including arbitrary code execution as the user running the API, so only mount it into trusted containers.
|
||||
|
||||
For rootless Podman, enable the socket for the user that runs Homarr:
|
||||
|
||||
```bash
|
||||
systemctl --user enable --now podman.socket
|
||||
```
|
||||
|
||||
The rootless socket is located at `$XDG_RUNTIME_DIR/podman/podman.sock` (usually `/run/user/<uid>/podman/podman.sock`).
|
||||
You can confirm the path with:
|
||||
|
||||
```bash
|
||||
podman info --format '{{.Host.RemoteSocket.Path}}'
|
||||
```
|
||||
|
||||
Mount that socket into the Homarr container and point `DOCKER_SOCKET_PATHS` to its path **inside** the container:
|
||||
|
||||
```yaml
|
||||
services:
|
||||
homarr:
|
||||
container_name: homarr
|
||||
image: ghcr.io/homarr-labs/homarr:latest
|
||||
restart: unless-stopped
|
||||
volumes:
|
||||
- ${XDG_RUNTIME_DIR}/podman/podman.sock:/var/run/podman.sock
|
||||
- ./homarr/appdata:/appdata
|
||||
environment:
|
||||
SECRET_ENCRYPTION_KEY: your_64_character_hex_string
|
||||
DOCKER_SOCKET_PATHS: /var/run/podman.sock
|
||||
ports:
|
||||
- "7575:7575"
|
||||
```
|
||||
|
||||
Start Homarr with `podman compose up -d`.
|
||||
Run the compose project as the same user that owns the rootless Podman socket so `$XDG_RUNTIME_DIR` resolves to the correct path.
|
||||
To keep the user socket available after logout and across reboots, enable lingering with `loginctl enable-linger <user>`.
|
||||
|
||||
For rootful Podman, enable the system socket with `sudo systemctl enable --now podman.socket`.
|
||||
Its default path is `/run/podman/podman.sock`; mount that path instead and start Homarr with `sudo podman compose up -d`.
|
||||
|
||||
:::note SELinux
|
||||
On systems with SELinux enabled, Podman's documentation recommends disabling label separation for a container that accesses the API socket.
|
||||
Add the following to the Homarr service:
|
||||
|
||||
```yaml
|
||||
security_opt:
|
||||
- label=disable
|
||||
```
|
||||
|
||||
:::
|
||||
|
||||
You can connect Homarr to multiple Docker-compatible sockets by mounting each socket and listing their in-container paths, separated by commas:
|
||||
|
||||
```yaml
|
||||
services:
|
||||
homarr:
|
||||
image: ghcr.io/homarr-labs/homarr:latest
|
||||
volumes:
|
||||
- /var/run/docker.sock:/var/run/docker.sock
|
||||
- ${XDG_RUNTIME_DIR}/podman/podman.sock:/var/run/podman.sock
|
||||
environment:
|
||||
DOCKER_SOCKET_PATHS: /var/run/docker.sock,/var/run/podman.sock
|
||||
```
|
||||
|
||||
### Managing your Docker containers within Homarr
|
||||
Homarr allows you to interact with Docker containers running on your system.
|
||||
Each container row has an action menu with the following options:
|
||||
|
||||
@@ -10,19 +10,21 @@ import { AddingIntegration } from '@site/src/components/integrations/adding';
|
||||
import { IntegrationSecrets } from '@site/src/components/integrations/secrets';
|
||||
import { navidromeIntegration } from '.';
|
||||
import { audioStatsWidget } from '@site/docs/widgets/audio-stats';
|
||||
import { mediaServerWidget } from '@site/docs/widgets/media-server';
|
||||
|
||||
|
||||
<IntegrationHeader
|
||||
integration={navidromeIntegration}
|
||||
categories={['Media']}
|
||||
categories={['Media', 'Media server']}
|
||||
/>
|
||||
|
||||
Navidrome provides music library statistics including artist, album, and song counts, as well as now playing information via the Subsonic API.
|
||||
Navidrome provides music library statistics including artist, album, and song counts, as well as now playing audio streams via the Subsonic API.
|
||||
|
||||
### Widgets & Capabilities
|
||||
<IntegrationCapabilites
|
||||
items={[
|
||||
{ widget: audioStatsWidget },
|
||||
{ widget: mediaServerWidget },
|
||||
]}
|
||||
/>
|
||||
|
||||
|
||||
@@ -28,7 +28,7 @@ The name must be at least one character long and can be chosen freely.
|
||||
### Icon URL
|
||||
|
||||
This is the URL to the icon that will be displayed on the app widget.
|
||||
It can be a url to an image in the internet, one from the included icon repositories or a local file uploaded through the upload button.
|
||||
You can paste a direct HTTP(S) URL to an image, search the included icon repositories by name, or upload a local file through the upload button. Direct image URLs are used as entered and are not searched in the icon repositories.
|
||||
|
||||

|
||||
|
||||
@@ -50,4 +50,4 @@ It's useful when you want to ping the service internally for example with a cust
|
||||
|
||||
On the apps management page you find all apps that exist in your Homarr instance. You can edit and delete them.
|
||||
|
||||

|
||||

|
||||
@@ -1,43 +1,45 @@
|
||||
---
|
||||
title: 'Audio Stats'
|
||||
description: 'Displays library statistics from Navidrome or Audiobookshelf, adapting its display based on the linked integration.'
|
||||
title: "Audio Stats"
|
||||
description: "Displays media and listening statistics from Navidrome or Audiobookshelf, adapting its display based on the linked integration."
|
||||
hide_title: true
|
||||
---
|
||||
|
||||
import { WidgetHeader } from '@site/src/components/widgets/header';
|
||||
import { AddingWidget } from '@site/src/components/widgets/adding';
|
||||
import { WidgetConfig } from '@site/src/components/widgets/configuration';
|
||||
import { WidgetIntegrations } from '@site/src/components/widgets/integrations';
|
||||
import { audioStatsWidget } from '.';
|
||||
import { navidromeIntegration } from '@site/docs/integrations/navidrome';
|
||||
import { audiobookshelfIntegration } from '@site/docs/integrations/audiobookshelf';
|
||||
import { WidgetHeader } from "@site/src/components/widgets/header";
|
||||
import { AddingWidget } from "@site/src/components/widgets/adding";
|
||||
import { WidgetConfig } from "@site/src/components/widgets/configuration";
|
||||
import { WidgetIntegrations } from "@site/src/components/widgets/integrations";
|
||||
import { audioStatsWidget } from ".";
|
||||
import { navidromeIntegration } from "@site/docs/integrations/navidrome";
|
||||
import { audiobookshelfIntegration } from "@site/docs/integrations/audiobookshelf";
|
||||
|
||||
|
||||
<WidgetHeader
|
||||
widget={audioStatsWidget}
|
||||
categories={['Media']}
|
||||
/>
|
||||
<WidgetHeader widget={audioStatsWidget} categories={["Media"]} />
|
||||
|
||||
This widget adapts its display based on the linked integration:
|
||||
|
||||
- **Navidrome**: Shows artist, album, and song counts, plus a now playing section with active streams
|
||||
- **Navidrome**: Shows artist, album, and song counts
|
||||
- **Audiobookshelf**: Shows library count, audiobook/podcast totals, listening time, and active sessions
|
||||
|
||||
Only options relevant to your linked integration are shown in the configuration panel.
|
||||
|
||||
### Supported Integrations
|
||||
|
||||
<WidgetIntegrations items={[{
|
||||
integration: navidromeIntegration,
|
||||
note: "Displays music library stats and now playing"
|
||||
}, {
|
||||
integration: audiobookshelfIntegration,
|
||||
note: "Displays audiobook/podcast library stats and listening time"
|
||||
}]} />
|
||||
<WidgetIntegrations
|
||||
items={[
|
||||
{
|
||||
integration: navidromeIntegration,
|
||||
note: "Displays music library statistics",
|
||||
},
|
||||
{
|
||||
integration: audiobookshelfIntegration,
|
||||
note: "Displays audiobook/podcast library stats and listening time",
|
||||
},
|
||||
]}
|
||||
/>
|
||||
|
||||
### Adding the widget
|
||||
|
||||
<AddingWidget />
|
||||
|
||||
### Configuration
|
||||
|
||||
<WidgetConfig configuration={audioStatsWidget.configuration} />
|
||||
@@ -27,24 +27,6 @@ export const audioStatsWidget: WidgetDefinition = {
|
||||
values: { type: "boolean" },
|
||||
defaultValue: "yes",
|
||||
},
|
||||
{
|
||||
name: "Show now playing",
|
||||
description: "Displays currently playing tracks (Navidrome only)",
|
||||
values: { type: "boolean" },
|
||||
defaultValue: "yes",
|
||||
},
|
||||
{
|
||||
name: "Show now playing list",
|
||||
description: "Displays a detailed list of now playing tracks (Navidrome only)",
|
||||
values: { type: "boolean" },
|
||||
defaultValue: "yes",
|
||||
},
|
||||
{
|
||||
name: "Max now playing items",
|
||||
description: "Maximum number of now playing tracks to display (Navidrome only)",
|
||||
values: "Number (1-5)",
|
||||
defaultValue: "3",
|
||||
},
|
||||
{
|
||||
name: "Show library count",
|
||||
description: "Displays the number of libraries (Audiobookshelf only)",
|
||||
|
||||
@@ -14,6 +14,7 @@ import TabItem from '@theme/TabItem';
|
||||
import { mediaServerWidget } from '.';
|
||||
import { embyIntegration } from '@site/docs/integrations/emby';
|
||||
import { jellyfinIntegration } from '@site/docs/integrations/jellyfin';
|
||||
import { navidromeIntegration } from '@site/docs/integrations/navidrome';
|
||||
import { plexIntegration } from '@site/docs/integrations/plex';
|
||||
|
||||
|
||||
@@ -39,6 +40,9 @@ import mediaTable from './img/table.png';
|
||||
integration: embyIntegration,
|
||||
}, {
|
||||
integration: jellyfinIntegration,
|
||||
}, {
|
||||
integration: navidromeIntegration,
|
||||
note: "Will always show only currently playing audio streams, not all active sessions."
|
||||
}, {
|
||||
integration: plexIntegration,
|
||||
note: "Will always show only currently playing streams, not all active sessions."
|
||||
@@ -50,4 +54,3 @@ import mediaTable from './img/table.png';
|
||||
|
||||
### Configuration
|
||||
<WidgetConfig configuration={mediaServerWidget.configuration} />
|
||||
|
||||
@@ -10,7 +10,7 @@ export const mediaServerWidget: WidgetDefinition = {
|
||||
items: [
|
||||
{
|
||||
name: "Show only currently playing",
|
||||
description: "Disabling this will not work for plex.",
|
||||
description: "Plex and Navidrome always show only currently playing streams.",
|
||||
values: { type: "boolean" },
|
||||
defaultValue: "yes",
|
||||
},
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "homarr",
|
||||
"version": "1.72.0",
|
||||
"version": "1.73.0",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"build": "cross-env CI=true turbo build",
|
||||
|
||||
@@ -17,7 +17,7 @@ export const mediaServerRouter = createTRPCRouter({
|
||||
mcp: {
|
||||
enabled: true,
|
||||
description:
|
||||
"Get currently active streams from Plex/Jellyfin/Emby media servers. REQUIRED: integrationIds (array of media server integration IDs from integration_all), showOnlyPlaying (boolean — true to filter to actively playing streams only)",
|
||||
"Get currently active streams from Plex/Jellyfin/Emby/Navidrome media servers. REQUIRED: integrationIds (array of media server integration IDs from integration_all), showOnlyPlaying (boolean — true to filter to actively playing streams only)",
|
||||
},
|
||||
})
|
||||
.concat(createMediaServerIntegrationMiddleware("query"))
|
||||
|
||||
@@ -418,7 +418,7 @@ export const integrationDefs = {
|
||||
name: "Navidrome",
|
||||
secretKinds: [["username", "password"]],
|
||||
iconUrl: "https://cdn.jsdelivr.net/gh/homarr-labs/dashboard-icons@master/svg/navidrome.svg",
|
||||
category: ["mediaLibrary"],
|
||||
category: ["mediaLibrary", "mediaService"],
|
||||
documentationUrl: null,
|
||||
defaultPort: 4533,
|
||||
},
|
||||
|
||||
@@ -0,0 +1,109 @@
|
||||
import { act, createElement } from "react";
|
||||
import { createRoot } from "react-dom/client";
|
||||
import { afterEach, beforeAll, beforeEach, describe, expect, test, vi } from "vitest";
|
||||
import { MantineProvider } from "@mantine/core";
|
||||
|
||||
import type { Root } from "react-dom/client";
|
||||
|
||||
const { findIconsQuery } = vi.hoisted(() => ({
|
||||
findIconsQuery: vi.fn((_query: { searchText: string }) => ({
|
||||
data: { icons: [], countIcons: 0 },
|
||||
isLoading: false,
|
||||
isError: false,
|
||||
refetch: vi.fn(),
|
||||
})),
|
||||
}));
|
||||
|
||||
vi.mock("@homarr/api/client", () => ({
|
||||
clientApi: { icon: { findIcons: { useQuery: findIconsQuery } } },
|
||||
}));
|
||||
vi.mock("@homarr/auth/client", () => ({
|
||||
useSession: () => ({ data: { user: { permissions: [] } } }),
|
||||
}));
|
||||
vi.mock("@homarr/translation", () => ({ supportedLanguages: [] }));
|
||||
vi.mock("@homarr/translation/client", () => ({
|
||||
useScopedI18n: () => (key: string) => key,
|
||||
}));
|
||||
vi.mock("../upload-media/upload-media", () => ({ UploadMedia: () => null }));
|
||||
|
||||
import { IconPicker } from "./icon-picker";
|
||||
|
||||
const directIconUrl = "https://cdn.example.com/shopify.svg";
|
||||
|
||||
const setInputValue = (input: HTMLInputElement, value: string) => {
|
||||
const setter = Object.getOwnPropertyDescriptor(HTMLInputElement.prototype, "value")?.set;
|
||||
if (!setter) throw new Error("Input value setter was not found");
|
||||
setter.call(input, value);
|
||||
input.dispatchEvent(new Event("input", { bubbles: true }));
|
||||
};
|
||||
|
||||
describe("IconPicker", () => {
|
||||
let container: HTMLDivElement;
|
||||
let root: Root;
|
||||
|
||||
beforeAll(() => {
|
||||
Object.defineProperty(globalThis, "IS_REACT_ACT_ENVIRONMENT", { value: true, writable: true });
|
||||
Object.defineProperty(window, "matchMedia", {
|
||||
writable: true,
|
||||
value: (query: string) => ({
|
||||
matches: false,
|
||||
media: query,
|
||||
onchange: null,
|
||||
addListener: () => undefined,
|
||||
removeListener: () => undefined,
|
||||
addEventListener: () => undefined,
|
||||
removeEventListener: () => undefined,
|
||||
dispatchEvent: () => false,
|
||||
}),
|
||||
});
|
||||
});
|
||||
|
||||
beforeEach(() => {
|
||||
findIconsQuery.mockClear();
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
root.unmount();
|
||||
container.remove();
|
||||
});
|
||||
|
||||
const renderPicker = async (onChange: (value: string) => void) => {
|
||||
container = document.createElement("div");
|
||||
document.body.appendChild(container);
|
||||
root = createRoot(container);
|
||||
await act(async () => {
|
||||
root.render(createElement(MantineProvider, null, createElement(IconPicker, { value: "", onChange })));
|
||||
});
|
||||
const input = container.querySelector("input");
|
||||
if (!input) throw new Error("Icon picker input was not rendered");
|
||||
return input;
|
||||
};
|
||||
|
||||
test("keeps a direct URL visible without searching the icon repositories", async () => {
|
||||
const onChange = vi.fn();
|
||||
const input = await renderPicker(onChange);
|
||||
|
||||
await act(async () => {
|
||||
setInputValue(input, directIconUrl);
|
||||
await new Promise((resolve) => setTimeout(resolve, 150));
|
||||
});
|
||||
|
||||
expect(onChange).toHaveBeenCalledWith(directIconUrl);
|
||||
expect(input.value).toBe(directIconUrl);
|
||||
expect(findIconsQuery.mock.calls.some(([query]) => query.searchText === directIconUrl)).toBe(false);
|
||||
});
|
||||
|
||||
test("keeps icon names in repository search mode", async () => {
|
||||
const onChange = vi.fn();
|
||||
const input = await renderPicker(onChange);
|
||||
|
||||
await act(async () => {
|
||||
setInputValue(input, "shopify");
|
||||
await new Promise((resolve) => setTimeout(resolve, 150));
|
||||
});
|
||||
|
||||
expect(onChange).not.toHaveBeenCalled();
|
||||
expect(input.value).toBe("shopify");
|
||||
expect(findIconsQuery.mock.calls.some(([query]) => query.searchText === "shopify")).toBe(true);
|
||||
});
|
||||
});
|
||||
@@ -63,7 +63,7 @@ export const IconPicker = ({
|
||||
const tCommon = useScopedI18n("common");
|
||||
const [debouncedQuery] = useDebouncedValue(query, 100);
|
||||
|
||||
const searchText = (debouncedQuery !== (value ?? "") && debouncedQuery) || "";
|
||||
const searchText = !isDirectIconUrl(debouncedQuery) && debouncedQuery !== (value ?? "") ? debouncedQuery : "";
|
||||
|
||||
const { data, isLoading, isError, refetch } = clientApi.icon.findIcons.useQuery(
|
||||
{ searchText },
|
||||
@@ -165,8 +165,15 @@ export const IconPicker = ({
|
||||
leftSection={leftSection}
|
||||
value={inputValue}
|
||||
onChange={(event) => {
|
||||
combobox.openDropdown();
|
||||
setQuery(event.currentTarget.value);
|
||||
const nextValue = event.currentTarget.value;
|
||||
const trimmedValue = nextValue.trim();
|
||||
setQuery(nextValue);
|
||||
if (isDirectIconUrl(trimmedValue)) {
|
||||
setValue(trimmedValue);
|
||||
combobox.closeDropdown();
|
||||
} else {
|
||||
combobox.openDropdown();
|
||||
}
|
||||
}}
|
||||
onClick={() => combobox.openDropdown()}
|
||||
onFocus={(event) => {
|
||||
@@ -220,3 +227,12 @@ const shouldShowPreview = (value: string | null | undefined): value is string =>
|
||||
if (!value) return false;
|
||||
return !localizationPathRegex.test(value);
|
||||
};
|
||||
|
||||
const isDirectIconUrl = (value: string) => {
|
||||
try {
|
||||
const url = new URL(value.trim());
|
||||
return (url.protocol === "http:" || url.protocol === "https:") && Boolean(url.hostname);
|
||||
} catch {
|
||||
return false;
|
||||
}
|
||||
};
|
||||
@@ -6,6 +6,8 @@ import type { IntegrationTestingInput } from "../base/integration";
|
||||
import { Integration } from "../base/integration";
|
||||
import { TestConnectionError } from "../base/test-connection/test-connection-error";
|
||||
import type { TestingResult } from "../base/test-connection/test-connection-service";
|
||||
import type { IMediaServerIntegration } from "../interfaces/media-server/media-server-integration";
|
||||
import type { CurrentSessionsInput, StreamSession } from "../interfaces/media-server/media-server-types";
|
||||
import type { NavidromeDashboardData, NavidromeNowPlayingEntry, SubsonicResponseBody } from "./navidrome-types";
|
||||
import { subsonicResponseSchema } from "./navidrome-types";
|
||||
|
||||
@@ -22,7 +24,7 @@ const subsonicAuthErrorCodes = new Set([40, 41]);
|
||||
const asArray = <TValue>(value: TValue | TValue[] | undefined): TValue[] =>
|
||||
[value].flat().filter((item): item is TValue => item !== undefined);
|
||||
|
||||
export class NavidromeIntegration extends Integration {
|
||||
export class NavidromeIntegration extends Integration implements IMediaServerIntegration {
|
||||
protected async testingAsync(input: IntegrationTestingInput): Promise<TestingResult> {
|
||||
const url = this.url("/rest/ping.view", this.getAuthParams());
|
||||
const response = await input.fetchAsync(url);
|
||||
@@ -53,20 +55,49 @@ export class NavidromeIntegration extends Integration {
|
||||
}
|
||||
|
||||
public async getDashboardDataAsync(): Promise<NavidromeDashboardData> {
|
||||
const [artistCount, libraryCounts, nowPlaying] = await Promise.all([
|
||||
const [artistCount, libraryCounts] = await Promise.all([
|
||||
this.getArtistCountAsync(),
|
||||
this.getAlbumAndSongCountsAsync(),
|
||||
this.getNowPlayingAsync(),
|
||||
]);
|
||||
|
||||
return {
|
||||
artistCount,
|
||||
albumCount: libraryCounts.albumCount,
|
||||
songCount: libraryCounts.songCount,
|
||||
nowPlaying,
|
||||
};
|
||||
}
|
||||
|
||||
public async getCurrentSessionsAsync(_options: CurrentSessionsInput): Promise<StreamSession[]> {
|
||||
const nowPlaying = await this.getNowPlayingAsync();
|
||||
|
||||
return nowPlaying.map(
|
||||
(entry): StreamSession => ({
|
||||
sessionId: `${entry.username}-${entry.playerName}`,
|
||||
sessionName: entry.playerName,
|
||||
user: {
|
||||
userId: entry.username,
|
||||
username: entry.username,
|
||||
profilePictureUrl: null,
|
||||
},
|
||||
currentlyPlaying: {
|
||||
type: "audio",
|
||||
name: entry.title,
|
||||
seasonName: entry.artist || undefined,
|
||||
episodeName: null,
|
||||
albumName: entry.album,
|
||||
episodeCount: null,
|
||||
playback: {
|
||||
state: null,
|
||||
positionMs: null,
|
||||
durationMs: null,
|
||||
},
|
||||
location: null,
|
||||
metadata: null,
|
||||
},
|
||||
}),
|
||||
);
|
||||
}
|
||||
|
||||
private async getArtistCountAsync(): Promise<number> {
|
||||
const response = await this.subsonicRequestAsync("/rest/getArtists.view", {}, { tolerateEmptyLibrary: true });
|
||||
return asArray(response.artists?.index).reduce((count, index) => count + asArray(index.artist).length, 0);
|
||||
|
||||
@@ -67,5 +67,4 @@ export interface NavidromeDashboardData {
|
||||
artistCount: number;
|
||||
albumCount: number;
|
||||
songCount: number;
|
||||
nowPlaying: NavidromeNowPlayingEntry[];
|
||||
}
|
||||
@@ -1,6 +1,12 @@
|
||||
// @vitest-environment node
|
||||
import { Response } from "undici";
|
||||
import { beforeEach, describe, expect, test, vi } from "vitest";
|
||||
|
||||
vi.hoisted(() => {
|
||||
process.env.SKIP_ENV_VALIDATION = "true";
|
||||
process.env.SECRET_ENCRYPTION_KEY = "0".repeat(64);
|
||||
});
|
||||
|
||||
import { fetchWithTrustedCertificatesAsync } from "@homarr/core/infrastructure/http";
|
||||
|
||||
import type { IntegrationSecret } from "../../base/types";
|
||||
@@ -34,24 +40,24 @@ const subsonicOk = <T extends Record<string, unknown>>(data: T) =>
|
||||
"subsonic-response": { status: "ok", version: "1.16.1", ...data },
|
||||
});
|
||||
|
||||
const subsonicFailed = (message: string) =>
|
||||
const subsonicFailed = (message: string, code = 70) =>
|
||||
JSON.stringify({
|
||||
"subsonic-response": { status: "failed", error: { code: 70, message } },
|
||||
"subsonic-response": { status: "failed", error: { code, message } },
|
||||
});
|
||||
|
||||
const makeAlbums = (count: number, songCount: number) =>
|
||||
Array.from({ length: count }, (_, index) => ({
|
||||
id: `album-${index}`,
|
||||
name: `Album ${index}`,
|
||||
songCount,
|
||||
}));
|
||||
|
||||
beforeEach(() => {
|
||||
mockFetch.mockReset();
|
||||
});
|
||||
|
||||
describe("NavidromeIntegration.getDashboardDataAsync", () => {
|
||||
test("paginates album list and counts songs", async () => {
|
||||
const makeAlbums = (count: number, songCount: number) =>
|
||||
Array.from({ length: count }, (_, i) => ({
|
||||
id: `album-${i}`,
|
||||
name: `Album ${i}`,
|
||||
songCount,
|
||||
}));
|
||||
|
||||
mockFetch.mockImplementation((url) => {
|
||||
const urlStr = toUrlString(url);
|
||||
|
||||
@@ -84,13 +90,7 @@ describe("NavidromeIntegration.getDashboardDataAsync", () => {
|
||||
>;
|
||||
}
|
||||
|
||||
if (urlStr.includes("getNowPlaying")) {
|
||||
return Promise.resolve(new Response(subsonicOk({ nowPlaying: {} }), { status: 200 })) as unknown as ReturnType<
|
||||
typeof fetchWithTrustedCertificatesAsync
|
||||
>;
|
||||
}
|
||||
|
||||
return Promise.resolve(new Response(subsonicOk({}), { status: 200 })) as unknown as ReturnType<
|
||||
return Promise.reject(new Error(`Unexpected dashboard request: ${urlStr}`)) as unknown as ReturnType<
|
||||
typeof fetchWithTrustedCertificatesAsync
|
||||
>;
|
||||
});
|
||||
@@ -101,7 +101,6 @@ describe("NavidromeIntegration.getDashboardDataAsync", () => {
|
||||
expect(result.albumCount).toBe(700);
|
||||
expect(result.songCount).toBe(500 * 10 + 200 * 5);
|
||||
expect(result.artistCount).toBe(1);
|
||||
expect(result.nowPlaying).toEqual([]);
|
||||
});
|
||||
|
||||
test("handles empty library gracefully", async () => {
|
||||
@@ -120,13 +119,7 @@ describe("NavidromeIntegration.getDashboardDataAsync", () => {
|
||||
) as unknown as ReturnType<typeof fetchWithTrustedCertificatesAsync>;
|
||||
}
|
||||
|
||||
if (urlStr.includes("getNowPlaying")) {
|
||||
return Promise.resolve(
|
||||
new Response(subsonicFailed("Library not found or empty"), { status: 200 }),
|
||||
) as unknown as ReturnType<typeof fetchWithTrustedCertificatesAsync>;
|
||||
}
|
||||
|
||||
return Promise.resolve(new Response(subsonicOk({}), { status: 200 })) as unknown as ReturnType<
|
||||
return Promise.reject(new Error(`Unexpected dashboard request: ${urlStr}`)) as unknown as ReturnType<
|
||||
typeof fetchWithTrustedCertificatesAsync
|
||||
>;
|
||||
});
|
||||
@@ -137,7 +130,6 @@ describe("NavidromeIntegration.getDashboardDataAsync", () => {
|
||||
expect(result.artistCount).toBe(0);
|
||||
expect(result.albumCount).toBe(0);
|
||||
expect(result.songCount).toBe(0);
|
||||
expect(result.nowPlaying).toEqual([]);
|
||||
});
|
||||
|
||||
test("throws on non-empty-library subsonic error", async () => {
|
||||
@@ -151,8 +143,10 @@ describe("NavidromeIntegration.getDashboardDataAsync", () => {
|
||||
const integration = createIntegration();
|
||||
await expect(integration.getDashboardDataAsync()).rejects.toThrow();
|
||||
});
|
||||
});
|
||||
|
||||
test("now playing maps entries correctly", async () => {
|
||||
describe("NavidromeIntegration.getCurrentSessionsAsync", () => {
|
||||
test("maps now playing entries to stream sessions", async () => {
|
||||
mockFetch.mockImplementation((url) => {
|
||||
const urlStr = toUrlString(url);
|
||||
|
||||
@@ -161,7 +155,22 @@ describe("NavidromeIntegration.getDashboardDataAsync", () => {
|
||||
new Response(
|
||||
subsonicOk({
|
||||
nowPlaying: {
|
||||
entry: { title: "Song", artist: "Band", album: "LP", username: "user1", playerName: "Chrome" },
|
||||
entry: [
|
||||
{
|
||||
title: "Song",
|
||||
artist: "Band",
|
||||
album: "LP",
|
||||
username: "user1",
|
||||
playerName: "Chrome",
|
||||
},
|
||||
{
|
||||
title: "Second Song",
|
||||
artist: "Second Artist",
|
||||
album: "Second Album",
|
||||
username: "user2",
|
||||
playerName: "Mobile",
|
||||
},
|
||||
],
|
||||
},
|
||||
}),
|
||||
{ status: 200 },
|
||||
@@ -169,14 +178,72 @@ describe("NavidromeIntegration.getDashboardDataAsync", () => {
|
||||
) as unknown as ReturnType<typeof fetchWithTrustedCertificatesAsync>;
|
||||
}
|
||||
|
||||
if (urlStr.includes("getArtists")) {
|
||||
return Promise.resolve(new Response(subsonicOk({ artists: {} }), { status: 200 })) as unknown as ReturnType<
|
||||
typeof fetchWithTrustedCertificatesAsync
|
||||
>;
|
||||
}
|
||||
return Promise.resolve(new Response(subsonicOk({}), { status: 200 })) as unknown as ReturnType<
|
||||
typeof fetchWithTrustedCertificatesAsync
|
||||
>;
|
||||
});
|
||||
|
||||
if (urlStr.includes("getAlbumList2")) {
|
||||
return Promise.resolve(new Response(subsonicOk({ albumList2: {} }), { status: 200 })) as unknown as ReturnType<
|
||||
const integration = createIntegration();
|
||||
const result = await integration.getCurrentSessionsAsync({ showOnlyPlaying: true });
|
||||
|
||||
expect(result).toEqual([
|
||||
{
|
||||
sessionId: "user1-Chrome",
|
||||
sessionName: "Chrome",
|
||||
user: {
|
||||
userId: "user1",
|
||||
username: "user1",
|
||||
profilePictureUrl: null,
|
||||
},
|
||||
currentlyPlaying: {
|
||||
type: "audio",
|
||||
name: "Song",
|
||||
seasonName: "Band",
|
||||
episodeName: null,
|
||||
albumName: "LP",
|
||||
episodeCount: null,
|
||||
playback: {
|
||||
state: null,
|
||||
positionMs: null,
|
||||
durationMs: null,
|
||||
},
|
||||
location: null,
|
||||
metadata: null,
|
||||
},
|
||||
},
|
||||
{
|
||||
sessionId: "user2-Mobile",
|
||||
sessionName: "Mobile",
|
||||
user: {
|
||||
userId: "user2",
|
||||
username: "user2",
|
||||
profilePictureUrl: null,
|
||||
},
|
||||
currentlyPlaying: {
|
||||
type: "audio",
|
||||
name: "Second Song",
|
||||
seasonName: "Second Artist",
|
||||
episodeName: null,
|
||||
albumName: "Second Album",
|
||||
episodeCount: null,
|
||||
playback: {
|
||||
state: null,
|
||||
positionMs: null,
|
||||
durationMs: null,
|
||||
},
|
||||
location: null,
|
||||
metadata: null,
|
||||
},
|
||||
},
|
||||
]);
|
||||
});
|
||||
|
||||
test("returns an empty array when there are no now playing entries", async () => {
|
||||
mockFetch.mockImplementation((url) => {
|
||||
const urlStr = toUrlString(url);
|
||||
|
||||
if (urlStr.includes("getNowPlaying")) {
|
||||
return Promise.resolve(new Response(subsonicOk({ nowPlaying: {} }), { status: 200 })) as unknown as ReturnType<
|
||||
typeof fetchWithTrustedCertificatesAsync
|
||||
>;
|
||||
}
|
||||
@@ -187,15 +254,31 @@ describe("NavidromeIntegration.getDashboardDataAsync", () => {
|
||||
});
|
||||
|
||||
const integration = createIntegration();
|
||||
const result = await integration.getDashboardDataAsync();
|
||||
const result = await integration.getCurrentSessionsAsync({ showOnlyPlaying: false });
|
||||
|
||||
expect(result.nowPlaying).toHaveLength(1);
|
||||
expect(result.nowPlaying[0]).toEqual({
|
||||
title: "Song",
|
||||
artist: "Band",
|
||||
album: "LP",
|
||||
username: "user1",
|
||||
playerName: "Chrome",
|
||||
expect(result).toEqual([]);
|
||||
});
|
||||
|
||||
test("throws on subsonic auth failure", async () => {
|
||||
mockFetch.mockImplementation((url) => {
|
||||
const urlStr = toUrlString(url);
|
||||
|
||||
if (urlStr.includes("getNowPlaying")) {
|
||||
return Promise.resolve(
|
||||
new Response(subsonicFailed("Wrong username or password", 40), { status: 200 }),
|
||||
) as unknown as ReturnType<typeof fetchWithTrustedCertificatesAsync>;
|
||||
}
|
||||
|
||||
return Promise.resolve(new Response(subsonicOk({}), { status: 200 })) as unknown as ReturnType<
|
||||
typeof fetchWithTrustedCertificatesAsync
|
||||
>;
|
||||
});
|
||||
|
||||
const integration = createIntegration();
|
||||
|
||||
await expect(integration.getCurrentSessionsAsync({ showOnlyPlaying: true })).rejects.toMatchObject({
|
||||
message: "An unknown error occured while executing Integration method",
|
||||
cause: { message: "Wrong username or password" },
|
||||
});
|
||||
});
|
||||
});
|
||||
+1261
-1234
File diff suppressed because it is too large.
Load diff
File diff suppressed because it is too large.
Load diff
@@ -3079,11 +3079,20 @@
|
||||
"limitPerIntegration": {
|
||||
"label": "crwdns3442:0crwdne3442:0",
|
||||
"description": "crwdns3444:0crwdne3444:0"
|
||||
},
|
||||
"columnOrder": {
|
||||
"label": "crwdns6121:0crwdne6121:0"
|
||||
},
|
||||
"columnWidths": {
|
||||
"label": "crwdns6123:0crwdne6123:0"
|
||||
}
|
||||
},
|
||||
"errors": {
|
||||
"noColumns": "crwdns1194:0crwdne1194:0",
|
||||
"noCommunications": "crwdns1196:0crwdne1196:0"
|
||||
"noCommunications": "crwdns1196:0crwdne1196:0",
|
||||
"noItems": "crwdns6125:0crwdne6125:0",
|
||||
"actionFailed": "crwdns6127:0crwdne6127:0",
|
||||
"actionFailedMessage": "crwdns6129:0crwdne6129:0"
|
||||
},
|
||||
"items": {
|
||||
"actions": {
|
||||
@@ -3106,7 +3115,8 @@
|
||||
"detailsTitle": "crwdns1214:0crwdne1214:0"
|
||||
},
|
||||
"id": {
|
||||
"columnTitle": "crwdns1216:0crwdne1216:0"
|
||||
"columnTitle": "crwdns1216:0crwdne1216:0",
|
||||
"detailsTitle": "crwdns6131:0crwdne6131:0"
|
||||
},
|
||||
"integration": {
|
||||
"columnTitle": "crwdns1218:0crwdne1218:0"
|
||||
@@ -3140,7 +3150,8 @@
|
||||
},
|
||||
"time": {
|
||||
"columnTitle": "crwdns1246:0crwdne1246:0",
|
||||
"detailsTitle": "crwdns1248:0crwdne1248:0"
|
||||
"detailsTitle": "crwdns1248:0crwdne1248:0",
|
||||
"eta": "crwdns6133:0crwdne6133:0"
|
||||
},
|
||||
"type": {
|
||||
"columnTitle": "crwdns1250:0crwdne1250:0",
|
||||
@@ -3184,7 +3195,23 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"globalRatio": "crwdns1300:0crwdne1300:0"
|
||||
"globalRatio": "crwdns1300:0crwdne1300:0",
|
||||
"contextMenu": {
|
||||
"copyName": "crwdns6135:0crwdne6135:0",
|
||||
"copyId": "crwdns6137:0crwdne6137:0",
|
||||
"clearFilters": "crwdns6139:0crwdne6139:0"
|
||||
},
|
||||
"footer": {
|
||||
"filter": "crwdns6141:0crwdne6141:0"
|
||||
},
|
||||
"stats": {
|
||||
"show": "crwdns6143:0crwdne6143:0",
|
||||
"hide": "crwdns6145:0crwdne6145:0",
|
||||
"overallProgress": "crwdns6147:0crwdne6147:0",
|
||||
"totalSize": "crwdns6149:0crwdne6149:0",
|
||||
"clients": "crwdns6151:0count={count}crwdne6151:0"
|
||||
},
|
||||
"disconnected": "crwdns6153:0crwdne6153:0"
|
||||
},
|
||||
"mediaReleases": {
|
||||
"name": "crwdns3532:0crwdne3532:0",
|
||||
|
||||
File diff suppressed because it is too large.
Load diff
File diff suppressed because it is too large.
Load diff
@@ -3079,11 +3079,20 @@
|
||||
"limitPerIntegration": {
|
||||
"label": "",
|
||||
"description": ""
|
||||
},
|
||||
"columnOrder": {
|
||||
"label": ""
|
||||
},
|
||||
"columnWidths": {
|
||||
"label": ""
|
||||
}
|
||||
},
|
||||
"errors": {
|
||||
"noColumns": "Spalten in Elementen auswählen",
|
||||
"noCommunications": "Kann keine Daten von der Integration laden"
|
||||
"noCommunications": "Kann keine Daten von der Integration laden",
|
||||
"noItems": "",
|
||||
"actionFailed": "",
|
||||
"actionFailedMessage": ""
|
||||
},
|
||||
"items": {
|
||||
"actions": {
|
||||
@@ -3106,7 +3115,8 @@
|
||||
"detailsTitle": "Aktueller Index im Client"
|
||||
},
|
||||
"id": {
|
||||
"columnTitle": "ID"
|
||||
"columnTitle": "ID",
|
||||
"detailsTitle": ""
|
||||
},
|
||||
"integration": {
|
||||
"columnTitle": ""
|
||||
@@ -3140,7 +3150,8 @@
|
||||
},
|
||||
"time": {
|
||||
"columnTitle": "Endzeit",
|
||||
"detailsTitle": "Zeit danach/zur Fertigstellung"
|
||||
"detailsTitle": "Zeit danach/zur Fertigstellung",
|
||||
"eta": ""
|
||||
},
|
||||
"type": {
|
||||
"columnTitle": "Typ",
|
||||
@@ -3184,7 +3195,23 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"globalRatio": "Globales Verhältnis"
|
||||
"globalRatio": "Globales Verhältnis",
|
||||
"contextMenu": {
|
||||
"copyName": "",
|
||||
"copyId": "",
|
||||
"clearFilters": ""
|
||||
},
|
||||
"footer": {
|
||||
"filter": ""
|
||||
},
|
||||
"stats": {
|
||||
"show": "",
|
||||
"hide": "",
|
||||
"overallProgress": "",
|
||||
"totalSize": "",
|
||||
"clients": ""
|
||||
},
|
||||
"disconnected": ""
|
||||
},
|
||||
"mediaReleases": {
|
||||
"name": "",
|
||||
|
||||
@@ -199,8 +199,8 @@
|
||||
"label": "Symbole für Pings verwenden"
|
||||
},
|
||||
"enableRightClickOnWidgets": {
|
||||
"label": "",
|
||||
"description": ""
|
||||
"label": "Aktiviere Rechtsklick auf Widgets",
|
||||
"description": "Zeigt Homarrs Kontextmenü, wenn mit der rechten Maustaste auf ein Widget geklickt wird. Deaktivieren, um das Standardmenü des Browsers zu verwenden (z.B. \"Link in neuem Tab öffnen\")."
|
||||
},
|
||||
"defaultSearchEngine": {
|
||||
"label": "Standard Suchmaschine"
|
||||
@@ -1353,7 +1353,7 @@
|
||||
"description": ""
|
||||
},
|
||||
"bazarr": {
|
||||
"name": "",
|
||||
"name": "Bazarr",
|
||||
"description": ""
|
||||
}
|
||||
},
|
||||
@@ -1492,7 +1492,7 @@
|
||||
"switchToDarkMode": "Zum dunklen Design wechseln",
|
||||
"switchToLightMode": "Zum hellen Design wechseln",
|
||||
"management": "Verwaltung",
|
||||
"docker": "",
|
||||
"docker": "Docker",
|
||||
"preferences": "Ihre Einstellungen",
|
||||
"logout": "Abmelden",
|
||||
"login": "Anmelden",
|
||||
@@ -1628,7 +1628,7 @@
|
||||
"actions": "Aktionen"
|
||||
},
|
||||
"status": {
|
||||
"success": "",
|
||||
"success": "Ok",
|
||||
"error": "Fehler",
|
||||
"loading": "Wird geladen",
|
||||
"idle": "Leerlauf"
|
||||
@@ -1907,14 +1907,14 @@
|
||||
"description": "ISO 8601 Standard benutzen um das Datum zu formatieren (dies wird andere Optionen überschreiben)"
|
||||
},
|
||||
"showWeather": {
|
||||
"label": "",
|
||||
"description": ""
|
||||
"label": "Wetter anzeigen",
|
||||
"description": "Zeigt ein kleines animiertes Wettersymbol und die Temperatur in der Ecke der Karte an"
|
||||
},
|
||||
"weatherLocation": {
|
||||
"label": ""
|
||||
"label": "Ort für Wetterbericht"
|
||||
},
|
||||
"isWeatherFormatFahrenheit": {
|
||||
"label": ""
|
||||
"label": "Fahrenheit verwenden"
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -1944,7 +1944,7 @@
|
||||
"noStation": "Keine Station ausgewählt",
|
||||
"option": {
|
||||
"baseUrl": {
|
||||
"label": ""
|
||||
"label": "Search.ch URL"
|
||||
},
|
||||
"station": {
|
||||
"label": "Station"
|
||||
@@ -1976,8 +1976,8 @@
|
||||
"clear": "Formatierung entfernen",
|
||||
"heading": "Überschrift {level}",
|
||||
"align": "Text ausrichten: {position}",
|
||||
"directionLtr": "",
|
||||
"directionRtl": "",
|
||||
"directionLtr": "Setze Textausrichtung von links nach rechts",
|
||||
"directionRtl": "Setze Textausrichtung von rechts nach links",
|
||||
"blockquote": "Blockzitat",
|
||||
"horizontalLine": "Horizontale Linie",
|
||||
"bulletList": "Aufzählung",
|
||||
@@ -2268,7 +2268,7 @@
|
||||
"sunset": "Sonnenuntergang",
|
||||
"maxWindSpeed": "Maximale Windgeschwindigkeit: {maxWindSpeed} {unit}",
|
||||
"maxWindGusts": "Maximale Windböen: {maxWindGusts} {unit}",
|
||||
"humidity": ""
|
||||
"humidity": "Luftfeuchtigkeit: {humidity}%"
|
||||
},
|
||||
"kind": {
|
||||
"clear": "Klar",
|
||||
@@ -2412,7 +2412,7 @@
|
||||
"description": "Statistiken Ihrer Container (Dieses Widget kann nur mit Administratorrechten hinzugefügt werden)",
|
||||
"option": {
|
||||
"columns": {
|
||||
"label": ""
|
||||
"label": "Anzuzeigende Spalten"
|
||||
},
|
||||
"enableRowSorting": {
|
||||
"label": "Sortierung von Elementen aktivieren"
|
||||
@@ -2468,7 +2468,7 @@
|
||||
}
|
||||
},
|
||||
"vpn": {
|
||||
"name": "",
|
||||
"name": "VPN",
|
||||
"description": "Übersicht deiner VPN-Verbindungen",
|
||||
"serviceUnavailable": "VPN nicht verfügbar",
|
||||
"option": {}
|
||||
@@ -2733,10 +2733,10 @@
|
||||
"name": "Name",
|
||||
"id": "Id",
|
||||
"status": "Status",
|
||||
"directPlay": "",
|
||||
"transcoding": "",
|
||||
"paused": "",
|
||||
"remaining": "",
|
||||
"directPlay": "Direkte Wiedergabe",
|
||||
"transcoding": "Transkodierung",
|
||||
"paused": "Pausiert",
|
||||
"remaining": "{minutes} Min. verbleibend",
|
||||
"metadata": {
|
||||
"title": "Statistiken für Nerds",
|
||||
"video": {
|
||||
@@ -2806,14 +2806,14 @@
|
||||
"name": "",
|
||||
"description": "",
|
||||
"title": "",
|
||||
"totalHosts": "",
|
||||
"hostsNeedingUpdates": "",
|
||||
"securityUpdates": "",
|
||||
"totalHosts": "Hosts gesamt",
|
||||
"hostsNeedingUpdates": "Update erforderlich",
|
||||
"securityUpdates": "Sicherheits-Updates",
|
||||
"upToDateHosts": "",
|
||||
"hostsWithSecurityUpdates": "",
|
||||
"recentUpdates24h": "",
|
||||
"totalOutdatedPackages": "",
|
||||
"totalRepos": "",
|
||||
"hostsWithSecurityUpdates": "Hosts mit Sicherheits-Updates",
|
||||
"recentUpdates24h": "Updates (24h)",
|
||||
"totalOutdatedPackages": "Veraltete Pakete",
|
||||
"totalRepos": "Repositories",
|
||||
"osDistribution": "",
|
||||
"compliance": "",
|
||||
"complianceRatio": "",
|
||||
@@ -2832,7 +2832,7 @@
|
||||
"description": "Gesamtzahl der verfügbaren Sicherheits-Updates anzeigen"
|
||||
},
|
||||
"showUpToDateHosts": {
|
||||
"label": "",
|
||||
"label": "Zeige aktuelle Hosts",
|
||||
"description": ""
|
||||
},
|
||||
"showHostsWithSecurityUpdates": {
|
||||
@@ -3079,11 +3079,20 @@
|
||||
"limitPerIntegration": {
|
||||
"label": "Elemente pro Integration begrenzen",
|
||||
"description": "Dies begrenzt die Anzahl der Elemente pro Integration, jedoch nicht global"
|
||||
},
|
||||
"columnOrder": {
|
||||
"label": ""
|
||||
},
|
||||
"columnWidths": {
|
||||
"label": ""
|
||||
}
|
||||
},
|
||||
"errors": {
|
||||
"noColumns": "Spalten in Elementen auswählen",
|
||||
"noCommunications": "Kann keine Daten von der Integration laden"
|
||||
"noCommunications": "Kann keine Daten von der Integration laden",
|
||||
"noItems": "",
|
||||
"actionFailed": "",
|
||||
"actionFailedMessage": ""
|
||||
},
|
||||
"items": {
|
||||
"actions": {
|
||||
@@ -3106,7 +3115,8 @@
|
||||
"detailsTitle": "Aktueller Index im Client"
|
||||
},
|
||||
"id": {
|
||||
"columnTitle": "ID"
|
||||
"columnTitle": "ID",
|
||||
"detailsTitle": ""
|
||||
},
|
||||
"integration": {
|
||||
"columnTitle": "Integration"
|
||||
@@ -3140,7 +3150,8 @@
|
||||
},
|
||||
"time": {
|
||||
"columnTitle": "Endzeit",
|
||||
"detailsTitle": "Zeit danach/zur Fertigstellung"
|
||||
"detailsTitle": "Zeit danach/zur Fertigstellung",
|
||||
"eta": ""
|
||||
},
|
||||
"type": {
|
||||
"columnTitle": "Typ",
|
||||
@@ -3184,7 +3195,23 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"globalRatio": "Globales Verhältnis"
|
||||
"globalRatio": "Globales Verhältnis",
|
||||
"contextMenu": {
|
||||
"copyName": "",
|
||||
"copyId": "",
|
||||
"clearFilters": ""
|
||||
},
|
||||
"footer": {
|
||||
"filter": ""
|
||||
},
|
||||
"stats": {
|
||||
"show": "",
|
||||
"hide": "",
|
||||
"overallProgress": "",
|
||||
"totalSize": "",
|
||||
"clients": ""
|
||||
},
|
||||
"disconnected": ""
|
||||
},
|
||||
"mediaReleases": {
|
||||
"name": "Medien Veröffentlichungen",
|
||||
@@ -5207,8 +5234,8 @@
|
||||
"subtitle": "{count} tragen Übersetzungen in viele Sprachen bei"
|
||||
},
|
||||
"sponsors": {
|
||||
"title": "",
|
||||
"subtitle": ""
|
||||
"title": "Sponsoren",
|
||||
"subtitle": "{count} unterstützen das Projekt finanziell"
|
||||
},
|
||||
"libraries": {
|
||||
"title": "Bibliotheken",
|
||||
|
||||
File diff suppressed because it is too large.
Load diff
File diff suppressed because it is too large.
Load diff
@@ -3768,18 +3768,6 @@
|
||||
"label": "Show songs",
|
||||
"description": "Show the total number of songs in your music library (Navidrome)"
|
||||
},
|
||||
"showNowPlaying": {
|
||||
"label": "Show now playing",
|
||||
"description": "Show tracks currently being played (Navidrome)"
|
||||
},
|
||||
"showNowPlayingList": {
|
||||
"label": "Show now playing list",
|
||||
"description": "Show individual tracks instead of only the active stream count (Navidrome)"
|
||||
},
|
||||
"maxNowPlayingItems": {
|
||||
"label": "Max now playing items",
|
||||
"description": "Maximum number of tracks to show in the now playing list (Navidrome)"
|
||||
},
|
||||
"showLibraryCount": {
|
||||
"label": "Show library count",
|
||||
"description": "Show the number of libraries on your instance (Audiobookshelf)"
|
||||
@@ -3813,8 +3801,6 @@
|
||||
"podcasts": "Podcasts",
|
||||
"listeningTime": "Listening Time",
|
||||
"activeSessions": "Active Sessions",
|
||||
"nowPlaying": "Now Playing",
|
||||
"nowPlayingCount": "{count, plural, one {# stream} other {# streams}}",
|
||||
"error": {
|
||||
"internalServerError": "Failed to fetch audio stats data"
|
||||
}
|
||||
|
||||
@@ -2560,30 +2560,30 @@
|
||||
}
|
||||
},
|
||||
"umami": {
|
||||
"name": "",
|
||||
"description": "",
|
||||
"visitors": "",
|
||||
"active": "",
|
||||
"pageviews": "",
|
||||
"visits": "",
|
||||
"bounceRate": "",
|
||||
"avgDuration": "",
|
||||
"name": "Estadísticas Umami",
|
||||
"description": "Mostrar estadísticas de visitantes de su instancia de Umami Analytics",
|
||||
"visitors": "visitantes",
|
||||
"active": "activo",
|
||||
"pageviews": "vistas de página",
|
||||
"visits": "visitas",
|
||||
"bounceRate": "rebote",
|
||||
"avgDuration": "promedio",
|
||||
"option": {
|
||||
"websiteId": {
|
||||
"label": "",
|
||||
"description": "",
|
||||
"placeholder": "",
|
||||
"loading": "",
|
||||
"noWebsites": "",
|
||||
"configureIntegrationFirst": ""
|
||||
"label": "Sitio web",
|
||||
"description": "Seleccione un sitio web rastreado por su instancia de Umami",
|
||||
"placeholder": "Seleccione un sitio web",
|
||||
"loading": "Cargando sitios web...",
|
||||
"noWebsites": "No se encontraron sitios web",
|
||||
"configureIntegrationFirst": "Conecte primero una integración de Umami"
|
||||
},
|
||||
"timeFrame": {
|
||||
"label": "",
|
||||
"description": "",
|
||||
"label": "Período de tiempo",
|
||||
"description": "El período de tiempo para mostrar los datos de los visitantes",
|
||||
"option": {
|
||||
"today": "",
|
||||
"24h": "",
|
||||
"7d": "",
|
||||
"today": "Hoy",
|
||||
"24h": "Últimas 24 horas",
|
||||
"7d": "Últimos 7 días",
|
||||
"30d": "",
|
||||
"month": "",
|
||||
"lastMonth": ""
|
||||
@@ -3079,11 +3079,20 @@
|
||||
"limitPerIntegration": {
|
||||
"label": "Limitar elementos por integración",
|
||||
"description": "Esto limitará el número de elementos mostrados por integración, no globalmente"
|
||||
},
|
||||
"columnOrder": {
|
||||
"label": ""
|
||||
},
|
||||
"columnWidths": {
|
||||
"label": ""
|
||||
}
|
||||
},
|
||||
"errors": {
|
||||
"noColumns": "Seleccionar Columnas en Artículos",
|
||||
"noCommunications": "No se pueden cargar los datos desde la integración"
|
||||
"noCommunications": "No se pueden cargar los datos desde la integración",
|
||||
"noItems": "",
|
||||
"actionFailed": "",
|
||||
"actionFailedMessage": ""
|
||||
},
|
||||
"items": {
|
||||
"actions": {
|
||||
@@ -3106,7 +3115,8 @@
|
||||
"detailsTitle": "Índice actual dentro del cliente"
|
||||
},
|
||||
"id": {
|
||||
"columnTitle": "ID"
|
||||
"columnTitle": "ID",
|
||||
"detailsTitle": ""
|
||||
},
|
||||
"integration": {
|
||||
"columnTitle": "Integración"
|
||||
@@ -3140,7 +3150,8 @@
|
||||
},
|
||||
"time": {
|
||||
"columnTitle": "Hora de finalización",
|
||||
"detailsTitle": "Tiempo desde/hasta la finalización"
|
||||
"detailsTitle": "Tiempo desde/hasta la finalización",
|
||||
"eta": ""
|
||||
},
|
||||
"type": {
|
||||
"columnTitle": "Tipo",
|
||||
@@ -3184,7 +3195,23 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"globalRatio": "Relación global"
|
||||
"globalRatio": "Relación global",
|
||||
"contextMenu": {
|
||||
"copyName": "",
|
||||
"copyId": "",
|
||||
"clearFilters": ""
|
||||
},
|
||||
"footer": {
|
||||
"filter": ""
|
||||
},
|
||||
"stats": {
|
||||
"show": "",
|
||||
"hide": "",
|
||||
"overallProgress": "",
|
||||
"totalSize": "",
|
||||
"clients": ""
|
||||
},
|
||||
"disconnected": ""
|
||||
},
|
||||
"mediaReleases": {
|
||||
"name": "Lanzamientos de medios",
|
||||
@@ -5207,8 +5234,8 @@
|
||||
"subtitle": "{count} contribuyendo con las traducciones en muchos idiomas"
|
||||
},
|
||||
"sponsors": {
|
||||
"title": "",
|
||||
"subtitle": ""
|
||||
"title": "Patrocinadores",
|
||||
"subtitle": "{count} apoyando económicamente el proyecto"
|
||||
},
|
||||
"libraries": {
|
||||
"title": "Librerías",
|
||||
|
||||
File diff suppressed because it is too large.
Load diff
File diff suppressed because it is too large.
Load diff
File diff suppressed because it is too large.
Load diff
@@ -1505,8 +1505,8 @@
|
||||
"noResults": "לא נמצאו תוצאות",
|
||||
"unsavedChanges": "ישנם שינויים שלא נשמרו!",
|
||||
"servers": "שרתים",
|
||||
"applications": "",
|
||||
"services": "",
|
||||
"applications": "אפליקציות",
|
||||
"services": "שירותים",
|
||||
"preview": {
|
||||
"show": "הצג תצוגה מקדימה",
|
||||
"hide": "הסתר תצוגה המקדימה"
|
||||
@@ -1938,16 +1938,16 @@
|
||||
}
|
||||
},
|
||||
"timetable": {
|
||||
"name": "",
|
||||
"description": "",
|
||||
"title": "",
|
||||
"noStation": "",
|
||||
"name": "לוח זמנים",
|
||||
"description": "מציג זמני יציאה לתחנה",
|
||||
"title": "יציאות {station}",
|
||||
"noStation": "לא נבחרה תחנה",
|
||||
"option": {
|
||||
"baseUrl": {
|
||||
"label": ""
|
||||
},
|
||||
"station": {
|
||||
"label": ""
|
||||
"label": "תחנה"
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -2024,32 +2024,32 @@
|
||||
}
|
||||
},
|
||||
"anchorNote": {
|
||||
"name": "",
|
||||
"description": "",
|
||||
"name": "פתק Anchor",
|
||||
"description": "מציג פתק נבחר מ-Anchor",
|
||||
"option": {
|
||||
"noteId": {
|
||||
"label": ""
|
||||
"label": "פתק"
|
||||
},
|
||||
"showTitle": {
|
||||
"label": ""
|
||||
"label": "הצג כותרת"
|
||||
},
|
||||
"showUpdatedAt": {
|
||||
"label": ""
|
||||
"label": "הצג עדכון אחרון"
|
||||
}
|
||||
},
|
||||
"empty": "",
|
||||
"emptyContent": "",
|
||||
"notFound": "",
|
||||
"noNotes": "",
|
||||
"integrationRequired": "",
|
||||
"updatedAt": "",
|
||||
"untitled": "",
|
||||
"edit": "",
|
||||
"save": "",
|
||||
"cancel": "",
|
||||
"readOnlyViewer": "",
|
||||
"saveForbidden": "",
|
||||
"saveFailed": ""
|
||||
"empty": "בחר פתק להצגה",
|
||||
"emptyContent": "לפתק זה אין תוכן",
|
||||
"notFound": "הפתק לא נמצא",
|
||||
"noNotes": "לא נמצאו פתקים",
|
||||
"integrationRequired": "בחר תחילה אינטגרציית Anchor",
|
||||
"updatedAt": "עודכן ב- {date}",
|
||||
"untitled": "ללא כותרת",
|
||||
"edit": "עריכה",
|
||||
"save": "שמור",
|
||||
"cancel": "בטל",
|
||||
"readOnlyViewer": "יש לך גישת צפייה לפתק זה. עריכה מושבתת.",
|
||||
"saveForbidden": "אין לך הרשאה לערוך פתק זה.",
|
||||
"saveFailed": "שמירת הפתק נכשלה. נסה שוב."
|
||||
},
|
||||
"iframe": {
|
||||
"name": "iFrame",
|
||||
@@ -2083,7 +2083,7 @@
|
||||
"label": "אפשר מיקום גיאוגרפי"
|
||||
},
|
||||
"allowModals": {
|
||||
"label": ""
|
||||
"label": "אפשר חלונות קופצים"
|
||||
}
|
||||
},
|
||||
"error": {
|
||||
@@ -2319,7 +2319,7 @@
|
||||
"label": "הצג מידע זיכרון"
|
||||
},
|
||||
"gpu": {
|
||||
"label": ""
|
||||
"label": "הצג מידע GPU"
|
||||
},
|
||||
"showUptime": {
|
||||
"label": "הצג זמן פעולה"
|
||||
@@ -2435,36 +2435,36 @@
|
||||
}
|
||||
},
|
||||
"coolify": {
|
||||
"name": "",
|
||||
"description": "",
|
||||
"name": "קוליפיי",
|
||||
"description": "סקירה של מופע Coolify שלך עם שרתים ואפליקציות",
|
||||
"option": {
|
||||
"showServers": {
|
||||
"label": ""
|
||||
"label": "הצג שרתים"
|
||||
},
|
||||
"showApplications": {
|
||||
"label": ""
|
||||
"label": "הצג אפליקציות"
|
||||
},
|
||||
"showServices": {
|
||||
"label": ""
|
||||
"label": "הצג שירותים"
|
||||
}
|
||||
},
|
||||
"empty": {
|
||||
"servers": "",
|
||||
"applications": "",
|
||||
"services": ""
|
||||
"servers": "לא נמצאו שרתים",
|
||||
"applications": "לא נמצאו אפליקציות",
|
||||
"services": "לא נמצאו שירותים"
|
||||
},
|
||||
"footer": {
|
||||
"updated": ""
|
||||
"updated": "עודכן ב- {when}"
|
||||
},
|
||||
"error": {
|
||||
"noIntegration": "",
|
||||
"internalServerError": ""
|
||||
"noIntegration": "לא הוגדרה אינטגרציית Coolify",
|
||||
"internalServerError": "אחזור נתוני Coolify נכשל"
|
||||
},
|
||||
"server": {
|
||||
"buildServer": ""
|
||||
"buildServer": "בנייה"
|
||||
},
|
||||
"instances": {
|
||||
"title": ""
|
||||
"title": "מופעים"
|
||||
}
|
||||
},
|
||||
"vpn": {
|
||||
@@ -2505,85 +2505,85 @@
|
||||
}
|
||||
},
|
||||
"tracearr": {
|
||||
"name": "",
|
||||
"description": "",
|
||||
"name": "טרייסאר",
|
||||
"description": "ניטור שרת מדיה משופר עם נתוני זרם וקידוד מפורטים",
|
||||
"option": {
|
||||
"showStreams": {
|
||||
"label": ""
|
||||
"label": "הצג זרמים פעילים"
|
||||
},
|
||||
"showStats": {
|
||||
"label": ""
|
||||
"label": "הצג סיכום סטטיסטיקות"
|
||||
},
|
||||
"showRecentActivity": {
|
||||
"label": ""
|
||||
"label": "הצג פעילות אחרונה"
|
||||
},
|
||||
"showViolations": {
|
||||
"label": ""
|
||||
"label": "הצג הפרות"
|
||||
}
|
||||
},
|
||||
"stats": {
|
||||
"activeStreams": "",
|
||||
"totalUsers": "",
|
||||
"transcodes": "",
|
||||
"bandwidth": ""
|
||||
"activeStreams": "זרמים פעילים",
|
||||
"totalUsers": "סך המשתמשים",
|
||||
"transcodes": "קידודים",
|
||||
"bandwidth": "רוחב פס"
|
||||
},
|
||||
"streams": {
|
||||
"empty": "",
|
||||
"user": "",
|
||||
"media": "",
|
||||
"state": "",
|
||||
"quality": "",
|
||||
"device": "",
|
||||
"progress": "",
|
||||
"empty": "אין זרמים פעילים",
|
||||
"user": "משתמש",
|
||||
"media": "מדיה",
|
||||
"state": "מצב",
|
||||
"quality": "איכות",
|
||||
"device": "מכשיר",
|
||||
"progress": "התקדמות",
|
||||
"videoDecision": {
|
||||
"directPlay": "",
|
||||
"transcode": "",
|
||||
"directStream": ""
|
||||
"directPlay": "הפעלה ישירה",
|
||||
"transcode": "קידוד",
|
||||
"directStream": "זרם ישיר"
|
||||
}
|
||||
},
|
||||
"recentActivity": {
|
||||
"title": "",
|
||||
"empty": "",
|
||||
"watched": "",
|
||||
"partial": ""
|
||||
"title": "פעילות אחרונה",
|
||||
"empty": "אין פעילות אחרונה",
|
||||
"watched": "נצפה",
|
||||
"partial": "חלקי"
|
||||
},
|
||||
"violations": {
|
||||
"title": "",
|
||||
"empty": "",
|
||||
"rule": "",
|
||||
"user": ""
|
||||
"title": "הפרות",
|
||||
"empty": "אין הפרות אחרונות",
|
||||
"rule": "כלל",
|
||||
"user": "משתמש"
|
||||
},
|
||||
"noSectionsEnabled": "",
|
||||
"noSectionsEnabled": "לא הופעלו מקטעים",
|
||||
"error": {
|
||||
"noIntegration": "",
|
||||
"internalServerError": ""
|
||||
"noIntegration": "לא הוגדרה אינטגרציית Tracearr",
|
||||
"internalServerError": "אחזור נתוני Tracearr נכשל"
|
||||
}
|
||||
},
|
||||
"umami": {
|
||||
"name": "",
|
||||
"description": "",
|
||||
"visitors": "",
|
||||
"active": "",
|
||||
"pageviews": "",
|
||||
"visits": "",
|
||||
"bounceRate": "",
|
||||
"avgDuration": "",
|
||||
"name": "Umami ניתוחים",
|
||||
"description": "הצג נתוני מבקרים ממופע Umami Analytics שלך",
|
||||
"visitors": "מבקרים",
|
||||
"active": "פעילים",
|
||||
"pageviews": "צפיות דף",
|
||||
"visits": "ביקורים",
|
||||
"bounceRate": "נטישה",
|
||||
"avgDuration": "ממוצע",
|
||||
"option": {
|
||||
"websiteId": {
|
||||
"label": "",
|
||||
"description": "",
|
||||
"placeholder": "",
|
||||
"loading": "",
|
||||
"noWebsites": "",
|
||||
"configureIntegrationFirst": ""
|
||||
"label": "אתר",
|
||||
"description": "בחר אתר המנוטר על ידי מופע ה-Umami שלך",
|
||||
"placeholder": "בחר אתר",
|
||||
"loading": "טוען אתרים...",
|
||||
"noWebsites": "לא נמצאו אתרים",
|
||||
"configureIntegrationFirst": "חבר תחילה אינטגרציית Umami"
|
||||
},
|
||||
"timeFrame": {
|
||||
"label": "",
|
||||
"description": "",
|
||||
"label": "מסגרת זמן",
|
||||
"description": "פרק הזמן להצגת נתוני מבקרים",
|
||||
"option": {
|
||||
"today": "",
|
||||
"24h": "",
|
||||
"7d": "",
|
||||
"today": "היום",
|
||||
"24h": "24 השעות האחרונות",
|
||||
"7d": "7 הימים האחרונים",
|
||||
"30d": "",
|
||||
"month": "",
|
||||
"lastMonth": ""
|
||||
@@ -2990,33 +2990,33 @@
|
||||
}
|
||||
},
|
||||
"immich-serverStats": {
|
||||
"name": "",
|
||||
"description": "",
|
||||
"name": "סטטיסטיקות שרת Immich",
|
||||
"description": "מידע על מופע ה-Immich שלך",
|
||||
"option": {
|
||||
"showUsers": {
|
||||
"label": "",
|
||||
"description": ""
|
||||
"label": "הצג משתמשים",
|
||||
"description": "הצג מספר משתמשים במופע שלך"
|
||||
},
|
||||
"showPhotos": {
|
||||
"label": "",
|
||||
"description": ""
|
||||
"label": "הצג תמונות",
|
||||
"description": "הצג מספר תמונות במופע שלך"
|
||||
},
|
||||
"showVideos": {
|
||||
"label": "",
|
||||
"description": ""
|
||||
"label": "הצג סרטונים",
|
||||
"description": "הצג מספר סרטונים במופע שלך"
|
||||
},
|
||||
"showStorage": {
|
||||
"label": "",
|
||||
"description": ""
|
||||
"label": "הצג אחסון",
|
||||
"description": "הצג את כמות האחסון הכוללת בשימוש"
|
||||
}
|
||||
},
|
||||
"users": "",
|
||||
"photos": "",
|
||||
"videos": "",
|
||||
"storage": ""
|
||||
"users": "משתמשים",
|
||||
"photos": "תמונות",
|
||||
"videos": "סרטונים",
|
||||
"storage": "אחסון בשימוש"
|
||||
},
|
||||
"immich-albumCarousel": {
|
||||
"name": "",
|
||||
"name": "אלבום Immich",
|
||||
"allPhotos": "",
|
||||
"option": {
|
||||
"albumId": {
|
||||
@@ -3024,12 +3024,12 @@
|
||||
"description": ""
|
||||
},
|
||||
"rotationIntervalSeconds": {
|
||||
"label": "",
|
||||
"description": ""
|
||||
"label": "מרווח בשניות",
|
||||
"description": "מחליף תמונות באלבום כל X שניות. חייב להיות לפחות 1. חייב להיות פחות מ-3600."
|
||||
},
|
||||
"showPhotoInfo": {
|
||||
"label": "",
|
||||
"description": ""
|
||||
"label": "הצג מידע תמונה",
|
||||
"description": "הצג תאריך התמונה והאינדקס הנוכחי בתחתית המצגת"
|
||||
},
|
||||
"randomizePhotos": {
|
||||
"label": "",
|
||||
@@ -3079,11 +3079,20 @@
|
||||
"limitPerIntegration": {
|
||||
"label": "הגבלת פריטים לכל אינטגרציה",
|
||||
"description": "פעולה זו תגביל את מספר הפריטים המוצגים בכל אינטגרציה, לא באופן גלובלי"
|
||||
},
|
||||
"columnOrder": {
|
||||
"label": ""
|
||||
},
|
||||
"columnWidths": {
|
||||
"label": ""
|
||||
}
|
||||
},
|
||||
"errors": {
|
||||
"noColumns": "בחר עמודות בפריטים",
|
||||
"noCommunications": "לא ניתן לטעון נתונים מהאינטגרציה"
|
||||
"noCommunications": "לא ניתן לטעון נתונים מהאינטגרציה",
|
||||
"noItems": "",
|
||||
"actionFailed": "",
|
||||
"actionFailedMessage": ""
|
||||
},
|
||||
"items": {
|
||||
"actions": {
|
||||
@@ -3106,7 +3115,8 @@
|
||||
"detailsTitle": "מדד נוכחי בתוך הלקוח"
|
||||
},
|
||||
"id": {
|
||||
"columnTitle": "מזהה"
|
||||
"columnTitle": "מזהה",
|
||||
"detailsTitle": ""
|
||||
},
|
||||
"integration": {
|
||||
"columnTitle": "אינטגרציה"
|
||||
@@ -3140,7 +3150,8 @@
|
||||
},
|
||||
"time": {
|
||||
"columnTitle": "זמן סיום",
|
||||
"detailsTitle": "זמן מאז/עד סיום"
|
||||
"detailsTitle": "זמן מאז/עד סיום",
|
||||
"eta": ""
|
||||
},
|
||||
"type": {
|
||||
"columnTitle": "סוּג",
|
||||
@@ -3184,7 +3195,23 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"globalRatio": "יחס גלובלי"
|
||||
"globalRatio": "יחס גלובלי",
|
||||
"contextMenu": {
|
||||
"copyName": "",
|
||||
"copyId": "",
|
||||
"clearFilters": ""
|
||||
},
|
||||
"footer": {
|
||||
"filter": ""
|
||||
},
|
||||
"stats": {
|
||||
"show": "",
|
||||
"hide": "",
|
||||
"overallProgress": "",
|
||||
"totalSize": "",
|
||||
"clients": ""
|
||||
},
|
||||
"disconnected": ""
|
||||
},
|
||||
"mediaReleases": {
|
||||
"name": "מדיה משוחררת",
|
||||
@@ -3383,7 +3410,7 @@
|
||||
"label": "הסתר תיאור"
|
||||
},
|
||||
"showPosterImage": {
|
||||
"label": ""
|
||||
"label": "הצג תמונת פוסטר"
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -3613,42 +3640,42 @@
|
||||
}
|
||||
},
|
||||
"speedtestTracker": {
|
||||
"name": "",
|
||||
"description": "",
|
||||
"name": "מעקב Speedtest",
|
||||
"description": "מציג תוצאות בדיקת מהירות ממופע מעקב Speedtest שלך.",
|
||||
"option": {
|
||||
"showLatestResult": {
|
||||
"label": ""
|
||||
"label": "הצג תוצאה אחרונה"
|
||||
},
|
||||
"showStats": {
|
||||
"label": ""
|
||||
"label": "הצג ממוצעים"
|
||||
},
|
||||
"showRecentResults": {
|
||||
"label": ""
|
||||
"label": "הצג תוצאות אחרונות"
|
||||
},
|
||||
"showPingGraph": {
|
||||
"label": ""
|
||||
"label": "הצג גרף פינג"
|
||||
}
|
||||
},
|
||||
"latestResult": "",
|
||||
"averages": "",
|
||||
"tests": "",
|
||||
"recentResults": "",
|
||||
"recentResultsSpeed": "",
|
||||
"recentResultsPing": "",
|
||||
"download": "",
|
||||
"upload": "",
|
||||
"ping": "",
|
||||
"status": "",
|
||||
"avgDownload": "",
|
||||
"avgUpload": "",
|
||||
"avgPing": "",
|
||||
"healthy": "",
|
||||
"unhealthy": "",
|
||||
"ok": "",
|
||||
"fail": "",
|
||||
"noSectionsEnabled": "",
|
||||
"latestResult": "תוצאה אחרונה",
|
||||
"averages": "ממוצעים",
|
||||
"tests": "{count} בדיקות",
|
||||
"recentResults": "תוצאות אחרונות",
|
||||
"recentResultsSpeed": "מהירות",
|
||||
"recentResultsPing": "פינג",
|
||||
"download": "הורדה",
|
||||
"upload": "העלאה",
|
||||
"ping": "פינג",
|
||||
"status": "מצב",
|
||||
"avgDownload": "הורדה ממוצעת",
|
||||
"avgUpload": "העלאה ממוצעת",
|
||||
"avgPing": "פינג ממוצע",
|
||||
"healthy": "בריא",
|
||||
"unhealthy": "לא בריא",
|
||||
"ok": "בסדר",
|
||||
"fail": "כשל",
|
||||
"noSectionsEnabled": "הפעל לפחות מקטע אחד באפשרויות הווידג'ט.",
|
||||
"error": {
|
||||
"internalServerError": ""
|
||||
"internalServerError": "אחזור נתוני speedtest נכשל"
|
||||
}
|
||||
},
|
||||
"uptimeKuma": {
|
||||
@@ -3805,7 +3832,7 @@
|
||||
"option": {
|
||||
"cpu": "מעבד",
|
||||
"memory": "זיכרון",
|
||||
"gpu": "",
|
||||
"gpu": "מעבד גרפי",
|
||||
"network": "רשת"
|
||||
}
|
||||
},
|
||||
@@ -3822,35 +3849,35 @@
|
||||
"card": {
|
||||
"cpu": "מעבד",
|
||||
"memory": "זיכרון",
|
||||
"gpu": "",
|
||||
"gpu": "מעבד גרפי",
|
||||
"network": "רשת",
|
||||
"up": "העלאה",
|
||||
"down": "הורדה"
|
||||
}
|
||||
},
|
||||
"systemDisks": {
|
||||
"name": "",
|
||||
"description": "",
|
||||
"name": "דיסקי מערכת",
|
||||
"description": "שימוש בדיסקים במערכת",
|
||||
"option": {
|
||||
"showTemperatureIfAvailable": {
|
||||
"label": ""
|
||||
"label": "הצג טמפרטורה אם זמינה"
|
||||
},
|
||||
"displayMode": {
|
||||
"label": "",
|
||||
"label": "מצב תצוגה",
|
||||
"option": {
|
||||
"percentage": {
|
||||
"label": ""
|
||||
"label": "אחוז (לדוגמה, 76%)"
|
||||
},
|
||||
"absolute": {
|
||||
"label": ""
|
||||
"label": "ערכים מוחלטים (לדוגמה, 800GB / 1TB)"
|
||||
},
|
||||
"free": {
|
||||
"label": ""
|
||||
"label": "אחוז שטח פנוי (לדוגמה, 24% פנוי)"
|
||||
}
|
||||
}
|
||||
},
|
||||
"showBackgroundBar": {
|
||||
"label": ""
|
||||
"label": "הצג סרגל שימוש ברקע"
|
||||
},
|
||||
"visibleStorageVolumes": {
|
||||
"label": "",
|
||||
@@ -3859,7 +3886,7 @@
|
||||
}
|
||||
},
|
||||
"status": {
|
||||
"unhealthy": ""
|
||||
"unhealthy": "לא בריא"
|
||||
}
|
||||
},
|
||||
"customApi": {
|
||||
@@ -4828,8 +4855,8 @@
|
||||
"user": {
|
||||
"title": "משתמשים",
|
||||
"enableGravatar": {
|
||||
"label": "",
|
||||
"description": ""
|
||||
"label": "הפעל Gravatar",
|
||||
"description": "מציג אווטר מ-Libravatar/Gravatar כברירת מחדל כשאין אווטר מותאם אישית וקיים דוא\"ל"
|
||||
}
|
||||
},
|
||||
"search": {
|
||||
@@ -5207,8 +5234,8 @@
|
||||
"subtitle": "{count} תורמים בתרגום לשפות שונות"
|
||||
},
|
||||
"sponsors": {
|
||||
"title": "",
|
||||
"subtitle": ""
|
||||
"title": "ספונסרים",
|
||||
"subtitle": "{count} תומכים בפרויקט כלכלית"
|
||||
},
|
||||
"libraries": {
|
||||
"title": "ספריות",
|
||||
|
||||
+1209
-1182
File diff suppressed because it is too large.
Load diff
+1244
-1217
File diff suppressed because it is too large.
Load diff
@@ -1907,14 +1907,14 @@
|
||||
"description": "Usa ISO 8601 per formattare la data (questo sovrascriverà altre opzioni)"
|
||||
},
|
||||
"showWeather": {
|
||||
"label": "",
|
||||
"description": ""
|
||||
"label": "Mostra meteo",
|
||||
"description": "Mostra una piccola icona animata del meteo e la temperatura nell'angolo della scheda"
|
||||
},
|
||||
"weatherLocation": {
|
||||
"label": ""
|
||||
"label": "Località meteo"
|
||||
},
|
||||
"isWeatherFormatFahrenheit": {
|
||||
"label": ""
|
||||
"label": "Usa Fahrenheit"
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -3079,11 +3079,20 @@
|
||||
"limitPerIntegration": {
|
||||
"label": "Limite elementi per integrazione",
|
||||
"description": "Ciò limiterà il numero di elementi mostrati per integrazione, non globalmente"
|
||||
},
|
||||
"columnOrder": {
|
||||
"label": "Ordine delle colonne"
|
||||
},
|
||||
"columnWidths": {
|
||||
"label": "Larghezza delle colonne"
|
||||
}
|
||||
},
|
||||
"errors": {
|
||||
"noColumns": "Seleziona colonne in elementi",
|
||||
"noCommunications": "Impossibile caricare i dati dall'integrazione"
|
||||
"noCommunications": "Impossibile caricare i dati dall'integrazione",
|
||||
"noItems": "Nessun download trovato",
|
||||
"actionFailed": "Azione non riuscita",
|
||||
"actionFailedMessage": "L'azione non può essere completata. Per favore riprova."
|
||||
},
|
||||
"items": {
|
||||
"actions": {
|
||||
@@ -3106,7 +3115,8 @@
|
||||
"detailsTitle": "Indice corrente all'interno del client"
|
||||
},
|
||||
"id": {
|
||||
"columnTitle": "Id"
|
||||
"columnTitle": "Id",
|
||||
"detailsTitle": "ID elemento"
|
||||
},
|
||||
"integration": {
|
||||
"columnTitle": "Integrazione"
|
||||
@@ -3140,7 +3150,8 @@
|
||||
},
|
||||
"time": {
|
||||
"columnTitle": "Ora di fine",
|
||||
"detailsTitle": "Tempo dal/al completamento"
|
||||
"detailsTitle": "Tempo dal/al completamento",
|
||||
"eta": "ETA"
|
||||
},
|
||||
"type": {
|
||||
"columnTitle": "Tipo",
|
||||
@@ -3184,7 +3195,23 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"globalRatio": "Rapporto globale"
|
||||
"globalRatio": "Rapporto globale",
|
||||
"contextMenu": {
|
||||
"copyName": "Copia nome",
|
||||
"copyId": "Copia ID",
|
||||
"clearFilters": "Resetta filtri"
|
||||
},
|
||||
"footer": {
|
||||
"filter": "Filtro download"
|
||||
},
|
||||
"stats": {
|
||||
"show": "Mostra statistiche globali",
|
||||
"hide": "Nascondi statistiche globali",
|
||||
"overallProgress": "Avanzamento complessivo della coda",
|
||||
"totalSize": "Dimensione totale della coda",
|
||||
"clients": "{count, plural, one {# cliente} other {# clienti}}"
|
||||
},
|
||||
"disconnected": "(disconnesso)"
|
||||
},
|
||||
"mediaReleases": {
|
||||
"name": "Comunicati stampa",
|
||||
|
||||
@@ -2560,30 +2560,30 @@
|
||||
}
|
||||
},
|
||||
"umami": {
|
||||
"name": "",
|
||||
"description": "",
|
||||
"visitors": "",
|
||||
"active": "",
|
||||
"pageviews": "",
|
||||
"visits": "",
|
||||
"bounceRate": "",
|
||||
"avgDuration": "",
|
||||
"name": "Umami 統計情報",
|
||||
"description": "あなたの Umami 統計情報インスタンスから訪問者統計を表示します",
|
||||
"visitors": "訪問者数",
|
||||
"active": "活動中",
|
||||
"pageviews": "ページビュー",
|
||||
"visits": "訪問数",
|
||||
"bounceRate": "直帰率",
|
||||
"avgDuration": "平均",
|
||||
"option": {
|
||||
"websiteId": {
|
||||
"label": "",
|
||||
"description": "",
|
||||
"placeholder": "",
|
||||
"loading": "",
|
||||
"noWebsites": "",
|
||||
"configureIntegrationFirst": ""
|
||||
"label": "ウェブサイト",
|
||||
"description": "あなたの Umami インスタンスで追跡されているウェブサイトを選択してください",
|
||||
"placeholder": "ウェブサイトを選択",
|
||||
"loading": "ウェブサイトを読み込み中…",
|
||||
"noWebsites": "ウェブサイトが見つかりません",
|
||||
"configureIntegrationFirst": "最初に Umami 統合を接続してください"
|
||||
},
|
||||
"timeFrame": {
|
||||
"label": "",
|
||||
"description": "",
|
||||
"label": "期間",
|
||||
"description": "訪問者データを表示する期間",
|
||||
"option": {
|
||||
"today": "",
|
||||
"24h": "",
|
||||
"7d": "",
|
||||
"today": "今日",
|
||||
"24h": "過去24時間",
|
||||
"7d": "過去7日間",
|
||||
"30d": "",
|
||||
"month": "",
|
||||
"lastMonth": ""
|
||||
@@ -3079,11 +3079,20 @@
|
||||
"limitPerIntegration": {
|
||||
"label": "連携機能ごとに項目を制限",
|
||||
"description": "これは、連携機能ごとに表示されるアイテム数を制限します。グローバルではありません"
|
||||
},
|
||||
"columnOrder": {
|
||||
"label": ""
|
||||
},
|
||||
"columnWidths": {
|
||||
"label": ""
|
||||
}
|
||||
},
|
||||
"errors": {
|
||||
"noColumns": "項目内の列を選択",
|
||||
"noCommunications": "連携機能からデータを読み込めません"
|
||||
"noCommunications": "連携機能からデータを読み込めません",
|
||||
"noItems": "",
|
||||
"actionFailed": "",
|
||||
"actionFailedMessage": ""
|
||||
},
|
||||
"items": {
|
||||
"actions": {
|
||||
@@ -3106,7 +3115,8 @@
|
||||
"detailsTitle": "クライアント内の現在のインデックス"
|
||||
},
|
||||
"id": {
|
||||
"columnTitle": "Id"
|
||||
"columnTitle": "Id",
|
||||
"detailsTitle": ""
|
||||
},
|
||||
"integration": {
|
||||
"columnTitle": "連携機能"
|
||||
@@ -3140,7 +3150,8 @@
|
||||
},
|
||||
"time": {
|
||||
"columnTitle": "終了時刻",
|
||||
"detailsTitle": "完了までの時間"
|
||||
"detailsTitle": "完了までの時間",
|
||||
"eta": ""
|
||||
},
|
||||
"type": {
|
||||
"columnTitle": "種類",
|
||||
@@ -3184,7 +3195,23 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"globalRatio": "グローバル比"
|
||||
"globalRatio": "グローバル比",
|
||||
"contextMenu": {
|
||||
"copyName": "",
|
||||
"copyId": "",
|
||||
"clearFilters": ""
|
||||
},
|
||||
"footer": {
|
||||
"filter": ""
|
||||
},
|
||||
"stats": {
|
||||
"show": "",
|
||||
"hide": "",
|
||||
"overallProgress": "",
|
||||
"totalSize": "",
|
||||
"clients": ""
|
||||
},
|
||||
"disconnected": ""
|
||||
},
|
||||
"mediaReleases": {
|
||||
"name": "メディアリリース",
|
||||
@@ -5207,8 +5234,8 @@
|
||||
"subtitle": "{count} の多くの言語で翻訳を行っている"
|
||||
},
|
||||
"sponsors": {
|
||||
"title": "",
|
||||
"subtitle": ""
|
||||
"title": "スポンサー",
|
||||
"subtitle": "{count}人がプロジェクトを財政的に支援しています"
|
||||
},
|
||||
"libraries": {
|
||||
"title": "ライブラリ",
|
||||
|
||||
+1081
-1054
File diff suppressed because it is too large.
Load diff
+1194
-1167
File diff suppressed because it is too large.
Load diff
File diff suppressed because it is too large.
Load diff
File diff suppressed because it is too large.
Load diff
@@ -3079,11 +3079,20 @@
|
||||
"limitPerIntegration": {
|
||||
"label": "Begrens elementer per integrasjon",
|
||||
"description": "Dette begrenser antall elementer vist per integrasjon, ikke globalt"
|
||||
},
|
||||
"columnOrder": {
|
||||
"label": ""
|
||||
},
|
||||
"columnWidths": {
|
||||
"label": ""
|
||||
}
|
||||
},
|
||||
"errors": {
|
||||
"noColumns": "Velg kolonner i elementer",
|
||||
"noCommunications": "Kan ikke laste inn data fra integrasjon"
|
||||
"noCommunications": "Kan ikke laste inn data fra integrasjon",
|
||||
"noItems": "",
|
||||
"actionFailed": "",
|
||||
"actionFailedMessage": ""
|
||||
},
|
||||
"items": {
|
||||
"actions": {
|
||||
@@ -3106,7 +3115,8 @@
|
||||
"detailsTitle": "Gjeldende indeks i klienten"
|
||||
},
|
||||
"id": {
|
||||
"columnTitle": "Id"
|
||||
"columnTitle": "Id",
|
||||
"detailsTitle": ""
|
||||
},
|
||||
"integration": {
|
||||
"columnTitle": "Integrasjon"
|
||||
@@ -3140,7 +3150,8 @@
|
||||
},
|
||||
"time": {
|
||||
"columnTitle": "Fullfør tid",
|
||||
"detailsTitle": "Tid siden/til fullførelse"
|
||||
"detailsTitle": "Tid siden/til fullførelse",
|
||||
"eta": ""
|
||||
},
|
||||
"type": {
|
||||
"columnTitle": "Type",
|
||||
@@ -3184,7 +3195,23 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"globalRatio": "Global ratio"
|
||||
"globalRatio": "Global ratio",
|
||||
"contextMenu": {
|
||||
"copyName": "",
|
||||
"copyId": "",
|
||||
"clearFilters": ""
|
||||
},
|
||||
"footer": {
|
||||
"filter": ""
|
||||
},
|
||||
"stats": {
|
||||
"show": "",
|
||||
"hide": "",
|
||||
"overallProgress": "",
|
||||
"totalSize": "",
|
||||
"clients": ""
|
||||
},
|
||||
"disconnected": ""
|
||||
},
|
||||
"mediaReleases": {
|
||||
"name": "Medieutgivelser",
|
||||
|
||||
@@ -199,8 +199,8 @@
|
||||
"label": "Użyj ikon dla pingów"
|
||||
},
|
||||
"enableRightClickOnWidgets": {
|
||||
"label": "",
|
||||
"description": ""
|
||||
"label": "Włącz prawe kliknięcie na widżetach",
|
||||
"description": "Pokaż menu kontekstowe Homarr po kliknięciu prawym przyciskiem na widżet. Wyłącz, aby używać domyślnego menu przeglądarki (np. \"Otwórz link w nowej karcie\")."
|
||||
},
|
||||
"defaultSearchEngine": {
|
||||
"label": "Domyślna wyszukiwarka"
|
||||
@@ -1290,12 +1290,12 @@
|
||||
"newLabel": "Nowy klucz API (Secret)"
|
||||
},
|
||||
"patchmonApiKey": {
|
||||
"label": "",
|
||||
"newLabel": ""
|
||||
"label": "Klucz API",
|
||||
"newLabel": "Nowy klucz API"
|
||||
},
|
||||
"patchmonApiSecret": {
|
||||
"label": "",
|
||||
"newLabel": ""
|
||||
"label": "Sekret API",
|
||||
"newLabel": "Nowy sekret API"
|
||||
},
|
||||
"githubAppId": {
|
||||
"label": "Identyfikator aplikacji",
|
||||
@@ -1341,20 +1341,20 @@
|
||||
}
|
||||
},
|
||||
"traefik": {
|
||||
"name": "",
|
||||
"description": ""
|
||||
"name": "Traefik",
|
||||
"description": "Chmurowy reverse proxy i load balancer"
|
||||
},
|
||||
"paperlessNgx": {
|
||||
"name": "Paperless-ngx",
|
||||
"description": "System zarządzania dokumentami do archiwizacji i organizacji zeskanowaych dokumnteów"
|
||||
},
|
||||
"patchmon": {
|
||||
"name": "",
|
||||
"description": ""
|
||||
"name": "PatchMon",
|
||||
"description": "Zarządzanie łatkami i monitorowanie hostów Linux"
|
||||
},
|
||||
"bazarr": {
|
||||
"name": "",
|
||||
"description": ""
|
||||
"name": "Bazarr",
|
||||
"description": "Aplikacja towarzysząca Sonarr i Radarr do zarządzania i pobierania napisów"
|
||||
}
|
||||
},
|
||||
"media": {
|
||||
@@ -1628,10 +1628,10 @@
|
||||
"actions": "Akcje"
|
||||
},
|
||||
"status": {
|
||||
"success": "",
|
||||
"error": "",
|
||||
"loading": "",
|
||||
"idle": ""
|
||||
"success": "OK",
|
||||
"error": "Błąd",
|
||||
"loading": "Ładowanie",
|
||||
"idle": "Bezczynny"
|
||||
}
|
||||
},
|
||||
"create": {
|
||||
@@ -1907,14 +1907,14 @@
|
||||
"description": "Użyj ISO 8601 do formatu daty (spowoduje to nadpisanie innych opcji)"
|
||||
},
|
||||
"showWeather": {
|
||||
"label": "",
|
||||
"description": ""
|
||||
"label": "Pokaż pogodę",
|
||||
"description": "Wyświetl małą animowaną ikonę pogody i temperaturę w rogu karty"
|
||||
},
|
||||
"weatherLocation": {
|
||||
"label": ""
|
||||
"label": "Lokalizacja pogody"
|
||||
},
|
||||
"isWeatherFormatFahrenheit": {
|
||||
"label": ""
|
||||
"label": "Użyj Fahrenheita"
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -1976,8 +1976,8 @@
|
||||
"clear": "Wyczyść formatowanie",
|
||||
"heading": "Nagłówek {level}",
|
||||
"align": "Wyrównanie tekstu: {position}",
|
||||
"directionLtr": "",
|
||||
"directionRtl": "",
|
||||
"directionLtr": "Ustaw kierunek tekstu od lewej do prawej",
|
||||
"directionRtl": "Ustaw kierunek tekstu od prawej do lewej",
|
||||
"blockquote": "Cytat",
|
||||
"horizontalLine": "Linia pozioma",
|
||||
"bulletList": "Lista punktowana",
|
||||
@@ -2268,7 +2268,7 @@
|
||||
"sunset": "Zachód słońca",
|
||||
"maxWindSpeed": "Maksymalna prędkość wiatru: {maxWindSpeed} km/h",
|
||||
"maxWindGusts": "Maksymalne porywy wiatru: {maxWindGusts} km/h",
|
||||
"humidity": ""
|
||||
"humidity": "Wilgotność: {humidity}%"
|
||||
},
|
||||
"kind": {
|
||||
"clear": "Bezchmurnie",
|
||||
@@ -2328,9 +2328,9 @@
|
||||
"label": "Pokaż informacje o systemie plików"
|
||||
},
|
||||
"visibleStorageVolumes": {
|
||||
"label": "",
|
||||
"description": "",
|
||||
"placeholder": ""
|
||||
"label": "Widoczne woluminy pamięci",
|
||||
"description": "Dostępne tylko gdy wszystkie wybrane integracje to Synology. Pozostaw puste, aby wyświetlić wszystkie wykryte woluminy pamięci.",
|
||||
"placeholder": "Wybierz woluminy pamięci"
|
||||
},
|
||||
"defaultTab": {
|
||||
"label": "Domyślna karta"
|
||||
@@ -2732,11 +2732,11 @@
|
||||
"user": "Użytkownik",
|
||||
"name": "Nazwa",
|
||||
"id": "ID",
|
||||
"status": "",
|
||||
"directPlay": "",
|
||||
"transcoding": "",
|
||||
"paused": "",
|
||||
"remaining": "",
|
||||
"status": "Status",
|
||||
"directPlay": "Odtwarzanie bezpośrednie",
|
||||
"transcoding": "Transkodowanie",
|
||||
"paused": "Zatrzymane",
|
||||
"remaining": "{minutes} min pozostało",
|
||||
"metadata": {
|
||||
"title": "Statystyki dla nerdów",
|
||||
"video": {
|
||||
@@ -2803,190 +2803,190 @@
|
||||
}
|
||||
},
|
||||
"patchmon": {
|
||||
"name": "",
|
||||
"description": "",
|
||||
"title": "",
|
||||
"totalHosts": "",
|
||||
"hostsNeedingUpdates": "",
|
||||
"securityUpdates": "",
|
||||
"upToDateHosts": "",
|
||||
"hostsWithSecurityUpdates": "",
|
||||
"recentUpdates24h": "",
|
||||
"totalOutdatedPackages": "",
|
||||
"totalRepos": "",
|
||||
"osDistribution": "",
|
||||
"compliance": "",
|
||||
"complianceRatio": "",
|
||||
"lastUpdated": "",
|
||||
"name": "PatchMon",
|
||||
"description": "Przegląd stanu poprawek hostów z PatchMon",
|
||||
"title": "Statystyki PatchMon",
|
||||
"totalHosts": "Łączna liczba hostów",
|
||||
"hostsNeedingUpdates": "Wymaga aktualizacji",
|
||||
"securityUpdates": "Aktualizacje zabezpieczeń",
|
||||
"upToDateHosts": "Aktualne hosty",
|
||||
"hostsWithSecurityUpdates": "Hosty z aktualizacjami zabezpieczeń",
|
||||
"recentUpdates24h": "Aktualizacje (24h)",
|
||||
"totalOutdatedPackages": "Nieaktualne pakiety",
|
||||
"totalRepos": "Repozytoria",
|
||||
"osDistribution": "Dystrybucja systemu",
|
||||
"compliance": "Zgodność poprawek",
|
||||
"complianceRatio": "{upToDate} / {total}",
|
||||
"lastUpdated": "Zaktualizowano {time}",
|
||||
"option": {
|
||||
"showTotalHosts": {
|
||||
"label": "",
|
||||
"description": ""
|
||||
"label": "Pokaż łączną liczbę hostów",
|
||||
"description": "Wyświetla łączną liczbę monitorowanych hostów"
|
||||
},
|
||||
"showHostsNeedingUpdates": {
|
||||
"label": "",
|
||||
"description": ""
|
||||
"label": "Pokaż hosty wymagające aktualizacji",
|
||||
"description": "Wyświetla hosty z co najmniej jednym nieaktualnym pakietem"
|
||||
},
|
||||
"showSecurityUpdates": {
|
||||
"label": "",
|
||||
"description": ""
|
||||
"label": "Pokaż aktualizacje zabezpieczeń",
|
||||
"description": "Wyświetla całkowitą liczbę dostępnych aktualizacji zabezpieczeń"
|
||||
},
|
||||
"showUpToDateHosts": {
|
||||
"label": "",
|
||||
"description": ""
|
||||
"label": "Pokaż aktualne hosty",
|
||||
"description": "Wyświetla hosty bez nieaktualnych pakietów"
|
||||
},
|
||||
"showHostsWithSecurityUpdates": {
|
||||
"label": "",
|
||||
"description": ""
|
||||
"label": "Pokaż hosty z aktualizacjami zabezpieczeń",
|
||||
"description": "Wyświetla hosty wymagające poprawek bezpieczeństwa"
|
||||
},
|
||||
"showRecentUpdates24h": {
|
||||
"label": "",
|
||||
"description": ""
|
||||
"label": "Pokaż ostatnie aktualizacje (24h)",
|
||||
"description": "Wyświetla liczbę aktualizacji zastosowanych w ciągu ostatnich 24 godzin"
|
||||
},
|
||||
"showTotalOutdatedPackages": {
|
||||
"label": "",
|
||||
"description": ""
|
||||
"label": "Pokaż nieaktualne pakiety",
|
||||
"description": "Wyświetla całkowitą liczbę nieaktualnych pakietów na wszystkich hostach"
|
||||
},
|
||||
"showTotalRepos": {
|
||||
"label": "",
|
||||
"description": ""
|
||||
"label": "Pokaż repozytoria",
|
||||
"description": "Wyświetla liczbę monitorowanych aktywnych repozytoriów"
|
||||
},
|
||||
"enableThresholdColors": {
|
||||
"label": "",
|
||||
"description": ""
|
||||
"label": "Włącz kolory progów",
|
||||
"description": "Koloruj wartości statystyk na zielono, żółto lub czerwono w zależności od ustawionych progów ważności"
|
||||
},
|
||||
"useCustomThresholds": {
|
||||
"label": "",
|
||||
"description": ""
|
||||
"label": "Zaawansowane progi",
|
||||
"description": "Dostosuj progi ostrzeżeń i krytyczne dla każdej statystyki, używając liczby bezwzględnej lub procentu wszystkich hostów"
|
||||
},
|
||||
"thresholdMode": {
|
||||
"option": {
|
||||
"absolute": "",
|
||||
"percent": ""
|
||||
"absolute": "Liczba bezwzględna",
|
||||
"percent": "Procent wszystkich hostów"
|
||||
}
|
||||
},
|
||||
"hostsNeedingUpdatesThresholdMode": {
|
||||
"label": "",
|
||||
"description": ""
|
||||
"label": "Tryb progu dla wymagających aktualizacji",
|
||||
"description": "Porównaj liczbę hostów wymagających aktualizacji jako wartość bezwzględną lub procent wszystkich hostów"
|
||||
},
|
||||
"hostsNeedingUpdatesWarningAt": {
|
||||
"label": "",
|
||||
"description": ""
|
||||
"label": "Próg ostrzeżenia dla wymagających aktualizacji",
|
||||
"description": "Zmień na żółty, gdy wartość osiągnie ten próg"
|
||||
},
|
||||
"hostsNeedingUpdatesCriticalAt": {
|
||||
"label": "",
|
||||
"description": ""
|
||||
"label": "Próg krytyczny dla wymagających aktualizacji",
|
||||
"description": "Zmień na czerwony, gdy wartość osiągnie ten próg"
|
||||
},
|
||||
"securityUpdatesThresholdMode": {
|
||||
"label": "",
|
||||
"description": ""
|
||||
"label": "Tryb progu dla aktualizacji zabezpieczeń",
|
||||
"description": "Porównaj liczbę aktualizacji zabezpieczeń jako wartość bezwzględną lub procent wszystkich hostów"
|
||||
},
|
||||
"securityUpdatesWarningAt": {
|
||||
"label": "",
|
||||
"description": ""
|
||||
"label": "Próg ostrzeżenia dla aktualizacji zabezpieczeń",
|
||||
"description": "Ustaw żółty kolor, gdy wartość osiągnie ten próg"
|
||||
},
|
||||
"securityUpdatesCriticalAt": {
|
||||
"label": "",
|
||||
"description": ""
|
||||
"label": "Próg krytyczny aktualizacji zabezpieczeń",
|
||||
"description": "Ustaw czerwony kolor, gdy wartość osiągnie ten próg"
|
||||
},
|
||||
"hostsWithSecurityUpdatesThresholdMode": {
|
||||
"label": "",
|
||||
"description": ""
|
||||
"label": "Tryb progu liczby hostów z aktualizacjami zabezpieczeń",
|
||||
"description": "Porównaj liczbę hostów jako wartość bezwzględną lub procent całkowitej liczby hostów"
|
||||
},
|
||||
"hostsWithSecurityUpdatesWarningAt": {
|
||||
"label": "",
|
||||
"description": ""
|
||||
"label": "Próg ostrzegawczy dla hostów z aktualizacjami zabezpieczeń",
|
||||
"description": "Ustaw żółty kolor, gdy wartość osiągnie ten próg"
|
||||
},
|
||||
"hostsWithSecurityUpdatesCriticalAt": {
|
||||
"label": "",
|
||||
"description": ""
|
||||
"label": "Próg krytyczny dla hostów z aktualizacjami zabezpieczeń",
|
||||
"description": "Ustaw czerwony kolor, gdy wartość osiągnie ten próg"
|
||||
},
|
||||
"upToDateHostsThresholdMode": {
|
||||
"label": "",
|
||||
"description": ""
|
||||
"label": "Tryb progu dla aktualnych hostów",
|
||||
"description": "Porównaj liczbę aktualnych hostów jako wartość bezwzględną lub procent całkowitej liczby hostów"
|
||||
},
|
||||
"upToDateHostsWarningAt": {
|
||||
"label": "",
|
||||
"description": ""
|
||||
"label": "Próg ostrzegawczy dla aktualnych hostów",
|
||||
"description": "Ustaw żółty kolor, gdy wartość jest równa lub wyższa od tego progu, ale poniżej pełnego pokrycia"
|
||||
},
|
||||
"upToDateHostsCriticalAt": {
|
||||
"label": "",
|
||||
"description": ""
|
||||
"label": "Próg krytyczny dla aktualnych hostów",
|
||||
"description": "Ustaw czerwony kolor, gdy wartość spadnie poniżej tego progu"
|
||||
},
|
||||
"totalOutdatedPackagesThresholdMode": {
|
||||
"label": "",
|
||||
"description": ""
|
||||
"label": "Tryb progu dla nieaktualnych pakietów",
|
||||
"description": "Porównaj liczbę nieaktualnych pakietów jako wartość bezwzględną lub procent całkowitej liczby hostów"
|
||||
},
|
||||
"totalOutdatedPackagesWarningAt": {
|
||||
"label": "",
|
||||
"description": ""
|
||||
"label": "Próg ostrzegawczy dla nieaktualnych pakietów",
|
||||
"description": "Ustaw żółty kolor, gdy wartość osiągnie ten próg"
|
||||
},
|
||||
"totalOutdatedPackagesCriticalAt": {
|
||||
"label": "",
|
||||
"description": ""
|
||||
"label": "Próg krytyczny dla nieaktualnych pakietów",
|
||||
"description": "Ustaw czerwony kolor, gdy wartość osiągnie ten próg"
|
||||
},
|
||||
"showOsDistribution": {
|
||||
"label": "",
|
||||
"description": ""
|
||||
"label": "Pokaż dystrybucję systemu operacyjnego",
|
||||
"description": "Wyświetl podział monitorowanych hostów według systemu operacyjnego"
|
||||
},
|
||||
"osDistributionLimit": {
|
||||
"label": "",
|
||||
"description": "",
|
||||
"label": "Limit dystrybucji systemu operacyjnego",
|
||||
"description": "Maksymalna liczba systemów operacyjnych do wyświetlenia",
|
||||
"option": {
|
||||
"3": "",
|
||||
"5": "",
|
||||
"10": "",
|
||||
"all": ""
|
||||
"3": "Top 3",
|
||||
"5": "Top 5",
|
||||
"10": "Top 10",
|
||||
"all": "Wszystkie"
|
||||
}
|
||||
},
|
||||
"showOsVersion": {
|
||||
"label": "",
|
||||
"description": ""
|
||||
"label": "Pokaż wersję systemu operacyjnego",
|
||||
"description": "Dodaj wersję systemu operacyjnego do każdej etykiety dystrybucji, jeśli jest dostępna"
|
||||
},
|
||||
"showComplianceHero": {
|
||||
"label": "",
|
||||
"description": ""
|
||||
"label": "Pokaż wskaźnik zgodności",
|
||||
"description": "Wyświetl pierścień zgodności pokazujący procent aktualnych hostów"
|
||||
},
|
||||
"osDisplayMode": {
|
||||
"label": "",
|
||||
"description": "",
|
||||
"label": "Tryb wyświetlania systemu operacyjnego",
|
||||
"description": "Wybierz sposób wyświetlania dystrybucji systemu operacyjnego",
|
||||
"option": {
|
||||
"bars": "",
|
||||
"donut": ""
|
||||
"bars": "Paski poziome",
|
||||
"donut": "Wykres pierścieniowy"
|
||||
}
|
||||
}
|
||||
},
|
||||
"error": {
|
||||
"internalServerError": ""
|
||||
"internalServerError": "Nie udało się pobrać danych PatchMon"
|
||||
}
|
||||
},
|
||||
"bazarr": {
|
||||
"name": "",
|
||||
"description": "",
|
||||
"episodes": "",
|
||||
"movies": "",
|
||||
"providers": "",
|
||||
"status": "",
|
||||
"name": "Bazarr",
|
||||
"description": "Przegląd brakujących napisów i stanu zdrowia z instancji Bazarr",
|
||||
"episodes": "Brakujące odcinki",
|
||||
"movies": "Brakujące filmy",
|
||||
"providers": "Problemy dostawców",
|
||||
"status": "Problemy ze stanem",
|
||||
"option": {
|
||||
"showMissingEpisodes": {
|
||||
"label": "",
|
||||
"description": ""
|
||||
"label": "Pokaż brakujące odcinki",
|
||||
"description": "Wyświetla liczbę odcinków z brakującymi napisami"
|
||||
},
|
||||
"showMissingMovies": {
|
||||
"label": "",
|
||||
"description": ""
|
||||
"label": "Pokaż brakujące filmy",
|
||||
"description": "Wyświetla liczbę filmów z brakującymi napisami"
|
||||
},
|
||||
"showProviderIssues": {
|
||||
"label": "",
|
||||
"description": ""
|
||||
"label": "Pokaż problemy dostawców",
|
||||
"description": "Wyświetla liczbę dostawców napisów z problemami"
|
||||
},
|
||||
"showHealthIssues": {
|
||||
"label": "",
|
||||
"description": ""
|
||||
"label": "Pokaż problemy ze stanem",
|
||||
"description": "Wyświetla liczbę problemów ze stanem Bazarr"
|
||||
}
|
||||
},
|
||||
"error": {
|
||||
"internalServerError": ""
|
||||
"internalServerError": "Nie udało się pobrać danych z Bazarr"
|
||||
}
|
||||
},
|
||||
"immich-serverStats": {
|
||||
@@ -3017,7 +3017,7 @@
|
||||
},
|
||||
"immich-albumCarousel": {
|
||||
"name": "Album Immich",
|
||||
"allPhotos": "",
|
||||
"allPhotos": "Wszystkie zdjęcia",
|
||||
"option": {
|
||||
"albumId": {
|
||||
"label": "ID albumu",
|
||||
@@ -3079,11 +3079,20 @@
|
||||
"limitPerIntegration": {
|
||||
"label": "Limit elementów na integrację",
|
||||
"description": "To ograniczy liczbę wyświetlanych elementów dla każdej integracji, a nie globalnie."
|
||||
},
|
||||
"columnOrder": {
|
||||
"label": ""
|
||||
},
|
||||
"columnWidths": {
|
||||
"label": ""
|
||||
}
|
||||
},
|
||||
"errors": {
|
||||
"noColumns": "Wybierz kolumny w elementach",
|
||||
"noCommunications": "Nie można załadować danych z integracji"
|
||||
"noCommunications": "Nie można załadować danych z integracji",
|
||||
"noItems": "",
|
||||
"actionFailed": "",
|
||||
"actionFailedMessage": ""
|
||||
},
|
||||
"items": {
|
||||
"actions": {
|
||||
@@ -3106,7 +3115,8 @@
|
||||
"detailsTitle": "Bieżący indeks w ramach klienta"
|
||||
},
|
||||
"id": {
|
||||
"columnTitle": "ID"
|
||||
"columnTitle": "ID",
|
||||
"detailsTitle": ""
|
||||
},
|
||||
"integration": {
|
||||
"columnTitle": "Integracja"
|
||||
@@ -3140,7 +3150,8 @@
|
||||
},
|
||||
"time": {
|
||||
"columnTitle": "Czas zakończenia",
|
||||
"detailsTitle": "Czas od/do zakończenia"
|
||||
"detailsTitle": "Czas od/do zakończenia",
|
||||
"eta": ""
|
||||
},
|
||||
"type": {
|
||||
"columnTitle": "Typ",
|
||||
@@ -3184,7 +3195,23 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"globalRatio": "Wskaźnik globalny"
|
||||
"globalRatio": "Wskaźnik globalny",
|
||||
"contextMenu": {
|
||||
"copyName": "",
|
||||
"copyId": "",
|
||||
"clearFilters": ""
|
||||
},
|
||||
"footer": {
|
||||
"filter": ""
|
||||
},
|
||||
"stats": {
|
||||
"show": "",
|
||||
"hide": "",
|
||||
"overallProgress": "",
|
||||
"totalSize": "",
|
||||
"clients": ""
|
||||
},
|
||||
"disconnected": ""
|
||||
},
|
||||
"mediaReleases": {
|
||||
"name": "Wydania mediów",
|
||||
@@ -3223,10 +3250,10 @@
|
||||
"label": "Otwieraj linki w nowej karcie"
|
||||
},
|
||||
"statusFilter": {
|
||||
"label": ""
|
||||
"label": "Statusy do wyświetlenia"
|
||||
},
|
||||
"recentDays": {
|
||||
"label": ""
|
||||
"label": "Pokaż tylko ostatnie żądania"
|
||||
}
|
||||
},
|
||||
"pending": {
|
||||
@@ -3335,33 +3362,33 @@
|
||||
}
|
||||
},
|
||||
"mediaMissing": {
|
||||
"name": "",
|
||||
"description": "",
|
||||
"name": "Brakujące i oczekujące media",
|
||||
"description": "Pokazuje brakujące i oczekujące filmy i odcinki z Radarr i Sonarr",
|
||||
"option": {
|
||||
"showMissing": {
|
||||
"label": ""
|
||||
"label": "Pokaż brakujące elementy"
|
||||
},
|
||||
"showQueued": {
|
||||
"label": ""
|
||||
"label": "Pokaż oczekujące elementy"
|
||||
},
|
||||
"pageSize": {
|
||||
"label": ""
|
||||
"label": "Elementów na stronę"
|
||||
}
|
||||
},
|
||||
"tab": {
|
||||
"missing": "",
|
||||
"queued": ""
|
||||
"missing": "Brakujące",
|
||||
"queued": "Oczekujące"
|
||||
},
|
||||
"type": {
|
||||
"movie": "",
|
||||
"episode": ""
|
||||
"movie": "Film",
|
||||
"episode": "Odcinek"
|
||||
},
|
||||
"empty": {
|
||||
"missing": "",
|
||||
"queued": "",
|
||||
"noTabsEnabled": ""
|
||||
"missing": "Brak brakujących elementów",
|
||||
"queued": "Brak oczekujących elementów",
|
||||
"noTabsEnabled": "Włącz co najmniej jedną kartę w ustawieniach widżetu"
|
||||
},
|
||||
"timeLeft": ""
|
||||
"timeLeft": "Pozostały czas"
|
||||
},
|
||||
"rssFeed": {
|
||||
"name": "Kanały RSS",
|
||||
@@ -3608,7 +3635,7 @@
|
||||
"noItems": "Brak powiadomień do wyświetlenia.",
|
||||
"option": {
|
||||
"hideLogos": {
|
||||
"label": ""
|
||||
"label": "Ukryj loga"
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -3692,37 +3719,37 @@
|
||||
}
|
||||
},
|
||||
"traefik": {
|
||||
"name": "",
|
||||
"description": "",
|
||||
"name": "Traefik",
|
||||
"description": "Przegląd routerów, usług, middleware i punktów wejścia Traefik",
|
||||
"option": {
|
||||
"showTcp": {
|
||||
"label": ""
|
||||
"label": "Pokaż TCP"
|
||||
},
|
||||
"showUdp": {
|
||||
"label": ""
|
||||
"label": "Pokaż UDP"
|
||||
},
|
||||
"showEntryPoints": {
|
||||
"label": ""
|
||||
"label": "Pokaż punkty wejścia"
|
||||
}
|
||||
},
|
||||
"instances": "",
|
||||
"versionUnknown": "",
|
||||
"instances": "Instancje Traefik",
|
||||
"versionUnknown": "Wersja nieznana",
|
||||
"summary": {
|
||||
"routers": "",
|
||||
"entryPoints": ""
|
||||
"routers": "Routery",
|
||||
"entryPoints": "Punkty wejścia"
|
||||
},
|
||||
"resource": {
|
||||
"routers": "",
|
||||
"services": "",
|
||||
"middlewares": ""
|
||||
"routers": "Routery",
|
||||
"services": "Usługi",
|
||||
"middlewares": "Middleware"
|
||||
},
|
||||
"status": {
|
||||
"healthy": "",
|
||||
"errors": "",
|
||||
"warnings": ""
|
||||
"healthy": "Dobry",
|
||||
"errors": "{count, plural, one {<b>#</b> błąd} few {<b>#</b> błędy} many {<b>#</b> błędów} other {<b>#</b> błędów}}",
|
||||
"warnings": "{count, plural, one {<b>#</b> ostrzeżenie} few {<b>#</b> ostrzeżenia} many {<b>#</b> ostrzeżeń} other {<b>#</b> ostrzeżeń}}"
|
||||
},
|
||||
"error": {
|
||||
"internalServerError": ""
|
||||
"internalServerError": "Nie udało się pobrać danych Traefik"
|
||||
}
|
||||
},
|
||||
"audioStats": {
|
||||
@@ -3853,9 +3880,9 @@
|
||||
"label": "Pokaż pasek wykorzystania w tle"
|
||||
},
|
||||
"visibleStorageVolumes": {
|
||||
"label": "",
|
||||
"description": "",
|
||||
"placeholder": ""
|
||||
"label": "Widoczne woluminy pamięci",
|
||||
"description": "Dostępne tylko gdy wszystkie wybrane integracje to Synology. Pozostaw puste, aby wyświetlić wszystkie wykryte woluminy pamięci.",
|
||||
"placeholder": "Wybierz woluminy pamięci"
|
||||
}
|
||||
},
|
||||
"status": {
|
||||
@@ -4101,9 +4128,9 @@
|
||||
"write": "Zapis"
|
||||
},
|
||||
"storage": {
|
||||
"title": "",
|
||||
"subtitle": "",
|
||||
"series": ""
|
||||
"title": "Pamięć",
|
||||
"subtitle": "Użycie dysku według systemu plików",
|
||||
"series": "Używane"
|
||||
},
|
||||
"network": {
|
||||
"title": "Przepustowość",
|
||||
@@ -5238,7 +5265,7 @@
|
||||
"table": {
|
||||
"updated": "Zaktualizowano {when}",
|
||||
"refresh": {
|
||||
"lastUpdated": ""
|
||||
"lastUpdated": "Ostatnie odświeżenie {when}"
|
||||
},
|
||||
"search": "Szukaj wśród {count} kontenerów",
|
||||
"selected": "Wybrano {selectCount} z {totalCount} kontenerów",
|
||||
@@ -5969,10 +5996,10 @@
|
||||
}
|
||||
},
|
||||
"enableRightClickOnWidgets": {
|
||||
"label": "",
|
||||
"label": "Włącz prawe kliknięcie na widżetach",
|
||||
"children": {
|
||||
"detail": {
|
||||
"title": ""
|
||||
"title": "Włącz prawe kliknięcie na widżetach"
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
File diff suppressed because it is too large.
Load diff
+1470
-1443
File diff suppressed because it is too large.
Load diff
File diff suppressed because it is too large.
Load diff
File diff suppressed because it is too large.
Load diff
File diff suppressed because it is too large.
Load diff
File diff suppressed because it is too large.
Load diff
File diff suppressed because it is too large.
Load diff
File diff suppressed because it is too large.
Load diff
+1782
-1755
File diff suppressed because it is too large.
Load diff
File diff suppressed because it is too large.
Load diff
File diff suppressed because it is too large.
Load diff
@@ -1,8 +1,7 @@
|
||||
"use client";
|
||||
|
||||
import type { CSSProperties } from "react";
|
||||
import { Badge, Text } from "@mantine/core";
|
||||
import { IconHeadphones } from "@tabler/icons-react";
|
||||
import { Text } from "@mantine/core";
|
||||
|
||||
import type { AudiobookshelfDashboardData, NavidromeDashboardData } from "@homarr/integrations/types";
|
||||
import { useScopedI18n } from "@homarr/translation/client";
|
||||
@@ -40,29 +39,6 @@ export function AudioStatsContent({ backend, stats, options, width }: AudioStats
|
||||
const gridCols = getGridCols(width, visibleStats.length, options.compactMode ?? false);
|
||||
const iconSize = getIconSize(width, options.compactMode ?? false);
|
||||
|
||||
const navidromeStatsByBackend: Record<AudioStatsBackend, NavidromeDashboardData | null> = {
|
||||
navidrome: stats as NavidromeDashboardData,
|
||||
audiobookshelf: null,
|
||||
};
|
||||
const navidromeStats = navidromeStatsByBackend[backend];
|
||||
const showNowPlayingSection =
|
||||
navidromeStats !== null && Boolean(options.showNowPlaying) && navidromeStats.nowPlaying.length > 0;
|
||||
|
||||
const nowPlayingLimitByListVisibility = {
|
||||
true: options.maxNowPlayingItems ?? 3,
|
||||
false: 0,
|
||||
} as const;
|
||||
|
||||
const nowPlayingTracks =
|
||||
navidromeStats?.nowPlaying.slice(
|
||||
0,
|
||||
nowPlayingLimitByListVisibility[
|
||||
String(options.showNowPlayingList) as keyof typeof nowPlayingLimitByListVisibility
|
||||
],
|
||||
) ?? [];
|
||||
|
||||
const hasContent = visibleStats.length > 0 || showNowPlayingSection;
|
||||
|
||||
return (
|
||||
<div className={`${classes.root} ${rootClassByCompact[compactKey]}`}>
|
||||
{visibleStats.length > 0 && (
|
||||
@@ -80,40 +56,7 @@ export function AudioStatsContent({ backend, stats, options, width }: AudioStats
|
||||
</div>
|
||||
)}
|
||||
|
||||
{showNowPlayingSection && navidromeStats && (
|
||||
<div className={classes.nowPlaying}>
|
||||
<div className={classes.nowPlayingHeader}>
|
||||
<IconHeadphones size={iconSize} stroke={1.5} />
|
||||
<span className={classes.nowPlayingTitle}>{t("nowPlaying" as never)}</span>
|
||||
{!options.showNowPlayingList && (
|
||||
<Badge className={classes.nowPlayingCount} variant="light" size="sm">
|
||||
{(t as unknown as (key: string, params?: { count: number }) => string)("nowPlayingCount", {
|
||||
count: navidromeStats.nowPlaying.length,
|
||||
})}
|
||||
</Badge>
|
||||
)}
|
||||
</div>
|
||||
{options.showNowPlayingList && (
|
||||
<div className={classes.nowPlayingList}>
|
||||
{nowPlayingTracks.map((track, index) => (
|
||||
<div key={`${track.username}-${track.title}-${index}`} className={classes.nowPlayingItem}>
|
||||
<div className={classes.trackInfo}>
|
||||
<span className={classes.trackTitle}>{track.title}</span>
|
||||
<span className={classes.trackArtist}>
|
||||
{[track.artist, track.album].filter(Boolean).join(" · ")}
|
||||
</span>
|
||||
</div>
|
||||
<Badge className={classes.trackUser} variant="outline" size="xs">
|
||||
{track.username || track.playerName}
|
||||
</Badge>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
)}
|
||||
|
||||
{!hasContent && (
|
||||
{visibleStats.length === 0 && (
|
||||
<div className={classes.emptyState}>
|
||||
<Text size="sm" c="dimmed">
|
||||
—
|
||||
|
||||
@@ -42,7 +42,6 @@ describe("getVisibleStats", () => {
|
||||
artistCount: 100,
|
||||
albumCount: 200,
|
||||
songCount: 3000,
|
||||
nowPlaying: [],
|
||||
};
|
||||
|
||||
const audiobookshelfStats: AudiobookshelfDashboardData = {
|
||||
|
||||
@@ -87,92 +87,6 @@
|
||||
font-size: clamp(11px, 4cqi, 16px);
|
||||
}
|
||||
|
||||
.nowPlaying {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: clamp(3px, 1.2cqi, 5px);
|
||||
flex: 1;
|
||||
min-height: 0;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.nowPlayingHeader {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: clamp(4px, 1.5cqi, 6px);
|
||||
font-size: clamp(10px, 2.8cqi, 12px);
|
||||
font-weight: 600;
|
||||
flex-shrink: 0;
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
.nowPlayingTitle {
|
||||
min-width: 0;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.nowPlayingCount {
|
||||
flex-shrink: 0;
|
||||
margin-inline-start: auto;
|
||||
}
|
||||
|
||||
.nowPlayingList {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: clamp(2px, 0.8cqi, 4px);
|
||||
flex: 1;
|
||||
min-height: 0;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.nowPlayingItem {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
gap: clamp(4px, 1.5cqi, 6px);
|
||||
padding: clamp(3px, 1.2cqi, 6px) clamp(4px, 1.5cqi, 8px);
|
||||
border-radius: var(--mantine-radius-sm);
|
||||
background-color: light-dark(var(--mantine-color-gray-0), var(--mantine-color-dark-6));
|
||||
min-width: 0;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.trackInfo {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 1px;
|
||||
min-width: 0;
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.trackTitle {
|
||||
font-size: clamp(9px, 2.6cqi, 12px);
|
||||
font-weight: 500;
|
||||
line-height: 1.2;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.trackArtist {
|
||||
font-size: clamp(8px, 2.2cqi, 10px);
|
||||
color: var(--mantine-color-dimmed);
|
||||
line-height: 1.2;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.trackUser {
|
||||
flex-shrink: 0;
|
||||
max-width: clamp(40px, 22cqi, 88px);
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.emptyState {
|
||||
display: flex;
|
||||
flex: 1;
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
import { IconHeadphones, IconServerOff } from "@tabler/icons-react";
|
||||
import { z } from "zod/v4";
|
||||
|
||||
import { createWidgetDefinition } from "../definition";
|
||||
import { optionsBuilder } from "../options";
|
||||
@@ -23,14 +22,6 @@ export const { definition, componentLoader } = createWidgetDefinition("audioStat
|
||||
showArtists: factory.switch({ defaultValue: true, withDescription: true }),
|
||||
showAlbums: factory.switch({ defaultValue: true, withDescription: true }),
|
||||
showSongs: factory.switch({ defaultValue: true, withDescription: true }),
|
||||
showNowPlaying: factory.switch({ defaultValue: true, withDescription: true }),
|
||||
showNowPlayingList: factory.switch({ defaultValue: true, withDescription: true }),
|
||||
maxNowPlayingItems: factory.number({
|
||||
defaultValue: 3,
|
||||
validate: z.number().min(1).max(5),
|
||||
step: 1,
|
||||
withDescription: true,
|
||||
}),
|
||||
showLibraryCount: factory.switch({ defaultValue: true, withDescription: true }),
|
||||
showAudiobooks: factory.switch({ defaultValue: true, withDescription: true }),
|
||||
showPodcasts: factory.switch({ defaultValue: true, withDescription: true }),
|
||||
@@ -42,9 +33,6 @@ export const { definition, componentLoader } = createWidgetDefinition("audioStat
|
||||
showArtists: hideUnlessNavidrome,
|
||||
showAlbums: hideUnlessNavidrome,
|
||||
showSongs: hideUnlessNavidrome,
|
||||
showNowPlaying: hideUnlessNavidrome,
|
||||
showNowPlayingList: hideUnlessNavidrome,
|
||||
maxNowPlayingItems: hideUnlessNavidrome,
|
||||
showLibraryCount: hideUnlessAudiobookshelf,
|
||||
showAudiobooks: hideUnlessAudiobookshelf,
|
||||
showPodcasts: hideUnlessAudiobookshelf,
|
||||
|
||||
@@ -19,9 +19,6 @@ export interface NavidromeDisplayOptions {
|
||||
showArtists: boolean;
|
||||
showAlbums: boolean;
|
||||
showSongs: boolean;
|
||||
showNowPlaying: boolean;
|
||||
showNowPlayingList: boolean;
|
||||
maxNowPlayingItems: number;
|
||||
compactMode?: boolean;
|
||||
}
|
||||
|
||||
|
||||
@@ -1 +1 @@
|
||||
[{"login":"ajnart","avatar_url":"https://avatars.githubusercontent.com/u/49837342?v=4"},{"login":"manuel-rw","avatar_url":"https://avatars.githubusercontent.com/u/30572287?v=4"},{"login":"Meierschlumpf","avatar_url":"https://avatars.githubusercontent.com/u/63781622?v=4"},{"login":"SeDemal","avatar_url":"https://avatars.githubusercontent.com/u/26098587?v=4"},{"login":"lammersbjorn","avatar_url":"https://avatars.githubusercontent.com/u/71191962?v=4"},{"login":"LarveyOfficial","avatar_url":"https://avatars.githubusercontent.com/u/39219859?v=4"},{"login":"c00ldude1oo","avatar_url":"https://avatars.githubusercontent.com/u/15677803?v=4"},{"login":"InterN0te","avatar_url":"https://avatars.githubusercontent.com/u/10882916?v=4"},{"login":"Aimsucks","avatar_url":"https://avatars.githubusercontent.com/u/1828486?v=4"},{"login":"JannesV","avatar_url":"https://avatars.githubusercontent.com/u/5984244?v=4"},{"login":"MauriceNino","avatar_url":"https://avatars.githubusercontent.com/u/18658092?v=4"},{"login":"hillaliy","avatar_url":"https://avatars.githubusercontent.com/u/950010?v=4"},{"login":"Skeeww","avatar_url":"https://avatars.githubusercontent.com/u/9639992?v=4"},{"login":"RichyHBM","avatar_url":"https://avatars.githubusercontent.com/u/5472275?v=4"},{"login":"Bonfire","avatar_url":"https://avatars.githubusercontent.com/u/5704760?v=4"},{"login":"wieli99","avatar_url":"https://avatars.githubusercontent.com/u/46794825?v=4"},{"login":"ishaanparlikar","avatar_url":"https://avatars.githubusercontent.com/u/43013132?v=4"},{"login":"Zareix","avatar_url":"https://avatars.githubusercontent.com/u/29818713?v=4"},{"login":"tuggan","avatar_url":"https://avatars.githubusercontent.com/u/4325608?v=4"},{"login":"Spillebulle","avatar_url":"https://avatars.githubusercontent.com/u/46653946?v=4"},{"login":"marektancak0106","avatar_url":"https://avatars.githubusercontent.com/u/25422667?v=4"},{"login":"spkesDE","avatar_url":"https://avatars.githubusercontent.com/u/1682314?v=4"},{"login":"j3lte","avatar_url":"https://avatars.githubusercontent.com/u/2557568?v=4"},{"login":"dslatt","avatar_url":"https://avatars.githubusercontent.com/u/5211001?v=4"},{"login":"Malong11-007","avatar_url":"https://avatars.githubusercontent.com/u/40298510?v=4"},{"login":"StefanB7","avatar_url":"https://avatars.githubusercontent.com/u/22056509?v=4"},{"login":"souravghosh01","avatar_url":"https://avatars.githubusercontent.com/u/37548139?v=4"},{"login":"SR3u","avatar_url":"https://avatars.githubusercontent.com/u/2380522?v=4"},{"login":"Rikpat","avatar_url":"https://avatars.githubusercontent.com/u/33869814?v=4"},{"login":"NormanJS","avatar_url":"https://avatars.githubusercontent.com/u/83409549?v=4"},{"login":"No-Maines-Land","avatar_url":"https://avatars.githubusercontent.com/u/20687725?v=4"},{"login":"stark1tty","avatar_url":"https://avatars.githubusercontent.com/u/69326376?v=4"},{"login":"Momcilo42","avatar_url":"https://avatars.githubusercontent.com/u/10118137?v=4"},{"login":"marius-arch","avatar_url":"https://avatars.githubusercontent.com/u/72494359?v=4"},{"login":"Lumilias","avatar_url":"https://avatars.githubusercontent.com/u/10852161?v=4"},{"login":"Havock94","avatar_url":"https://avatars.githubusercontent.com/u/7635248?v=4"},{"login":"Lollyde","avatar_url":"https://avatars.githubusercontent.com/u/11347524?v=4"},{"login":"krishnamuppaneni","avatar_url":"https://avatars.githubusercontent.com/u/4703366?v=4"},{"login":"devtobi","avatar_url":"https://avatars.githubusercontent.com/u/28538704?v=4"},{"login":"TyxTang","avatar_url":"https://avatars.githubusercontent.com/u/90897955?v=4"},{"login":"beanbag420","avatar_url":"https://avatars.githubusercontent.com/u/19630511?v=4"},{"login":"WillyJL","avatar_url":"https://avatars.githubusercontent.com/u/49810075?v=4"},{"login":"anonysoul","avatar_url":"https://avatars.githubusercontent.com/u/105715150?v=4"},{"login":"cospeedster","avatar_url":"https://avatars.githubusercontent.com/u/52749645?v=4"},{"login":"diederbert","avatar_url":"https://avatars.githubusercontent.com/u/162878798?v=4"},{"login":"digdilem","avatar_url":"https://avatars.githubusercontent.com/u/4052275?v=4"},{"login":"dinghino","avatar_url":"https://avatars.githubusercontent.com/u/14729459?v=4"},{"login":"gfomichev","avatar_url":"https://avatars.githubusercontent.com/u/1596146?v=4"},{"login":"gnattu","avatar_url":"https://avatars.githubusercontent.com/u/12995396?v=4"},{"login":"tuxpizza","avatar_url":"https://avatars.githubusercontent.com/u/84710786?v=4"},{"login":"xmarkurion","avatar_url":"https://avatars.githubusercontent.com/u/46654687?v=4"},{"login":"huanga","avatar_url":"https://avatars.githubusercontent.com/u/732970?v=4"},{"login":"taos15","avatar_url":"https://avatars.githubusercontent.com/u/122130728?v=4"},{"login":"arghyadipchak","avatar_url":"https://avatars.githubusercontent.com/u/32430374?v=4"},{"login":"AuthorShin","avatar_url":"https://avatars.githubusercontent.com/u/4959043?v=4"},{"login":"benniblot","avatar_url":"https://avatars.githubusercontentLine truncated
|
||||
[{"login":"ajnart","avatar_url":"https://avatars.githubusercontent.com/u/49837342?v=4"},{"login":"manuel-rw","avatar_url":"https://avatars.githubusercontent.com/u/30572287?v=4"},{"login":"Meierschlumpf","avatar_url":"https://avatars.githubusercontent.com/u/63781622?v=4"},{"login":"SeDemal","avatar_url":"https://avatars.githubusercontent.com/u/26098587?v=4"},{"login":"lammersbjorn","avatar_url":"https://avatars.githubusercontent.com/u/71191962?v=4"},{"login":"LarveyOfficial","avatar_url":"https://avatars.githubusercontent.com/u/39219859?v=4"},{"login":"c00ldude1oo","avatar_url":"https://avatars.githubusercontent.com/u/15677803?v=4"},{"login":"InterN0te","avatar_url":"https://avatars.githubusercontent.com/u/10882916?v=4"},{"login":"Aimsucks","avatar_url":"https://avatars.githubusercontent.com/u/1828486?v=4"},{"login":"JannesV","avatar_url":"https://avatars.githubusercontent.com/u/5984244?v=4"},{"login":"MauriceNino","avatar_url":"https://avatars.githubusercontent.com/u/18658092?v=4"},{"login":"hillaliy","avatar_url":"https://avatars.githubusercontent.com/u/950010?v=4"},{"login":"Skeeww","avatar_url":"https://avatars.githubusercontent.com/u/9639992?v=4"},{"login":"RichyHBM","avatar_url":"https://avatars.githubusercontent.com/u/5472275?v=4"},{"login":"Bonfire","avatar_url":"https://avatars.githubusercontent.com/u/5704760?v=4"},{"login":"wieli99","avatar_url":"https://avatars.githubusercontent.com/u/46794825?v=4"},{"login":"ishaanparlikar","avatar_url":"https://avatars.githubusercontent.com/u/43013132?v=4"},{"login":"Zareix","avatar_url":"https://avatars.githubusercontent.com/u/29818713?v=4"},{"login":"tuggan","avatar_url":"https://avatars.githubusercontent.com/u/4325608?v=4"},{"login":"Spillebulle","avatar_url":"https://avatars.githubusercontent.com/u/46653946?v=4"},{"login":"marektancak0106","avatar_url":"https://avatars.githubusercontent.com/u/25422667?v=4"},{"login":"spkesDE","avatar_url":"https://avatars.githubusercontent.com/u/1682314?v=4"},{"login":"j3lte","avatar_url":"https://avatars.githubusercontent.com/u/2557568?v=4"},{"login":"dslatt","avatar_url":"https://avatars.githubusercontent.com/u/5211001?v=4"},{"login":"Malong11-007","avatar_url":"https://avatars.githubusercontent.com/u/40298510?v=4"},{"login":"StefanB7","avatar_url":"https://avatars.githubusercontent.com/u/22056509?v=4"},{"login":"souravghosh01","avatar_url":"https://avatars.githubusercontent.com/u/37548139?v=4"},{"login":"SR3u","avatar_url":"https://avatars.githubusercontent.com/u/2380522?v=4"},{"login":"Rikpat","avatar_url":"https://avatars.githubusercontent.com/u/33869814?v=4"},{"login":"NormanJS","avatar_url":"https://avatars.githubusercontent.com/u/83409549?v=4"},{"login":"No-Maines-Land","avatar_url":"https://avatars.githubusercontent.com/u/20687725?v=4"},{"login":"stark1tty","avatar_url":"https://avatars.githubusercontent.com/u/69326376?v=4"},{"login":"Momcilo42","avatar_url":"https://avatars.githubusercontent.com/u/10118137?v=4"},{"login":"marius-arch","avatar_url":"https://avatars.githubusercontent.com/u/72494359?v=4"},{"login":"Lumilias","avatar_url":"https://avatars.githubusercontent.com/u/10852161?v=4"},{"login":"Havock94","avatar_url":"https://avatars.githubusercontent.com/u/7635248?v=4"},{"login":"Lollyde","avatar_url":"https://avatars.githubusercontent.com/u/11347524?v=4"},{"login":"krishnamuppaneni","avatar_url":"https://avatars.githubusercontent.com/u/4703366?v=4"},{"login":"devtobi","avatar_url":"https://avatars.githubusercontent.com/u/28538704?v=4"},{"login":"TyxTang","avatar_url":"https://avatars.githubusercontent.com/u/90897955?v=4"},{"login":"beanbag420","avatar_url":"https://avatars.githubusercontent.com/u/19630511?v=4"},{"login":"WillyJL","avatar_url":"https://avatars.githubusercontent.com/u/49810075?v=4"},{"login":"anonysoul","avatar_url":"https://avatars.githubusercontent.com/u/105715150?v=4"},{"login":"cospeedster","avatar_url":"https://avatars.githubusercontent.com/u/52749645?v=4"},{"login":"diederbert","avatar_url":"https://avatars.githubusercontent.com/u/162878798?v=4"},{"login":"digdilem","avatar_url":"https://avatars.githubusercontent.com/u/4052275?v=4"},{"login":"dinghino","avatar_url":"https://avatars.githubusercontent.com/u/14729459?v=4"},{"login":"gfomichev","avatar_url":"https://avatars.githubusercontent.com/u/1596146?v=4"},{"login":"gnattu","avatar_url":"https://avatars.githubusercontent.com/u/12995396?v=4"},{"login":"tuxpizza","avatar_url":"https://avatars.githubusercontent.com/u/84710786?v=4"},{"login":"xmarkurion","avatar_url":"https://avatars.githubusercontent.com/u/46654687?v=4"},{"login":"huanga","avatar_url":"https://avatars.githubusercontent.com/u/732970?v=4"},{"login":"taos15","avatar_url":"https://avatars.githubusercontent.com/u/122130728?v=4"},{"login":"arghyadipchak","avatar_url":"https://avatars.githubusercontent.com/u/32430374?v=4"},{"login":"AuthorShin","avatar_url":"https://avatars.githubusercontent.com/u/4959043?v=4"},{"login":"benniblot","avatar_url":"https://avatars.githubusercontentLine truncated
|
||||
@@ -1 +1 @@
|
||||
[{"id":"zaxon793-jy8gpl0v-d89pbrkd-emwl5v04","name":"Mike","slug":"guest-5da646e8","imageUrl":"https://images.opencollective.com/guest-5da646e8/avatar.png"},{"id":"ywz9j4av-god8pgwg-db36mr35-nxklb0e7","name":"Guest","slug":"guest-554ec68f","imageUrl":"https://images.opencollective.com/guest-554ec68f/avatar.png"},{"id":"mlo94zn7-x08dpo09-xlxpewga-3vjbrky5","name":"Robert Hermann","slug":"robert-hermann","imageUrl":"https://images.opencollective.com/robert-hermann/avatar.png"},{"id":"zaxon793-jy8gpl0n-8r3pbrkd-emwl5v04","name":"Sebastian Raubuch","slug":"sebastian-raubuch","imageUrl":"https://images.opencollective.com/sebastian-raubuch/avatar.png"},{"id":"nmlo94zn-7x08dpod-ykm6ewga-3vjbrky5","name":"Didier LUTHI","slug":"didier-luthi","imageUrl":"https://images.opencollective.com/didier-luthi/avatar.png"},{"id":"vedj9wro-z3a56dgk-z3z67blg-8x4m0ykn","name":"Guest","slug":"guest-b1459a68","imageUrl":"https://images.opencollective.com/guest-b1459a68/avatar.png"},{"id":"gm9bnk80-437xqry4-8vepvzeo-ljdayw5r","name":"Mohister","slug":"mohister","imageUrl":"https://images.opencollective.com/mohister/1d8a592/avatar.png"},{"id":"vrgbk357-l4x96e70-m0apomew-a0jdyzn8","name":"sidens","slug":"sidens","imageUrl":"https://images.opencollective.com/sidens/avatar.png"},{"id":"mlo94zn7-x08dpo0d-l7epewga-3vjbrky5","name":"Chris","slug":"guest-937065bb","imageUrl":"https://images.opencollective.com/guest-937065bb/avatar.png"},{"id":"k9mbw7y4-8r3zq3ol-7zlq0ej5-lavnodgx","name":"Nick W","slug":"guest-7501840a","imageUrl":"https://images.opencollective.com/guest-7501840a/avatar.png"},{"id":"e0adkjrv-8xwm69o8-5al67z5n-4l93bgoy","name":"Jeppedy","slug":"guest-ab78e46a","imageUrl":"https://images.opencollective.com/guest-ab78e46a/avatar.png"},{"id":"a47byg9n-xozdp8xo-jgm6mjlv-03rek5w8","name":"naru","slug":"guest-02fd264a","imageUrl":"https://images.opencollective.com/guest-02fd264a/avatar.png"},{"id":"3k0exgzn-m8yj64g3-ll865wao-9r7b4dlv","name":"Jared Hocutt","slug":"jared-hocutt","imageUrl":"https://images.opencollective.com/jared-hocutt/avatar.png"},{"id":"eng0kzdy-vor4pz8l-exopbma8-37xlw95j","name":"Incognito","slug":"user-e63f4a5b","imageUrl":"https://images.opencollective.com/user-e63f4a5b/avatar.png"},{"id":"8k03reyd-5agmq50v-8vyplbwo-z7j4nxv9","name":"dazi","slug":"guest-11663a46","imageUrl":"https://images.opencollective.com/guest-11663a46/avatar.png"},{"id":"vedj9wro-z3a56dgd-zwl67blg-8x4m0ykn","name":"ZoopaMario","slug":"zoopamario","imageUrl":"https://images.opencollective.com/zoopamario/bea900d/avatar.png"},{"id":"a47byg9n-xozdp8xe-xmb6mjlv-03rek5w8","name":"FlamebergUA","slug":"guest-a59fd500","imageUrl":"https://images.opencollective.com/guest-a59fd500/avatar.png"},{"id":"8k03reyd-5agmq50y-kzoplbwo-z7j4nxv9","name":"StLCards","slug":"guest-e1de33dc","imageUrl":"https://images.opencollective.com/guest-e1de33dc/avatar.png"},{"id":"ejoxl3az-45w9pa54-dk46y870-mgkbrvdn","name":"Varadha","slug":"guest-6f68eed9","imageUrl":"https://images.opencollective.com/guest-6f68eed9/avatar.png"},{"id":"jrkx5lmn-v904qjl0-3oz68bwa-7zdygoe3","name":"Guest","slug":"guest-6da419b5","imageUrl":"https://images.opencollective.com/guest-6da419b5/avatar.png"},{"id":"mywxoz34-09rl6k3z-lmlqvenb-dj7gk85a","name":"Guest","slug":"guest-122d7e0a","imageUrl":"https://images.opencollective.com/guest-122d7e0a/avatar.png"},{"id":"3z8arxve-ymko60vm-3eaqgl5n-bj9w704d","name":"Ricardo","slug":"ricardo34","imageUrl":"https://images.opencollective.com/ricardo34/avatar.png"},{"id":"e0adkjrv-8xwm69or-reo67z5n-4l93bgoy","name":"GoM","slug":"guest-3944feab","imageUrl":"https://images.opencollective.com/guest-3944feab/avatar.png"},{"id":"gm9bnk80-437xqrnr-r5o6vzeo-ljdayw5r","name":"Brent Maxwell","slug":"brentmaxwell","imageUrl":"https://images.opencollective.com/brentmaxwell/avatar.png"},{"id":"gnxdwzj3-le5mpwzd-ll0py8rv-bko04a97","name":"Eric G","slug":"guest-478270f1","imageUrl":"https://images.opencollective.com/guest-478270f1/avatar.png"},{"id":"v349mrwg-z75lpyjo-ez8pa08d-jeybknox","name":"ninja","slug":"guest-0bb6ba36","imageUrl":"https://images.opencollective.com/guest-0bb6ba36/avatar.png"},{"id":"ywz9j4av-god8pgw0-53y6mr35-nxklb0e7","name":"s11","slug":"guest-6e9a2588","imageUrl":"https://images.opencollective.com/guest-6e9a2588/avatar.png"},{"id":"mlo94zn7-x08dpo30-v73pewga-3vjbrky5","name":"Incognito","slug":"user-cbad11af","imageUrl":"https://images.opencollective.com/user-cbad11af/avatar.png"},{"id":"v349mrwg-z75lpy7l-yzgpa08d-jeybknox","name":"Ronald Simmons","slug":"ronald-simmons","imageUrl":"https://images.opencollective.com/ronald-simmons/avatar.png"},{"id":"7ywz9j4a-vgod8pgl-me9qmr35-nxklb0e7","name":"Joel","slug":"guest-3376ab02","imageUrl":"https://images.opencollective.com/guest-3376ab02/avatar.png"},{"id":"v349mrwg-z75lpyjw-kxzpa08d-jeybknox","name":"Gokay Yamankurt","slug":"gokay-yamankurt","imageUrl":"https://images.opencollective.com/gokay-yamankurt/avatar.png"},{"id":"v349mrwg-z75lpyjv-59rpa08d-jeybknox","name":"Rhiz3K","slug":"rhiz3k","imagLine truncated
|
||||
[{"id":"zaxon793-jy8gpl0v-d89pbrkd-emwl5v04","name":"Mike","slug":"guest-5da646e8","imageUrl":"https://images.opencollective.com/guest-5da646e8/avatar.png"},{"id":"ywz9j4av-god8pgwg-db36mr35-nxklb0e7","name":"Guest","slug":"guest-554ec68f","imageUrl":"https://images.opencollective.com/guest-554ec68f/avatar.png"},{"id":"mlo94zn7-x08dpo09-xlxpewga-3vjbrky5","name":"Robert Hermann","slug":"robert-hermann","imageUrl":"https://images.opencollective.com/robert-hermann/avatar.png"},{"id":"zaxon793-jy8gpl0n-8r3pbrkd-emwl5v04","name":"Sebastian Raubuch","slug":"sebastian-raubuch","imageUrl":"https://images.opencollective.com/sebastian-raubuch/avatar.png"},{"id":"nmlo94zn-7x08dpod-ykm6ewga-3vjbrky5","name":"Didier LUTHI","slug":"didier-luthi","imageUrl":"https://images.opencollective.com/didier-luthi/avatar.png"},{"id":"vedj9wro-z3a56dgk-z3z67blg-8x4m0ykn","name":"Guest","slug":"guest-b1459a68","imageUrl":"https://images.opencollective.com/guest-b1459a68/avatar.png"},{"id":"gm9bnk80-437xqry4-8vepvzeo-ljdayw5r","name":"Mohister","slug":"mohister","imageUrl":"https://images.opencollective.com/mohister/1d8a592/avatar.png"},{"id":"vrgbk357-l4x96e70-m0apomew-a0jdyzn8","name":"sidens","slug":"sidens","imageUrl":"https://images.opencollective.com/sidens/avatar.png"},{"id":"mlo94zn7-x08dpo0d-l7epewga-3vjbrky5","name":"Chris","slug":"guest-937065bb","imageUrl":"https://images.opencollective.com/guest-937065bb/avatar.png"},{"id":"k9mbw7y4-8r3zq3ol-7zlq0ej5-lavnodgx","name":"Nick W","slug":"guest-7501840a","imageUrl":"https://images.opencollective.com/guest-7501840a/avatar.png"},{"id":"e0adkjrv-8xwm69o8-5al67z5n-4l93bgoy","name":"Jeppedy","slug":"guest-ab78e46a","imageUrl":"https://images.opencollective.com/guest-ab78e46a/avatar.png"},{"id":"a47byg9n-xozdp8xo-jgm6mjlv-03rek5w8","name":"naru","slug":"guest-02fd264a","imageUrl":"https://images.opencollective.com/guest-02fd264a/avatar.png"},{"id":"3k0exgzn-m8yj64g3-ll865wao-9r7b4dlv","name":"Jared Hocutt","slug":"jared-hocutt","imageUrl":"https://images.opencollective.com/jared-hocutt/avatar.png"},{"id":"eng0kzdy-vor4pz8l-exopbma8-37xlw95j","name":"Incognito","slug":"user-e63f4a5b","imageUrl":"https://images.opencollective.com/user-e63f4a5b/avatar.png"},{"id":"8k03reyd-5agmq50v-8vyplbwo-z7j4nxv9","name":"dazi","slug":"guest-11663a46","imageUrl":"https://images.opencollective.com/guest-11663a46/avatar.png"},{"id":"vedj9wro-z3a56dgd-zwl67blg-8x4m0ykn","name":"ZoopaMario","slug":"zoopamario","imageUrl":"https://images.opencollective.com/zoopamario/bea900d/avatar.png"},{"id":"a47byg9n-xozdp8xe-xmb6mjlv-03rek5w8","name":"FlamebergUA","slug":"guest-a59fd500","imageUrl":"https://images.opencollective.com/guest-a59fd500/avatar.png"},{"id":"8k03reyd-5agmq50y-kzoplbwo-z7j4nxv9","name":"StLCards","slug":"guest-e1de33dc","imageUrl":"https://images.opencollective.com/guest-e1de33dc/avatar.png"},{"id":"ejoxl3az-45w9pa54-dk46y870-mgkbrvdn","name":"Varadha","slug":"guest-6f68eed9","imageUrl":"https://images.opencollective.com/guest-6f68eed9/avatar.png"},{"id":"jrkx5lmn-v904qjl0-3oz68bwa-7zdygoe3","name":"Guest","slug":"guest-6da419b5","imageUrl":"https://images.opencollective.com/guest-6da419b5/avatar.png"},{"id":"mywxoz34-09rl6k3z-lmlqvenb-dj7gk85a","name":"Guest","slug":"guest-122d7e0a","imageUrl":"https://images.opencollective.com/guest-122d7e0a/avatar.png"},{"id":"3z8arxve-ymko60vm-3eaqgl5n-bj9w704d","name":"Ricardo","slug":"ricardo34","imageUrl":"https://images.opencollective.com/ricardo34/avatar.png"},{"id":"e0adkjrv-8xwm69or-reo67z5n-4l93bgoy","name":"GoM","slug":"guest-3944feab","imageUrl":"https://images.opencollective.com/guest-3944feab/avatar.png"},{"id":"gm9bnk80-437xqrnr-r5o6vzeo-ljdayw5r","name":"Brent Maxwell","slug":"brentmaxwell","imageUrl":"https://images.opencollective.com/brentmaxwell/avatar.png"},{"id":"gnxdwzj3-le5mpwzd-ll0py8rv-bko04a97","name":"Eric G","slug":"guest-478270f1","imageUrl":"https://images.opencollective.com/guest-478270f1/avatar.png"},{"id":"v349mrwg-z75lpyjo-ez8pa08d-jeybknox","name":"ninja","slug":"guest-0bb6ba36","imageUrl":"https://images.opencollective.com/guest-0bb6ba36/avatar.png"},{"id":"ywz9j4av-god8pgw0-53y6mr35-nxklb0e7","name":"s11","slug":"guest-6e9a2588","imageUrl":"https://images.opencollective.com/guest-6e9a2588/avatar.png"},{"id":"mlo94zn7-x08dpo30-v73pewga-3vjbrky5","name":"Incognito","slug":"user-cbad11af","imageUrl":"https://images.opencollective.com/user-cbad11af/avatar.png"},{"id":"v349mrwg-z75lpy7l-yzgpa08d-jeybknox","name":"Ronald Simmons","slug":"ronald-simmons","imageUrl":"https://images.opencollective.com/ronald-simmons/avatar.png"},{"id":"7ywz9j4a-vgod8pgl-me9qmr35-nxklb0e7","name":"Joel","slug":"guest-3376ab02","imageUrl":"https://images.opencollective.com/guest-3376ab02/avatar.png"},{"id":"v349mrwg-z75lpyjw-kxzpa08d-jeybknox","name":"Gokay Yamankurt","slug":"gokay-yamankurt","imageUrl":"https://images.opencollective.com/gokay-yamankurt/avatar.png"},{"id":"v349mrwg-z75lpyjv-59rpa08d-jeybknox","name":"Rhiz3K","slug":"rhiz3k","imagLine truncated
|
||||
@@ -1 +1 @@
|
||||
[{"username":"carlchina","avatarUrl":"https://crowdin-static.cf-downloads.crowdin.com/avatar/6697/medium/d22bbe7797bbeb30dbdc73a5648d329a_default.png"},{"username":"zielmann","avatarUrl":"https://crowdin-static.cf-downloads.crowdin.com/avatar/7795/medium/ad22b8b8d5eb33e4154d53a454c862fd_default.png"},{"username":"Thalyn","avatarUrl":"https://crowdin-static.cf-downloads.crowdin.com/avatar/12494028/medium/5faf5acc945a874ed116c4567edaa09f_default.png"},{"username":"magnushj","avatarUrl":"https://crowdin-static.cf-downloads.crowdin.com/avatar/12503488/medium/68f32e33ea7b891960055c9f831f7344_default.png"},{"username":"almontegil","avatarUrl":"https://crowdin-static.cf-downloads.crowdin.com/avatar/12580457/medium/f4136cacbdfdb4c28ae7f85dc5f840db_default.png"},{"username":"andibing","avatarUrl":"https://crowdin-static.cf-downloads.crowdin.com/avatar/12664938/medium/b8be63e4dcb2e791ced1ffc9e3a049a5.jpg"},{"username":"gronare","avatarUrl":"https://crowdin-static.cf-downloads.crowdin.com/avatar/12680911/medium/c6eb14d1504156f34a158e507f73aa3d_default.png"},{"username":"SmartPhoneLover","avatarUrl":"https://crowdin-static.cf-downloads.crowdin.com/avatar/12701640/medium/ec95486662ec875cda080e778c3ff702.jpg"},{"username":"marcelotk_15","avatarUrl":"https://crowdin-static.cf-downloads.crowdin.com/avatar/12773227/medium/ecf6bea16ab0c873c131df2154ee9718_default.png"},{"username":"S3OD177","avatarUrl":"https://crowdin-static.cf-downloads.crowdin.com/avatar/13051544/medium/11dd990837f61f7e8f7d36b041a7fddb_default.png"},{"username":"marcg","avatarUrl":"https://crowdin-static.cf-downloads.crowdin.com/avatar/13153301/medium/ebcf60fbf27deb148ec40a659566c6ff_default.png"},{"username":"BeersTeddy","avatarUrl":"https://crowdin-static.cf-downloads.crowdin.com/avatar/13185230/medium/2f1f4e1effe74a23422b195cbefb2a95_default.png"},{"username":"jamesmcmahon0","avatarUrl":"https://crowdin-static.cf-downloads.crowdin.com/avatar/13245578/medium/586aa873b4abddbd9abc6f3de99ab70e.jpeg"},{"username":"b1nar10","avatarUrl":"https://crowdin-static.cf-downloads.crowdin.com/avatar/13286752/medium/aaa1f083e04c572f953fde4563171e4a.jpeg"},{"username":"vannCN","avatarUrl":"https://crowdin-static.cf-downloads.crowdin.com/avatar/13330448/medium/9b8a9ee3611e51e951e22d5fd4eb7d8d.jpg"},{"username":"binswm","avatarUrl":"https://crowdin-static.cf-downloads.crowdin.com/avatar/13343482/medium/45dde0e6097b9b72705d2eba9dbbc276_default.png"},{"username":"SkewRam","avatarUrl":"https://crowdin-static.cf-downloads.crowdin.com/avatar/13496556/medium/188f5c2deb7938eda51eb786cc4539ca.jpeg"},{"username":"raphcatarino","avatarUrl":"https://crowdin-static.cf-downloads.crowdin.com/avatar/13547726/medium/b003511e67df13a4b4b5689488fa8099.jpg"},{"username":"shillos5","avatarUrl":"https://crowdin-static.cf-downloads.crowdin.com/avatar/13600557/medium/b17650b2b84f829d54fa548c44c1ab27.jpeg"},{"username":"wolong98","avatarUrl":"https://crowdin-static.cf-downloads.crowdin.com/avatar/13641407/medium/f4634edc58c7857a357e5293543c15cf.jpg"},{"username":"spair0039","avatarUrl":"https://crowdin-static.cf-downloads.crowdin.com/avatar/14012333/medium/72430e96027c09c19141cac38eae4617.png"},{"username":"MajorMarcin","avatarUrl":"https://crowdin-static.cf-downloads.crowdin.com/avatar/14072183/medium/0a197e64bb92b6ea94cecbb607512c45.jpg"},{"username":"KosmoMoustache","avatarUrl":"https://crowdin-static.cf-downloads.crowdin.com/avatar/14103535/medium/51c438cdd9f86e8811c75f4869de479c.png"},{"username":"Soochaehwa","avatarUrl":"https://crowdin-static.cf-downloads.crowdin.com/avatar/14118689/medium/496a1ce63111547bf455a1e0a7ac75f1_default.png"},{"username":"garryfield","avatarUrl":"https://crowdin-static.cf-downloads.crowdin.com/avatar/14187035/medium/520c964706676045f6eeec1b08edc880.jpg"},{"username":"droidenko","avatarUrl":"https://crowdin-static.cf-downloads.crowdin.com/avatar/14444264/medium/4aa3a8e824f72bc9e5ec0d8de307095e.jpeg"},{"username":"maathis","avatarUrl":"https://crowdin-static.cf-downloads.crowdin.com/avatar/14489950/medium/6eeddf13a757ee35f78f1763f94d95e1.jpeg"},{"username":"bukvam","avatarUrl":"https://crowdin-static.cf-downloads.crowdin.com/avatar/14546502/medium/a819dc40a13c57395a17dc46e847d3ce.jpg"},{"username":"gm.cinalli","avatarUrl":"https://crowdin-static.cf-downloads.crowdin.com/avatar/14670666/medium/2d466a0fdbda40764526be86c97c0ab4.jpeg"},{"username":"antoine2tt","avatarUrl":"https://crowdin-static.cf-downloads.crowdin.com/avatar/14722148/medium/f88d926900862dd59007ea4b3419cb9d.png"},{"username":"cretzen","avatarUrl":"https://crowdin-static.cf-downloads.crowdin.com/avatar/14799754/medium/3ba5c1805ec20c000d5810c07985afe9.jpg"},{"username":"ktKongTong","avatarUrl":"https://crowdin-static.cf-downloads.crowdin.com/avatar/14817246/medium/97cfc3c028dbdaf85ebd1102da71e58c.jpeg"},{"username":"marinkaberg","avatarUrl":"https://crowdin-static.cf-downloads.crowdin.com/avatar/14861042/medium/2d5c4e62613f03082f3e645fa92efd59.jpeg"},{"username":"djismgaming","avatarUrl":"https://crowLine truncated
|
||||
[{"username":"carlchina","avatarUrl":"https://crowdin-static.cf-downloads.crowdin.com/avatar/6697/medium/d22bbe7797bbeb30dbdc73a5648d329a_default.png"},{"username":"zielmann","avatarUrl":"https://crowdin-static.cf-downloads.crowdin.com/avatar/7795/medium/ad22b8b8d5eb33e4154d53a454c862fd_default.png"},{"username":"Thalyn","avatarUrl":"https://crowdin-static.cf-downloads.crowdin.com/avatar/12494028/medium/5faf5acc945a874ed116c4567edaa09f_default.png"},{"username":"magnushj","avatarUrl":"https://crowdin-static.cf-downloads.crowdin.com/avatar/12503488/medium/68f32e33ea7b891960055c9f831f7344_default.png"},{"username":"almontegil","avatarUrl":"https://crowdin-static.cf-downloads.crowdin.com/avatar/12580457/medium/f4136cacbdfdb4c28ae7f85dc5f840db_default.png"},{"username":"andibing","avatarUrl":"https://crowdin-static.cf-downloads.crowdin.com/avatar/12664938/medium/b8be63e4dcb2e791ced1ffc9e3a049a5.jpg"},{"username":"gronare","avatarUrl":"https://crowdin-static.cf-downloads.crowdin.com/avatar/12680911/medium/c6eb14d1504156f34a158e507f73aa3d_default.png"},{"username":"SmartPhoneLover","avatarUrl":"https://crowdin-static.cf-downloads.crowdin.com/avatar/12701640/medium/ec95486662ec875cda080e778c3ff702.jpg"},{"username":"marcelotk_15","avatarUrl":"https://crowdin-static.cf-downloads.crowdin.com/avatar/12773227/medium/ecf6bea16ab0c873c131df2154ee9718_default.png"},{"username":"S3OD177","avatarUrl":"https://crowdin-static.cf-downloads.crowdin.com/avatar/13051544/medium/11dd990837f61f7e8f7d36b041a7fddb_default.png"},{"username":"marcg","avatarUrl":"https://crowdin-static.cf-downloads.crowdin.com/avatar/13153301/medium/ebcf60fbf27deb148ec40a659566c6ff_default.png"},{"username":"BeersTeddy","avatarUrl":"https://crowdin-static.cf-downloads.crowdin.com/avatar/13185230/medium/2f1f4e1effe74a23422b195cbefb2a95_default.png"},{"username":"jamesmcmahon0","avatarUrl":"https://crowdin-static.cf-downloads.crowdin.com/avatar/13245578/medium/586aa873b4abddbd9abc6f3de99ab70e.jpeg"},{"username":"b1nar10","avatarUrl":"https://crowdin-static.cf-downloads.crowdin.com/avatar/13286752/medium/aaa1f083e04c572f953fde4563171e4a.jpeg"},{"username":"vannCN","avatarUrl":"https://crowdin-static.cf-downloads.crowdin.com/avatar/13330448/medium/9b8a9ee3611e51e951e22d5fd4eb7d8d.jpg"},{"username":"binswm","avatarUrl":"https://crowdin-static.cf-downloads.crowdin.com/avatar/13343482/medium/45dde0e6097b9b72705d2eba9dbbc276_default.png"},{"username":"SkewRam","avatarUrl":"https://crowdin-static.cf-downloads.crowdin.com/avatar/13496556/medium/188f5c2deb7938eda51eb786cc4539ca.jpeg"},{"username":"raphcatarino","avatarUrl":"https://crowdin-static.cf-downloads.crowdin.com/avatar/13547726/medium/b003511e67df13a4b4b5689488fa8099.jpg"},{"username":"shillos5","avatarUrl":"https://crowdin-static.cf-downloads.crowdin.com/avatar/13600557/medium/b17650b2b84f829d54fa548c44c1ab27.jpeg"},{"username":"wolong98","avatarUrl":"https://crowdin-static.cf-downloads.crowdin.com/avatar/13641407/medium/f4634edc58c7857a357e5293543c15cf.jpg"},{"username":"spair0039","avatarUrl":"https://crowdin-static.cf-downloads.crowdin.com/avatar/14012333/medium/72430e96027c09c19141cac38eae4617.png"},{"username":"MajorMarcin","avatarUrl":"https://crowdin-static.cf-downloads.crowdin.com/avatar/14072183/medium/0a197e64bb92b6ea94cecbb607512c45.jpg"},{"username":"KosmoMoustache","avatarUrl":"https://crowdin-static.cf-downloads.crowdin.com/avatar/14103535/medium/51c438cdd9f86e8811c75f4869de479c.png"},{"username":"Soochaehwa","avatarUrl":"https://crowdin-static.cf-downloads.crowdin.com/avatar/14118689/medium/496a1ce63111547bf455a1e0a7ac75f1_default.png"},{"username":"garryfield","avatarUrl":"https://crowdin-static.cf-downloads.crowdin.com/avatar/14187035/medium/520c964706676045f6eeec1b08edc880.jpg"},{"username":"droidenko","avatarUrl":"https://crowdin-static.cf-downloads.crowdin.com/avatar/14444264/medium/4aa3a8e824f72bc9e5ec0d8de307095e.jpeg"},{"username":"maathis","avatarUrl":"https://crowdin-static.cf-downloads.crowdin.com/avatar/14489950/medium/6eeddf13a757ee35f78f1763f94d95e1.jpeg"},{"username":"bukvam","avatarUrl":"https://crowdin-static.cf-downloads.crowdin.com/avatar/14546502/medium/a819dc40a13c57395a17dc46e847d3ce.jpg"},{"username":"gm.cinalli","avatarUrl":"https://crowdin-static.cf-downloads.crowdin.com/avatar/14670666/medium/2d466a0fdbda40764526be86c97c0ab4.jpeg"},{"username":"antoine2tt","avatarUrl":"https://crowdin-static.cf-downloads.crowdin.com/avatar/14722148/medium/f88d926900862dd59007ea4b3419cb9d.png"},{"username":"cretzen","avatarUrl":"https://crowdin-static.cf-downloads.crowdin.com/avatar/14799754/medium/3ba5c1805ec20c000d5810c07985afe9.jpg"},{"username":"ktKongTong","avatarUrl":"https://crowdin-static.cf-downloads.crowdin.com/avatar/14817246/medium/97cfc3c028dbdaf85ebd1102da71e58c.jpeg"},{"username":"marinkaberg","avatarUrl":"https://crowdin-static.cf-downloads.crowdin.com/avatar/14861042/medium/2d5c4e62613f03082f3e645fa92efd59.jpeg"},{"username":"djismgaming","avatarUrl":"https://crowLine truncated
|
||||
Reference in new issue
Block a user