aboutsummaryrefslogtreecommitdiff
path: root/pkg
diff options
context:
space:
mode:
authorArthur Zamarin <arthurzam@gentoo.org>2024-02-15 22:06:22 +0200
committerArthur Zamarin <arthurzam@gentoo.org>2024-02-20 09:08:41 +0200
commit2686c931924411bc6fb57d21a4365cc958ef2d1d (patch)
treef35f1d5acecb8bb3a9ad46f41a059d0ad827903a /pkg
parentmigrate index page (diff)
downloadsoko-2686c931924411bc6fb57d21a4365cc958ef2d1d.tar.gz
soko-2686c931924411bc6fb57d21a4365cc958ef2d1d.tar.bz2
soko-2686c931924411bc6fb57d21a4365cc958ef2d1d.zip
migrate useflags pages
Signed-off-by: Arthur Zamarin <arthurzam@gentoo.org>
Diffstat (limited to 'pkg')
-rw-r--r--pkg/app/handler/useflags/expand.go45
-rw-r--r--pkg/app/handler/useflags/expand.templ60
-rw-r--r--pkg/app/handler/useflags/global.go46
-rw-r--r--pkg/app/handler/useflags/global.templ44
-rw-r--r--pkg/app/handler/useflags/index.go30
-rw-r--r--pkg/app/handler/useflags/local.go46
-rw-r--r--pkg/app/handler/useflags/local.templ48
-rw-r--r--pkg/app/handler/useflags/popular.templ31
-rw-r--r--pkg/app/handler/useflags/search.go59
-rw-r--r--pkg/app/handler/useflags/search.templ92
-rw-r--r--pkg/app/handler/useflags/show.go132
-rw-r--r--pkg/app/handler/useflags/show.templ175
-rw-r--r--pkg/app/handler/useflags/utils.go20
-rw-r--r--pkg/app/layout/page.templ86
-rw-r--r--pkg/app/serve.go2
15 files changed, 533 insertions, 383 deletions
diff --git a/pkg/app/handler/useflags/expand.go b/pkg/app/handler/useflags/expand.go
deleted file mode 100644
index 631f70a..0000000
--- a/pkg/app/handler/useflags/expand.go
+++ /dev/null
@@ -1,45 +0,0 @@
-package useflags
-
-import (
- "html/template"
- "net/http"
- "soko/pkg/app/utils"
- "soko/pkg/database"
- "soko/pkg/models"
-
- "github.com/go-pg/pg"
-)
-
-func Expand(w http.ResponseWriter, r *http.Request) {
- var useflags []models.Useflag
- err := database.DBCon.Model(&useflags).
- Where("scope = 'use_expand'").
- Order("use_expand", "name").
- Select()
- if err != nil && err != pg.ErrNoRows {
- http.Error(w, http.StatusText(http.StatusInternalServerError),
- http.StatusInternalServerError)
- return
- }
-
- data := struct {
- Header models.Header
- Page string
- Useflags []models.Useflag
- Application models.Application
- }{
- Header: models.Header{Title: "Use Expand" + " – ", Tab: "useflags"},
- Page: "expand",
- Useflags: useflags,
- Application: utils.GetApplicationData(),
- }
-
- templates := template.Must(
- template.Must(
- template.Must(
- template.New("Show").ParseGlob("web/templates/layout/*.tmpl")).
- ParseGlob("web/templates/useflags/browseuseflagsheader.tmpl")).
- ParseGlob("web/templates/useflags/listexpand.tmpl"))
-
- templates.ExecuteTemplate(w, "listexpand.tmpl", data)
-}
diff --git a/pkg/app/handler/useflags/expand.templ b/pkg/app/handler/useflags/expand.templ
new file mode 100644
index 0000000..82581f2
--- /dev/null
+++ b/pkg/app/handler/useflags/expand.templ
@@ -0,0 +1,60 @@
+package useflags
+
+import "net/http"
+import "soko/pkg/database"
+import "soko/pkg/models"
+import "github.com/go-pg/pg/v10"
+
+templ expand(useflags []models.Useflag) {
+ <div class="container mb-5">
+ <div class="row">
+ <div class="col-md-9">
+ <div class="card border-0">
+ <div class="list-group">
+ for i, use := range useflags {
+ if i == 0 || use.UseExpand != useflags[i-1].UseExpand {
+ @templ.Raw("</div></div>")
+ <h3 class={ templ.KV("mt-4", i > 0) } id={ use.UseExpand }>{ use.UseExpand }</h3>
+ @templ.Raw(`<div class="card border-0"><div class="list-group">`)
+ }
+ <a
+ class="list-group-item list-group-item-action text-dark"
+ href={ templ.SafeURL("/useflags/" + use.Name) }
+ >
+ <h3 class="kk-search-result-header">{ use.Name }</h3>
+ { use.Description }
+ </a>
+ }
+ </div>
+ </div>
+ </div>
+ <div class="col-md-3">
+ <dl>
+ <dd class="ml-3 mb-0">
+ for i, use := range useflags {
+ if i == 0 || use.UseExpand != useflags[i-1].UseExpand {
+ <a href={ templ.URL("#" + use.UseExpand) } class="text-muted">{ use.UseExpand }</a>
+ <br/>
+ }
+ }
+ </dd>
+ </dl>
+ </div>
+ </div>
+ </div>
+}
+
+func Expand(w http.ResponseWriter, r *http.Request) {
+ var useflags []models.Useflag
+ err := database.DBCon.Model(&useflags).
+ Where("scope = 'use_expand'").
+ Order("use_expand", "name").
+ Column("use_expand", "name", "description").
+ Select()
+ if err != nil && err != pg.ErrNoRows {
+ http.Error(w, http.StatusText(http.StatusInternalServerError),
+ http.StatusInternalServerError)
+ return
+ }
+ RenderPage(w, r, "USE Expand", "USE Expand", expand(useflags))
+}
diff --git a/pkg/app/handler/useflags/global.go b/pkg/app/handler/useflags/global.go
deleted file mode 100644
index 63e8e3e..0000000
--- a/pkg/app/handler/useflags/global.go
+++ /dev/null
@@ -1,46 +0,0 @@
-package useflags
-
-import (
- "html/template"
- "net/http"
- "soko/pkg/app/utils"
- "soko/pkg/database"
- "soko/pkg/models"
-
- "github.com/go-pg/pg"
-)
-
-func Global(w http.ResponseWriter, r *http.Request) {
-
- var useflags []models.Useflag
- err := database.DBCon.Model(&useflags).
- Order("name").
- Where("scope = 'global'").
- Select()
- if err != nil && err != pg.ErrNoRows {
- http.Error(w, http.StatusText(http.StatusInternalServerError),
- http.StatusInternalServerError)
- return
- }
-
- data := struct {
- Header models.Header
- Page string
- Useflags []models.Useflag
- Application models.Application
- }{
- Header: models.Header{Title: "Global" + " – ", Tab: "useflags"},
- Page: "global",
- Useflags: useflags,
- Application: utils.GetApplicationData(),
- }
-
- templates := template.Must(
- template.Must(
- template.Must(
- template.New("Show").ParseGlob("web/templates/layout/*.tmpl")).
- ParseGlob("web/templates/useflags/browseuseflagsheader.tmpl")).
- ParseGlob("web/templates/useflags/list.tmpl"))
-
- templates.ExecuteTemplate(w, "list.tmpl", data)
-}
diff --git a/pkg/app/handler/useflags/global.templ b/pkg/app/handler/useflags/global.templ
new file mode 100644
index 0000000..46fe1f0
--- /dev/null
+++ b/pkg/app/handler/useflags/global.templ
@@ -0,0 +1,44 @@
+package useflags
+
+import "net/http"
+import "soko/pkg/database"
+import "soko/pkg/models"
+import "github.com/go-pg/pg/v10"
+
+templ global(useflags []models.Useflag) {
+ <div class="container mb-5">
+ <div class="row">
+ <div class="col-12">
+ <h3><span class="text-capitalize">Global</span> USE flags</h3>
+ <div class="card border-0">
+ <div class="list-group">
+ for _, use := range useflags {
+ <a
+ class="list-group-item list-group-item-action text-dark"
+ href={ templ.SafeURL("/useflags/" + use.Name) }
+ >
+ <h3 class="kk-search-result-header">{ use.Name }</h3>
+ { use.Description }
+ </a>
+ }
+ </div>
+ </div>
+ </div>
+ </div>
+ </div>
+}
+
+func Global(w http.ResponseWriter, r *http.Request) {
+ var useflags []models.Useflag
+ err := database.DBCon.Model(&useflags).
+ Where("scope = 'global'").
+ Order("name").
+ Column("name", "description").
+ Select()
+ if err != nil && err != pg.ErrNoRows {
+ http.Error(w, http.StatusText(http.StatusInternalServerError),
+ http.StatusInternalServerError)
+ return
+ }
+ RenderPage(w, r, "Global", "Global", global(useflags))
+}
diff --git a/pkg/app/handler/useflags/index.go b/pkg/app/handler/useflags/index.go
index c14161e..d08d62b 100644
--- a/pkg/app/handler/useflags/index.go
+++ b/pkg/app/handler/useflags/index.go
@@ -3,40 +3,14 @@
package useflags
import (
- "html/template"
"net/http"
- utils2 "soko/pkg/app/utils"
- "soko/pkg/models"
+ "soko/pkg/app/utils"
)
// Index renders a template to show the index page of the USE flags
// section containing a bubble chart of popular USE flags
-func Index(w http.ResponseWriter, r *http.Request) {
-
- data := struct {
- Header models.Header
- Page string
- Application models.Application
- }{
- Header: models.Header{Title: "Useflags – ", Tab: "useflags"},
- Page: "browse",
- Application: utils2.GetApplicationData(),
- }
-
- templates := template.Must(
- template.Must(
- template.Must(
- template.New("Show").ParseGlob("web/templates/layout/*.tmpl")).
- ParseGlob("web/templates/useflags/browseuseflagsheader.tmpl")).
- ParseGlob("web/templates/useflags/index.tmpl"))
-
- templates.ExecuteTemplate(w, "index.tmpl", data)
-}
-
-// Index renders a template to show the index page of the USE flags
-// section containing a bubble chart of popular USE flags
func Default(w http.ResponseWriter, r *http.Request) {
- userPreferences := utils2.GetUserPreferences(r)
+ userPreferences := utils.GetUserPreferences(r)
if userPreferences.Useflags.Layout == "bubble" {
http.Redirect(w, r, "/useflags/popular", http.StatusSeeOther)
} else {
diff --git a/pkg/app/handler/useflags/local.go b/pkg/app/handler/useflags/local.go
deleted file mode 100644
index 63a5a76..0000000
--- a/pkg/app/handler/useflags/local.go
+++ /dev/null
@@ -1,46 +0,0 @@
-package useflags
-
-import (
- "html/template"
- "net/http"
- "soko/pkg/app/utils"
- "soko/pkg/database"
- "soko/pkg/models"
-
- "github.com/go-pg/pg"
-)
-
-func Local(w http.ResponseWriter, r *http.Request) {
-
- var useflags []models.Useflag
- err := database.DBCon.Model(&useflags).
- Where("scope = 'local'").
- Order("package", "name").
- Select()
- if err != nil && err != pg.ErrNoRows {
- http.Error(w, http.StatusText(http.StatusInternalServerError),
- http.StatusInternalServerError)
- return
- }
-
- data := struct {
- Header models.Header
- Page string
- Useflags []models.Useflag
- Application models.Application
- }{
- Header: models.Header{Title: "Local" + " – ", Tab: "useflags"},
- Page: "local",
- Useflags: useflags,
- Application: utils.GetApplicationData(),
- }
-
- templates := template.Must(
- template.Must(
- template.Must(
- template.New("Show").ParseGlob("web/templates/layout/*.tmpl")).
- ParseGlob("web/templates/useflags/browseuseflagsheader.tmpl")).
- ParseGlob("web/templates/useflags/listlocal.tmpl"))
-
- templates.ExecuteTemplate(w, "listlocal.tmpl", data)
-}
diff --git a/pkg/app/handler/useflags/local.templ b/pkg/app/handler/useflags/local.templ
new file mode 100644
index 0000000..01a7544
--- /dev/null
+++ b/pkg/app/handler/useflags/local.templ
@@ -0,0 +1,48 @@
+package useflags
+
+import "net/http"
+import "soko/pkg/database"
+import "soko/pkg/models"
+import "github.com/go-pg/pg/v10"
+
+templ local(useflags []models.Useflag) {
+ <div class="container mb-5">
+ <div class="row">
+ <div class="col-12">
+ <div class="card border-0">
+ <div class="list-group">
+ for i, use := range useflags {
+ if i == 0 || use.Package != useflags[i-1].Package {
+ @templ.Raw("</div></div>")
+ <h3 class={ templ.KV("mt-4", i > 0) }>{ use.Package }</h3>
+ @templ.Raw(`<div class="card border-0"><div class="list-group">`)
+ }
+ <a
+ class="list-group-item list-group-item-action text-dark"
+ href={ templ.SafeURL("/useflags/" + use.Name) }
+ >
+ <h3 class="kk-search-result-header">{ use.Name }</h3>
+ { use.Description }
+ </a>
+ }
+ </div>
+ </div>
+ </div>
+ </div>
+ </div>
+}
+
+func Local(w http.ResponseWriter, r *http.Request) {
+ var useflags []models.Useflag
+ err := database.DBCon.Model(&useflags).
+ Where("scope = 'local'").
+ Order("package", "name").
+ Column("package", "name", "description").
+ Select()
+ if err != nil && err != pg.ErrNoRows {
+ http.Error(w, http.StatusText(http.StatusInternalServerError),
+ http.StatusInternalServerError)
+ return
+ }
+ RenderPage(w, r, "Local", "Local", local(useflags))
+}
diff --git a/pkg/app/handler/useflags/popular.templ b/pkg/app/handler/useflags/popular.templ
new file mode 100644
index 0000000..716a73a
--- /dev/null
+++ b/pkg/app/handler/useflags/popular.templ
@@ -0,0 +1,31 @@
+package useflags
+
+import "net/http"
+
+templ popular() {
+ <div class="container mb-5">
+ <div class="row">
+ <div class="col-12">
+ <div class="card" style="background: none;border: none;">
+ <noscript>
+ <div class="panel-body kk-panel-content-sorry">
+ This feature requires JavaScript to work.
+ </div>
+ </noscript>
+ <div
+ class="panel-body kk-useflag-bubble-container"
+ id="bubble-placeholder"
+ style="overflow: hidden!important; display: none;"
+ ></div>
+ </div>
+ </div>
+ </div>
+ </div>
+ <script src="/assets/useflags.js"></script>
+}
+
+// PopularPage renders a template to show the index page of the USE flags
+// section containing a bubble chart of popular USE flags
+func PopularPage(w http.ResponseWriter, r *http.Request) {
+ RenderPage(w, r, "Useflags", "Widely used", popular())
+}
diff --git a/pkg/app/handler/useflags/search.go b/pkg/app/handler/useflags/search.go
deleted file mode 100644
index 31d0bae..0000000
--- a/pkg/app/handler/useflags/search.go
+++ /dev/null
@@ -1,59 +0,0 @@
-// Used to search for USE flags
-
-package useflags
-
-import (
- "html/template"
- "net/http"
- "soko/pkg/app/utils"
- "soko/pkg/database"
- "soko/pkg/models"
-
- "github.com/go-pg/pg"
-)
-
-// Search renders a template containing a list of search results
-// for a given query of USE flags
-func Search(w http.ResponseWriter, r *http.Request) {
-
- results := r.URL.Query()["q"]
-
- param := ""
- var useflags []models.Useflag
- if len(results) != 0 {
- param = results[0]
- err := database.DBCon.Model(&useflags).
- Column("name", "description", "scope", "package").
- Where("name LIKE ?", param+"%").
- OrderExpr("scope, name <-> ?", param).
- Select()
- if err != nil && err != pg.ErrNoRows {
- http.Error(w, http.StatusText(http.StatusInternalServerError),
- http.StatusInternalServerError)
- return
- }
- }
-
- data := struct {
- Header models.Header
- Page string
- Search string
- Useflags []models.Useflag
- Application models.Application
- }{
- Header: models.Header{Title: param + " – ", Tab: "useflags"},
- Page: "search",
- Search: param,
- Useflags: useflags,
- Application: utils.GetApplicationData(),
- }
-
- templates := template.Must(
- template.Must(
- template.Must(
- template.New("Show").ParseGlob("web/templates/layout/*.tmpl")).
- ParseGlob("web/templates/useflags/browseuseflagsheader.tmpl")).
- ParseGlob("web/templates/useflags/search.tmpl"))
-
- templates.ExecuteTemplate(w, "search.tmpl", data)
-}
diff --git a/pkg/app/handler/useflags/search.templ b/pkg/app/handler/useflags/search.templ
new file mode 100644
index 0000000..bcfa88a
--- /dev/null
+++ b/pkg/app/handler/useflags/search.templ
@@ -0,0 +1,92 @@
+package useflags
+
+import "net/http"
+import "soko/pkg/database"
+import "soko/pkg/models"
+import "github.com/go-pg/pg/v10"
+
+css searchButton() {
+ border-top-right-radius: 0.25rem !important;
+ border-bottom-right-radius: 0.25rem !important;
+ font-size: 1.1em !important;
+ height: 2.3em !important;
+ border-left: 0px;
+ box-shadow: inset 0 1px 1px rgba(0,0,0,0.075) !important;
+}
+
+templ search(query string, useflags []models.Useflag) {
+ <div class="container mb-5">
+ <div class="row">
+ <div class={ "col-12", templ.KV("mt-5", len(useflags) == 0), templ.KV("pt-5", len(useflags) == 0) }>
+ <div class="col-12 mt-3 text-center">
+ <h2>Find USE flags</h2>
+ </div>
+ <div class="col-12">
+ <form action="/useflags/search" method="get" class="useflag-search mt-3 mb-5 mx-5 px-5">
+ <div class="typeahead__container mx-5 px-5">
+ <div class="typeahead__field">
+ <span class="typeahead__query" style="font-size: 1.1em; height: 2.3em;">
+ <input id="q" name="q" class="rounded-left" style="font-size: 1.1em; height: 2.3em;border-right: 0px;" type="search" autocomplete="off" placeholder="Find USE flags"/>
+ </span>
+ <span class="typeahead__button" style="font-size: 1.1em!important; height: 2.3em!important;border-left: 0px;">
+ <button class={ searchButton() } type="submit">
+ <span class="typeahead__search-icon"></span>
+ </button>
+ </span>
+ </div>
+ </div>
+ </form>
+ </div>
+ if query != "" {
+ if len(useflags) > 0 {
+ <h2>USE Flag Search Results <small>{ "for" } { query }</small></h2>
+ <div class="card border-0">
+ <div class="list-group">
+ for _, use := range useflags {
+ <a
+ class="list-group-item list-group-item-action text-dark"
+ href={ templ.URL("/useflags/" + use.Name) }
+ >
+ <h3 class="kk-search-result-header">
+ { use.Name }
+ if use.Scope == "local" {
+ <span class="text-secondary">({ use.Package })</span>
+ }
+ </h3>
+ { use.Description }
+ </a>
+ }
+ </div>
+ </div>
+ } else {
+ <h2>No results found <small>{ "for" } { query }</small></h2>
+ }
+ }
+ </div>
+ </div>
+ </div>
+ <script src="/assets/useflags.js"></script>
+}
+
+// Search renders a template containing a list of search results
+// for a given query of USE flags
+func Search(w http.ResponseWriter, r *http.Request) {
+ results := r.URL.Query()["q"]
+
+ param := ""
+ var useflags []models.Useflag
+ if len(results) != 0 {
+ param = results[0]
+ err := database.DBCon.Model(&useflags).
+ Column("name", "description", "scope", "package").
+ Where("name LIKE ?", param+"%").
+ OrderExpr("scope, name <-> ?", param).
+ Select()
+ if err != nil && err != pg.ErrNoRows {
+ http.Error(w, http.StatusText(http.StatusInternalServerError),
+ http.StatusInternalServerError)
+ return
+ }
+ }
+ RenderPage(w, r, param, "Search", search(param, useflags))
+}
diff --git a/pkg/app/handler/useflags/show.go b/pkg/app/handler/useflags/show.go
deleted file mode 100644
index 6823274..0000000
--- a/pkg/app/handler/useflags/show.go
+++ /dev/null
@@ -1,132 +0,0 @@
-// Used to show a specific package
-
-package useflags
-
-import (
- "html/template"
- "net/http"
- "soko/pkg/app/utils"
- "soko/pkg/database"
- "soko/pkg/models"
- "strings"
-
- "github.com/go-pg/pg/v10"
-)
-
-// Show renders a template to show a given USE flag
-func Show(w http.ResponseWriter, r *http.Request) {
- useFlagName := r.URL.Path[len("/useflags/"):]
-
- var useflags []models.Useflag
- err := database.DBCon.Model(&useflags).Where("name = ?", useFlagName).Select()
- if err != nil || len(useflags) < 1 {
- http.NotFound(w, r)
- return
- }
-
- useflag := useflags[0]
- var localuseflags []models.Useflag
-
- for _, use := range useflags {
- if use.Scope == "global" {
- useflag = use
- } else if use.Scope == "local" {
- localuseflags = append(localuseflags, use)
- } else if use.Scope == "use_expand" {
- ShowUseExpand(w, r, use)
- return
- }
- }
-
- var packages []string
- err = database.DBCon.Model((*models.Version)(nil)).
- Column("atom").Distinct().
- Where("useflags::jsonb @> ?", "\""+useFlagName+"\"").
- Select(&packages)
- if err != nil && err != pg.ErrNoRows {
- http.Error(w, http.StatusText(http.StatusInternalServerError),
- http.StatusInternalServerError)
- return
- }
-
- data := struct {
- Header models.Header
- Page string
- Useflag models.Useflag
- LocalUseflags []models.Useflag
- Packages []string
- Application models.Application
- }{
- Header: models.Header{Title: useflag.Name + " – ", Tab: "useflags"},
- Page: "show",
- Useflag: useflag,
- LocalUseflags: localuseflags,
- Packages: packages,
- Application: utils.GetApplicationData(),
- }
-
- templates := template.Must(
- template.Must(
- template.Must(
- template.New("Show").Funcs(template.FuncMap{
- "replaceall": strings.ReplaceAll,
- }).ParseGlob("web/templates/layout/*.tmpl")).
- ParseGlob("web/templates/useflags/useflagsheader.tmpl")).
- ParseGlob("web/templates/useflags/show.tmpl"))
-
- templates.ExecuteTemplate(w, "show.tmpl", data)
-}
-
-// ShowUseExpand renders a template to show a given use_expand
-func ShowUseExpand(w http.ResponseWriter, r *http.Request, useExpand models.Useflag) {
- funcMap := template.FuncMap{
- "replaceall": strings.ReplaceAll,
- }
-
- var otherUseExpands []models.Useflag
- err := database.DBCon.Model(&otherUseExpands).
- Column("name", "description").
- Where("use_expand = ?", useExpand.UseExpand).
- Select()
- if err != nil && err != pg.ErrNoRows {
- http.Error(w, http.StatusText(http.StatusInternalServerError),
- http.StatusInternalServerError)
- return
- }
-
- var packages []string
- err = database.DBCon.Model((*models.Version)(nil)).
- Column("atom").Distinct().
- Where("useflags::jsonb @> ?", "\""+useExpand.Name+"\"").
- Select(&packages)
- if err != nil && err != pg.ErrNoRows {
- http.Error(w, http.StatusText(http.StatusInternalServerError),
- http.StatusInternalServerError)
- return
- }
-
- data := struct {
- Header models.Header
- Page string
- Useflag models.Useflag
- OtherUseExpands []models.Useflag
- Packages []string
- Application models.Application
- }{
- Header: models.Header{Title: useExpand.Name + " – ", Tab: "useflags"},
- Page: "show",
- Useflag: useExpand,
- OtherUseExpands: otherUseExpands,
- Packages: packages,
- Application: utils.GetApplicationData(),
- }
-
- templates := template.Must(
- template.Must(
- template.Must(
- template.New("Show").Funcs(funcMap).ParseGlob("web/templates/layout/*.tmpl")).
- ParseGlob("web/templates/useflags/useflagsheader.tmpl")).
- ParseGlob("web/templates/useflags/showexpand.tmpl"))
-
- templates.ExecuteTemplate(w, "showexpand.tmpl", data)
-}
diff --git a/pkg/app/handler/useflags/show.templ b/pkg/app/handler/useflags/show.templ
new file mode 100644
index 0000000..aa8dd80
--- /dev/null
+++ b/pkg/app/handler/useflags/show.templ
@@ -0,0 +1,175 @@
+package useflags
+
+import "net/http"
+import "strconv"
+import "strings"
+import "soko/pkg/app/layout"
+import "soko/pkg/database"
+import "soko/pkg/models"
+import "github.com/go-pg/pg/v10"
+
+templ showUseflagHeader(useflag models.Useflag) {
+ <div class="kk-header-container">
+ <div class="container">
+ <div class="row">
+ <div class="col-12">
+ <div class="row mt-3 pt-2">
+ <div class="col-md-5">
+ <h1 class="stick-top kk-package-title" id="package-title">
+ <small class="kk-package-cat">
+ <a href="/useflags" class={ "text-dark", "ml-1", templ.KV("text-capitalize", useflag.UseExpand == "") }>
+ if useflag.UseExpand != "" {
+ { useflag.UseExpand }
+ } else {
+ { useflag.Scope } USE flag
+ }
+ </a>
+ </small>
+ <div>
+ <div class="kk-package-name" style="margin-left: 0px!important;">
+ <span class="fa fa-fw fa-sliders"></span>
+ <span class="ml-2">
+ if useflag.UseExpand != "" {
+ { strings.TrimPrefix(useflag.Name, useflag.UseExpand + "_") }
+ } else {
+ { useflag.Name }
+ }
+ </span>
+ </div>
+ </div>
+ </h1>
+ </div>
+ if useflag.Scope != "local" {
+ <div class="col-md-7">
+ <p class="lead kk-package-maindesc">
+ { useflag.Description }
+ </p>
+ </div>
+ }
+ <div class="col-md-12 pt-4 mt-1"></div>
+ </div>
+ </div>
+ </div>
+ </div>
+ </div>
+}
+
+templ show(useflag models.Useflag, localUseflags, otherUseExpands []models.Useflag, Packages []string) {
+ @showUseflagHeader(useflag)
+ <div class="tab-content" id="myTabContent">
+ <div class="container mb-5">
+ <div class="row">
+ <div class="col-12">
+ if len(otherUseExpands) != 0 {
+ <h3 class="mb-2">Other “{ useflag.UseExpand }” USE_EXPAND flag values</h3>
+ <div class="card">
+ <div class="table-responsive">
+ <table class="table">
+ <thead>
+ <th>Use Flag</th>
+ <th>Description</th>
+ </thead>
+ <tbody>
+ for _, use := range otherUseExpands {
+ <tr>
+ <th class="kk-nobreak-cell">
+ <a href={ templ.URL("/useflags/" + use.Name) }>{ use.Name }</a>
+ </th>
+ <td>{ use.Description }</td>
+ </tr>
+ }
+ </tbody>
+ </table>
+ </div>
+ </div>
+ }
+ if len(localUseflags) != 0 {
+ <h3 class="mb-2">Packages describing “{ useflag.Name }” as local USE flag</h3>
+ <div class="card mb-4 border-top-0">
+ <div class="table-responsive">
+ <table class="table mb-0">
+ <thead>
+ <th>Package</th>
+ <th>“{ useflag.Name }” Flag Description</th>
+ </thead>
+ <tbody>
+ for _, use := range localUseflags {
+ <tr>
+ <th class="kk-nobreak-cell">
+ <a href={ templ.URL("/packages/" + use.Package) }>{ use.Package }</a>
+ </th>
+ <td>{ use.Description }</td>
+ </tr>
+ }
+ </tbody>
+ </table>
+ </div>
+ </div>
+ }
+ if len(Packages) != 0 {
+ <h3 class="mb-2 pt-2">All packages providing a “{ useflag.Name }” USE flag ({ strconv.Itoa(len(Packages)) })</h3>
+ <div class="card">
+ <div class="card-body">
+ <ul class="kk-col-list kk-3col-list kk-useflag-listing mb-0">
+ for _, pkg := range Packages {
+ <li><a href={ templ.URL("/packages/" + pkg) }>{ pkg }</a></li>
+ }
+ </ul>
+ </div>
+ </div>
+ }
+ </div>
+ </div>
+ </div>
+ </div>
+}
+
+// Show renders a template to show a given USE flag
+func Show(w http.ResponseWriter, r *http.Request) {
+ useFlagName := r.URL.Path[len("/useflags/"):]
+
+ var useflags []models.Useflag
+ err := database.DBCon.Model(&useflags).
+ Where("name = ?", useFlagName).
+ Order("scope", "package").
+ Select()
+ if err != nil || len(useflags) < 1 {
+ http.NotFound(w, r)
+ return
+ }
+
+ var packages []string
+ err = database.DBCon.Model((*models.Version)(nil)).
+ Column("atom").Distinct().
+ Where("useflags::jsonb @> ?", "\""+useFlagName+"\"").
+ Order("atom").
+ Select(&packages)
+ if err != nil && err != pg.ErrNoRows {
+ http.Error(w, http.StatusText(http.StatusInternalServerError),
+ http.StatusInternalServerError)
+ return
+ }
+
+ useflag := useflags[0]
+
+ var localUseFlags, otherUseExpands []models.Useflag
+ if use := useflags[len(useflags)-1]; use.Scope == "use_expand" {
+ err := database.DBCon.Model(&otherUseExpands).
+ Column("name", "description").
+ Where("use_expand = ?", useflag.UseExpand).
+ Order("name").
+ Select()
+ if err != nil && err != pg.ErrNoRows {
+ http.Error(w, http.StatusText(http.StatusInternalServerError),
+ http.StatusInternalServerError)
+ return
+ }
+ } else if useflag.Scope == "global" {
+ localUseFlags = useflags[1:]
+ } else {
+ localUseFlags = useflags
+ }
+
+ layout.Layout(useFlagName, "useflags",
+ show(useflag, localUseFlags, otherUseExpands, packages)).Render(r.Context(), w)
+}
diff --git a/pkg/app/handler/useflags/utils.go b/pkg/app/handler/useflags/utils.go
new file mode 100644
index 0000000..54d0828
--- /dev/null
+++ b/pkg/app/handler/useflags/utils.go
@@ -0,0 +1,20 @@
+package useflags
+
+import (
+ "net/http"
+ "soko/pkg/app/layout"
+
+ "github.com/a-h/templ"
+)
+
+var tabs = []layout.SubTab{
+ {Name: "Widely used", Link: templ.URL("/useflags"), Icon: "fa fa-line-chart mr-1"},
+ {Name: "Search", Link: templ.URL("/useflags/search"), Icon: "fa fa-search mr-1"},
+ {Name: "Global", Link: templ.URL("/useflags/global"), Icon: "fa fa-globe mr-1"},
+ {Name: "Local", Link: templ.URL("/useflags/local"), Icon: "fa fa-map-marker mr-1"},
+ {Name: "USE Expand", Link: templ.URL("/useflags/expand"), Icon: "fa fa-list mr-1"},
+}
+
+func RenderPage(w http.ResponseWriter, r *http.Request, title string, currentTab string, content templ.Component) {
+ layout.TabbedLayout(title, "useflags", "USE flags", "fa fa-fw fa-sliders", tabs, currentTab, content).Render(r.Context(), w)
+}
diff --git a/pkg/app/layout/page.templ b/pkg/app/layout/page.templ
index 98509ce..7fc5a24 100644
--- a/pkg/app/layout/page.templ
+++ b/pkg/app/layout/page.templ
@@ -5,12 +5,12 @@ import "soko/pkg/config"
templ head(title string) {
<head>
<title>
- if title != "" {
- { title } – Gentoo Packages
- } else {
- Gentoo Packages
- }
- </title>
+ if title != "" {
+ { title } – Gentoo Packages
+ } else {
+ Gentoo Packages
+ }
+ </title>
<meta charset="utf-8"/>
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
<meta name="theme-color" content="#54487a"/>
@@ -59,13 +59,6 @@ templ siteTitle() {
</div>
}
-func activeClass(tab string, currentTab string) string {
- if tab == currentTab {
- return "nav-item active"
- }
- return "nav-item"
-}
-
templ navigationBar(tab string) {
<nav class="tyrian-navbar navbar navbar-dark navbar-expand-lg bg-primary" role="navigation">
<div class="container">
@@ -76,12 +69,12 @@ templ navigationBar(tab string) {
</div>
<div class="collapse navbar-collapse navbar-main-collapse" id="navbar-main-collapse">
<ul class="navbar-nav mr-auto">
- <li class={ activeClass("home", tab) }><a class="nav-link" href="/">Home</a></li>
- <li class={ activeClass("packages", tab) }><a class="nav-link" href="/categories">Packages</a></li>
- <li class={ activeClass("maintainers", tab) }><a class="nav-link" href="/maintainers">Maintainers</a></li>
- <li class={ activeClass("useflags", tab) }><a class="nav-link" href="/useflags">USE flags</a></li>
- <li class={ activeClass("arches", tab) }><a class="nav-link" href="/arches">Architectures</a></li>
- <li class={ activeClass("about", tab) }><a class="nav-link" href="/about">About</a></li>
+ <li class={ "nav-item", templ.KV("active", tab == "home") }><a class="nav-link" href="/">Home</a></li>
+ <li class={ "nav-item", templ.KV("active", tab == "packages") }><a class="nav-link" href="/categories">Packages</a></li>
+ <li class={ "nav-item", templ.KV("active", tab == "maintainers") }><a class="nav-link" href="/maintainers">Maintainers</a></li>
+ <li class={ "nav-item", templ.KV("active", tab == "useflags") }><a class="nav-link" href="/useflags">USE flags</a></li>
+ <li class={ "nav-item", templ.KV("active", tab == "arches") }><a class="nav-link" href="/arches">Architectures</a></li>
+ <li class={ "nav-item", templ.KV("active", tab == "about") }><a class="nav-link" href="/about">About</a></li>
</ul>
if tab != "home" {
<form class="form-inline inlinesearch" role="search" action="/packages/search" method="get">
@@ -110,7 +103,7 @@ templ footer() {
</ul>
</div>
<div class="col-8 col-sm-8 col-md-8">
- <strong>&copy; 2001&ndash;2023 Gentoo Authors</strong>
+ <strong>&copy; 2001&ndash;2024 Gentoo Authors</strong>
<br/>
<small>
Gentoo is a trademark of the Gentoo Foundation, Inc.
@@ -121,10 +114,8 @@ templ footer() {
</div>
<div class="col-2 col-sm-2 col-md-2 text-right">
<strong><a class="text-dark" href="https://www.gentoo.org/inside-gentoo/contact/">Contact</a></strong>
- <br />
- <small>
- { config.Version() }
- </small>
+ <br/>
+ <small>{ config.Version() }</small>
</div>
</div>
</div>
@@ -140,8 +131,51 @@ templ Layout(title string, tab string, contents templ.Component) {
@siteTitle()
@navigationBar(tab)
</header>
- @contents
- @footer()
+ @contents
+ @footer()
</body>
</html>
}
+
+type SubTab struct {
+ Name string
+ Link templ.SafeURL
+ Icon string
+}
+
+templ tabbedHeader(subTitle string, icon string, tabs []SubTab, currentSubTab string, contents templ.Component) {
+ <div class="kk-header-container">
+ <div class="container">
+ <div class="row">
+ <div class="col-12">
+ <div class="row mt-3 pt-2">
+ <div class="col-md-5">
+ <h1 class="stick-top kk-package-title" id="package-title">
+ <div>
+ <div class="kk-package-name" style="margin-left: 0px!important;"><span class={ icon }></span><span class="ml-2">{ subTitle }</span></div>
+ </div>
+ </h1>
+ </div>
+ <div class="col-md-7"></div>
+ <div class="col-md-12 pt-4 mt-1">
+ <nav class="nav kk-package-nav">
+ for _, tab := range tabs {
+ <a class={ "nav-link", templ.KV("active", tab.Name == currentSubTab) } href={ tab.Link }>
+ <i class={ tab.Icon } aria-hidden="true"></i> { tab.Name }
+ </a>
+ }
+ </nav>
+ </div>
+ </div>
+ </div>
+ </div>
+ </div>
+ </div>
+ <div class="tab-content" id="myTabContent">
+ @contents
+ </div>
+}
+
+templ TabbedLayout(title string, tab string, subTitle string, icon string, tabs []SubTab, currentSubTab string, contents templ.Component) {
+ @Layout(title, tab, tabbedHeader(subTitle, icon, tabs, currentSubTab, contents))
+}
diff --git a/pkg/app/serve.go b/pkg/app/serve.go
index 7f9f618..bd6c6ff 100644
--- a/pkg/app/serve.go
+++ b/pkg/app/serve.go
@@ -41,7 +41,7 @@ func Serve() {
setRoute("/useflags/global", useflags.Global)
setRoute("/useflags/local", useflags.Local)
setRoute("/useflags/expand", useflags.Expand)
- setRoute("/useflags/popular", useflags.Index)
+ setRoute("/useflags/popular", useflags.PopularPage)
setRoute("/useflags", useflags.Default)
setRoute("/useflags/", useflags.Show)