浏览代码

Allow specifying links for stock symbol & chart

Svilen Markov 1 年之前
父节点
当前提交
0fbc8dcb41

+ 12 - 10
docs/configuration.md

@@ -979,18 +979,12 @@ Example:
       name: S&P 500
     - symbol: BTC-USD
       name: Bitcoin
+      chart-link: https://www.tradingview.com/chart/?symbol=INDEX:BTCUSD
     - symbol: NVDA
       name: NVIDIA
     - symbol: AAPL
+      symbol-link: https://www.google.com/search?tbm=nws&q=apple
       name: Apple
-    - symbol: MSFT
-      name: Microsoft
-    - symbol: GOOGL
-      name: Google
-    - symbol: AMD
-      name: AMD
-    - symbol: RDDT
-      name: Reddit
 ```
 
 Preview:
@@ -1007,11 +1001,16 @@ Preview:
 ##### `stocks`
 An array of stocks for which to display information about.
 
+##### `sort-by`
+By default the stocks 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.
+
 ###### Properties for each stock
 | Name | Type | Required |
 | ---- | ---- | -------- |
 | symbol | string | yes |
 | name | string | no |
+| symbol-link | string | no |
+| chart-link | string | no |
 
 `symbol`
 
@@ -1021,8 +1020,11 @@ The symbol, as seen in Yahoo Finance.
 
 The name that will be displayed under the symbol.
 
-##### `sort-by`
-By default the stocks 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.
+`symbol-link`
+The link to go to when clicking on the symbol.
+
+`chart-link`
+The link to go to when clicking on the chart.
 
 ### Twitch Channels
 Display a list of channels from Twitch.

+ 4 - 0
internal/assets/static/main.css

@@ -545,6 +545,10 @@ body {
     width: 6.5rem;
 }
 
+.stock-chart svg {
+    width: 100%;
+}
+
 .stock-values {
     min-width: 8rem;
 }

+ 6 - 4
internal/assets/templates/stocks.html

@@ -5,13 +5,15 @@
     {{ range .Stocks }}
     <li class="flex items-center gap-15">
         <div class="shrink min-width-0">
-            <div class="color-highlight size-h3 text-truncate">{{ .Symbol }}</div>
+            <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>
 
-        <svg class="stock-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 class="stock-chart" {{ if ne "" .ChartLink }} href="{{ .ChartLink }}" target="_blank" rel="noreferrer"{{ end }}>
+            <svg class="stock-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="stock-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>

+ 8 - 6
internal/feed/primitives.go

@@ -85,12 +85,14 @@ var currencyToSymbol = map[string]string{
 }
 
 type Stock struct {
-	Name           string
-	Symbol         string
-	Currency       string
-	Price          float64
-	PercentChange  float64
-	SvgChartPoints string
+	Name           string  `yaml:"name"`
+	Symbol         string  `yaml:"symbol"`
+	ChartLink      string  `yaml:"chart-link"`
+	SymbolLink     string  `yaml:"symbol-link"`
+	Currency       string  `yaml:"-"`
+	Price          float64 `yaml:"-"`
+	PercentChange  float64 `yaml:"-"`
+	SvgChartPoints string  `yaml:"-"`
 }
 
 type Stocks []Stock

+ 7 - 10
internal/feed/yahoo.go

@@ -24,15 +24,10 @@ type stockResponseJson struct {
 	} `json:"chart"`
 }
 
-type StockRequest struct {
-	Symbol string
-	Name   string
-}
-
 // TODO: allow changing chart time frame
 const stockChartDays = 21
 
-func FetchStocksDataFromYahoo(stockRequests []StockRequest) (Stocks, error) {
+func FetchStocksDataFromYahoo(stockRequests Stocks) (Stocks, error) {
 	requests := make([]*http.Request, 0, len(stockRequests))
 
 	for i := range stockRequests {
@@ -86,10 +81,12 @@ func FetchStocksDataFromYahoo(stockRequests []StockRequest) (Stocks, error) {
 		}
 
 		stocks = append(stocks, Stock{
-			Name:     stockRequests[i].Name,
-			Symbol:   response.Chart.Result[0].Meta.Symbol,
-			Price:    response.Chart.Result[0].Meta.RegularMarketPrice,
-			Currency: currency,
+			Name:       stockRequests[i].Name,
+			Symbol:     response.Chart.Result[0].Meta.Symbol,
+			SymbolLink: stockRequests[i].SymbolLink,
+			ChartLink:  stockRequests[i].ChartLink,
+			Price:      response.Chart.Result[0].Meta.RegularMarketPrice,
+			Currency:   currency,
 			PercentChange: percentChange(
 				response.Chart.Result[0].Meta.RegularMarketPrice,
 				previous,

+ 4 - 4
internal/widget/stocks.go

@@ -9,11 +9,11 @@ import (
 	"github.com/glanceapp/glance/internal/feed"
 )
 
+// TODO: rename to Markets at some point
 type Stocks struct {
 	widgetBase `yaml:",inline"`
-	Stocks     feed.Stocks         `yaml:"-"`
-	Sort       string              `yaml:"sort-by"`
-	Tickers    []feed.StockRequest `yaml:"stocks"`
+	Stocks     feed.Stocks `yaml:"stocks"`
+	Sort       string      `yaml:"sort-by"`
 }
 
 func (widget *Stocks) Initialize() error {
@@ -23,7 +23,7 @@ func (widget *Stocks) Initialize() error {
 }
 
 func (widget *Stocks) Update(ctx context.Context) {
-	stocks, err := feed.FetchStocksDataFromYahoo(widget.Tickers)
+	stocks, err := feed.FetchStocksDataFromYahoo(widget.Stocks)
 
 	if !widget.canContinueUpdateAfterHandlingErr(err) {
 		return