0
0
mirror of https://github.com/go-gitea/gitea.git synced 2025-07-26 11:04:27 -04:00
gitea/modules/fileicon/fileicon.go
2024-10-24 08:37:20 +02:00

106 lines
2.6 KiB
Go

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))
}