diff --git a/go.mod b/go.mod index c4fef24..4b42823 100644 --- a/go.mod +++ b/go.mod @@ -3,8 +3,7 @@ module github.com/dweymouth/supersonic go 1.19 require ( - fyne.io/fyne/v2 v2.3.5 - fyne.io/x/fyne v0.0.0-20230611151101-afdcd6b92cf3 + fyne.io/fyne/v2 v2.4.1 github.com/20after4/configdir v0.1.1 github.com/dweymouth/go-mpv v0.0.0-20230406003141-7f1858e503ee github.com/dweymouth/go-subsonic v0.0.0-20231014003317-6a0c88db38ce @@ -14,37 +13,36 @@ require ( github.com/pelletier/go-toml/v2 v2.0.8 github.com/quarckster/go-mpris-server v1.0.3 github.com/zalando/go-keyring v0.2.1 - golang.org/x/net v0.0.0-20220722155237-a158d28d115b + golang.org/x/net v0.14.0 ) require ( - fyne.io/systray v1.10.1-0.20230602210930-b6a2d6ca2a7b // indirect + fyne.io/systray v1.10.1-0.20230722100817-88df1e0ffa9a // indirect github.com/alessio/shellescape v1.4.1 // indirect github.com/danieljoos/wincred v1.1.0 // indirect github.com/davecgh/go-spew v1.1.1 // indirect - github.com/fredbi/uri v0.1.0 // indirect + github.com/fredbi/uri v1.0.0 // indirect github.com/fyne-io/gl-js v0.0.0-20220119005834-d2da28d9ccfe // indirect github.com/fyne-io/glfw-js v0.0.0-20220120001248-ee7290d23504 // indirect github.com/fyne-io/image v0.0.0-20220602074514-4956b0afb3d2 // indirect github.com/go-gl/gl v0.0.0-20211210172815-726fda9656d6 // indirect github.com/go-gl/glfw/v3.3/glfw v0.0.0-20221017161538-93cebf72946b // indirect - github.com/go-text/typesetting v0.0.0-20230405155246-bf9c697c6e16 // indirect - github.com/goki/freetype v0.0.0-20220119013949-7a161fd3728c // indirect + github.com/go-text/render v0.0.0-20230619120952-35bccb6164b8 // indirect + github.com/go-text/typesetting v0.0.0-20230616162802-9c17dd34aa4a // indirect github.com/gopherjs/gopherjs v1.17.2 // indirect github.com/jsummers/gobmp v0.0.0-20151104160322-e2ba15ffa76e // indirect - github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect - github.com/srwiley/oksvg v0.0.0-20220731023508-a61f04f16b76 // indirect - github.com/srwiley/rasterx v0.0.0-20210519020934-456a8d69b780 // indirect - github.com/stretchr/testify v1.8.3 // indirect + github.com/srwiley/oksvg v0.0.0-20221011165216-be6e8873101c // indirect + github.com/srwiley/rasterx v0.0.0-20220730225603-2ab79fcdd4ef // indirect + github.com/stretchr/testify v1.8.4 // indirect github.com/tevino/abool v1.2.0 // indirect - github.com/yuin/goldmark v1.4.13 // indirect - golang.org/x/image v0.3.0 // indirect - golang.org/x/mobile v0.0.0-20211207041440-4e6c2922fdee // indirect - golang.org/x/sys v0.0.0-20220908164124-27713097b956 // indirect - golang.org/x/text v0.6.0 // indirect + github.com/yuin/goldmark v1.5.5 // indirect + golang.org/x/image v0.11.0 // indirect + golang.org/x/mobile v0.0.0-20230531173138-3c911d8e3eda // indirect + golang.org/x/sys v0.11.0 // indirect + golang.org/x/text v0.12.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect honnef.co/go/js/dom v0.0.0-20210725211120-f030747120f2 // indirect ) -replace fyne.io/fyne/v2 v2.3.5 => github.com/dweymouth/fyne/v2 v2.3.0-rc1.0.20231019154213-5f32d36c2968 +replace fyne.io/fyne/v2 v2.4.1 => github.com/dweymouth/fyne/v2 v2.3.0-rc1.0.20231103053003-b6f79d3c81cd diff --git a/go.sum b/go.sum index d358c7b..af7f8b1 100644 --- a/go.sum +++ b/go.sum @@ -37,18 +37,12 @@ cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohl cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs= cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0= dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= -fyne.io/systray v1.10.1-0.20230403195833-7dc3c09283d6/go.mod h1:oM2AQqGJ1AMo4nNqZFYU8xYygSBZkW2hmdJ7n4yjedE= -fyne.io/systray v1.10.1-0.20230602210930-b6a2d6ca2a7b h1:MP1cUnIdF1cxrMhK9iw9H0JP3zopyD1zi84BqU6WTsE= -fyne.io/systray v1.10.1-0.20230602210930-b6a2d6ca2a7b/go.mod h1:oM2AQqGJ1AMo4nNqZFYU8xYygSBZkW2hmdJ7n4yjedE= -fyne.io/x/fyne v0.0.0-20230611151101-afdcd6b92cf3 h1:PYQpybIWYSfheDLt5qvd0acmDQIPs8Npem3INFXX72w= -fyne.io/x/fyne v0.0.0-20230611151101-afdcd6b92cf3/go.mod h1:Ygr+Jy2eAg35VdG3qX9WDyTnj8ruxJX3M4eh+PjRsoE= +fyne.io/systray v1.10.1-0.20230722100817-88df1e0ffa9a h1:6Xf9fP3/mt72NrqlQhJWhQGcNf6GoG9X96NTaXr+K6A= +fyne.io/systray v1.10.1-0.20230722100817-88df1e0ffa9a/go.mod h1:oM2AQqGJ1AMo4nNqZFYU8xYygSBZkW2hmdJ7n4yjedE= github.com/20after4/configdir v0.1.1 h1:ylL5dO+aGxBV4jDtG9Ej9hZfeE8Fw9jULQVq0N+ErJ8= github.com/20after4/configdir v0.1.1/go.mod h1:kZ7yOiD6MFUABqBI2/N62QA1wyEB8sGeI+mygme1pl4= -github.com/Andrew-M-C/go.jsonvalue v1.1.2-0.20211223013816-e873b56b4a84/go.mod h1:oTJGG91FhtsxvUFVwHSvr6zuaTcAuroj/ToxfT7Ox8U= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= -github.com/BurntSushi/toml v1.1.0/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ= github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= -github.com/akavel/rsrc v0.10.2/go.mod h1:uLoCtb9J+EyAqh+26kdrTgmzRBFPGOolLWKpdxkKq+c= github.com/alessio/shellescape v1.4.1 h1:V7yhSDDn8LP4lc4jS8pFkt0zCnzVJlG5JXy9BVKJUX0= github.com/alessio/shellescape v1.4.1/go.mod h1:PZAiSCk0LJaZkiCSkPv8qIobYglO3FPpyFjDCtHLS30= github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY= @@ -68,19 +62,17 @@ github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnht github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= github.com/coreos/go-systemd/v22 v22.3.2/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= -github.com/cpuguy83/go-md2man/v2 v2.0.1/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= github.com/danieljoos/wincred v1.1.0 h1:3RNcEpBg4IhIChZdFRSdlQt1QjCp1sMAPIrOnm7Yf8g= github.com/danieljoos/wincred v1.1.0/go.mod h1:XYlo+eRTsVA9aHGp7NGjFkPla4m+DCL7hqDjlFjiygg= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/dweymouth/fyne/v2 v2.3.0-rc1.0.20231019154213-5f32d36c2968 h1:RYHUvyoVXfXprkVU06XkzupfldcZ9vlhslxFYi00YCY= -github.com/dweymouth/fyne/v2 v2.3.0-rc1.0.20231019154213-5f32d36c2968/go.mod h1:X2+NrR+62mvAiAt2fwKT7035zQsE77KVV1NlvWo4vW8= +github.com/dweymouth/fyne/v2 v2.3.0-rc1.0.20231103053003-b6f79d3c81cd h1:7uiwltM4gnlMPhVxQ28eW7AQVPy6XZMkeB9+xrJM6s8= +github.com/dweymouth/fyne/v2 v2.3.0-rc1.0.20231103053003-b6f79d3c81cd/go.mod h1:AWM1iPM2YfliduZ4u/kQzP9E6ARIWm0gg+57GpYzWro= github.com/dweymouth/go-mpv v0.0.0-20230406003141-7f1858e503ee h1:ZGyJ6wp7CAfT31BugypcF/TPKEy2RrGR9JFq1JOjOpY= github.com/dweymouth/go-mpv v0.0.0-20230406003141-7f1858e503ee/go.mod h1:Ov0ieN90M7i+0k3OxhA/g1dozGs+UcPHDsMKqPgRDk0= github.com/dweymouth/go-subsonic v0.0.0-20231014003317-6a0c88db38ce h1:R12c/hE0licao74iAu2YDPJNI0jhGNuTyzmu3dMgFHE= github.com/dweymouth/go-subsonic v0.0.0-20231014003317-6a0c88db38ce/go.mod h1:fUez6NFiEJiQTZizZ1BThZr5GJXAbigzGYjEPNm4tdI= -github.com/eclipse/paho.mqtt.golang v1.3.5/go.mod h1:eTzb4gxwwyWpqBUHGQZ4ABAV7+Jgm1PklsYT/eo8Hcc= github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= @@ -89,10 +81,9 @@ github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.m github.com/envoyproxy/go-control-plane v0.9.9-0.20210217033140-668b12f5399d/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= -github.com/fredbi/uri v0.1.0 h1:8XBBD74STBLcWJ5smjEkKCZivSxSKMhFB0FbQUKeNyM= -github.com/fredbi/uri v0.1.0/go.mod h1:1xC40RnIOGCaQzswaOvrzvG/3M3F0hyDVb3aO/1iGy0= +github.com/fredbi/uri v1.0.0 h1:s4QwUAZ8fz+mbTsukND+4V5f+mJ/wjaTokwstGUAemg= +github.com/fredbi/uri v1.0.0/go.mod h1:1xC40RnIOGCaQzswaOvrzvG/3M3F0hyDVb3aO/1iGy0= github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= -github.com/fsnotify/fsnotify v1.5.4/go.mod h1:OVB6XrOHzAwXMpEM7uPOzcehqUV2UqJxmVXmkdnm1bU= github.com/fsnotify/fsnotify v1.6.0 h1:n+5WquG0fcWoWp6xPWfHdbskMCQaFnG6PfBrh1Ky4HY= github.com/fsnotify/fsnotify v1.6.0/go.mod h1:sl3t1tCWJFWoRz9R8WJCbQihKKwmorjAbSClcnxKAGw= github.com/fyne-io/gl-js v0.0.0-20220119005834-d2da28d9ccfe h1:A/wiwvQ0CAjPkuJytaD+SsXkPU0asQ+guQEIg1BJGX4= @@ -110,18 +101,16 @@ github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2 github.com/go-gl/glfw/v3.3/glfw v0.0.0-20211213063430-748e38ca8aec/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= github.com/go-gl/glfw/v3.3/glfw v0.0.0-20221017161538-93cebf72946b h1:GgabKamyOYguHqHjSkDACcgoPIz3w0Dis/zJ1wyHHHU= github.com/go-gl/glfw/v3.3/glfw v0.0.0-20221017161538-93cebf72946b/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= -github.com/go-ole/go-ole v1.2.6/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0= -github.com/go-text/typesetting v0.0.0-20230405155246-bf9c697c6e16 h1:DvHeDNqK8cxdZ7C6y88pt3uE7euZH7/LluzyfnUfH/Q= -github.com/go-text/typesetting v0.0.0-20230405155246-bf9c697c6e16/go.mod h1:zvWM81wAVW6QfVDI6yxfbCuoLnobSYTuMsrXU/u11y8= -github.com/go-text/typesetting-utils v0.0.0-20230326210548-458646692de6 h1:zAAA1U4ykFwqPbcj6YDxvq3F2g0wc/ngPfLJjkR/8zs= -github.com/go-text/typesetting-utils v0.0.0-20230326210548-458646692de6/go.mod h1:RaqFwjcYyM5BjbYGwON0H5K0UqwO3sJlo9ukKha80ZE= +github.com/go-text/render v0.0.0-20230619120952-35bccb6164b8 h1:VkKnvzbvHqgEfm351rfr8Uclu5fnwq8HP2ximUzJsBM= +github.com/go-text/render v0.0.0-20230619120952-35bccb6164b8/go.mod h1:h29xCucjNsDcYb7+0rJokxVwYAq+9kQ19WiFuBKkYtc= +github.com/go-text/typesetting v0.0.0-20230616162802-9c17dd34aa4a h1:VjN8ttdfklC0dnAdKbZqGNESdERUxtE3l8a/4Grgarc= +github.com/go-text/typesetting v0.0.0-20230616162802-9c17dd34aa4a/go.mod h1:evDBbvNR/KaVFZ2ZlDSOWWXIUKq0wCOEtzLxRM8SG3k= +github.com/go-text/typesetting-utils v0.0.0-20230616150549-2a7df14b6a22 h1:LBQTFxP2MfsyEDqSKmUBZaDuDHN1vpqDyOZjcqS7MYI= github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= github.com/godbus/dbus/v5 v5.0.6/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= github.com/godbus/dbus/v5 v5.1.0 h1:4KLkAxT3aOY8Li4FRJe/KvhoNFFxo0m6fNuFUO8QJUk= github.com/godbus/dbus/v5 v5.1.0/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= -github.com/goki/freetype v0.0.0-20220119013949-7a161fd3728c h1:JGCm/+tJ9gC6THUxooTldS+CUDsba0qvkvU3DHklqW8= -github.com/goki/freetype v0.0.0-20220119013949-7a161fd3728c/go.mod h1:wfqRWLHRBsRgkp5dmbG56SA0DmVtwrF5N3oPdI8t+Aw= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= @@ -190,7 +179,6 @@ github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORR github.com/gopherjs/gopherjs v0.0.0-20211219123610-ec9572f70e60/go.mod h1:cz9oNYuRUWGdHmLF2IodMLkAhcPtXeULvcBNagUrxTI= github.com/gopherjs/gopherjs v1.17.2 h1:fQnZVsXk8uxXIStYb0N4bGk7jeyTalG/wsZjQ25dO0g= github.com/gopherjs/gopherjs v1.17.2/go.mod h1:pRRIvn/QzFLrKfvEz3qUuEhtE/zLCWfreZ6J5gM2i+k= -github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= github.com/goxjs/gl v0.0.0-20210104184919-e3fafc6f8f2a/go.mod h1:dy/f2gjY09hwVfIyATps4G2ai7/hLwLkc5TrPqONuXY= github.com/goxjs/glfw v0.0.0-20191126052801-d2efb5f20838/go.mod h1:oS8P8gVOT4ywTcjV6wZlOU4GuVFQ8F5328KY3MJ79CY= github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw= @@ -217,8 +205,6 @@ github.com/hashicorp/serf v0.8.2/go.mod h1:6hOLApaqBFA1NXqRQAsxw9QxuDEvNxSQRwA/J github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= -github.com/jackmordaunt/icns/v2 v2.2.1/go.mod h1:6aYIB9eSzyfHHMKqDf17Xrs1zetQPReAkiUSHzdw4cI= -github.com/josephspurrier/goversioninfo v1.4.0/go.mod h1:JWzv5rKQr+MmW+LvM412ToT/IkYDZjaclF2pKDss8IY= github.com/json-iterator/go v1.1.11/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk= @@ -228,15 +214,14 @@ github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfV github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg= +github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= -github.com/lucor/goinfo v0.0.0-20210802170112-c078a2b0f08b/go.mod h1:PRq09yoB+Q2OJReAmwzKivcYyremnibWGbK7WfftHzc= github.com/magiconair/properties v1.8.5/go.mod h1:y3VJvCyxH9uVvJTWEGAELF3aiYNyPKd5NZ3oSwXrF60= github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= -github.com/mcuadros/go-version v0.0.0-20190830083331-035f6764e8d2/go.mod h1:76rfSfYPWj01Z85hUf/ituArm797mNKcvINh1OlsZKo= github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg= github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc= github.com/mitchellh/go-homedir v1.0.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= @@ -251,10 +236,6 @@ github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lN github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= github.com/neelance/astrewrite v0.0.0-20160511093645-99348263ae86/go.mod h1:kHJEU3ofeGjhHklVoIGuVj85JJwZ6kWPaJwCIxgnFmo= github.com/neelance/sourcemap v0.0.0-20200213170602-2833bce08e4c/go.mod h1:Qr6/a/Q4r9LP1IltGz7tA7iOK1WonHEYhu1HRBA7ZiM= -github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646 h1:zYyBkD/k9seD2A7fsi6Oo2LfFZAehjjQMERAvZLEDnQ= -github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646/go.mod h1:jpp1/29i3P1S/RLdc7JQKbRpFeM1dOBd8T9ki5s+AY8= -github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs= -github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= github.com/pelletier/go-toml v1.9.3/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c= github.com/pelletier/go-toml/v2 v2.0.8 h1:0ctb6s9mE31h0/lhu+J6OPmVeDxJn+kYnJc2jZR9tGQ= @@ -270,14 +251,12 @@ github.com/quarckster/go-mpris-server v1.0.3/go.mod h1:2b4IdrpnEoEfU+6fQKjYhAgdv github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= -github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc= github.com/shurcooL/go v0.0.0-20200502201357-93f07166e636/go.mod h1:TDJrrUr11Vxrven61rcy3hJMUqaf/CLWYhHNPmT14Lk= github.com/shurcooL/httpfs v0.0.0-20190707220628-8d4bc4ba7749/go.mod h1:ZY1cvUeJuFPAdZ/B6v7RHavJWZn2YPVFQ1OSXhCGOkg= github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= github.com/shurcooL/vfsgen v0.0.0-20200824052919-0d455de96546/go.mod h1:TrYk7fJVaAttu97ZZKrO9UbRa8izdowaMIZcxYMbVaw= -github.com/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= 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/spf13/afero v1.6.0/go.mod h1:Ai8FlHk4v/PARR026UzYexafAt9roJ7LcLMAmO6Z93I= @@ -286,10 +265,10 @@ github.com/spf13/cobra v1.2.1/go.mod h1:ExllRjgxM/piMAM+3tAZvg8fsklGAf3tPfi+i8t6 github.com/spf13/jwalterweatherman v1.1.0/go.mod h1:aNWZUN0dPAAO/Ljvb5BEdw96iTZ0EXowPYD95IqWIGo= github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= github.com/spf13/viper v1.8.1/go.mod h1:o0Pch8wJ9BVSWGQMbra6iw0oQ5oktSIBaujf1rJH9Ns= -github.com/srwiley/oksvg v0.0.0-20220731023508-a61f04f16b76 h1:Ga2uagHhDeGysCixLAzH0mS2TU+CrbQavmsHUNkEEVA= -github.com/srwiley/oksvg v0.0.0-20220731023508-a61f04f16b76/go.mod h1:cNQ3dwVJtS5Hmnjxy6AgTPd0Inb3pW05ftPSX7NZO7Q= -github.com/srwiley/rasterx v0.0.0-20210519020934-456a8d69b780 h1:oDMiXaTMyBEuZMU53atpxqYsSB3U1CHkeAu2zr6wTeY= -github.com/srwiley/rasterx v0.0.0-20210519020934-456a8d69b780/go.mod h1:mvWM0+15UqyrFKqdRjY6LuAVJR0HOVhJlEgZ5JWtSWU= +github.com/srwiley/oksvg v0.0.0-20221011165216-be6e8873101c h1:km8GpoQut05eY3GiYWEedbTT0qnSxrCjsVbb7yKY1KE= +github.com/srwiley/oksvg v0.0.0-20221011165216-be6e8873101c/go.mod h1:cNQ3dwVJtS5Hmnjxy6AgTPd0Inb3pW05ftPSX7NZO7Q= +github.com/srwiley/rasterx v0.0.0-20220730225603-2ab79fcdd4ef h1:Ch6Q+AZUxDBCVqdkI8FSpFyZDtCVBc2VmejdNrm5rRQ= +github.com/srwiley/rasterx v0.0.0-20220730225603-2ab79fcdd4ef/go.mod h1:nXTWP6+gD5+LUJ8krVhhoeHjvHTutPxMYl5SvkcnJNE= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= github.com/stretchr/objx v0.5.0 h1:1zr/of2m5FGMsad5YfcqgdqdWrIhu+EBEJRhR1U7z/c= @@ -302,21 +281,21 @@ github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/ github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= -github.com/stretchr/testify v1.8.3 h1:RP3t2pwF7cMEbC1dqtB6poj3niw/9gnV4Cjg5oW5gtY= github.com/stretchr/testify v1.8.3/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= +github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk= +github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw= github.com/tevino/abool v1.2.0 h1:heAkClL8H6w+mK5md9dzsuohKeXHUpY7Vw0ZCKW+huA= github.com/tevino/abool v1.2.0/go.mod h1:qc66Pna1RiIsPa7O4Egxxs9OqkuxDX55zznh9K07Tzg= -github.com/urfave/cli/v2 v2.4.0/go.mod h1:NX9W0zmTvedE5oDoOMs2RTC8RvdK98NTYZE5LbaEYPg= -github.com/wagslane/go-password-validator v0.3.0/go.mod h1:TI1XJ6T5fRdRnHqHt14pvy1tNVnrwe7m3/f1f2fDphQ= github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= github.com/yuin/goldmark v1.4.0/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= -github.com/yuin/goldmark v1.4.13 h1:fVcFKWvrslecOb/tg+Cc05dkeYx540o0FuFt3nUVDoE= github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= +github.com/yuin/goldmark v1.5.5 h1:IJznPe8wOzfIKETmMkd06F8nXkmlhaHqFRM9l1hAGsU= +github.com/yuin/goldmark v1.5.5/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= github.com/zalando/go-keyring v0.2.1 h1:MBRN/Z8H4U5wEKXiD67YbDAr5cj/DOStmSga70/2qKc= github.com/zalando/go-keyring v0.2.1/go.mod h1:g63M2PPn0w5vjmEbwAX3ib5I+41zdm4esSETOn9Y6Dw= go.etcd.io/etcd/api/v3 v3.5.0/go.mod h1:cbVKeC6lCfl7j/8jBhAK6aIYO9XOjdptoxU/nLQcPvs= @@ -354,9 +333,8 @@ golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EH golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU= golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= -golang.org/x/image v0.0.0-20211028202545-6944b10bf410/go.mod h1:023OzeP/+EPmXeapQh35lcL3II3LrY8Ic+EFFKVhULM= -golang.org/x/image v0.3.0 h1:HTDXbdK9bjfSWkPzDJIw89W8CAtfFGduujWs33NLLsg= -golang.org/x/image v0.3.0/go.mod h1:fXd9211C/0VTlYuAcOhW8dY/RtEJqODXOWBDpmYBf+A= +golang.org/x/image v0.11.0 h1:ds2RoQvBvYTiJkwpSFDwCcDFNX7DqjL2WsUgTNk0Ooo= +golang.org/x/image v0.11.0/go.mod h1:bglhjqbqVuEb9e9+eNR45Jfu7D+T4Qan+NhQk8Ck2P8= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= @@ -371,8 +349,9 @@ golang.org/x/lint v0.0.0-20201208152925-83fdc39ff7b5/go.mod h1:3xt1FjdF8hUf6vQPI golang.org/x/lint v0.0.0-20210508222113-6edffad5e616/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE= golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o= -golang.org/x/mobile v0.0.0-20211207041440-4e6c2922fdee h1:/tShaw8UTf0XzI8DOZwQHzC7d6Vi3EtrBnftiZ4vAvU= golang.org/x/mobile v0.0.0-20211207041440-4e6c2922fdee/go.mod h1:pe2sM7Uk+2Su1y7u/6Z8KJ24D7lepUjFZbhFOrmDfuQ= +golang.org/x/mobile v0.0.0-20230531173138-3c911d8e3eda h1:O+EUvnBNPwI4eLthn8W5K+cS8zQZfgTABPLNm6Bna34= +golang.org/x/mobile v0.0.0-20230531173138-3c911d8e3eda/go.mod h1:aAjjkJNdrh3PMckS4B10TGS2nag27cbKR1y2BpUxsiY= golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc= golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY= golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= @@ -383,6 +362,7 @@ golang.org/x/mod v0.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= +golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181023162649-9b4f9f5ad519/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -404,7 +384,6 @@ golang.org/x/net v0.0.0-20200222125558-5a598a2470a0/go.mod h1:z5CRVTTTmAJ677TzLL golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200301022130-244492dfa37a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= -golang.org/x/net v0.0.0-20200425230154-ff2c4b7c35a0/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20200501053045-e0ff5e5a1de5/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20200506145744-7e3656a0809f/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20200513185701-a91f0712d120/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= @@ -421,9 +400,10 @@ golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v golang.org/x/net v0.0.0-20210316092652-d523dce5a7f4/go.mod h1:RBQZq4jEuRlivfhVLdyRGr576XBO4/greRjx4P4O3yc= golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= golang.org/x/net v0.0.0-20210805182204-aaa1db679c0d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= -golang.org/x/net v0.0.0-20211118161319-6a13c67c3ce4/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= -golang.org/x/net v0.0.0-20220722155237-a158d28d115b h1:PxfKdU9lEEDYjdIzOtC4qFWgkU2rGHdKlKowJSMN9h0= golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= +golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= +golang.org/x/net v0.14.0 h1:BONx9s002vGdD9umnlX1Po8vOZmrgH34qlHcD1MfK14= +golang.org/x/net v0.14.0/go.mod h1:PpSgVXXLK0OxS0F31C1/tv6XNguvCrnXIDrFMspZIUI= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= @@ -448,6 +428,7 @@ golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181026203630-95b1ffbd15a5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -459,10 +440,8 @@ golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200113162924-86b910548bc1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -495,13 +474,15 @@ golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210809222454-d867a43fc93e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220412211240-33da011f77ad/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220908164124-27713097b956 h1:XeJjHH1KiLpKGb6lvMiksZ9l0fVUh+AmGcm0nOMEBOY= golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.11.0 h1:eG7RXZHdqOJ1i+0lgLgCpSXAp6M3LYlAo6osgSi0xOM= +golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= +golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -511,8 +492,9 @@ golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= -golang.org/x/text v0.6.0 h1:3XmdazWV+ubf7QgHSTWeykHOci5oeekaGJBLkrkaw4k= -golang.org/x/text v0.6.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= +golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= +golang.org/x/text v0.12.0 h1:k+n5B8goJNdU7hSvEtMUz3d1Q6D/XW4COJSJR6fN0mc= +golang.org/x/text v0.12.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= @@ -570,6 +552,7 @@ golang.org/x/tools v0.1.2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.8-0.20211022200916-316ba0b74098/go.mod h1:LGqMHiF4EqQNHR1JncWGqT5BVaXmza+X+BDGol+dOxo= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= +golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= @@ -677,9 +660,8 @@ google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlba google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f h1:BLraFXnmrev5lT+xlilqcH8XK9/i0At2xKjWk4p6zsU= -gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= gopkg.in/ini.v1 v1.62.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= diff --git a/res/bundled.go b/res/bundled.go index 0cd5803..d8f79e0 100644 --- a/res/bundled.go +++ b/res/bundled.go @@ -153,7 +153,7 @@ var ResRepeatoneSvg = &fyne.StaticResource{ var ResDefaultToml = &fyne.StaticResource{ StaticName: "default.toml", StaticContent: []byte( - "[SupersonicTheme]\nName = \"Default\"\nVersion = \"0.1\"\nSupportsDark = true\nSupportsLight = true\n\n[DarkColors]\nPageBackground = \"#0F0F0F\"\nListHeader = \"#232323\"\nBackground = \"#232323\"\nScrollBar = \"#F3F3F3\"\nButton = \"#14141432\"\nInputBackground = \"#14141432\"\n\n[LightColors]\nPageBackground = \"#FAFAFA\"\nListHeader = \"#E1DFE1\"\nBackground = \"#E1DFE1\"\nScrollBar = \"#565656\"\nButton = \"#C8C8C8F0\"\nDisabledButton = \"#CDCDCDF0\"\nForeground = \"#0A0A0A\"\nPrimary = \"#1919FA\""), + "[SupersonicTheme]\nName = \"Default\"\nVersion = \"0.2\"\nSupportsDark = true\nSupportsLight = true\n\n[DarkColors]\nPageBackground = \"#0F0F0F\"\nListHeader = \"#232323\"\nBackground = \"#232323\"\nScrollBar = \"#F3F3F3\"\nButton = \"#14141432\"\nInputBackground = \"#14141432\"\n\n[LightColors]\nPageBackground = \"#FAFAFA\"\nListHeader = \"#E1DFE1\"\nBackground = \"#E1DFE1\"\nScrollBar = \"#565656\"\nButton = \"#C8C8C8F0\"\nDisabledButton = \"#CDCDCDF0\"\nForeground = \"#0A0A0A\"\nHyperlink = \"#3737FB\""), } var ResLICENSE = &fyne.StaticResource{ StaticName: "LICENSE", diff --git a/res/themes/default.toml b/res/themes/default.toml index a7c0dc7..a126d3a 100644 --- a/res/themes/default.toml +++ b/res/themes/default.toml @@ -1,6 +1,6 @@ [SupersonicTheme] Name = "Default" -Version = "0.1" +Version = "0.2" SupportsDark = true SupportsLight = true @@ -20,4 +20,4 @@ ScrollBar = "#565656" Button = "#C8C8C8F0" DisabledButton = "#CDCDCDF0" Foreground = "#0A0A0A" -Primary = "#1919FA" \ No newline at end of file +Hyperlink = "#3737FB" \ No newline at end of file diff --git a/ui/browsing/browsingpane.go b/ui/browsing/browsingpane.go index 7c33c0d..d551dec 100644 --- a/ui/browsing/browsingpane.go +++ b/ui/browsing/browsingpane.go @@ -74,7 +74,7 @@ func NewBrowsingPane(app *backend.App) *BrowsingPane { b.app.PlaybackManager.OnSongChange(b.onSongChange) b.app.PlaybackManager.OnPlayTimeUpdate(b.onPlayTimeUpdate) bkgrnd := myTheme.NewThemedRectangle(myTheme.ColorNamePageBackground) - b.pageContainer = container.NewMax(bkgrnd, layout.NewSpacer()) + b.pageContainer = container.NewStack(bkgrnd, layout.NewSpacer()) b.settingsBtn = widget.NewButtonWithIcon("", theme.SettingsIcon(), func() { p := widget.NewPopUpMenu(b.settingsMenu, fyne.CurrentApp().Driver().CanvasForObject(b.settingsBtn)) diff --git a/ui/browsing/genrespage.go b/ui/browsing/genrespage.go index 0136601..c985400 100644 --- a/ui/browsing/genrespage.go +++ b/ui/browsing/genrespage.go @@ -144,7 +144,7 @@ type GenreList struct { columnsLayout *layouts.ColumnsLayout hdr *widgets.ListHeader - list *widget.List + list *widgets.DisabledList container *fyne.Container } @@ -184,7 +184,7 @@ func NewGenreList(sorting widgets.ListHeaderSort) *GenreList { {"Name", fyne.TextAlignLeading, false}, {"Album Count", fyne.TextAlignTrailing, false}, {"Track Count", fyne.TextAlignTrailing, false}}, a.columnsLayout) a.hdr.SetSorting(sorting) a.hdr.OnColumnSortChanged = a.onSorted - a.list = widget.NewList( + a.list = widgets.NewDisabledList( func() int { return len(a.genres) }, func() fyne.CanvasObject { r := NewGenreListRow(a.columnsLayout) diff --git a/ui/browsing/gridviewpage.go b/ui/browsing/gridviewpage.go index b462d13..64dee60 100644 --- a/ui/browsing/gridviewpage.go +++ b/ui/browsing/gridviewpage.go @@ -158,19 +158,16 @@ func (g *GridViewPage) createSearchAndFilter() { func (g *GridViewPage) createContainer() { header := container.NewHBox(util.NewHSpace(6), g.title) if g.sortOrder != nil { - sortVbox := container.NewVBox(layout.NewSpacer(), g.sortOrder, layout.NewSpacer()) - header.Add(sortVbox) + header.Add(container.NewCenter(g.sortOrder)) } if b := g.adapter.ActionButton(); b != nil { - btnVbox := container.NewVBox(layout.NewSpacer(), b, layout.NewSpacer()) - header.Add(btnVbox) + header.Add(container.NewCenter(b)) } header.Add(layout.NewSpacer()) if g.filterBtn != nil { header.Add(container.NewCenter(g.filterBtn)) } - searchVbox := container.NewVBox(layout.NewSpacer(), g.searcher, layout.NewSpacer()) - header.Add(searchVbox) + header.Add(container.NewCenter(g.searcher)) header.Add(util.NewHSpace(12)) g.container = container.NewBorder(header, nil, nil, nil, g.grid) } diff --git a/ui/browsing/playlistspage.go b/ui/browsing/playlistspage.go index dbf9b92..b77db8c 100644 --- a/ui/browsing/playlistspage.go +++ b/ui/browsing/playlistspage.go @@ -289,7 +289,7 @@ type PlaylistList struct { columnsLayout *layouts.ColumnsLayout header *widgets.ListHeader - list *widget.List + list *widgets.DisabledList container *fyne.Container } @@ -299,7 +299,7 @@ func NewPlaylistList(initialSort widgets.ListHeaderSort) *PlaylistList { columnsLayout: layouts.NewColumnsLayout([]float32{-1, -1, 200, 125}), } a.buildHeader() - a.list = widget.NewList( + a.list = widgets.NewDisabledList( func() int { return len(a.playlists) }, diff --git a/ui/dialogs/graphicequalizer.go b/ui/dialogs/graphicequalizer.go index c1030d3..9b7059f 100644 --- a/ui/dialogs/graphicequalizer.go +++ b/ui/dialogs/graphicequalizer.go @@ -63,7 +63,7 @@ func (g *GraphicEqualizer) buildSliders(preamp float64, bands []string, bandGain c := container.NewBorder(nil, l, nil, nil, s) bandSliders.Add(c) } - g.container = container.NewMax( + g.container = container.NewStack( container.NewBorder(nil, widget.NewLabel(""), nil, nil, container.NewBorder(nil, nil, util.NewHSpace(5), util.NewHSpace(5), container.NewVBox( diff --git a/ui/theme/theme.go b/ui/theme/theme.go index 889edd9..bd5594d 100644 --- a/ui/theme/theme.go +++ b/ui/theme/theme.go @@ -53,7 +53,10 @@ var _ fyne.Theme = (*MyTheme)(nil) func NewMyTheme(config *backend.ThemeConfig, themeFileDir string) *MyTheme { m := &MyTheme{config: config, themeFileDir: themeFileDir} - m.defaultThemeFile, _ = DecodeThemeFile(bytes.NewReader(res.ResDefaultToml.StaticContent)) + var err error + if m.defaultThemeFile, err = DecodeThemeFile(bytes.NewReader(res.ResDefaultToml.StaticContent)); err != nil { + log.Fatalf("Failed to load builtin theme: %v", err.Error()) + } m.createThemeIcons() return m } @@ -103,6 +106,8 @@ func (m *MyTheme) Color(name fyne.ThemeColorName, _ fyne.ThemeVariant) color.Col return colorOrDefault(colors.Foreground, defColors.Foreground, name, variant) case theme.ColorNameHover: return colorOrDefault(colors.Hover, defColors.Hover, name, variant) + case theme.ColorNameHyperlink: + return colorOrDefault(colors.Hyperlink, defColors.Hyperlink, name, variant) case theme.ColorNameInputBackground: return colorOrDefault(colors.InputBackground, defColors.InputBackground, name, variant) case theme.ColorNameInputBorder: diff --git a/ui/theme/themedrectangle.go b/ui/theme/themedrectangle.go index 843f592..34ca653 100644 --- a/ui/theme/themedrectangle.go +++ b/ui/theme/themedrectangle.go @@ -15,10 +15,11 @@ type ThemedRectangle struct { rect *canvas.Rectangle - ColorName fyne.ThemeColorName - Translucent bool - BorderWidth float32 - BorderColorName fyne.ThemeColorName + ColorName fyne.ThemeColorName + Translucent bool + BorderWidth float32 + BorderColorName fyne.ThemeColorName + CornerRadiusName fyne.ThemeSizeName } func NewThemedRectangle(colorName fyne.ThemeColorName) *ThemedRectangle { @@ -42,6 +43,9 @@ func (t *ThemedRectangle) Refresh() { t.rect.FillColor = fc t.rect.StrokeWidth = t.BorderWidth t.rect.StrokeColor = theme.Color(t.BorderColorName, settings.ThemeVariant()) + if t.CornerRadiusName != "" { + t.rect.CornerRadius = theme.Size(t.CornerRadiusName) + } t.BaseWidget.Refresh() } diff --git a/ui/theme/themefile.go b/ui/theme/themefile.go index 6cf2112..fab4a65 100644 --- a/ui/theme/themefile.go +++ b/ui/theme/themefile.go @@ -15,6 +15,8 @@ import ( "github.com/pelletier/go-toml/v2" ) +var validThemeVersions = []string{"0.1", "0.2"} + type ThemeFileHeader struct { Name string Version string @@ -54,6 +56,9 @@ type ThemeColors struct { Hover string + // since Supersonic theme file version 0.2 (Fyne version 2.4) + Hyperlink string + InputBackground string InputBorder string @@ -97,12 +102,13 @@ func DecodeThemeFile(reader io.Reader) (*ThemeFile, error) { return nil, err } - if theme.SupersonicTheme.Name == "" || theme.SupersonicTheme.Version != "0.1" { + if theme.SupersonicTheme.Name == "" || !sharedutil.SliceContains(validThemeVersions, theme.SupersonicTheme.Version) { return nil, errors.New("invalid theme file name or version") } if !(theme.SupersonicTheme.SupportsDark || theme.SupersonicTheme.SupportsLight) { return nil, errors.New("invalid theme file: must support one or both of light/dark") } + updateThemeToLatestVersion(theme) return theme, nil } @@ -129,3 +135,12 @@ func ColorStringToColor(colorStr string) (color.Color, error) { } return color.RGBA{R: colorBytes[0], G: colorBytes[1], B: colorBytes[2], A: colorBytes[3]}, nil } + +func updateThemeToLatestVersion(themeFile *ThemeFile) { + switch themeFile.SupersonicTheme.Version { + case "0.1": + // in version 0.1, hyperlinks were drawn with the Primary color + themeFile.DarkColors.Hyperlink = themeFile.DarkColors.Primary + themeFile.LightColors.Hyperlink = themeFile.LightColors.Primary + } +} diff --git a/ui/widgets/albumfilterbutton.go b/ui/widgets/albumfilterbutton.go index 4887d8a..2e01557 100644 --- a/ui/widgets/albumfilterbutton.go +++ b/ui/widgets/albumfilterbutton.go @@ -217,7 +217,7 @@ type GenreFilterSubsection struct { noneBtn *widget.Button listModelMutex sync.RWMutex genreListViewModel []string - genreListView *widget.List + genreListView *DisabledList container *fyne.Container } @@ -233,7 +233,7 @@ func NewGenreFilterSubsection(onChanged func([]string), initialSelectedGenres [] g.selectedGenres[genre] = nil } - g.genreListView = widget.NewList( + g.genreListView = NewDisabledList( func() int { g.listModelMutex.RLock() defer g.listModelMutex.RUnlock() diff --git a/ui/widgets/auxcontrols.go b/ui/widgets/auxcontrols.go index e426157..518a7d1 100644 --- a/ui/widgets/auxcontrols.go +++ b/ui/widgets/auxcontrols.go @@ -49,7 +49,6 @@ func NewAuxControls(initialVolume int) *AuxControls { a.container = container.NewHBox( layout.NewSpacer(), container.NewVBox( - util.NewHSpace(0), // hack to move everything down a tiny bit layout.NewSpacer(), a.VolumeControl, container.NewHBox(layout.NewSpacer(), a.loop, util.NewHSpace(5)), @@ -104,58 +103,21 @@ func NewVolumeSlider(width float32) *volumeSlider { return v } +func (v *volumeSlider) Tapped(e *fyne.PointEvent) { + v.Slider.Tapped(e) + fyne.CurrentApp().Driver().CanvasForObject(v).Unfocus() +} + func (v *volumeSlider) MinSize() fyne.Size { h := v.Slider.MinSize().Height - return fyne.NewSize(v.Width, h) + // give extra space for height to hack around mini button covering part of focus circle + return fyne.NewSize(v.Width, h+theme.Padding()*3) } func (v *volumeSlider) Scrolled(e *fyne.ScrollEvent) { v.SetValue(v.Value + float64(0.5*e.Scrolled.DY)) } -// This code will be OBSOLETE in Fyne 2.4 -// which will natively add Tappable behavior to slider -// Tapped is called when a pointer tapped event is captured. -// -// Since: 2.4 -func (v *volumeSlider) Tapped(e *fyne.PointEvent) { - ratio := v.getRatio(e) - val := v.Min + ratio*(v.Max-v.Min) - v.SetValue(val) - v.DragEnd() -} - -func (v *volumeSlider) endOffset() float32 { - return (theme.IconInlineSize()-4)/2 + theme.InnerPadding() - 1.5 // align with radio icons -} - -func (v *volumeSlider) getRatio(e *fyne.PointEvent) float64 { - pad := v.endOffset() - - x := e.Position.X - y := e.Position.Y - - switch v.Orientation { - case widget.Vertical: - if y > v.Size().Height-pad { - return 0.0 - } else if y < pad { - return 1.0 - } else { - return 1 - float64(y-pad)/float64(v.Size().Height-pad*2) - } - case widget.Horizontal: - if x > v.Size().Width-pad { - return 1.0 - } else if x < pad { - return 0.0 - } else { - return float64(x-pad) / float64(v.Size().Width-pad*2) - } - } - return 0.0 -} - type VolumeControl struct { widget.BaseWidget diff --git a/ui/widgets/disabledlist.go b/ui/widgets/disabledlist.go new file mode 100644 index 0000000..a09dc67 --- /dev/null +++ b/ui/widgets/disabledlist.go @@ -0,0 +1,33 @@ +package widgets + +import ( + "fyne.io/fyne/v2" + "fyne.io/fyne/v2/widget" +) + +// DisabledList extends List to be disabled so that the +// focus manager considers it unfocusable. +// This is needed since we handle row focusability ourselves. +type DisabledList struct { + widget.List +} + +func NewDisabledList(len func() int, create func() fyne.CanvasObject, update func(widget.GridWrapItemID, fyne.CanvasObject)) *DisabledList { + g := &DisabledList{ + List: widget.List{ + Length: len, + CreateItem: create, + UpdateItem: update, + }, + } + g.ExtendBaseWidget(g) + return g +} + +var _ fyne.Disableable = (*DisabledList)(nil) + +func (g *DisabledList) Disabled() bool { return true } + +func (g *DisabledList) Disable() {} + +func (g *DisabledList) Enable() {} diff --git a/ui/widgets/gridview.go b/ui/widgets/gridview.go index cd49670..21ed4ba 100644 --- a/ui/widgets/gridview.go +++ b/ui/widgets/gridview.go @@ -11,7 +11,6 @@ import ( "fyne.io/fyne/v2" "fyne.io/fyne/v2/widget" - xwidget "fyne.io/x/fyne/widget" ) const batchFetchSize = 6 @@ -75,7 +74,7 @@ type GridView struct { fetchCancel context.CancelFunc GridViewState - grid *xwidget.GridWrap + grid *disabledGridWrap menu *widget.PopUpMenu menuGridViewItemId string } @@ -197,7 +196,7 @@ func (g *GridView) ScrollToOffset(offs float32) { } func (g *GridView) createGridWrap() { - g.grid = xwidget.NewGridWrap( + g.grid = NewDisabledGridWrap( func() int { return g.lenItems() }, @@ -221,7 +220,7 @@ func (g *GridView) createGridWrap() { return card }, // update func - func(itemID xwidget.GridWrapItemID, obj fyne.CanvasObject) { + func(itemID widget.GridWrapItemID, obj fyne.CanvasObject) { ac := obj.(*GridViewItem) g.doUpdateItemCard(int(itemID), ac) }, @@ -369,3 +368,28 @@ func (g *GridView) onPlay(itemID string, shuffle bool) { func (g *GridView) CreateRenderer() fyne.WidgetRenderer { return widget.NewSimpleRenderer(g.grid) } + +// a disabled widget is not considered focusable by the focus manager +type disabledGridWrap struct { + widget.GridWrap +} + +func NewDisabledGridWrap(len func() int, create func() fyne.CanvasObject, update func(widget.GridWrapItemID, fyne.CanvasObject)) *disabledGridWrap { + g := &disabledGridWrap{ + GridWrap: widget.GridWrap{ + Length: len, + CreateItem: create, + UpdateItem: update, + }, + } + g.ExtendBaseWidget(g) + return g +} + +var _ fyne.Disableable = (*disabledGridWrap)(nil) + +func (g *disabledGridWrap) Disabled() bool { return true } + +func (g *disabledGridWrap) Disable() {} + +func (g *disabledGridWrap) Enable() {} diff --git a/ui/widgets/gridviewitem.go b/ui/widgets/gridviewitem.go index cfa9bf1..f9c36aa 100644 --- a/ui/widgets/gridviewitem.go +++ b/ui/widgets/gridviewitem.go @@ -50,7 +50,7 @@ func newCoverImage(placeholderResource fyne.Resource) *coverImage { func (c *coverImage) CreateRenderer() fyne.WidgetRenderer { return widget.NewSimpleRenderer( - container.NewMax(c.Im, container.NewCenter(c.playbtn)), + container.NewStack(c.Im, container.NewCenter(c.playbtn)), ) } @@ -216,3 +216,13 @@ func (g *GridViewItem) ItemID() string { func (g *GridViewItem) CreateRenderer() fyne.WidgetRenderer { return widget.NewSimpleRenderer(g.container) } + +// steal hover events from underlying GridWrap to prevent unwanted +// hover rectangle backgrounds +var _ desktop.Hoverable = (*GridViewItem)(nil) + +func (g *GridViewItem) MouseIn(e *desktop.MouseEvent) {} + +func (g *GridViewItem) MouseOut() {} + +func (g *GridViewItem) MouseMoved(e *desktop.MouseEvent) {} diff --git a/ui/widgets/imageplaceholder.go b/ui/widgets/imageplaceholder.go index 531d64c..03c3a82 100644 --- a/ui/widgets/imageplaceholder.go +++ b/ui/widgets/imageplaceholder.go @@ -43,7 +43,7 @@ func NewImagePlaceholder(centerIcon fyne.Resource, minSize float32) *ImagePlaceh i.border = myTheme.NewThemedRectangle(theme.ColorNameBackground) i.border.BorderColorName = theme.ColorNameForeground i.border.BorderWidth = 3 - i.content = container.NewMax( + i.content = container.NewStack( i.border, container.NewCenter(i.iconImage), i.imageDisp, diff --git a/ui/widgets/listheader.go b/ui/widgets/listheader.go index 3ad8911..6d3de3f 100644 --- a/ui/widgets/listheader.go +++ b/ui/widgets/listheader.go @@ -63,7 +63,9 @@ func NewListHeader(cols []ListColumn, layout *layouts.ColumnsLayout) *ListHeader for i := range l.columnVisible { l.columnVisible[i] = true } - l.container = container.NewMax(myTheme.NewThemedRectangle(myTheme.ColorNameListHeader), l.columnsContainer) + rect := myTheme.NewThemedRectangle(myTheme.ColorNameListHeader) + rect.CornerRadiusName = theme.SizeNameSelectionRadius + l.container = container.NewStack(rect, l.columnsContainer) l.ExtendBaseWidget(l) l.buildColumns() return l @@ -187,7 +189,7 @@ func newColHeader(columnCfg ListColumn, sortDisabled *bool) *colHeader { } r := myTheme.NewThemedRectangle(myTheme.ColorNameListHeader) r.Translucent = true - c.sortIconContainer = container.NewMax(widget.NewIcon(theme.MenuDropDownIcon()), r) + c.sortIconContainer = container.NewStack(widget.NewIcon(theme.MenuDropDownIcon()), r) // hack to remove extra icon space // should be hidden whenever sortIcon is hidden c.sortIconNegSpacer = util.NewHSpace(0) diff --git a/ui/widgets/listrowbase.go b/ui/widgets/listrowbase.go index bfeba84..afd1aca 100644 --- a/ui/widgets/listrowbase.go +++ b/ui/widgets/listrowbase.go @@ -85,13 +85,15 @@ func (l *ListRowBase) Refresh() { func (l *ListRowBase) CreateRenderer() fyne.WidgetRenderer { if l.selectionRect == nil { l.selectionRect = canvas.NewRectangle(theme.SelectionColor()) + l.selectionRect.CornerRadius = theme.SelectionRadiusSize() l.selectionRect.Hidden = !l.Selected } if l.focusedRect == nil { l.focusedRect = canvas.NewRectangle(theme.HoverColor()) + l.focusedRect.CornerRadius = theme.SelectionRadiusSize() l.focusedRect.Hidden = !l.Focused } return widget.NewSimpleRenderer( - container.NewMax(l.selectionRect, l.focusedRect, l.Content), + container.NewStack(l.selectionRect, l.focusedRect, l.Content), ) } diff --git a/ui/widgets/multihyperlink.go b/ui/widgets/multihyperlink.go index 8feddda..e481619 100644 --- a/ui/widgets/multihyperlink.go +++ b/ui/widgets/multihyperlink.go @@ -107,7 +107,7 @@ func (c *MultiHyperlink) layoutObjects() { obj = c.content.Objects[2*i-1] ms := obj.MinSize() obj.Resize(ms) - obj.Move(fyne.NewPos(x-ms.Width+c.getSeparatorWidth()+1, 0)) // this is really ugly + obj.Move(fyne.NewPos(x-ms.Width+c.getSeparatorWidth()+4, 0)) // this is really ugly x -= theme.Padding() * 2 } // move and resize text object diff --git a/ui/widgets/nowplayingcard.go b/ui/widgets/nowplayingcard.go index 5424a60..a5854bc 100644 --- a/ui/widgets/nowplayingcard.go +++ b/ui/widgets/nowplayingcard.go @@ -49,9 +49,9 @@ func NewNowPlayingCard() *NowPlayingCard { n.cover.FillMode = canvas.ImageFillContain n.cover.Hidden = true - n.c = container.New(&layouts.MaxPadLayout{PadLeft: -5}, + n.c = container.New(&layouts.MaxPadLayout{PadLeft: -4}, container.NewBorder(nil, nil, n.cover, nil, - container.New(&layouts.MaxPadLayout{PadBottom: -3}, + container.New(&layouts.MaxPadLayout{PadTop: -2}, container.New(&layouts.VboxCustomPadding{ExtraPad: -13}, n.trackName, n.artistName, n.albumName))), ) return n diff --git a/ui/widgets/playercontrols.go b/ui/widgets/playercontrols.go index c81ef49..9719160 100644 --- a/ui/widgets/playercontrols.go +++ b/ui/widgets/playercontrols.go @@ -10,15 +10,16 @@ import ( "fyne.io/fyne/v2/widget" ) -// TrackPosSlider is a custom slider that doesn't trigger -// the seek action until drag end. +// TrackPosSlider is a custom slider that exposes an additional +// IsDragging() API as well as some other customizations type TrackPosSlider struct { widget.Slider - OnDragEnd func(float64) + // to avoid "data echoes" when slider value is updated as + // playback position changes + IgnoreNextChangeEnded bool - isDragging bool - lastDraggedValue float64 + isDragging bool } func NewTrackPosSlider() *TrackPosSlider { @@ -35,18 +36,41 @@ func NewTrackPosSlider() *TrackPosSlider { return slider } +func (t *TrackPosSlider) SetValue(value float64) { + t.IgnoreNextChangeEnded = true + t.Slider.SetValue(value) +} + +func (t *TrackPosSlider) Tapped(e *fyne.PointEvent) { + t.isDragging = false + t.IgnoreNextChangeEnded = false + t.Slider.Tapped(e) + + // don't keep focus after being tapped + fyne.CurrentApp().Driver().CanvasForObject(t).Focus(nil) +} + +// override to increase the distance moved by keyboard control +func (t *TrackPosSlider) TypedKey(e *fyne.KeyEvent) { + switch e.Name { + case fyne.KeyLeft: + t.Slider.SetValue(t.Value - 0.05) + case fyne.KeyRight: + t.Slider.SetValue(t.Value + 0.05) + default: + t.Slider.TypedKey(e) + } +} + func (t *TrackPosSlider) DragEnd() { t.isDragging = false + t.IgnoreNextChangeEnded = false t.Slider.DragEnd() - if t.OnDragEnd != nil { - t.OnDragEnd(t.lastDraggedValue) - } } func (t *TrackPosSlider) Dragged(e *fyne.DragEvent) { t.isDragging = true t.Slider.Dragged(e) - t.lastDraggedValue = t.Value } func (t *TrackPosSlider) IsDragging() bool { @@ -116,7 +140,13 @@ func NewPlayerControls() *PlayerControls { } func (pc *PlayerControls) OnSeek(f func(float64)) { - pc.slider.OnDragEnd = f + pc.slider.OnChangeEnded = func(pos float64) { + if pc.slider.IgnoreNextChangeEnded { + pc.slider.IgnoreNextChangeEnded = false + } else { + f(pos) + } + } } func (pc *PlayerControls) OnSeekPrevious(f func()) { @@ -168,49 +198,3 @@ func (pc *PlayerControls) UpdatePlayTime(curTime, totalTime float64) { func (p *PlayerControls) CreateRenderer() fyne.WidgetRenderer { return widget.NewSimpleRenderer(p.container) } - -// This code will be OBSOLETE in Fyne 2.4 -// which will natively add Tappable behavior to slider -// Tapped is called when a pointer tapped event is captured. -// -// Since: 2.4 -func (t *TrackPosSlider) Tapped(e *fyne.PointEvent) { - ratio := t.getRatio(e) - val := t.Min + ratio*(t.Max-t.Min) - t.isDragging = true - t.SetValue(val) - t.lastDraggedValue = val - t.isDragging = false - t.DragEnd() -} - -func (t *TrackPosSlider) endOffset() float32 { - return (theme.IconInlineSize()-4)/2 + theme.InnerPadding() - 1.5 // align with radio icons -} - -func (t *TrackPosSlider) getRatio(e *fyne.PointEvent) float64 { - pad := t.endOffset() - - x := e.Position.X - y := e.Position.Y - - switch t.Orientation { - case widget.Vertical: - if y > t.Size().Height-pad { - return 0.0 - } else if y < pad { - return 1.0 - } else { - return 1 - float64(y-pad)/float64(t.Size().Height-pad*2) - } - case widget.Horizontal: - if x > t.Size().Width-pad { - return 1.0 - } else if x < pad { - return 0.0 - } else { - return float64(x-pad) / float64(t.Size().Width-pad*2) - } - } - return 0.0 -} diff --git a/ui/widgets/searchentry.go b/ui/widgets/searchentry.go index 33a6957..c26786b 100644 --- a/ui/widgets/searchentry.go +++ b/ui/widgets/searchentry.go @@ -28,16 +28,17 @@ func NewSearchEntry() *SearchEntry { debounceFunc := util.NewDebouncer(200*time.Millisecond, func() { sf.sendSearch(sf.Entry.Text) }) - sf.Entry.OnChanged = func(_ string) { debounceFunc() } + sf.Entry.OnChanged = func(_ string) { + if sf.updateActionButton() { + sf.ActionItem.Refresh() + } + debounceFunc() + } return sf } func (s *SearchEntry) Refresh() { - if s.Text == "" { - s.ActionItem.(*clearTextButton).Resource = theme.SearchIcon() - } else { - s.ActionItem.(*clearTextButton).Resource = theme.ContentClearIcon() - } + s.updateActionButton() s.Entry.Refresh() } @@ -45,6 +46,17 @@ func (s *SearchEntry) MinSize() fyne.Size { return fyne.NewSize(200, s.Entry.MinSize().Height) } +func (s *SearchEntry) updateActionButton() bool { + btn := s.ActionItem.(*clearTextButton) + oldResouce := btn.Resource + if s.Text == "" { + btn.Resource = theme.SearchIcon() + } else { + btn.Resource = theme.ContentClearIcon() + } + return oldResouce != btn.Resource +} + var _ fyne.Tappable = (*clearTextButton)(nil) type clearTextButton struct { diff --git a/ui/widgets/tracklist.go b/ui/widgets/tracklist.go index f48a3e0..1285230 100644 --- a/ui/widgets/tracklist.go +++ b/ui/widgets/tracklist.go @@ -99,7 +99,7 @@ type Tracklist struct { nowPlayingID string colLayout *layouts.ColumnsLayout hdr *ListHeader - list *widget.List + list *DisabledList ctxMenu *fyne.Menu container *fyne.Container } @@ -132,7 +132,7 @@ func NewTracklist(tracks []*mediaprovider.Track) *Tracklist { playIcon.ColorName = theme.ColorNamePrimary playingIcon := container.NewCenter(container.NewHBox(util.NewHSpace(2), widget.NewIcon(playIcon))) - t.list = widget.NewList( + t.list = NewDisabledList( t.lenTracks, func() fyne.CanvasObject { tr := NewTrackRow(t, playingIcon) @@ -251,17 +251,30 @@ func (t *Tracklist) SetSorting(sorting TracklistSort) { t.hdr.SetSorting(ListHeaderSort{ColNumber: ColNumber(sorting.ColumnName), Type: sorting.SortOrder}) } +// Sets the currently playing track ID and updates the list rendering func (t *Tracklist) SetNowPlaying(trackID string) { + prevNowPlaying := t.nowPlayingID + t.tracksMutex.RLock() + trPrev, idxPrev := t.findTrackByID(prevNowPlaying) + tr, idx := t.findTrackByID(trackID) + t.tracksMutex.RUnlock() t.nowPlayingID = trackID - t.list.Refresh() + if trPrev != nil { + t.list.RefreshItem(idxPrev) + } + if tr != nil { + t.list.RefreshItem(idx) + } } +// Increments the play count of the given track and updates the list rendering func (t *Tracklist) IncrementPlayCount(trackID string) { t.tracksMutex.RLock() + tr, idx := t.findTrackByID(trackID) t.tracksMutex.RUnlock() - if tr := t.findTrackByID(trackID); tr != nil { + if tr != nil { tr.PlayCount += 1 - t.list.Refresh() + t.list.RefreshItem(idx) } } @@ -551,7 +564,7 @@ func (t *Tracklist) onShowContextMenu(e *fyne.PointEvent, trackIdx int) { func (t *Tracklist) onSetFavorite(trackID string, fav bool) { t.tracksMutex.RLock() - tr := t.findTrackByID(trackID) + tr, _ := t.findTrackByID(trackID) t.tracksMutex.RUnlock() t.onSetFavorites([]*mediaprovider.Track{tr}, fav, false) } @@ -572,7 +585,7 @@ func (t *Tracklist) onSetFavorites(tracks []*mediaprovider.Track, fav bool, need func (t *Tracklist) onSetRating(trackID string, rating int) { // update our own track model t.tracksMutex.RLock() - tr := t.findTrackByID(trackID) + tr, _ := t.findTrackByID(trackID) t.tracksMutex.RUnlock() t.onSetRatings([]*mediaprovider.Track{tr}, rating, false) } @@ -608,14 +621,14 @@ func (t *Tracklist) onDownload(tracks []*mediaprovider.Track, downloadName strin } } -func (t *Tracklist) findTrackByID(id string) *mediaprovider.Track { +func (t *Tracklist) findTrackByID(id string) (*mediaprovider.Track, int) { idx := sharedutil.Find(t.tracks, func(tr *trackModel) bool { return tr.track.ID == id }) if idx >= 0 { - return t.tracks[idx].track + return t.tracks[idx].track, idx } - return nil + return nil, -1 } func (t *Tracklist) selectedTrackModels() []*trackModel {