-
-
Notifications
You must be signed in to change notification settings - Fork 5.7k
/
Copy pathfileicon.go
105 lines (88 loc) · 2.61 KB
/
fileicon.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
package fileicon
import (
"context"
"html/template"
"path"
"strings"
"code.gitea.io/gitea/modules/git"
"code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/modules/setting"
"code.gitea.io/gitea/modules/svg"
lru "github.com/hashicorp/golang-lru/v2"
)
var fileIconCache *lru.Cache[string, string]
func init() {
var err error
fileIconCache, err = lru.New[string, string](1000)
if err != nil {
log.Fatal("Failed to create file icon cache: %v", err)
}
}
func getBasicFileIconName(entry *git.TreeEntry) string {
switch {
case entry.IsLink():
te, err := entry.FollowLink()
if err != nil {
log.Debug(err.Error())
return "octicon-file-symlink-file"
}
if te.IsDir() {
return "octicon-file-directory-symlink"
}
return "octicon-file-symlink-file"
case entry.IsDir():
return "octicon-file-directory-fill"
case entry.IsSubModule():
return "octicon-file-submodule"
}
return "octicon-file"
}
// getFileIconNames returns a list of possible icon names for a file or directory
// Folder named `sub-folder` =>
// - `folder_sub-folder“ (. will be replaced with _)
// - `folder`
//
// File named `.gitignore` =>
// - `file__gitignore` (. will be replaced with _)
// - `file_`
//
// File named `README.md` =>
// - `file_readme_md`
// - `file_md`
func getFileIconNames(entry *git.TreeEntry) []string {
fileName := strings.ReplaceAll(strings.ToLower(path.Base(entry.Name())), ".", "_")
if entry.IsDir() {
return []string{"folder_" + fileName, "folder"}
}
if entry.IsRegular() {
ext := strings.ToLower(strings.TrimPrefix(path.Ext(entry.Name()), "."))
return []string{"file_" + fileName, "file_" + ext, "file"}
}
return nil
}
type fileIconBackend interface {
GetIcon(string) (string, error)
}
// FileIcon returns a custom icon from a folder or the default octicon for displaying files/directories
func FileIcon(ctx context.Context, entry *git.TreeEntry) template.HTML {
backend := &fileIconHTTPBackend{
theme: setting.UI.FileIconTheme,
baseURL: "https://raw.githubusercontent.com/anbraten/gitea-icons/refs/heads/master/gitea/",
}
iconTheme := setting.UI.FileIconTheme
if iconTheme != "" {
iconNames := getFileIconNames(entry)
// Try to load the custom icon
for _, iconName := range iconNames {
if icon, err := backend.GetIcon(iconName); err == nil {
if icon, ok := fileIconCache.Get(iconName); ok {
return svg.RenderHTMLFromString(icon)
}
fileIconCache.Add(iconName, string(icon))
return svg.RenderHTMLFromString(string(icon))
}
}
}
// If no custom icon was found or an error occurred, return the default icon
return svg.RenderHTML(getBasicFileIconName(entry))
}