Skip to content

Commit

Permalink
Home redesign
Browse files Browse the repository at this point in the history
  • Loading branch information
svera authored Nov 3, 2024
1 parent d371bb4 commit 4c251a9
Show file tree
Hide file tree
Showing 15 changed files with 197 additions and 98 deletions.
8 changes: 8 additions & 0 deletions internal/webserver/controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (
"github.com/svera/coreander/v4/internal/webserver/controller/auth"
"github.com/svera/coreander/v4/internal/webserver/controller/document"
"github.com/svera/coreander/v4/internal/webserver/controller/highlight"
"github.com/svera/coreander/v4/internal/webserver/controller/home"
"github.com/svera/coreander/v4/internal/webserver/controller/user"
"github.com/svera/coreander/v4/internal/webserver/model"
"gorm.io/gorm"
Expand All @@ -17,6 +18,7 @@ type Controllers struct {
Users *user.Controller
Highlights *highlight.Controller
Documents *document.Controller
Home *home.Controller
}

func SetupControllers(cfg Config, db *gorm.DB, metadataReaders map[string]metadata.Reader, idx *index.BleveIndexer, sender Sender, appFs afero.Fs) Controllers {
Expand Down Expand Up @@ -48,10 +50,16 @@ func SetupControllers(cfg Config, db *gorm.DB, metadataReaders map[string]metada
UploadDocumentMaxSize: cfg.UploadDocumentMaxSize,
}

homeCfg := home.Config{
LibraryPath: cfg.LibraryPath,
CoverMaxWidth: cfg.CoverMaxWidth,
}

return Controllers{
Auth: auth.NewController(usersRepository, sender, authCfg, printers),
Users: user.NewController(usersRepository, usersCfg),
Highlights: highlight.NewController(highlightsRepository, usersRepository, sender, cfg.WordsPerMinute, idx),
Documents: document.NewController(highlightsRepository, sender, idx, metadataReaders, appFs, documentsCfg),
Home: home.NewController(highlightsRepository, sender, idx, homeCfg),
}
}
10 changes: 7 additions & 3 deletions internal/webserver/controller/document/delete.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
package document

import (
"errors"
"log"
"os"
"path/filepath"

"github.com/gofiber/fiber/v2"
Expand All @@ -14,20 +16,22 @@ func (d *Controller) Delete(c *fiber.Ctx) error {
}

fullPath := filepath.Join(d.config.LibraryPath, document.ID)
if _, err := d.appFs.Stat(fullPath); err != nil {
if _, err := d.appFs.Stat(fullPath); err != nil && !errors.Is(err, os.ErrNotExist) {
log.Printf("error checking file %s for removal: %s\n", fullPath, err.Error())
return fiber.ErrBadRequest
}

if err := d.idx.RemoveFile(fullPath); err != nil {
log.Printf("error removing file %s from index: %s\n", fullPath, err.Error())
return fiber.ErrInternalServerError
}

if err := d.appFs.Remove(fullPath); err != nil {
log.Printf("error removing file %s", fullPath)
log.Printf("error removing file %s\n", fullPath)
}

if err := d.hlRepository.RemoveDocument(document.ID); err != nil {
log.Printf("error removing file %s from highlights", document.ID)
log.Printf("error removing file %s from highlights\n", document.ID)
}

return nil
Expand Down
6 changes: 6 additions & 0 deletions internal/webserver/controller/document/detail.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package document

import (
"fmt"
"log"
"os"
"path/filepath"
"strings"
Expand All @@ -28,6 +29,11 @@ func (d *Controller) Detail(c *fiber.Ctx) error {

document, err := d.idx.Document(c.Params("slug"))
if err != nil {
log.Println(err)
return fiber.ErrInternalServerError
}

if document.Slug == "" {
return fiber.ErrNotFound
}

Expand Down
9 changes: 7 additions & 2 deletions internal/webserver/controller/document/reader.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package document

import (
"fmt"
"log"
"os"
"path/filepath"
"strings"
Expand All @@ -12,8 +13,12 @@ import (
func (d *Controller) Reader(c *fiber.Ctx) error {
document, err := d.idx.Document(c.Params("slug"))
if err != nil {
fmt.Println(err)
return fiber.ErrBadRequest
log.Println(err)
return fiber.ErrInternalServerError
}

if document.Slug == "" {
return fiber.ErrNotFound
}

if _, err := os.Stat(filepath.Join(d.config.LibraryPath, document.ID)); err != nil {
Expand Down
61 changes: 16 additions & 45 deletions internal/webserver/controller/document/search.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,6 @@ func (d *Controller) Search(c *fiber.Ctx) error {
emailSendingConfigured = false
}

page, err := strconv.Atoi(c.Query("page"))
if err != nil {
page = 1
}

var session model.Session
if val, ok := c.Locals("Session").(model.Session); ok {
session = val
Expand All @@ -33,58 +28,34 @@ func (d *Controller) Search(c *fiber.Ctx) error {
}

var searchResults result.Paginated[[]index.Document]
keywords := c.Query("search")

if keywords := c.Query("search"); keywords != "" {
if searchResults, err = d.idx.Search(keywords, page, model.ResultsPerPage); err != nil {
log.Println(err)
return fiber.ErrInternalServerError
}

if session.ID > 0 {
searchResults = d.hlRepository.HighlightedPaginatedResult(int(session.ID), searchResults)
}

return c.Render("results", fiber.Map{
"Keywords": keywords,
"Results": searchResults,
"Paginator": view.Pagination(model.MaxPagesNavigator, searchResults, map[string]string{"search": keywords}),
"Title": "Search results",
"EmailSendingConfigured": emailSendingConfigured,
"EmailFrom": d.sender.From(),
"WordsPerMinute": d.config.WordsPerMinute,
}, "layout")
}

count, err := d.idx.Count()
if err != nil {
return fiber.ErrInternalServerError
if keywords == "" {
return fiber.ErrBadRequest
}

docsSortedByHighlightedDate, err := d.hlRepository.Highlights(int(session.ID), page, 6)
page, err := strconv.Atoi(c.Query("page"))
if err != nil {
return fiber.ErrInternalServerError
page = 1
}

docs, err := d.idx.Documents(docsSortedByHighlightedDate.Hits())
if err != nil {
if searchResults, err = d.idx.Search(keywords, page, model.ResultsPerPage); err != nil {
log.Println(err)
return fiber.ErrInternalServerError
}

highlights := make([]index.Document, 0, len(docs))
for _, path := range docsSortedByHighlightedDate.Hits() {
if _, ok := docs[path]; !ok {
continue
}
doc := docs[path]
doc.Highlighted = true
highlights = append(highlights, doc)
if session.ID > 0 {
searchResults = d.hlRepository.HighlightedPaginatedResult(int(session.ID), searchResults)
}

return c.Render("index", fiber.Map{
"Count": count,
"Title": "Coreander",
"Highlights": highlights,
return c.Render("results", fiber.Map{
"Keywords": keywords,
"Results": searchResults,
"Paginator": view.Pagination(model.MaxPagesNavigator, searchResults, map[string]string{"search": keywords}),
"Title": "Search results",
"EmailSendingConfigured": emailSendingConfigured,
"EmailFrom": d.sender.From(),
"WordsPerMinute": d.config.WordsPerMinute,
}, "layout")

}
44 changes: 44 additions & 0 deletions internal/webserver/controller/home/controller.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
package home

import (
"github.com/svera/coreander/v4/internal/index"
"github.com/svera/coreander/v4/internal/result"
)

const highlightsAmount = 6

type Sender interface {
SendDocument(address string, libraryPath string, fileName string) error
From() string
}

// IdxReaderWriter defines a set of reading and writing operations over an index
type IdxReaderWriter interface {
Documents(IDs []string) (map[string]index.Document, error)
Count() (uint64, error)
}

type highlightsRepository interface {
Highlights(userID int, page int, resultsPerPage int) (result.Paginated[[]string], error)
}

type Config struct {
LibraryPath string
CoverMaxWidth int
}

type Controller struct {
hlRepository highlightsRepository
idx IdxReaderWriter
sender Sender
config Config
}

func NewController(hlRepository highlightsRepository, sender Sender, idx IdxReaderWriter, cfg Config) *Controller {
return &Controller{
hlRepository: hlRepository,
idx: idx,
sender: sender,
config: cfg,
}
}
59 changes: 59 additions & 0 deletions internal/webserver/controller/home/index.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
package home

import (
"log"

"github.com/gofiber/fiber/v2"
"github.com/svera/coreander/v4/internal/index"
"github.com/svera/coreander/v4/internal/webserver/infrastructure"
"github.com/svera/coreander/v4/internal/webserver/model"
)

func (d *Controller) Index(c *fiber.Ctx) error {
emailSendingConfigured := true
if _, ok := d.sender.(*infrastructure.NoEmail); ok {
emailSendingConfigured = false
}

var session model.Session
if val, ok := c.Locals("Session").(model.Session); ok {
session = val
}

count, err := d.idx.Count()
if err != nil {
log.Println(err)
return fiber.ErrInternalServerError
}

docsSortedByHighlightedDate, err := d.hlRepository.Highlights(int(session.ID), 0, highlightsAmount)
if err != nil {
log.Println(err)
return fiber.ErrInternalServerError
}

docs, err := d.idx.Documents(docsSortedByHighlightedDate.Hits())
if err != nil {
log.Println(err)
return fiber.ErrInternalServerError
}

highlights := make([]index.Document, 0, len(docs))
for _, path := range docsSortedByHighlightedDate.Hits() {
if _, ok := docs[path]; !ok {
continue
}
doc := docs[path]
doc.Highlighted = true
highlights = append(highlights, doc)
}

return c.Render("index", fiber.Map{
"Count": count,
"Title": "Coreander",
"Highlights": highlights,
"EmailSendingConfigured": emailSendingConfigured,
"EmailFrom": d.sender.From(),
"HomeNavbar": true,
}, "layout")
}
22 changes: 0 additions & 22 deletions internal/webserver/controller/root.go

This file was deleted.

11 changes: 10 additions & 1 deletion internal/webserver/embedded/css/display.css
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ a.collapse-control.collapsed:after {
.nav-item .bi {
width: 1em;
height: 1em;
}
}

:root, [data-bs-theme=light] {
--bs-link-color-rgb: 0, 0, 0;
Expand All @@ -68,6 +68,9 @@ a.collapse-control.collapsed:after {
--bs-bg-opacity: 1;
background-color: rgba(var(--bs-light-rgb), var(--bs-bg-opacity)) !important;
}
.navbar-home {
background-color: white !important;
}
}

[data-bs-theme=dark] {
Expand All @@ -91,3 +94,9 @@ a.collapse-control.collapsed:after {
.card-img-overlay a, .card-img-overlay p, .card-img-overlay h2, .card-img-overlay h3, .card-img-overlay h4, .card-img-overlay h5 {
color: rgba(255,255,255,0.8);
}

[data-bs-theme=dark] {
.color-invertible {
filter: invert(100%);
}
}
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
14 changes: 1 addition & 13 deletions internal/webserver/embedded/views/index.html
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
<section class="pb-5 text-center">
<img src="/images/coreander-header.png" class="w-50 color-invertible"/>
{{template "partials/searchbox" .}}
<p>{{t .Lang "%d documents available" .Count}}</p>
</section>
Expand Down Expand Up @@ -46,17 +47,4 @@ <h2>{{t .Lang "Your highlights" }}</h2>
{{end}}
</section>
{{else}}
<section class="pt-5 text-center">
<h2 class="mb-3">{{t .Lang "Search tips"}}</h2>
<p>{{t .Lang "Use %s prefix in search box to search by authors only" `<span
class="font-monospace">Authors:</span>`}}</p>
<p>{{t .Lang "Use %s prefix in search box to search by title only" `<span
class="font-monospace">Title:</span>`}}</p>
<p>{{t .Lang "Use %s prefix in search box to search by series only" `<span
class="font-monospace">Series:</span>`}}</p>
<p>{{t .Lang "Use %s prefix in search box to search by subjects only" `<span
class="font-monospace">Subjects:</span>`}}</p>
<p>{{t .Lang "Enclose your search terms in double quotes to require all those terms and with the same order"}}
</p>
</section>
{{end}}
Loading

0 comments on commit 4c251a9

Please sign in to comment.