mirror of
https://github.com/AvengeMedia/DankMaterialShell.git
synced 2026-06-24 12:05:21 -04:00
feat(pluginBrowser): Add inline image previews while browsing
This commit is contained in:
@@ -5,6 +5,7 @@ import (
|
||||
"testing"
|
||||
|
||||
"github.com/AvengeMedia/DankMaterialShell/core/internal/mocks/net"
|
||||
coreplugins "github.com/AvengeMedia/DankMaterialShell/core/internal/plugins"
|
||||
"github.com/AvengeMedia/DankMaterialShell/core/internal/server/models"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/mock"
|
||||
@@ -165,6 +166,7 @@ func TestPluginInfoJSON(t *testing.T) {
|
||||
info := PluginInfo{
|
||||
Name: "test",
|
||||
Description: "test description",
|
||||
Screenshot: "https://raw.githubusercontent.com/test/repo/main/screenshot.png",
|
||||
Installed: true,
|
||||
FirstParty: true,
|
||||
}
|
||||
@@ -177,6 +179,59 @@ func TestPluginInfoJSON(t *testing.T) {
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, info.Name, unmarshaled.Name)
|
||||
assert.Equal(t, info.Installed, unmarshaled.Installed)
|
||||
assert.Equal(t, info.Screenshot, unmarshaled.Screenshot)
|
||||
}
|
||||
|
||||
func TestNormalizeScreenshotURL(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
raw string
|
||||
want string
|
||||
}{
|
||||
{
|
||||
name: "raw github url is unchanged",
|
||||
raw: "https://raw.githubusercontent.com/alcxyz/DankVault/main/docs/screenshot.png",
|
||||
want: "https://raw.githubusercontent.com/alcxyz/DankVault/main/docs/screenshot.png",
|
||||
},
|
||||
{
|
||||
name: "github blob url becomes raw content url",
|
||||
raw: "https://github.com/acmagn/DMS-UPS-Monitor/blob/main/assets/screenshot.png",
|
||||
want: "https://raw.githubusercontent.com/acmagn/DMS-UPS-Monitor/main/assets/screenshot.png",
|
||||
},
|
||||
{
|
||||
name: "github raw url becomes raw content url",
|
||||
raw: "https://github.com/antonjah/nix-monitor/raw/master/assets/scrot.png",
|
||||
want: "https://raw.githubusercontent.com/antonjah/nix-monitor/master/assets/scrot.png",
|
||||
},
|
||||
{
|
||||
name: "non github url is unchanged",
|
||||
raw: "https://example.com/screenshot.png",
|
||||
want: "https://example.com/screenshot.png",
|
||||
},
|
||||
{
|
||||
name: "empty url is empty",
|
||||
raw: " ",
|
||||
want: "",
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
assert.Equal(t, tt.want, normalizeScreenshotURL(tt.raw))
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestPluginInfoFromPluginIncludesScreenshot(t *testing.T) {
|
||||
info := pluginInfoFromPlugin(coreplugins.Plugin{
|
||||
ID: "dankVault",
|
||||
Name: "Vault",
|
||||
Repo: "https://github.com/AvengeMedia/dms-plugins",
|
||||
Screenshot: "https://github.com/AvengeMedia/dms-plugins/blob/master/DankNotepadModule/screenshot.png",
|
||||
})
|
||||
|
||||
assert.Equal(t, "https://raw.githubusercontent.com/AvengeMedia/dms-plugins/master/DankNotepadModule/screenshot.png", info.Screenshot)
|
||||
assert.True(t, info.FirstParty)
|
||||
}
|
||||
|
||||
func TestSuccessResult(t *testing.T) {
|
||||
|
||||
@@ -3,7 +3,6 @@ package plugins
|
||||
import (
|
||||
"fmt"
|
||||
"net"
|
||||
"strings"
|
||||
|
||||
"github.com/AvengeMedia/DankMaterialShell/core/internal/plugins"
|
||||
"github.com/AvengeMedia/DankMaterialShell/core/internal/server/models"
|
||||
@@ -34,25 +33,12 @@ func HandleList(conn net.Conn, req models.Request) {
|
||||
for i, p := range pluginList {
|
||||
installed, _ := manager.IsInstalled(p)
|
||||
fb := feedback[p.ID]
|
||||
result[i] = PluginInfo{
|
||||
ID: p.ID,
|
||||
Name: p.Name,
|
||||
Category: p.Category,
|
||||
Author: p.Author,
|
||||
Description: p.Description,
|
||||
Repo: p.Repo,
|
||||
Path: p.Path,
|
||||
Capabilities: p.Capabilities,
|
||||
Compositors: p.Compositors,
|
||||
Dependencies: p.Dependencies,
|
||||
Installed: installed,
|
||||
FirstParty: strings.HasPrefix(p.Repo, "https://github.com/AvengeMedia"),
|
||||
Featured: p.Featured,
|
||||
RequiresDMS: p.RequiresDMS,
|
||||
Upvotes: fb.Upvotes,
|
||||
Status: fb.Status,
|
||||
IssueURL: fb.IssueURL,
|
||||
}
|
||||
info := pluginInfoFromPlugin(p)
|
||||
info.Installed = installed
|
||||
info.Upvotes = fb.Upvotes
|
||||
info.Status = fb.Status
|
||||
info.IssueURL = fb.IssueURL
|
||||
result[i] = info
|
||||
}
|
||||
|
||||
models.Respond(conn, req.ID, result)
|
||||
|
||||
@@ -3,7 +3,6 @@ package plugins
|
||||
import (
|
||||
"fmt"
|
||||
"net"
|
||||
"strings"
|
||||
|
||||
"github.com/AvengeMedia/DankMaterialShell/core/internal/plugins"
|
||||
"github.com/AvengeMedia/DankMaterialShell/core/internal/server/models"
|
||||
@@ -47,21 +46,9 @@ func HandleListInstalled(conn net.Conn, req models.Request) {
|
||||
hasUpdate = hasUpdates
|
||||
}
|
||||
|
||||
result = append(result, PluginInfo{
|
||||
ID: plugin.ID,
|
||||
Name: plugin.Name,
|
||||
Category: plugin.Category,
|
||||
Author: plugin.Author,
|
||||
Description: plugin.Description,
|
||||
Repo: plugin.Repo,
|
||||
Path: plugin.Path,
|
||||
Capabilities: plugin.Capabilities,
|
||||
Compositors: plugin.Compositors,
|
||||
Dependencies: plugin.Dependencies,
|
||||
FirstParty: strings.HasPrefix(plugin.Repo, "https://github.com/AvengeMedia"),
|
||||
HasUpdate: hasUpdate,
|
||||
RequiresDMS: plugin.RequiresDMS,
|
||||
})
|
||||
info := pluginInfoFromPlugin(plugin)
|
||||
info.HasUpdate = hasUpdate
|
||||
result = append(result, info)
|
||||
} else {
|
||||
result = append(result, PluginInfo{
|
||||
ID: id,
|
||||
|
||||
@@ -3,7 +3,6 @@ package plugins
|
||||
import (
|
||||
"fmt"
|
||||
"net"
|
||||
"strings"
|
||||
|
||||
"github.com/AvengeMedia/DankMaterialShell/core/internal/plugins"
|
||||
"github.com/AvengeMedia/DankMaterialShell/core/internal/server/models"
|
||||
@@ -53,21 +52,9 @@ func HandleSearch(conn net.Conn, req models.Request) {
|
||||
result := make([]PluginInfo, len(searchResults))
|
||||
for i, p := range searchResults {
|
||||
installed, _ := manager.IsInstalled(p)
|
||||
result[i] = PluginInfo{
|
||||
ID: p.ID,
|
||||
Name: p.Name,
|
||||
Category: p.Category,
|
||||
Author: p.Author,
|
||||
Description: p.Description,
|
||||
Repo: p.Repo,
|
||||
Path: p.Path,
|
||||
Capabilities: p.Capabilities,
|
||||
Compositors: p.Compositors,
|
||||
Dependencies: p.Dependencies,
|
||||
Installed: installed,
|
||||
FirstParty: strings.HasPrefix(p.Repo, "https://github.com/AvengeMedia"),
|
||||
RequiresDMS: p.RequiresDMS,
|
||||
}
|
||||
info := pluginInfoFromPlugin(p)
|
||||
info.Installed = installed
|
||||
result[i] = info
|
||||
}
|
||||
|
||||
models.Respond(conn, req.ID, result)
|
||||
|
||||
@@ -8,6 +8,7 @@ type PluginInfo struct {
|
||||
Description string `json:"description,omitempty"`
|
||||
Repo string `json:"repo,omitempty"`
|
||||
Path string `json:"path,omitempty"`
|
||||
Screenshot string `json:"screenshot,omitempty"`
|
||||
Capabilities []string `json:"capabilities,omitempty"`
|
||||
Compositors []string `json:"compositors,omitempty"`
|
||||
Dependencies []string `json:"dependencies,omitempty"`
|
||||
|
||||
@@ -1,14 +1,65 @@
|
||||
package plugins
|
||||
|
||||
import (
|
||||
"net/url"
|
||||
"sort"
|
||||
"strings"
|
||||
|
||||
coreplugins "github.com/AvengeMedia/DankMaterialShell/core/internal/plugins"
|
||||
)
|
||||
|
||||
func pluginInfoFromPlugin(plugin coreplugins.Plugin) PluginInfo {
|
||||
return PluginInfo{
|
||||
ID: plugin.ID,
|
||||
Name: plugin.Name,
|
||||
Category: plugin.Category,
|
||||
Author: plugin.Author,
|
||||
Description: plugin.Description,
|
||||
Repo: plugin.Repo,
|
||||
Path: plugin.Path,
|
||||
Screenshot: normalizeScreenshotURL(plugin.Screenshot),
|
||||
Capabilities: plugin.Capabilities,
|
||||
Compositors: plugin.Compositors,
|
||||
Dependencies: plugin.Dependencies,
|
||||
FirstParty: isFirstPartyRepo(plugin.Repo),
|
||||
Featured: plugin.Featured,
|
||||
RequiresDMS: plugin.RequiresDMS,
|
||||
}
|
||||
}
|
||||
|
||||
func isFirstPartyRepo(repo string) bool {
|
||||
return strings.HasPrefix(repo, "https://github.com/AvengeMedia")
|
||||
}
|
||||
|
||||
func normalizeScreenshotURL(raw string) string {
|
||||
screenshotURL := strings.TrimSpace(raw)
|
||||
if screenshotURL == "" {
|
||||
return ""
|
||||
}
|
||||
|
||||
parsed, err := url.Parse(screenshotURL)
|
||||
if err != nil {
|
||||
return screenshotURL
|
||||
}
|
||||
|
||||
host := strings.ToLower(parsed.Host)
|
||||
if host != "github.com" && host != "www.github.com" {
|
||||
return screenshotURL
|
||||
}
|
||||
|
||||
parts := strings.Split(strings.Trim(parsed.EscapedPath(), "/"), "/")
|
||||
if len(parts) < 5 || (parts[2] != "blob" && parts[2] != "raw") {
|
||||
return screenshotURL
|
||||
}
|
||||
|
||||
rawParts := append([]string{parts[0], parts[1], parts[3]}, parts[4:]...)
|
||||
return "https://raw.githubusercontent.com/" + strings.Join(rawParts, "/")
|
||||
}
|
||||
|
||||
func SortPluginInfoByFirstParty(pluginInfos []PluginInfo) {
|
||||
sort.SliceStable(pluginInfos, func(i, j int) bool {
|
||||
isFirstPartyI := strings.HasPrefix(pluginInfos[i].Repo, "https://github.com/AvengeMedia")
|
||||
isFirstPartyJ := strings.HasPrefix(pluginInfos[j].Repo, "https://github.com/AvengeMedia")
|
||||
isFirstPartyI := isFirstPartyRepo(pluginInfos[i].Repo)
|
||||
isFirstPartyJ := isFirstPartyRepo(pluginInfos[j].Repo)
|
||||
if isFirstPartyI != isFirstPartyJ {
|
||||
return isFirstPartyI
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user