Add split-column widget
This commit is contained in:
parent
13700fe2b2
commit
e5bb102ab1
9 changed files with 129 additions and 11 deletions
|
@ -15,6 +15,7 @@
|
|||
- [Reddit](#reddit)
|
||||
- [Search](#search-widget)
|
||||
- [Group](#group)
|
||||
- [Split Column](#split-column)
|
||||
- [Extension](#extension)
|
||||
- [Weather](#weather)
|
||||
- [Monitor](#monitor)
|
||||
|
@ -890,7 +891,7 @@ url: https://www.amazon.com/s?k={QUERY}
|
|||
```
|
||||
|
||||
### Group
|
||||
Group multiple widgets into one using tabs. Widgets are defined using a `widgets` property exactly as you would on a page column. The only limitation is that you cannot place a group widget within a group widget.
|
||||
Group multiple widgets into one using tabs. Widgets are defined using a `widgets` property exactly as you would on a page column. The only limitation is that you cannot place a group widget or a split column widget within a group widget.
|
||||
|
||||
Example:
|
||||
|
||||
|
@ -933,6 +934,63 @@ Example:
|
|||
<<: *shared-properties
|
||||
```
|
||||
|
||||
### Split Column
|
||||
Splits a full sized column in half, allowing you to place widgets side by side. This is converted to a single column on mobile devices or if not enough width is available. Widgets are defined using a `widgets` property exactly as you would on a page column.
|
||||
|
||||
Example of a full page with an effective 4 column layout using two split column widgets inside of two full sized columns:
|
||||
|
||||
<details>
|
||||
<summary>View config</summary>
|
||||
|
||||
```yaml
|
||||
shared:
|
||||
- &reddit-props
|
||||
type: reddit
|
||||
collapse-after: 4
|
||||
show-thumbnails: true
|
||||
|
||||
pages:
|
||||
- name: Split Column Demo
|
||||
width: wide
|
||||
columns:
|
||||
- size: full
|
||||
widgets:
|
||||
- type: split-column
|
||||
widgets:
|
||||
- subreddit: gaming
|
||||
<<: *reddit-props
|
||||
- subreddit: worldnews
|
||||
<<: *reddit-props
|
||||
- subreddit: lifeprotips
|
||||
<<: *reddit-props
|
||||
show-thumbnails: false
|
||||
- subreddit: askreddit
|
||||
<<: *reddit-props
|
||||
show-thumbnails: false
|
||||
|
||||
- size: full
|
||||
widgets:
|
||||
- type: split-column
|
||||
widgets:
|
||||
- subreddit: todayilearned
|
||||
<<: *reddit-props
|
||||
collapse-after: 2
|
||||
- subreddit: aww
|
||||
<<: *reddit-props
|
||||
- subreddit: science
|
||||
<<: *reddit-props
|
||||
- subreddit: showerthoughts
|
||||
<<: *reddit-props
|
||||
show-thumbnails: false
|
||||
```
|
||||
</details>
|
||||
|
||||
<br>
|
||||
|
||||
Preview:
|
||||
|
||||

|
||||
|
||||
### Extension
|
||||
Display a widget provided by an external source (3rd party). If you want to learn more about developing extensions, checkout the [extensions documentation](extensions.md) (WIP).
|
||||
|
||||
|
|
BIN
docs/images/split-column-widget-preview.png
Normal file
BIN
docs/images/split-column-widget-preview.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 328 KiB |
|
@ -1,4 +1,5 @@
|
|||
import { setupPopovers } from './popover.js';
|
||||
import { setupMasonries } from './masonry.js';
|
||||
import { throttledDebounce, isElementVisible } from './utils.js';
|
||||
|
||||
async function fetchPageContent(pageData) {
|
||||
|
@ -581,6 +582,7 @@ async function setupPage() {
|
|||
setupCollapsibleLists();
|
||||
setupCollapsibleGrids();
|
||||
setupGroups();
|
||||
setupMasonries();
|
||||
setupDynamicRelativeTime();
|
||||
setupLazyImages();
|
||||
} finally {
|
||||
|
|
|
@ -39,6 +39,7 @@ var (
|
|||
ExtensionTemplate = compileTemplate("extension.html", "widget-base.html")
|
||||
GroupTemplate = compileTemplate("group.html", "widget-base.html")
|
||||
DNSStatsTemplate = compileTemplate("dns-stats.html", "widget-base.html")
|
||||
SplitColumnTemplate = compileTemplate("split-column.html", "widget-base.html")
|
||||
)
|
||||
|
||||
var globalTemplateFunctions = template.FuncMap{
|
||||
|
|
11
internal/assets/templates/split-column.html
Normal file
11
internal/assets/templates/split-column.html
Normal file
|
@ -0,0 +1,11 @@
|
|||
{{ template "widget-base.html" . }}
|
||||
|
||||
{{ define "widget-content-classes" }}widget-content-frameless{{ end }}
|
||||
|
||||
{{ define "widget-content" }}
|
||||
<div class="masonry" data-max-columns="2">
|
||||
{{ range .Widgets }}
|
||||
{{ .Render }}
|
||||
{{ end }}
|
||||
</div>
|
||||
{{ end }}
|
|
@ -6,11 +6,11 @@ import (
|
|||
"time"
|
||||
)
|
||||
|
||||
type containerWidget struct {
|
||||
type containerWidgetBase struct {
|
||||
Widgets Widgets `yaml:"widgets"`
|
||||
}
|
||||
|
||||
func (widget *containerWidget) Update(ctx context.Context) {
|
||||
func (widget *containerWidgetBase) Update(ctx context.Context) {
|
||||
var wg sync.WaitGroup
|
||||
now := time.Now()
|
||||
|
||||
|
@ -31,13 +31,13 @@ func (widget *containerWidget) Update(ctx context.Context) {
|
|||
wg.Wait()
|
||||
}
|
||||
|
||||
func (widget *containerWidget) SetProviders(providers *Providers) {
|
||||
func (widget *containerWidgetBase) SetProviders(providers *Providers) {
|
||||
for i := range widget.Widgets {
|
||||
widget.Widgets[i].SetProviders(providers)
|
||||
}
|
||||
}
|
||||
|
||||
func (widget *containerWidget) RequiresUpdate(now *time.Time) bool {
|
||||
func (widget *containerWidgetBase) RequiresUpdate(now *time.Time) bool {
|
||||
for i := range widget.Widgets {
|
||||
if widget.Widgets[i].RequiresUpdate(now) {
|
||||
return true
|
||||
|
|
|
@ -10,8 +10,8 @@ import (
|
|||
)
|
||||
|
||||
type Group struct {
|
||||
widgetBase `yaml:",inline"`
|
||||
containerWidget `yaml:",inline"`
|
||||
widgetBase `yaml:",inline"`
|
||||
containerWidgetBase `yaml:",inline"`
|
||||
}
|
||||
|
||||
func (widget *Group) Initialize() error {
|
||||
|
@ -22,7 +22,9 @@ func (widget *Group) Initialize() error {
|
|||
widget.Widgets[i].SetHideHeader(true)
|
||||
|
||||
if widget.Widgets[i].GetType() == "group" {
|
||||
return errors.New("nested groups are not allowed")
|
||||
return errors.New("nested groups are not supported")
|
||||
} else if widget.Widgets[i].GetType() == "split-column" {
|
||||
return errors.New("split columns inside of groups are not supported")
|
||||
}
|
||||
|
||||
if err := widget.Widgets[i].Initialize(); err != nil {
|
||||
|
@ -34,15 +36,15 @@ func (widget *Group) Initialize() error {
|
|||
}
|
||||
|
||||
func (widget *Group) Update(ctx context.Context) {
|
||||
widget.containerWidget.Update(ctx)
|
||||
widget.containerWidgetBase.Update(ctx)
|
||||
}
|
||||
|
||||
func (widget *Group) SetProviders(providers *Providers) {
|
||||
widget.containerWidget.SetProviders(providers)
|
||||
widget.containerWidgetBase.SetProviders(providers)
|
||||
}
|
||||
|
||||
func (widget *Group) RequiresUpdate(now *time.Time) bool {
|
||||
return widget.containerWidget.RequiresUpdate(now)
|
||||
return widget.containerWidgetBase.RequiresUpdate(now)
|
||||
}
|
||||
|
||||
func (widget *Group) Render() template.HTML {
|
||||
|
|
42
internal/widget/split-column.go
Normal file
42
internal/widget/split-column.go
Normal file
|
@ -0,0 +1,42 @@
|
|||
package widget
|
||||
|
||||
import (
|
||||
"context"
|
||||
"html/template"
|
||||
"time"
|
||||
|
||||
"github.com/glanceapp/glance/internal/assets"
|
||||
)
|
||||
|
||||
type SplitColumn struct {
|
||||
widgetBase `yaml:",inline"`
|
||||
containerWidgetBase `yaml:",inline"`
|
||||
}
|
||||
|
||||
func (widget *SplitColumn) Initialize() error {
|
||||
widget.withError(nil).withTitle("Split Column").SetHideHeader(true)
|
||||
|
||||
for i := range widget.Widgets {
|
||||
if err := widget.Widgets[i].Initialize(); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (widget *SplitColumn) Update(ctx context.Context) {
|
||||
widget.containerWidgetBase.Update(ctx)
|
||||
}
|
||||
|
||||
func (widget *SplitColumn) SetProviders(providers *Providers) {
|
||||
widget.containerWidgetBase.SetProviders(providers)
|
||||
}
|
||||
|
||||
func (widget *SplitColumn) RequiresUpdate(now *time.Time) bool {
|
||||
return widget.containerWidgetBase.RequiresUpdate(now)
|
||||
}
|
||||
|
||||
func (widget *SplitColumn) Render() template.HTML {
|
||||
return widget.render(widget, assets.SplitColumnTemplate)
|
||||
}
|
|
@ -67,6 +67,8 @@ func New(widgetType string) (Widget, error) {
|
|||
widget = &Group{}
|
||||
case "dns-stats":
|
||||
widget = &DNSStats{}
|
||||
case "split-column":
|
||||
widget = &SplitColumn{}
|
||||
default:
|
||||
return nil, fmt.Errorf("unknown widget type: %s", widgetType)
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue