mirror of
https://github.com/gethomepage/homepage.git
synced 2025-12-07 09:35:54 -08:00
Compare commits
6 Commits
c77dfa4c64
...
dev
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
cd34796b9d | ||
|
|
0d788e3d06 | ||
|
|
ed1dafadde | ||
|
|
96ac9046b3 | ||
|
|
6d5f35f07e | ||
|
|
8887281246 |
@@ -159,6 +159,19 @@ Widgets can tint their metric block text automatically based on rules defined al
|
|||||||
|
|
||||||
Supported numeric operators for the `when` property are `gt`, `gte`, `lt`, `lte`, `eq`, `ne`, `between`, and `outside`. String rules support `equals`, `includes`, `startsWith`, `endsWith`, and `regex`. Each rule can be inverted with `negate: true`, and string rules may pass `caseSensitive: true` or custom regex `flags`. The highlight engine does its best to coerce formatted values, but you will get the most reliable results when you pass plain numbers or strings into `<Block>`.
|
Supported numeric operators for the `when` property are `gt`, `gte`, `lt`, `lte`, `eq`, `ne`, `between`, and `outside`. String rules support `equals`, `includes`, `startsWith`, `endsWith`, and `regex`. Each rule can be inverted with `negate: true`, and string rules may pass `caseSensitive: true` or custom regex `flags`. The highlight engine does its best to coerce formatted values, but you will get the most reliable results when you pass plain numbers or strings into `<Block>`.
|
||||||
|
|
||||||
|
#### Value Only Highlighting
|
||||||
|
|
||||||
|
You can optionally apply highlighting only to the value portion of a block (not the label) by setting `valueOnly: true` on the field configuration. This keeps the label visible while highlighting only the metric value itself.
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
- Sonarr:
|
||||||
|
...
|
||||||
|
highlight:
|
||||||
|
queued:
|
||||||
|
valueOnly: true
|
||||||
|
...
|
||||||
|
```
|
||||||
|
|
||||||
## Descriptions
|
## Descriptions
|
||||||
|
|
||||||
Services may have descriptions,
|
Services may have descriptions,
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ services:
|
|||||||
- 3000:3000
|
- 3000:3000
|
||||||
volumes:
|
volumes:
|
||||||
- /path/to/config:/app/config # Make sure your local config directory exists
|
- /path/to/config:/app/config # Make sure your local config directory exists
|
||||||
- /var/run/docker.sock:/var/run/docker.sock # (optional) For docker integrations
|
- /var/run/docker.sock:/var/run/docker.sock:ro # (optional) For docker integrations
|
||||||
environment:
|
environment:
|
||||||
HOMEPAGE_ALLOWED_HOSTS: gethomepage.dev # required, may need port. See gethomepage.dev/installation/#homepage_allowed_hosts
|
HOMEPAGE_ALLOWED_HOSTS: gethomepage.dev # required, may need port. See gethomepage.dev/installation/#homepage_allowed_hosts
|
||||||
```
|
```
|
||||||
@@ -36,7 +36,7 @@ services:
|
|||||||
- 3000:3000
|
- 3000:3000
|
||||||
volumes:
|
volumes:
|
||||||
- /path/to/config:/app/config # Make sure your local config directory exists
|
- /path/to/config:/app/config # Make sure your local config directory exists
|
||||||
- /var/run/docker.sock:/var/run/docker.sock # (optional) For docker integrations, see alternative methods
|
- /var/run/docker.sock:/var/run/docker.sock:ro # (optional) For docker integrations, see alternative methods
|
||||||
environment:
|
environment:
|
||||||
HOMEPAGE_ALLOWED_HOSTS: gethomepage.dev # required, may need port. See gethomepage.dev/installation/#homepage_allowed_hosts
|
HOMEPAGE_ALLOWED_HOSTS: gethomepage.dev # required, may need port. See gethomepage.dev/installation/#homepage_allowed_hosts
|
||||||
PUID: $PUID
|
PUID: $PUID
|
||||||
|
|||||||
@@ -68,7 +68,19 @@ All service widgets work essentially the same, that is, homepage makes a proxied
|
|||||||
|
|
||||||
If, after correctly adding and mapping your custom icons via the [Icons](../configs/services.md#icons) instructions, you are still unable to see your icons please try recreating your container.
|
If, after correctly adding and mapping your custom icons via the [Icons](../configs/services.md#icons) instructions, you are still unable to see your icons please try recreating your container.
|
||||||
|
|
||||||
## Disabling IPv6
|
## Enabling IPv6 for the homepage container
|
||||||
|
|
||||||
|
To enable IPv6 support for the homepage container, you can set the `HOSTNAME` environment variable, for example:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
services:
|
||||||
|
homepage:
|
||||||
|
...
|
||||||
|
environment:
|
||||||
|
- HOSTNAME=::
|
||||||
|
```
|
||||||
|
|
||||||
|
## Disabling IPv6 for http requests {#disabling-ipv6}
|
||||||
|
|
||||||
If you are having issues with certain widgets that are unable to reach public APIs (e.g. weather), in certain setups you may need to disable IPv6. You can set the environment variable `HOMEPAGE_PROXY_DISABLE_IPV6` to `true` to disable IPv6 for the homepage proxy.
|
If you are having issues with certain widgets that are unable to reach public APIs (e.g. weather), in certain setups you may need to disable IPv6. You can set the environment variable `HOMEPAGE_PROXY_DISABLE_IPV6` to `true` to disable IPv6 for the homepage proxy.
|
||||||
|
|
||||||
|
|||||||
@@ -32,6 +32,8 @@ export default function Block({ value, label, field }) {
|
|||||||
return getHighlightClass(highlight.level, highlightConfig);
|
return getHighlightClass(highlight.level, highlightConfig);
|
||||||
}, [highlight, highlightConfig]);
|
}, [highlight, highlightConfig]);
|
||||||
|
|
||||||
|
const applyToValueOnly = highlight?.valueOnly === true;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
className={classNames(
|
className={classNames(
|
||||||
@@ -44,7 +46,11 @@ export default function Block({ value, label, field }) {
|
|||||||
data-highlight-source={highlight?.source}
|
data-highlight-source={highlight?.source}
|
||||||
>
|
>
|
||||||
<div className="font-thin text-sm">{value === undefined || value === null ? "-" : value}</div>
|
<div className="font-thin text-sm">{value === undefined || value === null ? "-" : value}</div>
|
||||||
<div className="font-bold text-xs uppercase">{t(label)}</div>
|
<div
|
||||||
|
className={classNames("font-bold text-xs uppercase", applyToValueOnly && "text-theme-700 dark:text-theme-200")}
|
||||||
|
>
|
||||||
|
{t(label)}
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -111,7 +111,7 @@ export async function servicesFromDocker() {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
let substitutedVal = substituteEnvironmentVars(containerLabels[label]);
|
let substitutedVal = substituteEnvironmentVars(containerLabels[label]);
|
||||||
if (value === "widget.version") {
|
if (value === "widget.version" || /^widgets\[\d+\]\.version$/.test(value)) {
|
||||||
substitutedVal = parseInt(substitutedVal, 10);
|
substitutedVal = parseInt(substitutedVal, 10);
|
||||||
}
|
}
|
||||||
shvl.set(constructedService, value, substitutedVal);
|
shvl.set(constructedService, value, substitutedVal);
|
||||||
|
|||||||
@@ -200,7 +200,7 @@ const ensureArray = (value) => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const findHighlightLevel = (ruleSet, numericValue, stringValue) => {
|
const findHighlightLevel = (ruleSet, numericValue, stringValue) => {
|
||||||
const { numeric, string } = ruleSet;
|
const { numeric, string, valueOnly } = ruleSet;
|
||||||
|
|
||||||
if (numeric && numericValue !== undefined) {
|
if (numeric && numericValue !== undefined) {
|
||||||
const numericRules = ensureArray(numeric);
|
const numericRules = ensureArray(numeric);
|
||||||
@@ -208,7 +208,7 @@ const findHighlightLevel = (ruleSet, numericValue, stringValue) => {
|
|||||||
for (const candidate of numericCandidates) {
|
for (const candidate of numericCandidates) {
|
||||||
for (const rule of numericRules) {
|
for (const rule of numericRules) {
|
||||||
if (rule?.level && evaluateNumericRule(candidate, rule)) {
|
if (rule?.level && evaluateNumericRule(candidate, rule)) {
|
||||||
return { level: rule.level, source: "numeric", rule };
|
return { level: rule.level, source: "numeric", rule, valueOnly };
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -218,7 +218,7 @@ const findHighlightLevel = (ruleSet, numericValue, stringValue) => {
|
|||||||
const stringRules = ensureArray(string);
|
const stringRules = ensureArray(string);
|
||||||
for (const rule of stringRules) {
|
for (const rule of stringRules) {
|
||||||
if (rule?.level && evaluateStringRule(stringValue, rule)) {
|
if (rule?.level && evaluateStringRule(stringValue, rule)) {
|
||||||
return { level: rule.level, source: "string", rule };
|
return { level: rule.level, source: "string", rule, valueOnly };
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -111,7 +111,7 @@ export async function cachedRequest(url, duration = 5, ua = "homepage") {
|
|||||||
export async function httpProxy(url, params = {}) {
|
export async function httpProxy(url, params = {}) {
|
||||||
const constructedUrl = new URL(url);
|
const constructedUrl = new URL(url);
|
||||||
const disableIpv6 = process.env.HOMEPAGE_PROXY_DISABLE_IPV6 === "true";
|
const disableIpv6 = process.env.HOMEPAGE_PROXY_DISABLE_IPV6 === "true";
|
||||||
const agentOptions = disableIpv6 ? { family: 4, autoSelectFamily: false } : {};
|
const agentOptions = disableIpv6 ? { family: 4, autoSelectFamily: false } : { autoSelectFamilyAttemptTimeout: 500 };
|
||||||
|
|
||||||
let request = null;
|
let request = null;
|
||||||
if (constructedUrl.protocol === "https:") {
|
if (constructedUrl.protocol === "https:") {
|
||||||
|
|||||||
Reference in New Issue
Block a user