diff --git a/modules/fileicon/fileicon.go b/modules/fileicon/fileicon.go index 30a4b28d48..daf2df35f5 100644 --- a/modules/fileicon/fileicon.go +++ b/modules/fileicon/fileicon.go @@ -3,7 +3,6 @@ package fileicon import ( "context" "html/template" - "os" "path" "strings" @@ -72,39 +71,31 @@ func getFileIconNames(entry *git.TreeEntry) []string { return nil } -func loadCustomIcon(iconPath string) (string, error) { - log.Debug("Loading custom icon from %s", iconPath) - - if icon, ok := fileIconCache.Get(iconPath); ok { - return icon, nil - } - - // Try to load the icon from the filesystem - if _, err := os.Stat(iconPath); err != nil { - return "", err - } - - iconData, err := os.ReadFile(iconPath) - if err != nil { - return "", err - } - - fileIconCache.Add(iconPath, string(iconData)) - - return string(iconData), 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 { - iconPath := path.Join(setting.AppDataPath, "icons", iconTheme, iconName+".svg") - if icon, err := loadCustomIcon(iconPath); err == nil { - return svg.RenderHTMLFromString(icon) + 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)) } } } diff --git a/modules/fileicon/fs.go b/modules/fileicon/fs.go new file mode 100644 index 0000000000..89b8b1ae50 --- /dev/null +++ b/modules/fileicon/fs.go @@ -0,0 +1,31 @@ +package fileicon + +import ( + "os" + "path" + + "code.gitea.io/gitea/modules/log" + "code.gitea.io/gitea/modules/setting" +) + +type fileIconFolderBackend struct { + theme string +} + +func (f *fileIconFolderBackend) GetIcon(iconName string) (string, error) { + iconPath := path.Join(setting.AppDataPath, "icons", f.theme, iconName+".svg") + + log.Debug("Loading custom icon from %s", iconPath) + + // Try to load the icon from the filesystem + if _, err := os.Stat(iconPath); err != nil { + return "", err + } + + iconData, err := os.ReadFile(iconPath) + if err != nil { + return "", err + } + + return string(iconData), nil +} diff --git a/modules/fileicon/http.go b/modules/fileicon/http.go new file mode 100644 index 0000000000..a1fa3aae49 --- /dev/null +++ b/modules/fileicon/http.go @@ -0,0 +1,38 @@ +package fileicon + +import ( + "fmt" + "io" + "net/http" + "path" + + "code.gitea.io/gitea/modules/log" +) + +type fileIconHTTPBackend struct { + theme string + baseURL string +} + +func (f *fileIconHTTPBackend) GetIcon(iconName string) (string, error) { + iconPath := path.Join(f.baseURL, f.theme, iconName+".svg") + + log.Info("Loading custom icon from %s", iconPath) + + // Try to load the icon via HTTP get + res, err := http.Get(iconPath) + if err != nil { + return "", err + } + + if res.StatusCode != http.StatusOK { + return "", fmt.Errorf("Failed to load icon: %s", res.Status) + } + + resBody, err := io.ReadAll(res.Body) + if err != nil { + return "", err + } + + return string(resBody), nil +}