feat: Directory page UI improvements
These changes are needed to prepare for the Directory page UI improvements implemented in https://github.com/ipfs/dir-index-html/issues/37. - update dir-index-html type structs - emit gateway URL for root links - emit CID of each directoryItem - emit size of directory - emit breadcrumbs
Kevin Neaton committed
Jul 9, 2020 at 23:46 UTC
044790a83857c4b396ce5c336045d6b10f5e4075
3 files changed
+86
-11
core/corehttp/gateway_handler.go
+37
-5
@@ -328,8 +328,20 @@ func (i *gatewayHandler) getOrHeadHandler(w http.ResponseWriter, r *http.Request
328
size = humanize.Bytes(uint64(s))
329
}
330
331
+ hash := ""
332
+ if r, err := i.api.ResolvePath(r.Context(), ipath.Join(resolvedPath, dirit.Name())); err == nil {
333
+ // Path may not be resolved. Continue anyways.
334
+ hash = r.Cid().String()
335
+ }
336
+
337
// See comment above where originalUrlPath is declared.
332
- di := directoryItem{size, dirit.Name(), gopath.Join(originalUrlPath, dirit.Name())}
338
+ di := directoryItem{
339
+ Size: size,
340
+ Name: dirit.Name(),
341
+ Path: gopath.Join(originalUrlPath, dirit.Name()),
342
+ Hash: hash,
343
+ ShortHash: shortHash(hash),
344
+ }
345
dirListing = append(dirListing, di)
346
}
347
if dirit.Err() != nil {
@@ -359,14 +371,34 @@ func (i *gatewayHandler) getOrHeadHandler(w http.ResponseWriter, r *http.Request
371
}
372
}
373
374
+ size := "?"
375
+ if s, err := dir.Size(); err == nil {
376
+ // Size may not be defined/supported. Continue anyways.
377
+ size = humanize.Bytes(uint64(s))
378
+ }
379
+
380
hash := resolvedPath.Cid().String()
381
382
+ // Storage for gateway URL to be used when linking to other rootIDs. This
383
+ // will be blank unless subdomain resolution is being used for this request.
384
+ var gwURL string
385
+
386
+ // Get gateway hostname and build gateway URL.
387
+ if h, ok := r.Context().Value("gw-hostname").(string); ok {
388
+ gwURL = "//" + h
389
+ } else {
390
+ gwURL = ""
391
+ }
392
+
393
// See comment above where originalUrlPath is declared.
394
tplData := listingTemplateData{
366
- Listing: dirListing,
367
- Path: urlPath,
368
- BackLink: backLink,
369
- Hash: hash,
395
+ GatewayURL: gwURL,
396
+ Listing: dirListing,
397
+ Size: size,
398
+ Path: urlPath,
399
+ Breadcrumbs: breadcrumbs(urlPath),
400
+ BackLink: backLink,
401
+ Hash: hash,
402
}
403
404
err = listingTemplate.Execute(w, tplData)
core/corehttp/gateway_indexPage.go
+44
-5
@@ -7,22 +7,61 @@ import (
7
"strings"
8
9
"github.com/ipfs/go-ipfs/assets"
10
+ ipfspath "github.com/ipfs/go-path"
11
)
12
13
// structs for directory listing
14
type listingTemplateData struct {
14
- Listing []directoryItem
15
- Path string
16
- BackLink string
17
- Hash string
15
+ GatewayURL string
16
+ Listing []directoryItem
17
+ Size string
18
+ Path string
19
+ Breadcrumbs []breadcrumb
20
+ BackLink string
21
+ Hash string
22
}
23
24
type directoryItem struct {
21
- Size string
25
+ Size string
26
+ Name string
27
+ Path string
28
+ Hash string
29
+ ShortHash string
30
+}
31
+
32
+type breadcrumb struct {
33
Name string
34
Path string
35
}
36
37
+func breadcrumbs(urlPath string) []breadcrumb {
38
+ var ret []breadcrumb
39
+
40
+ p, err := ipfspath.ParsePath(urlPath)
41
+ if err != nil {
42
+ // No breadcrumbs, fallback to bare Path in template
43
+ return ret
44
+ }
45
+
46
+ segs := p.Segments()
47
+ for i, seg := range segs {
48
+ if i == 0 {
49
+ ret = append(ret, breadcrumb{Name: seg})
50
+ } else {
51
+ ret = append(ret, breadcrumb{
52
+ Name: seg,
53
+ Path: "/" + strings.Join(segs[0:i+1], "/"),
54
+ })
55
+ }
56
+ }
57
+
58
+ return ret
59
+}
60
+
61
+func shortHash(hash string) string {
62
+ return (hash[0:4] + "\u2026" + hash[len(hash)-4:])
63
+}
64
+
65
var listingTemplate *template.Template
66
67
func init() {
core/corehttp/hostname.go
+5
-1
@@ -143,6 +143,10 @@ func HostnameOption() ServeOption {
143
if gw, hostname, ns, rootID, ok := knownSubdomainDetails(host, knownGateways); ok {
144
// Looks like we're using a known gateway in subdomain mode.
145
146
+ // Add gateway hostname context for linking to other root ids.
147
+ // Example: localhost/ipfs/{cid}
148
+ ctx := context.WithValue(r.Context(), "gw-hostname", hostname)
149
+
150
// Assemble original path prefix.
151
pathPrefix := "/" + ns + "/" + rootID
152
@@ -197,7 +201,7 @@ func HostnameOption() ServeOption {
201
r.URL.Path = pathPrefix + r.URL.Path
202
203
// Serve path request
200
- childMux.ServeHTTP(w, r)
204
+ childMux.ServeHTTP(w, r.WithContext(ctx))
205
return
206
}
207
// We don't have a known gateway. Fallback on DNSLink lookup