mirror of
https://github.com/glanceapp/glance.git
synced 2024-11-22 00:13:55 +01:00
Merge branch 'release/v0.6.0' into features
This commit is contained in:
commit
776fdcc6ce
@ -1044,13 +1044,13 @@ You can hover over the "ERROR" text to view more information.
|
|||||||
|
|
||||||
#### Properties
|
#### Properties
|
||||||
|
|
||||||
| Name | Type | Required |
|
| Name | Type | Required | Default |
|
||||||
| ---- | ---- | -------- |
|
| ---- | ---- | -------- | ------- |
|
||||||
| sites | array | yes |
|
| sites | array | yes | |
|
||||||
| style | string | no |
|
| show-failing-only | boolean | no | false |
|
||||||
|
|
||||||
##### `style`
|
##### `show-failing-only`
|
||||||
To make the widget scale appropriately in a `full` size column, set the style to the experimental `dynamic-columns-experimental` option.
|
Shows only a list of failing sites when set to `true`.
|
||||||
|
|
||||||
##### `sites`
|
##### `sites`
|
||||||
|
|
||||||
@ -1333,14 +1333,10 @@ Preview:
|
|||||||
| Name | Type | Required |
|
| Name | Type | Required |
|
||||||
| ---- | ---- | -------- |
|
| ---- | ---- | -------- |
|
||||||
| groups | array | yes |
|
| groups | array | yes |
|
||||||
| style | string | no |
|
|
||||||
|
|
||||||
##### `groups`
|
##### `groups`
|
||||||
An array of groups which can optionally have a title and a custom color.
|
An array of groups which can optionally have a title and a custom color.
|
||||||
|
|
||||||
##### `style`
|
|
||||||
To make the widget scale appropriately in a `full` size column, set the style to the experimental `dynamic-columns-experimental` option.
|
|
||||||
|
|
||||||
###### Properties for each group
|
###### Properties for each group
|
||||||
| Name | Type | Required | Default |
|
| Name | Type | Required | Default |
|
||||||
| ---- | ---- | -------- | ------- |
|
| ---- | ---- | -------- | ------- |
|
||||||
@ -1518,7 +1514,6 @@ Preview:
|
|||||||
| ---- | ---- | -------- |
|
| ---- | ---- | -------- |
|
||||||
| markets | array | yes |
|
| markets | array | yes |
|
||||||
| sort-by | string | no |
|
| sort-by | string | no |
|
||||||
| style | string | no |
|
|
||||||
|
|
||||||
##### `markets`
|
##### `markets`
|
||||||
An array of markets for which to display information about.
|
An array of markets for which to display information about.
|
||||||
@ -1526,9 +1521,6 @@ An array of markets for which to display information about.
|
|||||||
##### `sort-by`
|
##### `sort-by`
|
||||||
By default the markets are displayed in the order they were defined. You can customize their ordering by setting the `sort-by` property to `absolute-change` for descending order based on the stock's absolute price change.
|
By default the markets are displayed in the order they were defined. You can customize their ordering by setting the `sort-by` property to `absolute-change` for descending order based on the stock's absolute price change.
|
||||||
|
|
||||||
##### `style`
|
|
||||||
To make the widget scale appropriately in a `full` size column, set the style to the experimental `dynamic-columns-experimental` option.
|
|
||||||
|
|
||||||
###### Properties for each stock
|
###### Properties for each stock
|
||||||
| Name | Type | Required |
|
| Name | Type | Required |
|
||||||
| ---- | ---- | -------- |
|
| ---- | ---- | -------- |
|
||||||
|
@ -121,15 +121,6 @@
|
|||||||
color: var(--color-primary);
|
color: var(--color-primary);
|
||||||
}
|
}
|
||||||
|
|
||||||
.list { --list-half-gap: 0rem; }
|
|
||||||
.list-gap-2 { --list-half-gap: 0.1rem; }
|
|
||||||
.list-gap-4 { --list-half-gap: 0.2rem; }
|
|
||||||
.list-gap-10 { --list-half-gap: 0.5rem; }
|
|
||||||
.list-gap-14 { --list-half-gap: 0.7rem; }
|
|
||||||
.list-gap-20 { --list-half-gap: 1rem; }
|
|
||||||
.list-gap-24 { --list-half-gap: 1.2rem; }
|
|
||||||
.list-gap-34 { --list-half-gap: 1.7rem; }
|
|
||||||
|
|
||||||
.page-columns-transitioned .list-with-transition > * { animation: collapsibleItemReveal .25s backwards; }
|
.page-columns-transitioned .list-with-transition > * { animation: collapsibleItemReveal .25s backwards; }
|
||||||
.list-with-transition > *:nth-child(2) { animation-delay: 30ms; }
|
.list-with-transition > *:nth-child(2) { animation-delay: 30ms; }
|
||||||
.list-with-transition > *:nth-child(3) { animation-delay: 60ms; }
|
.list-with-transition > *:nth-child(3) { animation-delay: 60ms; }
|
||||||
@ -143,7 +134,7 @@
|
|||||||
margin-top: calc(var(--list-half-gap) * 2);
|
margin-top: calc(var(--list-half-gap) * 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
.list-with-separator > *:not(:first-child) {
|
.list.list-with-separator > *:not(:first-child) {
|
||||||
margin-top: var(--list-half-gap);
|
margin-top: var(--list-half-gap);
|
||||||
border-top: 1px solid var(--color-separator);
|
border-top: 1px solid var(--color-separator);
|
||||||
padding-top: var(--list-half-gap);
|
padding-top: var(--list-half-gap);
|
||||||
@ -570,17 +561,30 @@ details[open] .summary::after {
|
|||||||
max-width: 1100px;
|
max-width: 1100px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.page-center-vertically .page {
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* TODO: refactor, otherwise I hope I never have to change dynamic columns again */
|
||||||
.dynamic-columns {
|
.dynamic-columns {
|
||||||
gap: calc(var(--widget-content-vertical-padding) / 2);
|
--list-half-gap: 0.5rem;
|
||||||
|
gap: var(--widget-content-vertical-padding) var(--widget-content-horizontal-padding);
|
||||||
display: grid;
|
display: grid;
|
||||||
grid-template-columns: repeat(var(--columns-per-row), 1fr);
|
grid-template-columns: repeat(var(--columns-per-row), 1fr);
|
||||||
margin: calc(0px - var(--widget-content-vertical-padding) / 2) calc(0px - var(--widget-content-horizontal-padding) / 2);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.dynamic-columns > * {
|
.dynamic-columns > * {
|
||||||
padding: calc(var(--widget-content-vertical-padding) / 2) calc(var(--widget-content-horizontal-padding) / 1.5);
|
padding-left: var(--widget-content-horizontal-padding);
|
||||||
background-color: var(--color-background);
|
border-left: 1px solid var(--color-separator);
|
||||||
border-radius: var(--border-radius);
|
min-width: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dynamic-columns > *:first-child {
|
||||||
|
padding-top: 0;
|
||||||
|
border-top: none;
|
||||||
|
border-left: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
.dynamic-columns:has(> :nth-child(1)) { --columns-per-row: 1; }
|
.dynamic-columns:has(> :nth-child(1)) { --columns-per-row: 1; }
|
||||||
@ -589,23 +593,49 @@ details[open] .summary::after {
|
|||||||
.dynamic-columns:has(> :nth-child(4)) { --columns-per-row: 4; }
|
.dynamic-columns:has(> :nth-child(4)) { --columns-per-row: 4; }
|
||||||
.dynamic-columns:has(> :nth-child(5)) { --columns-per-row: 5; }
|
.dynamic-columns:has(> :nth-child(5)) { --columns-per-row: 5; }
|
||||||
|
|
||||||
@container widget (max-width: 1500px) {
|
@container widget (max-width: 599px) {
|
||||||
|
.dynamic-columns { gap: 0; }
|
||||||
.dynamic-columns:has(> :nth-child(1)) { --columns-per-row: 1; }
|
.dynamic-columns:has(> :nth-child(1)) { --columns-per-row: 1; }
|
||||||
|
.dynamic-columns > * {
|
||||||
|
border-left: none;
|
||||||
|
padding-left: 0;
|
||||||
|
}
|
||||||
|
.dynamic-columns > *:not(:first-child) {
|
||||||
|
margin-top: calc(var(--list-half-gap) * 2);
|
||||||
|
}
|
||||||
|
.dynamic-columns.list-with-separator > *:not(:first-child) {
|
||||||
|
margin-top: var(--list-half-gap);
|
||||||
|
border-top: 1px solid var(--color-separator);
|
||||||
|
padding-top: var(--list-half-gap);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@container widget (min-width: 600px) and (max-width: 849px) {
|
||||||
.dynamic-columns:has(> :nth-child(2)) { --columns-per-row: 2; }
|
.dynamic-columns:has(> :nth-child(2)) { --columns-per-row: 2; }
|
||||||
|
.dynamic-columns > :nth-child(2n-1) {
|
||||||
|
border-left: none;
|
||||||
|
padding-left: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@container widget (min-width: 850px) and (max-width: 1249px) {
|
||||||
.dynamic-columns:has(> :nth-child(3)) { --columns-per-row: 3; }
|
.dynamic-columns:has(> :nth-child(3)) { --columns-per-row: 3; }
|
||||||
|
.dynamic-columns > :nth-child(3n+1) {
|
||||||
|
border-left: none;
|
||||||
|
padding-left: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@container widget (min-width: 1250px) and (max-width: 1499px) {
|
||||||
.dynamic-columns:has(> :nth-child(4)) { --columns-per-row: 4; }
|
.dynamic-columns:has(> :nth-child(4)) { --columns-per-row: 4; }
|
||||||
|
.dynamic-columns > :nth-child(4n+1) {
|
||||||
|
border-left: none;
|
||||||
|
padding-left: 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@container widget (max-width: 1250px) {
|
@container widget (min-width: 1500px) {
|
||||||
.dynamic-columns:has(> :nth-child(1)) { --columns-per-row: 1; }
|
.dynamic-columns:has(> :nth-child(5)) { --columns-per-row: 5; }
|
||||||
.dynamic-columns:has(> :nth-child(2)) { --columns-per-row: 2; }
|
.dynamic-columns > :nth-child(5n+1) {
|
||||||
.dynamic-columns:has(> :nth-child(3)) { --columns-per-row: 3; }
|
border-left: none;
|
||||||
}
|
padding-left: 0;
|
||||||
@container widget (max-width: 850px) {
|
}
|
||||||
.dynamic-columns:has(> :nth-child(1)) { --columns-per-row: 1; }
|
|
||||||
.dynamic-columns:has(> :nth-child(2)) { --columns-per-row: 2; }
|
|
||||||
}
|
|
||||||
@container widget (max-width: 550px) {
|
|
||||||
.dynamic-columns:has(> :nth-child(1)) { --columns-per-row: 1; }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.cards-vertical {
|
.cards-vertical {
|
||||||
@ -839,6 +869,7 @@ details[open] .summary::after {
|
|||||||
.market-chart {
|
.market-chart {
|
||||||
margin-left: auto;
|
margin-left: auto;
|
||||||
width: 6.5rem;
|
width: 6.5rem;
|
||||||
|
flex-shrink: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.market-chart svg {
|
.market-chart svg {
|
||||||
@ -1325,10 +1356,13 @@ details[open] .summary::after {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.monitor-site:hover .monitor-site-icon {
|
.monitor-site:hover .monitor-site-icon {
|
||||||
filter: grayscale(0);
|
|
||||||
opacity: 1;
|
opacity: 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.monitor-site:hover .monitor-site-icon:not(.simple-icon) {
|
||||||
|
filter: grayscale(0);
|
||||||
|
}
|
||||||
|
|
||||||
.monitor-site-status-icon {
|
.monitor-site-status-icon {
|
||||||
flex-shrink: 0;
|
flex-shrink: 0;
|
||||||
margin-left: auto;
|
margin-left: auto;
|
||||||
@ -1764,4 +1798,13 @@ details[open] .summary::after {
|
|||||||
.margin-bottom-10 { margin-bottom: 1rem; }
|
.margin-bottom-10 { margin-bottom: 1rem; }
|
||||||
.margin-bottom-15 { margin-bottom: 1.5rem; }
|
.margin-bottom-15 { margin-bottom: 1.5rem; }
|
||||||
.margin-bottom-auto { margin-bottom: auto; }
|
.margin-bottom-auto { margin-bottom: auto; }
|
||||||
|
.padding-block-5 { padding-block: 0.5rem; }
|
||||||
.scale-half { transform: scale(0.5); }
|
.scale-half { transform: scale(0.5); }
|
||||||
|
.list { --list-half-gap: 0rem; }
|
||||||
|
.list-gap-2 { --list-half-gap: 0.1rem; }
|
||||||
|
.list-gap-4 { --list-half-gap: 0.2rem; }
|
||||||
|
.list-gap-10 { --list-half-gap: 0.5rem; }
|
||||||
|
.list-gap-14 { --list-half-gap: 0.7rem; }
|
||||||
|
.list-gap-20 { --list-half-gap: 1rem; }
|
||||||
|
.list-gap-24 { --list-half-gap: 1.2rem; }
|
||||||
|
.list-gap-34 { --list-half-gap: 1.7rem; }
|
||||||
|
@ -1,37 +1,23 @@
|
|||||||
{{ template "widget-base.html" . }}
|
{{ template "widget-base.html" . }}
|
||||||
|
|
||||||
{{ define "widget-content" }}
|
{{ define "widget-content" }}
|
||||||
{{ if ne .Style "dynamic-columns-experimental" }}
|
<div class="dynamic-columns list-gap-24 list-with-separator">
|
||||||
<ul class="list list-gap-24 list-with-separator">
|
|
||||||
{{ range .Groups }}
|
|
||||||
<li class="bookmarks-group"{{ if .Color }} style="--bookmarks-group-color: {{ .Color.AsCSSValue }}"{{ end }}>
|
|
||||||
{{ template "group" . }}
|
|
||||||
</li>
|
|
||||||
{{ end }}
|
|
||||||
</ul>
|
|
||||||
{{ else }}
|
|
||||||
<div class="dynamic-columns">
|
|
||||||
{{ range .Groups }}
|
{{ range .Groups }}
|
||||||
<div class="bookmarks-group"{{ if .Color }} style="--bookmarks-group-color: {{ .Color.AsCSSValue }}"{{ end }}>
|
<div class="bookmarks-group"{{ if .Color }} style="--bookmarks-group-color: {{ .Color.AsCSSValue }}"{{ end }}>
|
||||||
{{ template "group" . }}
|
{{ if ne .Title "" }}<div class="bookmarks-group-title size-h3 margin-bottom-3">{{ .Title }}</div>{{ end }}
|
||||||
|
<ul class="list list-gap-2">
|
||||||
|
{{ range .Links }}
|
||||||
|
<li class="flex items-center gap-10">
|
||||||
|
{{ if ne "" .Icon }}
|
||||||
|
<div class="bookmarks-icon-container">
|
||||||
|
<img class="bookmarks-icon{{ if .IsSimpleIcon }} simple-icon{{ end }}" src="{{ .Icon }}" alt="" loading="lazy">
|
||||||
|
</div>
|
||||||
|
{{ end }}
|
||||||
|
<a href="{{ .URL }}" class="bookmarks-link {{ if .HideArrow }}bookmarks-link-no-arrow {{ end }}color-highlight size-h4" {{ if not .SameTab }}target="_blank"{{ end }} rel="noreferrer">{{ .Title }}</a>
|
||||||
|
</li>
|
||||||
|
{{ end }}
|
||||||
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
{{ end }}
|
{{ end }}
|
||||||
</div>
|
</div>
|
||||||
{{ end }}
|
{{ end }}
|
||||||
{{ end }}
|
|
||||||
|
|
||||||
{{ define "group" }}
|
|
||||||
{{ if ne .Title "" }}<div class="bookmarks-group-title size-h3 margin-bottom-3">{{ .Title }}</div>{{ end }}
|
|
||||||
<ul class="list list-gap-2">
|
|
||||||
{{ range .Links }}
|
|
||||||
<li class="flex items-center gap-10">
|
|
||||||
{{ if ne "" .Icon }}
|
|
||||||
<div class="bookmarks-icon-container">
|
|
||||||
<img class="bookmarks-icon{{ if .IsSimpleIcon }} simple-icon{{ end }}" src="{{ .Icon }}" alt="" loading="lazy">
|
|
||||||
</div>
|
|
||||||
{{ end }}
|
|
||||||
<a href="{{ .URL }}" class="bookmarks-link {{ if .HideArrow }}bookmarks-link-no-arrow {{ end }}color-highlight size-h4" {{ if not .SameTab }}target="_blank"{{ end }} rel="noreferrer">{{ .Title }}</a>
|
|
||||||
</li>
|
|
||||||
{{ end }}
|
|
||||||
</ul>
|
|
||||||
{{ end }}
|
|
||||||
|
@ -1,39 +1,25 @@
|
|||||||
{{ template "widget-base.html" . }}
|
{{ template "widget-base.html" . }}
|
||||||
|
|
||||||
{{ define "widget-content" }}
|
{{ define "widget-content" }}
|
||||||
{{ if ne .Style "dynamic-columns-experimental" }}
|
<div class="dynamic-columns list-gap-20 list-with-separator">
|
||||||
<ul class="list list-gap-20 list-with-separator">
|
|
||||||
{{ range .Markets }}
|
|
||||||
<li class="flex items-center gap-15">
|
|
||||||
{{ template "market" . }}
|
|
||||||
</li>
|
|
||||||
{{ end }}
|
|
||||||
</ul>
|
|
||||||
{{ else }}
|
|
||||||
<div class="dynamic-columns">
|
|
||||||
{{ range .Markets }}
|
{{ range .Markets }}
|
||||||
<div class="flex items-center gap-15">
|
<div class="flex items-center gap-15">
|
||||||
{{ template "market" . }}
|
<div class="min-width-0">
|
||||||
|
<a{{ if ne "" .SymbolLink }} href="{{ .SymbolLink }}" target="_blank" rel="noreferrer"{{ end }} class="color-highlight size-h3 block text-truncate">{{ .Symbol }}</a>
|
||||||
|
<div class="text-truncate">{{ .Name }}</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<a class="market-chart" {{ if ne "" .ChartLink }} href="{{ .ChartLink }}" target="_blank" rel="noreferrer"{{ end }}>
|
||||||
|
<svg class="market-chart shrink-0" viewBox="0 0 100 50">
|
||||||
|
<polyline fill="none" stroke="var(--color-text-subdue)" stroke-width="1.5px" points="{{ .SvgChartPoints }}" vector-effect="non-scaling-stroke"></polyline>
|
||||||
|
</svg>
|
||||||
|
</a>
|
||||||
|
|
||||||
|
<div class="market-values shrink-0">
|
||||||
|
<div class="size-h3 text-right {{ if eq .PercentChange 0.0 }}{{ else if gt .PercentChange 0.0 }}color-positive{{ else }}color-negative{{ end }}">{{ printf "%+.2f" .PercentChange }}%</div>
|
||||||
|
<div class="text-right">{{ .Currency }}{{ .Price | formatPrice }}</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{{ end }}
|
{{ end }}
|
||||||
</div>
|
</div>
|
||||||
{{ end }}
|
{{ end }}
|
||||||
{{ end }}
|
|
||||||
|
|
||||||
{{ define "market" }}
|
|
||||||
<div class="min-width-0">
|
|
||||||
<a{{ if ne "" .SymbolLink }} href="{{ .SymbolLink }}" target="_blank" rel="noreferrer"{{ end }} class="color-highlight size-h3 block text-truncate">{{ .Symbol }}</a>
|
|
||||||
<div class="text-truncate">{{ .Name }}</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<a class="market-chart" {{ if ne "" .ChartLink }} href="{{ .ChartLink }}" target="_blank" rel="noreferrer"{{ end }}>
|
|
||||||
<svg class="market-chart shrink-0" viewBox="0 0 100 50">
|
|
||||||
<polyline fill="none" stroke="var(--color-text-subdue)" stroke-width="1.5px" points="{{ .SvgChartPoints }}" vector-effect="non-scaling-stroke"></polyline>
|
|
||||||
</svg>
|
|
||||||
</a>
|
|
||||||
|
|
||||||
<div class="market-values shrink-0">
|
|
||||||
<div class="size-h3 text-right {{ if eq .PercentChange 0.0 }}{{ else if gt .PercentChange 0.0 }}color-positive{{ else }}color-negative{{ end }}">{{ printf "%+.2f" .PercentChange }}%</div>
|
|
||||||
<div class="text-right">{{ .Currency }}{{ .Price | formatPrice }}</div>
|
|
||||||
</div>
|
|
||||||
{{ end }}
|
|
||||||
|
@ -1,22 +1,22 @@
|
|||||||
{{ template "widget-base.html" . }}
|
{{ template "widget-base.html" . }}
|
||||||
|
|
||||||
{{ define "widget-content" }}
|
{{ define "widget-content" }}
|
||||||
{{ if ne .Style "dynamic-columns-experimental" }}
|
{{ if not (and .ShowFailingOnly (not .HasFailing)) }}
|
||||||
<ul class="list list-gap-20 list-with-separator">
|
<ul class="dynamic-columns list-gap-20 list-with-separator">
|
||||||
{{ range .Sites }}
|
{{ range .Sites }}
|
||||||
<li class="monitor-site flex items-center gap-15">
|
{{ if and $.ShowFailingOnly (eq .StatusStyle "ok" ) }} {{ continue }} {{ end }}
|
||||||
{{ template "site" . }}
|
<div class="monitor-site flex items-center gap-15">
|
||||||
</li>
|
|
||||||
{{ end }}
|
|
||||||
</ul>
|
|
||||||
{{ else }}
|
|
||||||
<ul class="dynamic-columns">
|
|
||||||
{{ range .Sites }}
|
|
||||||
<div class="flex items-center gap-15">
|
|
||||||
{{ template "site" . }}
|
{{ template "site" . }}
|
||||||
</div>
|
</div>
|
||||||
{{ end }}
|
{{ end }}
|
||||||
</ul>
|
</ul>
|
||||||
|
{{ else }}
|
||||||
|
<div class="flex items-center justify-center gap-10 padding-block-5">
|
||||||
|
<p>All sites are online</p>
|
||||||
|
<svg class="shrink-0" style="width: 1.7rem;" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="var(--color-positive)">
|
||||||
|
<path fill-rule="evenodd" d="M2.25 12c0-5.385 4.365-9.75 9.75-9.75s9.75 4.365 9.75 9.75-4.365 9.75-9.75 9.75S2.25 17.385 2.25 12Zm13.36-1.814a.75.75 0 1 0-1.22-.872l-3.236 4.53L9.53 12.22a.75.75 0 0 0-1.06 1.06l2.25 2.25a.75.75 0 0 0 1.14-.094l3.75-5.25Z" clip-rule="evenodd" />
|
||||||
|
</svg>
|
||||||
|
</div>
|
||||||
{{ end }}
|
{{ end }}
|
||||||
{{ end }}
|
{{ end }}
|
||||||
|
|
||||||
@ -24,8 +24,8 @@
|
|||||||
{{ if .IconUrl }}
|
{{ if .IconUrl }}
|
||||||
<img class="monitor-site-icon{{ if .IsSimpleIcon }} simple-icon{{ end }}" src="{{ .IconUrl }}" alt="" loading="lazy">
|
<img class="monitor-site-icon{{ if .IsSimpleIcon }} simple-icon{{ end }}" src="{{ .IconUrl }}" alt="" loading="lazy">
|
||||||
{{ end }}
|
{{ end }}
|
||||||
<div>
|
<div class="min-width-0">
|
||||||
<a class="size-h3 color-highlight" href="{{ .URL }}" {{ if not .SameTab }}target="_blank"{{ end }} rel="noreferrer">{{ .Title }}</a>
|
<a class="size-h3 color-highlight text-truncate block" href="{{ .URL }}" {{ if not .SameTab }}target="_blank"{{ end }} rel="noreferrer">{{ .Title }}</a>
|
||||||
<ul class="list-horizontal-text">
|
<ul class="list-horizontal-text">
|
||||||
{{ if not .Status.Error }}
|
{{ if not .Status.Error }}
|
||||||
<li title="{{ .Status.Code }}">{{ .StatusText }}</li>
|
<li title="{{ .Status.Code }}">{{ .StatusText }}</li>
|
||||||
|
@ -11,7 +11,7 @@
|
|||||||
</script>
|
</script>
|
||||||
{{ end }}
|
{{ end }}
|
||||||
|
|
||||||
{{ define "document-root-attrs" }}class="{{ if .App.Config.Theme.Light }}light-scheme {{ end }}{{ if ne "" .Page.Width }}page-width-{{ .Page.Width }}{{ end }}"{{ end }}
|
{{ define "document-root-attrs" }}class="{{ if .App.Config.Theme.Light }}light-scheme {{ end }}{{ if ne "" .Page.Width }}page-width-{{ .Page.Width }} {{ end }}{{ if .Page.CenterVertically }}page-center-vertically{{ end }}"{{ end }}
|
||||||
|
|
||||||
{{ define "document-head-after" }}
|
{{ define "document-head-after" }}
|
||||||
{{ template "page-style-overrides.gotmpl" . }}
|
{{ template "page-style-overrides.gotmpl" . }}
|
||||||
|
@ -38,16 +38,10 @@ func fetchLatestGithubRelease(request *ReleaseRequest) (*AppRelease, error) {
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
version := response.TagName
|
|
||||||
|
|
||||||
if len(version) > 0 && version[0] != 'v' {
|
|
||||||
version = "v" + version
|
|
||||||
}
|
|
||||||
|
|
||||||
return &AppRelease{
|
return &AppRelease{
|
||||||
Source: ReleaseSourceGithub,
|
Source: ReleaseSourceGithub,
|
||||||
Name: request.Repository,
|
Name: request.Repository,
|
||||||
Version: version,
|
Version: normalizeVersionFormat(response.TagName),
|
||||||
NotesUrl: response.HtmlUrl,
|
NotesUrl: response.HtmlUrl,
|
||||||
TimeReleased: parseRFC3339Time(response.PublishedAt),
|
TimeReleased: parseRFC3339Time(response.PublishedAt),
|
||||||
Downvotes: response.Reactions.Downvotes,
|
Downvotes: response.Reactions.Downvotes,
|
||||||
|
@ -38,16 +38,10 @@ func fetchLatestGitLabRelease(request *ReleaseRequest) (*AppRelease, error) {
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
version := response.TagName
|
|
||||||
|
|
||||||
if len(version) > 0 && version[0] != 'v' {
|
|
||||||
version = "v" + version
|
|
||||||
}
|
|
||||||
|
|
||||||
return &AppRelease{
|
return &AppRelease{
|
||||||
Source: ReleaseSourceGitlab,
|
Source: ReleaseSourceGitlab,
|
||||||
Name: request.Repository,
|
Name: request.Repository,
|
||||||
Version: version,
|
Version: normalizeVersionFormat(response.TagName),
|
||||||
NotesUrl: response.Links.Self,
|
NotesUrl: response.Links.Self,
|
||||||
TimeReleased: parseRFC3339Time(response.ReleasedAt),
|
TimeReleased: parseRFC3339Time(response.ReleasedAt),
|
||||||
}, nil
|
}, nil
|
||||||
|
@ -105,3 +105,13 @@ func parseRFC3339Time(t string) time.Time {
|
|||||||
|
|
||||||
return parsed
|
return parsed
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func normalizeVersionFormat(version string) string {
|
||||||
|
version = strings.ToLower(strings.TrimSpace(version))
|
||||||
|
|
||||||
|
if len(version) > 0 && version[0] != 'v' {
|
||||||
|
return "v" + version
|
||||||
|
}
|
||||||
|
|
||||||
|
return version
|
||||||
|
}
|
||||||
|
@ -11,10 +11,8 @@ import (
|
|||||||
|
|
||||||
type youtubeFeedResponseXml struct {
|
type youtubeFeedResponseXml struct {
|
||||||
Channel string `xml:"author>name"`
|
Channel string `xml:"author>name"`
|
||||||
ChannelLink struct {
|
ChannelLink string `xml:"author>uri"`
|
||||||
Href string `xml:"href,attr"`
|
Videos []struct {
|
||||||
} `xml:"link"`
|
|
||||||
Videos []struct {
|
|
||||||
Title string `xml:"title"`
|
Title string `xml:"title"`
|
||||||
Published string `xml:"published"`
|
Published string `xml:"published"`
|
||||||
Link struct {
|
Link struct {
|
||||||
@ -97,7 +95,7 @@ func FetchYoutubeChannelUploads(channelIds []string, videoUrlTemplate string, in
|
|||||||
Title: video.Title,
|
Title: video.Title,
|
||||||
Url: videoUrl,
|
Url: videoUrl,
|
||||||
Author: response.Channel,
|
Author: response.Channel,
|
||||||
AuthorUrl: response.ChannelLink.Href + "/videos",
|
AuthorUrl: response.ChannelLink + "/videos",
|
||||||
TimePosted: parseYoutubeFeedTime(video.Published),
|
TimePosted: parseYoutubeFeedTime(video.Published),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -73,6 +73,7 @@ type Page struct {
|
|||||||
Width string `yaml:"width"`
|
Width string `yaml:"width"`
|
||||||
ShowMobileHeader bool `yaml:"show-mobile-header"`
|
ShowMobileHeader bool `yaml:"show-mobile-header"`
|
||||||
HideDesktopNavigation bool `yaml:"hide-desktop-navigation"`
|
HideDesktopNavigation bool `yaml:"hide-desktop-navigation"`
|
||||||
|
CenterVertically bool `yaml:"center-vertically"`
|
||||||
Columns []Column `yaml:"columns"`
|
Columns []Column `yaml:"columns"`
|
||||||
mu sync.Mutex
|
mu sync.Mutex
|
||||||
}
|
}
|
||||||
|
@ -21,7 +21,6 @@ type Bookmarks struct {
|
|||||||
HideArrow bool `yaml:"hide-arrow"`
|
HideArrow bool `yaml:"hide-arrow"`
|
||||||
} `yaml:"links"`
|
} `yaml:"links"`
|
||||||
} `yaml:"groups"`
|
} `yaml:"groups"`
|
||||||
Style string `yaml:"style"`
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (widget *Bookmarks) Initialize() error {
|
func (widget *Bookmarks) Initialize() error {
|
||||||
|
@ -14,7 +14,6 @@ type Markets struct {
|
|||||||
StocksRequests []feed.MarketRequest `yaml:"stocks"`
|
StocksRequests []feed.MarketRequest `yaml:"stocks"`
|
||||||
MarketRequests []feed.MarketRequest `yaml:"markets"`
|
MarketRequests []feed.MarketRequest `yaml:"markets"`
|
||||||
Sort string `yaml:"sort-by"`
|
Sort string `yaml:"sort-by"`
|
||||||
Style string `yaml:"style"`
|
|
||||||
Markets feed.Markets `yaml:"-"`
|
Markets feed.Markets `yaml:"-"`
|
||||||
}
|
}
|
||||||
|
|
@ -53,7 +53,8 @@ type Monitor struct {
|
|||||||
StatusText string `yaml:"-"`
|
StatusText string `yaml:"-"`
|
||||||
StatusStyle string `yaml:"-"`
|
StatusStyle string `yaml:"-"`
|
||||||
} `yaml:"sites"`
|
} `yaml:"sites"`
|
||||||
Style string `yaml:"style"`
|
ShowFailingOnly bool `yaml:"show-failing-only"`
|
||||||
|
HasFailing bool `yaml:"-"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (widget *Monitor) Initialize() error {
|
func (widget *Monitor) Initialize() error {
|
||||||
@ -79,12 +80,17 @@ func (widget *Monitor) Update(ctx context.Context) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
widget.HasFailing = false
|
||||||
|
|
||||||
for i := range widget.Sites {
|
for i := range widget.Sites {
|
||||||
site := &widget.Sites[i]
|
site := &widget.Sites[i]
|
||||||
status := &statuses[i]
|
status := &statuses[i]
|
||||||
|
|
||||||
site.Status = status
|
site.Status = status
|
||||||
|
|
||||||
|
if status.Code >= 400 || status.TimedOut || status.Error != nil {
|
||||||
|
widget.HasFailing = true
|
||||||
|
}
|
||||||
|
|
||||||
if !status.TimedOut {
|
if !status.TimedOut {
|
||||||
site.StatusText = statusCodeToText(status.Code)
|
site.StatusText = statusCodeToText(status.Code)
|
||||||
site.StatusStyle = statusCodeToStyle(status.Code)
|
site.StatusStyle = statusCodeToStyle(status.Code)
|
||||||
|
Loading…
Reference in New Issue
Block a user