main 5041353

favorite.go RawHistoryFolder

1package entity
2
3import (
4	"strings"
5	"time"
6)
7
8// FavoriteID uniquely identifies a favorite/bookmark.
9type FavoriteID int64
10
11// TagID uniquely identifies a tag.
12type TagID int64
13
14// Favorite represents a bookmarked URL.
15type Favorite struct {
16	ID          FavoriteID `json:"id"`
17	URL         string     `json:"url"`
18	Title       string     `json:"title"`
19	FaviconURL  string     `json:"favicon_url"`
20	ShortcutKey *int       `json:"shortcut_key"` // 1-9 for quick access (Alt+1 through Alt+9)
21	Position    int        `json:"position"`     // Order within tag or default list
22	Tags        []Tag      `json:"tags,omitempty"`
23	CreatedAt   time.Time  `json:"created_at"`
24	UpdatedAt   time.Time  `json:"updated_at"`
25}
26
27// NewFavorite creates a new favorite for a URL.
28func NewFavorite(url, title string) *Favorite {
29	now := time.Now()
30	return &Favorite{
31		URL:       url,
32		Title:     title,
33		CreatedAt: now,
34		UpdatedAt: now,
35	}
36}
37
38// HasShortcut returns true if this favorite has a keyboard shortcut.
39func (f *Favorite) HasShortcut() bool {
40	return f.ShortcutKey != nil && *f.ShortcutKey >= 1 && *f.ShortcutKey <= 9
41}
42
43// HasTag returns true if this favorite has the given tag.
44func (f *Favorite) HasTag(tagID TagID) bool {
45	for _, t := range f.Tags {
46		if t.ID == tagID {
47			return true
48		}
49	}
50	return false
51}
52
53// Tag represents a label that can be applied to favorites.
54type Tag struct {
55	ID        TagID     `json:"id"`
56	Name      string    `json:"name"`
57	Color     string    `json:"color"` // Hex color code (e.g., "#FF5733")
58	CreatedAt time.Time `json:"created_at"`
59}
60
61// NewTag creates a new tag with default color.
62func NewTag(name string) *Tag {
63	return &Tag{
64		Name:      strings.TrimSpace(name),
65		Color:     "#808080", // Default gray
66		CreatedAt: time.Now(),
67	}
68}

Keyboard shortcuts

Single-key shortcuts are on. ctrl k and esc work whatever this says.

ctrl k :
go to a section, branch, tag, file or repository
?
this list
j k
move the row cursor down / up
enter
open the row under the cursor; on Files, a directory opens or closes in place
↑ ↓ ← → home end
in the file tree (focus on a row): previous / next row, close / open a directory or go to its parent / first entry, first / last row. They never open a file
l h
on Files: open a directory or a file / close a directory or go up to its parent, then to the parent page. Elsewhere: into the side panel (on a merge request, its files) / back to the content; there j k move between its controls
g g G
first / last row
/
filter the list; on Files, find a file anywhere in the repository (esc clears, enter opens the best match)
b
switch branch or tag
g s g f g c g b g m g i g r g a
tabs: summary, files, commits, branches & tags, merge requests, issues, releases, actions (when available)
g h
home
w
wide mode: use the whole width of the screen, or not (remembered)
y
copy a permalink pinned to the commit
d u x
diff: split / unified / collapse or expand all
e E
diff: the whole file in view / every file, with the lines the hunks hide
n
merge request: next note in the diff
esc
close a dialog, leave a field

Branches 8

Tags 42

↑↓ moveenter openesc close