Преглед на файлове

:art: Brand new marketplace UI https://github.com/siyuan-note/siyuan/issues/8181

Liang Ding преди 2 години
родител
ревизия
9e1dbd9b96
променени са 8 файла, в които са добавени 129 реда и са изтрити 159 реда
  1. 12 20
      kernel/bazaar/icon.go
  2. 59 46
      kernel/bazaar/package.go
  3. 13 21
      kernel/bazaar/plugin.go
  4. 12 20
      kernel/bazaar/template.go
  5. 12 23
      kernel/bazaar/theme.go
  6. 12 20
      kernel/bazaar/widget.go
  7. 4 4
      kernel/model/appearance.go
  8. 5 5
      kernel/model/bazzar.go

+ 12 - 20
kernel/bazaar/icon.go

@@ -32,25 +32,24 @@ import (
 )
 
 type Icon struct {
-	Package
+	*Package
 }
 
 func Icons() (icons []*Icon) {
 	icons = []*Icon{}
 
-	pkgIndex, err := getPkgIndex("icons")
+	stageIndex, err := getStageIndex("icons")
 	if nil != err {
 		return
 	}
 	bazaarIndex := getBazaarIndex()
-	repos := pkgIndex["repos"].([]interface{})
 	waitGroup := &sync.WaitGroup{}
 	lock := &sync.Mutex{}
 	p, _ := ants.NewPoolWithFunc(2, func(arg interface{}) {
 		defer waitGroup.Done()
 
-		repo := arg.(map[string]interface{})
-		repoURL := repo["url"].(string)
+		repo := arg.(*StageRepo)
+		repoURL := repo.URL
 
 		icon := &Icon{}
 		innerU := util.BazaarOSSServer + "/package/" + repoURL + "/icon.json"
@@ -71,13 +70,13 @@ func Icons() (icons []*Icon) {
 		icon.PreviewURL = util.BazaarOSSServer + "/package/" + repoURL + "/preview.png?imageslim"
 		icon.PreviewURLThumb = util.BazaarOSSServer + "/package/" + repoURL + "/preview.png?imageView2/2/w/436/h/232"
 		icon.IconURL = util.BazaarOSSServer + "/package/" + repoURL + "/icon.png"
-		icon.Funding = parseFunding(repo["package"].(map[string]interface{}))
+		icon.Funding = repo.Package.Funding
 		icon.PreferredFunding = getPreferredFunding(icon.Funding)
 		icon.PreferredDesc = getPreferredDesc(icon.Description)
-		icon.Updated = repo["updated"].(string)
-		icon.Stars = int(repo["stars"].(float64))
-		icon.OpenIssues = int(repo["openIssues"].(float64))
-		icon.Size = int64(repo["size"].(float64))
+		icon.Updated = repo.Updated
+		icon.Stars = repo.Stars
+		icon.OpenIssues = repo.OpenIssues
+		icon.Size = repo.Size
 		icon.HSize = humanize.Bytes(uint64(icon.Size))
 		icon.HUpdated = formatUpdated(icon.Updated)
 		pkg := bazaarIndex[strings.Split(repoURL, "@")[0]]
@@ -88,7 +87,7 @@ func Icons() (icons []*Icon) {
 		icons = append(icons, icon)
 		lock.Unlock()
 	})
-	for _, repo := range repos {
+	for _, repo := range stageIndex.Repos {
 		waitGroup.Add(1)
 		p.Invoke(repo)
 	}
@@ -118,25 +117,18 @@ func InstalledIcons() (ret []*Icon) {
 			continue
 		}
 
-		iconConf, parseErr := IconJSON(dirName)
-		if nil != parseErr || nil == iconConf {
+		icon, parseErr := IconJSON(dirName)
+		if nil != parseErr || nil == icon {
 			continue
 		}
 
 		installPath := filepath.Join(util.IconsPath, dirName)
 
-		icon := &Icon{}
 		icon.Installed = true
-		icon.Name = iconConf["name"].(string)
-		icon.Author = iconConf["author"].(string)
-		icon.URL = iconConf["url"].(string)
-		icon.URL = strings.TrimSuffix(icon.URL, "/")
-		icon.Version = iconConf["version"].(string)
 		icon.RepoURL = icon.URL
 		icon.PreviewURL = "/appearance/icons/" + dirName + "/preview.png"
 		icon.PreviewURLThumb = "/appearance/icons/" + dirName + "/preview.png"
 		icon.IconURL = "/appearance/icons/" + dirName + "/icon.png"
-		icon.Funding = parseFunding(iconConf)
 		icon.PreferredFunding = getPreferredFunding(icon.Funding)
 		icon.PreferredDesc = getPreferredDesc(icon.Description)
 		info, statErr := os.Stat(filepath.Join(installPath, "README.md"))

+ 59 - 46
kernel/bazaar/package.go

@@ -93,24 +93,28 @@ type Package struct {
 	Downloads    int    `json:"downloads"`
 }
 
-func parseFunding(pkg map[string]interface{}) (ret *Funding) {
-	if nil == pkg["funding"] {
-		return
-	}
+type StagePackage struct {
+	Author      string       `json:"author"`
+	URL         string       `json:"url"`
+	Version     string       `json:"version"`
+	Description *Description `json:"description"`
+	Readme      *Readme      `json:"readme"`
+	I18N        []string     `json:"i18n"`
+	Funding     *Funding     `json:"funding"`
+}
 
-	ret = &Funding{}
-	funding := pkg["funding"].(map[string]interface{})
-	ret.OpenCollective = funding["openCollective"].(string)
-	ret.Patreon = funding["patreon"].(string)
-	ret.GitHub = funding["github"].(string)
+type StageRepo struct {
+	URL        string `json:"url"`
+	Updated    string `json:"updated"`
+	Stars      int    `json:"stars"`
+	OpenIssues int    `json:"openIssues"`
+	Size       int64  `json:"size"`
 
-	customURLs := funding["custom"].([]interface{})
-	var custom []string
-	for _, customURL := range customURLs {
-		custom = append(custom, customURL.(string))
-	}
-	ret.Custom = custom
-	return
+	Package *StagePackage `json:"package"`
+}
+
+type StageIndex struct {
+	Repos []*StageRepo `json:"repos"`
 }
 
 func getPreferredDesc(desc *Description) string {
@@ -156,7 +160,7 @@ func getPreferredFunding(funding *Funding) string {
 	return ""
 }
 
-func PluginJSON(pluginDirName string) (ret map[string]interface{}, err error) {
+func PluginJSON(pluginDirName string) (ret *Plugin, err error) {
 	p := filepath.Join(util.DataDir, "plugins", pluginDirName, "plugin.json")
 	if !gulu.File.IsExist(p) {
 		err = os.ErrNotExist
@@ -171,14 +175,12 @@ func PluginJSON(pluginDirName string) (ret map[string]interface{}, err error) {
 		logging.LogErrorf("parse plugin.json [%s] failed: %s", p, err)
 		return
 	}
-	if 4 > len(ret) {
-		logging.LogWarnf("invalid plugin.json [%s]", p)
-		return nil, errors.New("invalid plugin.json")
-	}
+
+	ret.URL = strings.TrimSuffix(ret.URL, "/")
 	return
 }
 
-func WidgetJSON(widgetDirName string) (ret map[string]interface{}, err error) {
+func WidgetJSON(widgetDirName string) (ret *Widget, err error) {
 	p := filepath.Join(util.DataDir, "widgets", widgetDirName, "widget.json")
 	if !gulu.File.IsExist(p) {
 		err = os.ErrNotExist
@@ -193,14 +195,12 @@ func WidgetJSON(widgetDirName string) (ret map[string]interface{}, err error) {
 		logging.LogErrorf("parse widget.json [%s] failed: %s", p, err)
 		return
 	}
-	if 4 > len(ret) {
-		logging.LogWarnf("invalid widget.json [%s]", p)
-		return nil, errors.New("invalid widget.json")
-	}
+
+	ret.URL = strings.TrimSuffix(ret.URL, "/")
 	return
 }
 
-func IconJSON(iconDirName string) (ret map[string]interface{}, err error) {
+func IconJSON(iconDirName string) (ret *Icon, err error) {
 	p := filepath.Join(util.IconsPath, iconDirName, "icon.json")
 	if !gulu.File.IsExist(p) {
 		err = os.ErrNotExist
@@ -215,14 +215,12 @@ func IconJSON(iconDirName string) (ret map[string]interface{}, err error) {
 		logging.LogErrorf("parse icon.json [%s] failed: %s", p, err)
 		return
 	}
-	if 4 > len(ret) {
-		logging.LogWarnf("invalid icon.json [%s]", p)
-		return nil, errors.New("invalid icon.json")
-	}
+
+	ret.URL = strings.TrimSuffix(ret.URL, "/")
 	return
 }
 
-func TemplateJSON(templateDirName string) (ret map[string]interface{}, err error) {
+func TemplateJSON(templateDirName string) (ret *Template, err error) {
 	p := filepath.Join(util.DataDir, "templates", templateDirName, "template.json")
 	if !gulu.File.IsExist(p) {
 		err = os.ErrNotExist
@@ -237,14 +235,12 @@ func TemplateJSON(templateDirName string) (ret map[string]interface{}, err error
 		logging.LogErrorf("parse template.json [%s] failed: %s", p, err)
 		return
 	}
-	if 4 > len(ret) {
-		logging.LogWarnf("invalid template.json [%s]", p)
-		return nil, errors.New("invalid template.json")
-	}
+
+	ret.URL = strings.TrimSuffix(ret.URL, "/")
 	return
 }
 
-func ThemeJSON(themeDirName string) (ret map[string]interface{}, err error) {
+func ThemeJSON(themeDirName string) (ret *Theme, err error) {
 	p := filepath.Join(util.ThemesPath, themeDirName, "theme.json")
 	if !gulu.File.IsExist(p) {
 		err = os.ErrNotExist
@@ -255,28 +251,41 @@ func ThemeJSON(themeDirName string) (ret map[string]interface{}, err error) {
 		logging.LogErrorf("read theme.json [%s] failed: %s", p, err)
 		return
 	}
+
+	ret = &Theme{}
 	if err = gulu.JSON.UnmarshalJSON(data, &ret); nil != err {
 		logging.LogErrorf("parse theme.json [%s] failed: %s", p, err)
 		return
 	}
-	if 5 > len(ret) {
-		logging.LogWarnf("invalid theme.json [%s]", p)
-		return nil, errors.New("invalid theme.json")
-	}
+
+	ret.URL = strings.TrimSuffix(ret.URL, "/")
 	return
 }
 
-func getPkgIndex(pkgType string) (ret map[string]interface{}, err error) {
-	ret, err = util.GetRhyResult(false)
+var cachedStageIndex *StageIndex
+var stageIndexCacheTime int64
+var stageIndexLock = sync.Mutex{}
+
+func getStageIndex(pkgType string) (ret *StageIndex, err error) {
+	rhyRet, err := util.GetRhyResult(false)
 	if nil != err {
 		return
 	}
 
-	bazaarHash := ret["bazaar"].(string)
-	ret = map[string]interface{}{}
+	stageIndexLock.Lock()
+	defer stageIndexLock.Unlock()
+
+	now := time.Now().Unix()
+	if 3600 >= now-stageIndexCacheTime {
+		ret = cachedStageIndex
+		return
+	}
+
+	bazaarHash := rhyRet["bazaar"].(string)
+	cachedStageIndex = &StageIndex{}
 	request := httpclient.NewBrowserRequest()
 	u := util.BazaarOSSServer + "/bazaar@" + bazaarHash + "/stage/" + pkgType + ".json"
-	resp, reqErr := request.SetSuccessResult(&ret).Get(u)
+	resp, reqErr := request.SetSuccessResult(cachedStageIndex).Get(u)
 	if nil != reqErr {
 		logging.LogErrorf("get community stage index [%s] failed: %s", u, reqErr)
 		return
@@ -285,6 +294,9 @@ func getPkgIndex(pkgType string) (ret map[string]interface{}, err error) {
 		logging.LogErrorf("get community stage index [%s] failed: %d", u, resp.StatusCode)
 		return
 	}
+
+	stageIndexCacheTime = now
+	ret = cachedStageIndex
 	return
 }
 
@@ -390,6 +402,7 @@ func isOutdatedTemplate(template *Template, bazaarTemplates []*Template) bool {
 
 func GetPackageREADME(repoURL, repoHash string, systemID string) (ret string) {
 	repoURLHash := repoURL + "@" + repoHash
+
 	data, err := downloadPackage(repoURLHash+"/README.md", false, systemID)
 	if nil != err {
 		ret = "Load bazaar package's README.md failed: " + err.Error()

+ 13 - 21
kernel/bazaar/plugin.go

@@ -33,28 +33,27 @@ import (
 )
 
 type Plugin struct {
-	Package
+	*Package
 }
 
 func Plugins() (plugins []*Plugin) {
 	plugins = []*Plugin{}
 
-	pkgIndex, err := getPkgIndex("plugins")
+	stageIndex, err := getStageIndex("plugins")
 	if nil != err {
 		return
 	}
 	bazaarIndex := getBazaarIndex()
 
-	repos := pkgIndex["repos"].([]interface{})
 	waitGroup := &sync.WaitGroup{}
 	lock := &sync.Mutex{}
 	p, _ := ants.NewPoolWithFunc(8, func(arg interface{}) {
 		defer waitGroup.Done()
 
-		repo := arg.(map[string]interface{})
-		repoURL := repo["url"].(string)
+		repo := arg.(*StageRepo)
+		repoURL := repo.URL
 
-		plugin := &Plugin{Package{Funding: &Funding{}, Description: &Description{}}}
+		plugin := &Plugin{}
 		innerU := util.BazaarOSSServer + "/package/" + repoURL + "/plugin.json"
 		innerResp, innerErr := httpclient.NewBrowserRequest().SetSuccessResult(plugin).Get(innerU)
 		if nil != innerErr {
@@ -73,13 +72,13 @@ func Plugins() (plugins []*Plugin) {
 		plugin.PreviewURL = util.BazaarOSSServer + "/package/" + repoURL + "/preview.png?imageslim"
 		plugin.PreviewURLThumb = util.BazaarOSSServer + "/package/" + repoURL + "/preview.png?imageView2/2/w/436/h/232"
 		plugin.IconURL = util.BazaarOSSServer + "/package/" + repoURL + "/icon.png"
-		plugin.Funding = parseFunding(repo["package"].(map[string]interface{}))
+		plugin.Funding = repo.Package.Funding
 		plugin.PreferredFunding = getPreferredFunding(plugin.Funding)
 		plugin.PreferredDesc = getPreferredDesc(plugin.Description)
-		plugin.Updated = repo["updated"].(string)
-		plugin.Stars = int(repo["stars"].(float64))
-		plugin.OpenIssues = int(repo["openIssues"].(float64))
-		plugin.Size = int64(repo["size"].(float64))
+		plugin.Updated = repo.Updated
+		plugin.Stars = repo.Stars
+		plugin.OpenIssues = repo.OpenIssues
+		plugin.Size = repo.Size
 		plugin.HSize = humanize.Bytes(uint64(plugin.Size))
 		plugin.HUpdated = formatUpdated(plugin.Updated)
 		pkg := bazaarIndex[strings.Split(repoURL, "@")[0]]
@@ -90,7 +89,7 @@ func Plugins() (plugins []*Plugin) {
 		plugins = append(plugins, plugin)
 		lock.Unlock()
 	})
-	for _, repo := range repos {
+	for _, repo := range stageIndex.Repos {
 		waitGroup.Add(1)
 		p.Invoke(repo)
 	}
@@ -123,25 +122,18 @@ func InstalledPlugins() (ret []*Plugin) {
 		}
 		dirName := pluginDir.Name()
 
-		pluginConf, parseErr := PluginJSON(dirName)
-		if nil != parseErr || nil == pluginConf {
+		plugin, parseErr := PluginJSON(dirName)
+		if nil != parseErr || nil == plugin {
 			continue
 		}
 
 		installPath := filepath.Join(util.DataDir, "plugins", dirName)
 
-		plugin := &Plugin{}
 		plugin.Installed = true
-		plugin.Name = pluginConf["name"].(string)
-		plugin.Author = pluginConf["author"].(string)
-		plugin.URL = pluginConf["url"].(string)
-		plugin.URL = strings.TrimSuffix(plugin.URL, "/")
-		plugin.Version = pluginConf["version"].(string)
 		plugin.RepoURL = plugin.URL
 		plugin.PreviewURL = "/plugins/" + dirName + "/preview.png"
 		plugin.PreviewURLThumb = "/plugins/" + dirName + "/preview.png"
 		plugin.IconURL = "/plugins/" + dirName + "/icon.png"
-		plugin.Funding = parseFunding(pluginConf)
 		plugin.PreferredFunding = getPreferredFunding(plugin.Funding)
 		plugin.PreferredDesc = getPreferredDesc(plugin.Description)
 		info, statErr := os.Stat(filepath.Join(installPath, "README.md"))

+ 12 - 20
kernel/bazaar/template.go

@@ -34,25 +34,24 @@ import (
 )
 
 type Template struct {
-	Package
+	*Package
 }
 
 func Templates() (templates []*Template) {
 	templates = []*Template{}
 
-	pkgIndex, err := getPkgIndex("templates")
+	stageIndex, err := getStageIndex("templates")
 	if nil != err {
 		return
 	}
 	bazaarIndex := getBazaarIndex()
-	repos := pkgIndex["repos"].([]interface{})
 	waitGroup := &sync.WaitGroup{}
 	lock := &sync.Mutex{}
 	p, _ := ants.NewPoolWithFunc(2, func(arg interface{}) {
 		defer waitGroup.Done()
 
-		repo := arg.(map[string]interface{})
-		repoURL := repo["url"].(string)
+		repo := arg.(*StageRepo)
+		repoURL := repo.URL
 
 		template := &Template{}
 		innerU := util.BazaarOSSServer + "/package/" + repoURL + "/template.json"
@@ -73,13 +72,13 @@ func Templates() (templates []*Template) {
 		template.PreviewURL = util.BazaarOSSServer + "/package/" + repoURL + "/preview.png?imageslim"
 		template.PreviewURLThumb = util.BazaarOSSServer + "/package/" + repoURL + "/preview.png?imageView2/2/w/436/h/232"
 		template.IconURL = util.BazaarOSSServer + "/package/" + repoURL + "/icon.png"
-		template.Funding = parseFunding(repo["package"].(map[string]interface{}))
+		template.Funding = repo.Package.Funding
 		template.PreferredFunding = getPreferredFunding(template.Funding)
 		template.PreferredDesc = getPreferredDesc(template.Description)
-		template.Updated = repo["updated"].(string)
-		template.Stars = int(repo["stars"].(float64))
-		template.OpenIssues = int(repo["openIssues"].(float64))
-		template.Size = int64(repo["size"].(float64))
+		template.Updated = repo.Updated
+		template.Stars = repo.Stars
+		template.OpenIssues = repo.OpenIssues
+		template.Size = repo.Size
 		template.HSize = humanize.Bytes(uint64(template.Size))
 		template.HUpdated = formatUpdated(template.Updated)
 		pkg := bazaarIndex[strings.Split(repoURL, "@")[0]]
@@ -90,7 +89,7 @@ func Templates() (templates []*Template) {
 		templates = append(templates, template)
 		lock.Unlock()
 	})
-	for _, repo := range repos {
+	for _, repo := range stageIndex.Repos {
 		waitGroup.Add(1)
 		p.Invoke(repo)
 	}
@@ -125,25 +124,18 @@ func InstalledTemplates() (ret []*Template) {
 		}
 		dirName := templateDir.Name()
 
-		templateConf, parseErr := TemplateJSON(dirName)
-		if nil != parseErr || nil == templateConf {
+		template, parseErr := TemplateJSON(dirName)
+		if nil != parseErr || nil == template {
 			continue
 		}
 
 		installPath := filepath.Join(util.DataDir, "templates", dirName)
 
-		template := &Template{}
 		template.Installed = true
-		template.Name = templateConf["name"].(string)
-		template.Author = templateConf["author"].(string)
-		template.URL = templateConf["url"].(string)
-		template.URL = strings.TrimSuffix(template.URL, "/")
-		template.Version = templateConf["version"].(string)
 		template.RepoURL = template.URL
 		template.PreviewURL = "/templates/" + dirName + "/preview.png"
 		template.PreviewURLThumb = "/templates/" + dirName + "/preview.png"
 		template.IconURL = "/templates/" + dirName + "/icon.png"
-		template.Funding = parseFunding(templateConf)
 		template.PreferredFunding = getPreferredFunding(template.Funding)
 		template.PreferredDesc = getPreferredDesc(template.Description)
 		info, statErr := os.Stat(filepath.Join(installPath, "README.md"))

+ 12 - 23
kernel/bazaar/theme.go

@@ -33,7 +33,7 @@ import (
 )
 
 type Theme struct {
-	Package
+	*Package
 
 	Modes []string `json:"modes"`
 }
@@ -41,19 +41,18 @@ type Theme struct {
 func Themes() (ret []*Theme) {
 	ret = []*Theme{}
 
-	pkgIndex, err := getPkgIndex("themes")
+	stageIndex, err := getStageIndex("themes")
 	if nil != err {
 		return
 	}
 	bazaarIndex := getBazaarIndex()
-	repos := pkgIndex["repos"].([]interface{})
 	waitGroup := &sync.WaitGroup{}
 	lock := &sync.Mutex{}
 	p, _ := ants.NewPoolWithFunc(8, func(arg interface{}) {
 		defer waitGroup.Done()
 
-		repo := arg.(map[string]interface{})
-		repoURL := repo["url"].(string)
+		repo := arg.(*StageRepo)
+		repoURL := repo.URL
 
 		theme := &Theme{}
 		innerU := util.BazaarOSSServer + "/package/" + repoURL + "/theme.json"
@@ -74,13 +73,13 @@ func Themes() (ret []*Theme) {
 		theme.PreviewURL = util.BazaarOSSServer + "/package/" + repoURL + "/preview.png?imageslim"
 		theme.PreviewURLThumb = util.BazaarOSSServer + "/package/" + repoURL + "/preview.png?imageView2/2/w/436/h/232"
 		theme.IconURL = util.BazaarOSSServer + "/package/" + repoURL + "/icon.png"
-		theme.Funding = parseFunding(repo["package"].(map[string]interface{}))
+		theme.Funding = repo.Package.Funding
 		theme.PreferredFunding = getPreferredFunding(theme.Funding)
 		theme.PreferredDesc = getPreferredDesc(theme.Description)
-		theme.Updated = repo["updated"].(string)
-		theme.Stars = int(repo["stars"].(float64))
-		theme.OpenIssues = int(repo["openIssues"].(float64))
-		theme.Size = int64(repo["size"].(float64))
+		theme.Updated = repo.Updated
+		theme.Stars = repo.Stars
+		theme.OpenIssues = repo.OpenIssues
+		theme.Size = repo.Size
 		theme.HSize = humanize.Bytes(uint64(theme.Size))
 		theme.HUpdated = formatUpdated(theme.Updated)
 		pkg := bazaarIndex[strings.Split(repoURL, "@")[0]]
@@ -91,7 +90,7 @@ func Themes() (ret []*Theme) {
 		ret = append(ret, theme)
 		lock.Unlock()
 	})
-	for _, repo := range repos {
+	for _, repo := range stageIndex.Repos {
 		waitGroup.Add(1)
 		p.Invoke(repo)
 	}
@@ -126,28 +125,18 @@ func InstalledThemes() (ret []*Theme) {
 			continue
 		}
 
-		themeConf, parseErr := ThemeJSON(dirName)
-		if nil != parseErr || nil == themeConf {
+		theme, parseErr := ThemeJSON(dirName)
+		if nil != parseErr || nil == theme {
 			continue
 		}
 
 		installPath := filepath.Join(util.ThemesPath, dirName)
 
-		theme := &Theme{}
 		theme.Installed = true
-		theme.Name = themeConf["name"].(string)
-		theme.Author = themeConf["author"].(string)
-		theme.URL = themeConf["url"].(string)
-		theme.URL = strings.TrimSuffix(theme.URL, "/")
-		theme.Version = themeConf["version"].(string)
-		for _, mode := range themeConf["modes"].([]interface{}) {
-			theme.Modes = append(theme.Modes, mode.(string))
-		}
 		theme.RepoURL = theme.URL
 		theme.PreviewURL = "/appearance/themes/" + dirName + "/preview.png"
 		theme.PreviewURLThumb = "/appearance/themes/" + dirName + "/preview.png"
 		theme.IconURL = "/appearance/themes/" + dirName + "/icon.png"
-		theme.Funding = parseFunding(themeConf)
 		theme.PreferredFunding = getPreferredFunding(theme.Funding)
 		theme.PreferredDesc = getPreferredDesc(theme.Description)
 		info, statErr := os.Stat(filepath.Join(installPath, "README.md"))

+ 12 - 20
kernel/bazaar/widget.go

@@ -33,26 +33,25 @@ import (
 )
 
 type Widget struct {
-	Package
+	*Package
 }
 
 func Widgets() (widgets []*Widget) {
 	widgets = []*Widget{}
 
-	pkgIndex, err := getPkgIndex("widgets")
+	stageIndex, err := getStageIndex("widgets")
 	if nil != err {
 		return
 	}
 	bazaarIndex := getBazaarIndex()
 
-	repos := pkgIndex["repos"].([]interface{})
 	waitGroup := &sync.WaitGroup{}
 	lock := &sync.Mutex{}
 	p, _ := ants.NewPoolWithFunc(8, func(arg interface{}) {
 		defer waitGroup.Done()
 
-		repo := arg.(map[string]interface{})
-		repoURL := repo["url"].(string)
+		repo := arg.(*StageRepo)
+		repoURL := repo.URL
 
 		widget := &Widget{}
 		innerU := util.BazaarOSSServer + "/package/" + repoURL + "/widget.json"
@@ -73,13 +72,13 @@ func Widgets() (widgets []*Widget) {
 		widget.PreviewURL = util.BazaarOSSServer + "/package/" + repoURL + "/preview.png?imageslim"
 		widget.PreviewURLThumb = util.BazaarOSSServer + "/package/" + repoURL + "/preview.png?imageView2/2/w/436/h/232"
 		widget.IconURL = util.BazaarOSSServer + "/package/" + repoURL + "/icon.png"
-		widget.Funding = parseFunding(repo["package"].(map[string]interface{}))
+		widget.Funding = repo.Package.Funding
 		widget.PreferredFunding = getPreferredFunding(widget.Funding)
 		widget.PreferredDesc = getPreferredDesc(widget.Description)
-		widget.Updated = repo["updated"].(string)
-		widget.Stars = int(repo["stars"].(float64))
-		widget.OpenIssues = int(repo["openIssues"].(float64))
-		widget.Size = int64(repo["size"].(float64))
+		widget.Updated = repo.Updated
+		widget.Stars = repo.Stars
+		widget.OpenIssues = repo.OpenIssues
+		widget.Size = repo.Size
 		widget.HSize = humanize.Bytes(uint64(widget.Size))
 		widget.HUpdated = formatUpdated(widget.Updated)
 		pkg := bazaarIndex[strings.Split(repoURL, "@")[0]]
@@ -90,7 +89,7 @@ func Widgets() (widgets []*Widget) {
 		widgets = append(widgets, widget)
 		lock.Unlock()
 	})
-	for _, repo := range repos {
+	for _, repo := range stageIndex.Repos {
 		waitGroup.Add(1)
 		p.Invoke(repo)
 	}
@@ -123,25 +122,18 @@ func InstalledWidgets() (ret []*Widget) {
 		}
 		dirName := widgetDir.Name()
 
-		widgetConf, parseErr := WidgetJSON(dirName)
-		if nil != parseErr || nil == widgetConf {
+		widget, parseErr := WidgetJSON(dirName)
+		if nil != parseErr || nil == widget {
 			continue
 		}
 
 		installPath := filepath.Join(util.DataDir, "widgets", dirName)
 
-		widget := &Widget{}
 		widget.Installed = true
-		widget.Name = widgetConf["name"].(string)
-		widget.Author = widgetConf["author"].(string)
-		widget.URL = widgetConf["url"].(string)
-		widget.URL = strings.TrimSuffix(widget.URL, "/")
-		widget.Version = widgetConf["version"].(string)
 		widget.RepoURL = widget.URL
 		widget.PreviewURL = "/widgets/" + dirName + "/preview.png"
 		widget.PreviewURLThumb = "/widgets/" + dirName + "/preview.png"
 		widget.IconURL = "/widgets/" + dirName + "/icon.png"
-		widget.Funding = parseFunding(widgetConf)
 		widget.PreferredFunding = getPreferredFunding(widget.Funding)
 		widget.PreferredDesc = getPreferredDesc(widget.Description)
 		info, statErr := os.Stat(filepath.Join(installPath, "README.md"))

+ 4 - 4
kernel/model/appearance.go

@@ -116,7 +116,7 @@ func loadThemes() {
 			continue
 		}
 
-		modes := themeConf["modes"].([]interface{})
+		modes := themeConf.Modes
 		for _, mode := range modes {
 			if "dark" == mode {
 				Conf.Appearance.DarkThemes = append(Conf.Appearance.DarkThemes, name)
@@ -127,12 +127,12 @@ func loadThemes() {
 
 		if 0 == Conf.Appearance.Mode {
 			if Conf.Appearance.ThemeLight == name {
-				Conf.Appearance.ThemeVer = themeConf["version"].(string)
+				Conf.Appearance.ThemeVer = themeConf.Version
 				Conf.Appearance.ThemeJS = gulu.File.IsExist(filepath.Join(util.ThemesPath, name, "theme.js"))
 			}
 		} else {
 			if Conf.Appearance.ThemeDark == name {
-				Conf.Appearance.ThemeVer = themeConf["version"].(string)
+				Conf.Appearance.ThemeVer = themeConf.Version
 				Conf.Appearance.ThemeJS = gulu.File.IsExist(filepath.Join(util.ThemesPath, name, "theme.js"))
 			}
 		}
@@ -161,7 +161,7 @@ func loadIcons() {
 		}
 		Conf.Appearance.Icons = append(Conf.Appearance.Icons, name)
 		if Conf.Appearance.Icon == name {
-			Conf.Appearance.IconVer = iconConf["version"].(string)
+			Conf.Appearance.IconVer = iconConf.Version
 		}
 	}
 }

+ 5 - 5
kernel/model/bazzar.go

@@ -39,7 +39,7 @@ func BazaarPlugins() (plugins []*bazaar.Plugin) {
 		if plugin.Installed {
 			if plugin.Installed {
 				if pluginConf, err := bazaar.PluginJSON(plugin.Name); nil == err && nil != plugin {
-					if plugin.Version != pluginConf["version"].(string) {
+					if plugin.Version != pluginConf.Version {
 						plugin.Outdated = true
 					}
 				}
@@ -79,7 +79,7 @@ func BazaarWidgets() (widgets []*bazaar.Widget) {
 		if widget.Installed {
 			if widget.Installed {
 				if widgetConf, err := bazaar.WidgetJSON(widget.Name); nil == err && nil != widget {
-					if widget.Version != widgetConf["version"].(string) {
+					if widget.Version != widgetConf.Version {
 						widget.Outdated = true
 					}
 				}
@@ -119,7 +119,7 @@ func BazaarIcons() (icons []*bazaar.Icon) {
 			if installed == icon.Name {
 				icon.Installed = true
 				if themeConf, err := bazaar.IconJSON(icon.Name); nil == err {
-					if icon.Version != themeConf["version"].(string) {
+					if icon.Version != themeConf.Version {
 						icon.Outdated = true
 					}
 				}
@@ -170,7 +170,7 @@ func BazaarThemes() (ret []*bazaar.Theme) {
 			if installed == theme.Name {
 				theme.Installed = true
 				if themeConf, err := bazaar.ThemeJSON(theme.Name); nil == err {
-					theme.Outdated = theme.Version != themeConf["version"].(string)
+					theme.Outdated = theme.Version != themeConf.Version
 				}
 				theme.Current = theme.Name == Conf.Appearance.ThemeDark || theme.Name == Conf.Appearance.ThemeLight
 			}
@@ -231,7 +231,7 @@ func BazaarTemplates() (templates []*bazaar.Template) {
 		template.Installed = gulu.File.IsExist(filepath.Join(util.DataDir, "templates", template.Name))
 		if template.Installed {
 			if themeConf, err := bazaar.TemplateJSON(template.Name); nil == err && nil != themeConf {
-				if template.Version != themeConf["version"].(string) {
+				if template.Version != themeConf.Version {
 					template.Outdated = true
 				}
 			}