mirror of
https://github.com/getAlby/lndhub.go.git
synced 2025-12-21 06:34:58 +01:00
add index page
This commit is contained in:
153
controllers/home.ctrl.go
Normal file
153
controllers/home.ctrl.go
Normal file
@@ -0,0 +1,153 @@
|
|||||||
|
package controllers
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"context"
|
||||||
|
"fmt"
|
||||||
|
"html/template"
|
||||||
|
"net/http"
|
||||||
|
"net/url"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"github.com/getAlby/lndhub.go/lib/service"
|
||||||
|
"github.com/labstack/echo/v4"
|
||||||
|
"github.com/lightningnetwork/lnd/lnrpc"
|
||||||
|
"github.com/skip2/go-qrcode"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
SAT_PER_BTC = 1e8
|
||||||
|
)
|
||||||
|
|
||||||
|
// HomeController : HomeController struct
|
||||||
|
type HomeController struct {
|
||||||
|
svc *service.LndhubService
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewHomeController(svc *service.LndhubService) *HomeController {
|
||||||
|
return &HomeController{
|
||||||
|
svc: svc,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
type HomepageContent struct {
|
||||||
|
NumActiveChannels int
|
||||||
|
NumPendingChannels int
|
||||||
|
NumPeers int
|
||||||
|
SyncedToChain bool
|
||||||
|
BlockHeight int
|
||||||
|
Uris []string
|
||||||
|
Channels []Channel
|
||||||
|
}
|
||||||
|
|
||||||
|
type Channel struct {
|
||||||
|
Name string
|
||||||
|
RemotePubkey string
|
||||||
|
CapacityBTC float64
|
||||||
|
Local int
|
||||||
|
Total int
|
||||||
|
Size int
|
||||||
|
Active bool
|
||||||
|
}
|
||||||
|
|
||||||
|
// Max returns the larger of x or y.
|
||||||
|
func Max(x, y int) int {
|
||||||
|
if x < y {
|
||||||
|
return y
|
||||||
|
}
|
||||||
|
return x
|
||||||
|
}
|
||||||
|
|
||||||
|
func (controller *HomeController) QR(c echo.Context) error {
|
||||||
|
customPath := strings.Replace(c.Request().URL.Path, "/qr", "", 1)
|
||||||
|
encoded := url.QueryEscape(fmt.Sprintf("%s://%s%s", c.Request().URL.Scheme, c.Request().Host, customPath))
|
||||||
|
url := fmt.Sprintf("bluewallet:setlndhuburl?url=%s", encoded)
|
||||||
|
png, err := qrcode.Encode(url, qrcode.Medium, 256)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return c.Blob(http.StatusOK, "image/png", png)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (controller *HomeController) Home(c echo.Context) error {
|
||||||
|
info, err := controller.svc.GetInfo(context.TODO())
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
channels, err := controller.svc.LndClient.ListChannels(context.TODO(), &lnrpc.ListChannelsRequest{})
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
tmpl, err := template.ParseFiles("templates/index.html")
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
// See original code: https://github.com/BlueWallet/LndHub/blob/master/controllers/website.js#L32
|
||||||
|
maxChanCapicity := -1
|
||||||
|
for _, ch := range channels.Channels {
|
||||||
|
maxChanCapicity = Max(maxChanCapicity, int(ch.Capacity))
|
||||||
|
}
|
||||||
|
channelSlice := []Channel{}
|
||||||
|
for _, ch := range channels.Channels {
|
||||||
|
|
||||||
|
magic := maxChanCapicity / 100
|
||||||
|
channelSlice = append(channelSlice, Channel{
|
||||||
|
Name: pubkeyToName[ch.RemotePubkey],
|
||||||
|
RemotePubkey: ch.RemotePubkey,
|
||||||
|
CapacityBTC: float64(ch.Capacity) / SAT_PER_BTC,
|
||||||
|
Local: int(ch.LocalBalance),
|
||||||
|
Total: int(ch.Capacity),
|
||||||
|
Size: int(ch.Capacity) / magic,
|
||||||
|
Active: ch.Active,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
content := HomepageContent{
|
||||||
|
NumActiveChannels: int(info.NumActiveChannels),
|
||||||
|
NumPendingChannels: int(info.NumPendingChannels),
|
||||||
|
NumPeers: int(info.NumPeers),
|
||||||
|
SyncedToChain: info.SyncedToChain,
|
||||||
|
BlockHeight: int(info.BlockHeight),
|
||||||
|
Channels: channelSlice,
|
||||||
|
Uris: info.Uris,
|
||||||
|
}
|
||||||
|
var buf bytes.Buffer
|
||||||
|
err = tmpl.Execute(&buf, content)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return c.HTMLBlob(http.StatusOK, buf.Bytes())
|
||||||
|
}
|
||||||
|
|
||||||
|
var pubkeyToName = map[string]string{
|
||||||
|
"03e50492eab4107a773141bb419e107bda3de3d55652e6e1a41225f06a0bbf2d56": "yalls.org",
|
||||||
|
"0232e20e7b68b9b673fb25f48322b151a93186bffe4550045040673797ceca43cf": "zigzag.io",
|
||||||
|
"02df5ffe895c778e10f7742a6c5b8a0cefbe9465df58b92fadeb883752c8107c8f": "blockstream store",
|
||||||
|
"030c3f19d742ca294a55c00376b3b355c3c90d61c6b6b39554dbc7ac19b141c14f": "bitrefill.com",
|
||||||
|
"03864ef025fde8fb587d989186ce6a4a186895ee44a926bfc370e2c366597a3f8f": "ACINQ",
|
||||||
|
"03abf6f44c355dec0d5aa155bdbdd6e0c8fefe318eff402de65c6eb2e1be55dc3e": "OpenNode",
|
||||||
|
"028d98b9969fbed53784a36617eb489a59ab6dc9b9d77fcdca9ff55307cd98e3c4": "OpenNode 2",
|
||||||
|
"0242a4ae0c5bef18048fbecf995094b74bfb0f7391418d71ed394784373f41e4f3": "coingate.com",
|
||||||
|
"0279c22ed7a068d10dc1a38ae66d2d6461e269226c60258c021b1ddcdfe4b00bc4": "ln1.satoshilabs.com",
|
||||||
|
"02c91d6aa51aa940608b497b6beebcb1aec05be3c47704b682b3889424679ca490": "lnd-21.LNBIG.com",
|
||||||
|
"024655b768ef40951b20053a5c4b951606d4d86085d51238f2c67c7dec29c792ca": "satoshis.place",
|
||||||
|
"03c2abfa93eacec04721c019644584424aab2ba4dff3ac9bdab4e9c97007491dda": "tippin.me",
|
||||||
|
"022c699df736064b51a33017abfc4d577d133f7124ac117d3d9f9633b6297a3b6a": "globee.com",
|
||||||
|
"0237fefbe8626bf888de0cad8c73630e32746a22a2c4faa91c1d9877a3826e1174": "1.ln.aantonop.com",
|
||||||
|
"026c7d28784791a4b31a64eb34d9ab01552055b795919165e6ae886de637632efb": "LivingRoomOfSatoshi",
|
||||||
|
"02816caed43171d3c9854e3b0ab2cf0c42be086ff1bd4005acc2a5f7db70d83774": "ln.pizza",
|
||||||
|
"0254ff808f53b2f8c45e74b70430f336c6c76ba2f4af289f48d6086ae6e60462d3": "bitrefill thor",
|
||||||
|
"03d607f3e69fd032524a867b288216bfab263b6eaee4e07783799a6fe69bb84fac": "bitrefill 3",
|
||||||
|
"02a0bc43557fae6af7be8e3a29fdebda819e439bea9c0f8eb8ed6a0201f3471ca9": "LightningPeachHub",
|
||||||
|
"02d4531a2f2e6e5a9033d37d548cff4834a3898e74c3abe1985b493c42ebbd707d": "coinfinity.co",
|
||||||
|
"02d23fa6794d8fd056c757f3c8f4877782138dafffedc831fc570cab572620dc61": "paywithmoon.com",
|
||||||
|
"025f1456582e70c4c06b61d5c8ed3ce229e6d0db538be337a2dc6d163b0ebc05a5": "paywithmoon.com",
|
||||||
|
"02004c625d622245606a1ea2c1c69cfb4516b703b47945a3647713c05fe4aaeb1c": "walletofsatoshi",
|
||||||
|
"0331f80652fb840239df8dc99205792bba2e559a05469915804c08420230e23c7c": "LightningPowerUsers.com",
|
||||||
|
"033d8656219478701227199cbd6f670335c8d408a92ae88b962c49d4dc0e83e025": "bfx-lnd0",
|
||||||
|
"03021c5f5f57322740e4ee6936452add19dc7ea7ccf90635f95119ab82a62ae268": "lnd1.bluewallet.io",
|
||||||
|
"037cc5f9f1da20ac0d60e83989729a204a33cc2d8e80438969fadf35c1c5f1233b": "lnd2.bluewallet.io",
|
||||||
|
"036b53093df5a932deac828cca6d663472dbc88322b05eec1d42b26ab9b16caa1c": "okcoin",
|
||||||
|
"038f8f113c580048d847d6949371726653e02b928196bad310e3eda39ff61723f6": "magnetron",
|
||||||
|
"03829249ef39746fd534a196510232df08b83db0967804ec71bf4120930864ff97": "blokada.org",
|
||||||
|
"02ce691b2e321954644514db708ba2a72769a6f9142ac63e65dd87964e9cf2add9": "Satoshis.Games",
|
||||||
|
}
|
||||||
1
go.mod
1
go.mod
@@ -111,6 +111,7 @@ require (
|
|||||||
github.com/rogpeppe/fastuuid v1.2.0 // indirect
|
github.com/rogpeppe/fastuuid v1.2.0 // indirect
|
||||||
github.com/rs/zerolog v1.26.0 // indirect
|
github.com/rs/zerolog v1.26.0 // indirect
|
||||||
github.com/sirupsen/logrus v1.7.0 // indirect
|
github.com/sirupsen/logrus v1.7.0 // indirect
|
||||||
|
github.com/skip2/go-qrcode v0.0.0-20200617195104-da1b6568686e // indirect
|
||||||
github.com/soheilhy/cmux v0.1.5 // indirect
|
github.com/soheilhy/cmux v0.1.5 // indirect
|
||||||
github.com/spf13/pflag v1.0.5 // indirect
|
github.com/spf13/pflag v1.0.5 // indirect
|
||||||
github.com/tmc/grpc-websocket-proxy v0.0.0-20201229170055-e5319fda7802 // indirect
|
github.com/tmc/grpc-websocket-proxy v0.0.0-20201229170055-e5319fda7802 // indirect
|
||||||
|
|||||||
2
go.sum
2
go.sum
@@ -677,6 +677,8 @@ github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6Mwd
|
|||||||
github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88=
|
github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88=
|
||||||
github.com/sirupsen/logrus v1.7.0 h1:ShrD1U9pZB12TX0cVy0DtePoCH97K8EtX+mg7ZARUtM=
|
github.com/sirupsen/logrus v1.7.0 h1:ShrD1U9pZB12TX0cVy0DtePoCH97K8EtX+mg7ZARUtM=
|
||||||
github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0=
|
github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0=
|
||||||
|
github.com/skip2/go-qrcode v0.0.0-20200617195104-da1b6568686e h1:MRM5ITcdelLK2j1vwZ3Je0FKVCfqOLp5zO6trqMLYs0=
|
||||||
|
github.com/skip2/go-qrcode v0.0.0-20200617195104-da1b6568686e/go.mod h1:XV66xRDqSt+GTGFMVlhk3ULuV0y9ZmzeVGR4mloJI3M=
|
||||||
github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc=
|
github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc=
|
||||||
github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA=
|
github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA=
|
||||||
github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM=
|
github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM=
|
||||||
|
|||||||
4
main.go
4
main.go
@@ -142,7 +142,9 @@ func main() {
|
|||||||
blankController := controllers.NewBlankController(svc)
|
blankController := controllers.NewBlankController(svc)
|
||||||
secured.GET("/getbtc", blankController.GetBtc)
|
secured.GET("/getbtc", blankController.GetBtc)
|
||||||
secured.GET("/getpending", blankController.GetPending)
|
secured.GET("/getpending", blankController.GetPending)
|
||||||
e.GET("/", blankController.Home)
|
e.GET("/", controllers.NewHomeController(svc).Home)
|
||||||
|
e.GET("/qr", controllers.NewHomeController(svc).QR)
|
||||||
|
e.Static("/static", "static")
|
||||||
|
|
||||||
// Subscribe to LND invoice updates in the background
|
// Subscribe to LND invoice updates in the background
|
||||||
go svc.InvoiceUpdateSubscription(context.Background())
|
go svc.InvoiceUpdateSubscription(context.Background())
|
||||||
|
|||||||
253
static/css/style.css
Normal file
253
static/css/style.css
Normal file
@@ -0,0 +1,253 @@
|
|||||||
|
html, body {
|
||||||
|
height: 100%;
|
||||||
|
background: #FAFBFE;
|
||||||
|
color: #000;
|
||||||
|
}
|
||||||
|
html {
|
||||||
|
-webkit-box-sizing: border-box;
|
||||||
|
-moz-box-sizing: border-box;
|
||||||
|
box-sizing: border-box
|
||||||
|
}
|
||||||
|
*, :before, :after {
|
||||||
|
box-sizing: inherit
|
||||||
|
}
|
||||||
|
body {
|
||||||
|
margin: 0;
|
||||||
|
font-family: Helvetica Neue, Menlo, Consolas, "Courier New", monospace;
|
||||||
|
word-wrap: break-word;
|
||||||
|
font-weight: 400;
|
||||||
|
height: 100%;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
.sidebar {
|
||||||
|
background: #fff;
|
||||||
|
box-shadow: 0 -1px 4px 0 rgba(0,0,0,.20);
|
||||||
|
}
|
||||||
|
.container32 {
|
||||||
|
padding: 32px;
|
||||||
|
}
|
||||||
|
.container24 {
|
||||||
|
padding: 24px;
|
||||||
|
}
|
||||||
|
.container16 {
|
||||||
|
padding: 16px;
|
||||||
|
}
|
||||||
|
.nosidepadding {
|
||||||
|
padding-right: 0;
|
||||||
|
padding-left: 0;
|
||||||
|
}
|
||||||
|
.boxes {
|
||||||
|
display: flex;
|
||||||
|
margin: 40px 0 56px 0;
|
||||||
|
}
|
||||||
|
.box {
|
||||||
|
background: #fff;
|
||||||
|
box-shadow: 0 1px 4px 0 rgba(0,0,0,.12);
|
||||||
|
border-radius: 6px;
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
.boxes .box {
|
||||||
|
width: 25%;
|
||||||
|
margin-right: 32px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.box h3 {
|
||||||
|
font-size: 18px;
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
font-weight: 500;
|
||||||
|
}
|
||||||
|
.meta {
|
||||||
|
font-size: 13px;
|
||||||
|
color: #9AA0AA;
|
||||||
|
margin: 0 0 4px 0;
|
||||||
|
padding: 0;
|
||||||
|
font-weight: 500;
|
||||||
|
}
|
||||||
|
.uri {
|
||||||
|
font-size: 13px;
|
||||||
|
color: #000;
|
||||||
|
font-weight: 500;
|
||||||
|
}
|
||||||
|
.number1 {
|
||||||
|
font-size: 30px;
|
||||||
|
font-weight: 500;
|
||||||
|
margin-top: 32px;
|
||||||
|
display: inline-block;
|
||||||
|
}
|
||||||
|
.right {
|
||||||
|
float: right;
|
||||||
|
}
|
||||||
|
.label {
|
||||||
|
padding: 4px 8px;
|
||||||
|
border-radius: 16px;
|
||||||
|
color: #fff;
|
||||||
|
font-size: 13px;
|
||||||
|
}
|
||||||
|
[title~=true], [title~=active] {
|
||||||
|
background: #50E3C2;
|
||||||
|
}
|
||||||
|
[title~=false], [title~=inactive] {
|
||||||
|
background: #8E8E8E;
|
||||||
|
}
|
||||||
|
.label[title~=true]::after {
|
||||||
|
content: "synced";
|
||||||
|
}
|
||||||
|
.label[title~=false]::after {
|
||||||
|
content: "not synced";
|
||||||
|
}
|
||||||
|
.label[title~=active]::after {
|
||||||
|
content: "active";
|
||||||
|
}
|
||||||
|
.label[title~=inactive]::after {
|
||||||
|
content: "inactive";
|
||||||
|
}
|
||||||
|
.synced {
|
||||||
|
position: absolute;
|
||||||
|
top: 24px;
|
||||||
|
right: 24px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#progressbar {
|
||||||
|
appearance: none;
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
max-width: 100%;
|
||||||
|
-webkit-appearance: none;
|
||||||
|
border-radius: 8px;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
#progressbar[max]::-webkit-progress-value {
|
||||||
|
border-radius: 8px 4px 4px 8px;
|
||||||
|
-webkit-appearance: none;
|
||||||
|
background: linear-gradient(0deg, rgba(47,95,179,1) 0%, rgba(63,120,220,1) 100%);
|
||||||
|
}
|
||||||
|
#progressbar[value]::-webkit-progress-bar {
|
||||||
|
background: linear-gradient(0deg, rgba(104,187,225,1) 0%, rgba(139,215,249,1) 100%);
|
||||||
|
height: 16px;
|
||||||
|
border-radius: 8px;
|
||||||
|
transition: 0.4s linear;
|
||||||
|
transition-property: width, background-color;
|
||||||
|
-webkit-appearance: none;
|
||||||
|
}
|
||||||
|
.row {
|
||||||
|
padding: 8px 0;
|
||||||
|
border-radius: 8px;
|
||||||
|
transition: 0.2s ease-in-out;
|
||||||
|
}
|
||||||
|
.row:hover {
|
||||||
|
background: #F4F8FB;
|
||||||
|
}
|
||||||
|
.row .name {
|
||||||
|
padding: 2px 4px 2px 8px;
|
||||||
|
}
|
||||||
|
.row .name h2 {
|
||||||
|
white-space: nowrap;
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
}
|
||||||
|
.row .graph {
|
||||||
|
flex-grow: 1;
|
||||||
|
padding: 0 16px 0 0;
|
||||||
|
align-self: center;
|
||||||
|
padding: 2px 4px;
|
||||||
|
}
|
||||||
|
.row .status {
|
||||||
|
align-self: center;
|
||||||
|
padding: 2px 8px 2px 4px;
|
||||||
|
}
|
||||||
|
.decor {
|
||||||
|
text-decoration : none;
|
||||||
|
}
|
||||||
|
.name h2 {
|
||||||
|
color: #000;
|
||||||
|
margin: 0;
|
||||||
|
font-weight: 500;
|
||||||
|
font-size: 18px;
|
||||||
|
}
|
||||||
|
.amount {
|
||||||
|
color: #9AA0AA;
|
||||||
|
margin: 4px 0;
|
||||||
|
font-weight: 500;
|
||||||
|
}
|
||||||
|
.qr {
|
||||||
|
margin: 0 -24px;
|
||||||
|
width: 268px
|
||||||
|
}
|
||||||
|
footer {
|
||||||
|
color: #9AA0AA;
|
||||||
|
}
|
||||||
|
footer a {
|
||||||
|
font-size: 14px;
|
||||||
|
color: #0070FF;
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
@media (min-width: 1200px){
|
||||||
|
body {
|
||||||
|
padding-right: 300px;
|
||||||
|
}
|
||||||
|
.sidebar {
|
||||||
|
position: fixed;
|
||||||
|
top: 0;
|
||||||
|
right: 0;
|
||||||
|
width: 300px;
|
||||||
|
height: 100%;
|
||||||
|
box-shadow: 0 0 4px 0 rgba(0,0,0,.20);
|
||||||
|
}
|
||||||
|
footer {
|
||||||
|
position: absolute;
|
||||||
|
bottom: 32px;
|
||||||
|
color: #9AA0AA;
|
||||||
|
}
|
||||||
|
.boxes .box:last-child {
|
||||||
|
margin-right: 0;
|
||||||
|
}
|
||||||
|
.row {
|
||||||
|
display: flex;
|
||||||
|
}
|
||||||
|
.row .name {
|
||||||
|
flex-grow: 0.2;
|
||||||
|
max-width: 20%;
|
||||||
|
}
|
||||||
|
.row .status {
|
||||||
|
flex-grow: 0.1;
|
||||||
|
max-width: 10%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@media (max-width: 1199px){
|
||||||
|
.logo {
|
||||||
|
width: 200px;
|
||||||
|
}
|
||||||
|
.scroll {
|
||||||
|
overflow: scroll;
|
||||||
|
padding: 0px 16px 0px 1px;
|
||||||
|
margin-right: -32px;
|
||||||
|
}
|
||||||
|
.boxes {
|
||||||
|
width: 900px;
|
||||||
|
}
|
||||||
|
.boxes .box {
|
||||||
|
width: 180px;
|
||||||
|
|
||||||
|
}
|
||||||
|
.row {
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
.row .name {
|
||||||
|
flex-grow: 0.8;
|
||||||
|
max-width: 80%;
|
||||||
|
}
|
||||||
|
.row .status {
|
||||||
|
position: absolute;
|
||||||
|
top: 16px;
|
||||||
|
right: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@media (max-width: 959px){
|
||||||
|
.logo {
|
||||||
|
width: 200px;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
BIN
static/img/favicon.png
Normal file
BIN
static/img/favicon.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 6.9 KiB |
135
templates/index.html
Normal file
135
templates/index.html
Normal file
File diff suppressed because one or more lines are too long
Reference in New Issue
Block a user