From a4b607d5a0c11c2f2fac8793f0be5144ffdd2f06 Mon Sep 17 00:00:00 2001 From: Laurynas Gadliauskas Date: Mon, 31 May 2021 14:06:42 +0300 Subject: [PATCH] feat: Distinguish symlinks (#3) --- files/file.go | 16 +++++++++- frontend/public/themes/dark.css | 3 ++ frontend/src/components/files/ListingItem.vue | 18 +++++++++-- frontend/src/components/prompts/Archive.vue | 4 +-- frontend/src/css/listing.css | 30 +++++++++++++++++++ frontend/src/views/files/Listing.vue | 4 +++ go.mod | 2 +- go.sum | 7 +++++ 8 files changed, 78 insertions(+), 6 deletions(-) diff --git a/files/file.go b/files/file.go index 830d9061..8dfc299c 100644 --- a/files/file.go +++ b/files/file.go @@ -34,6 +34,8 @@ type FileInfo struct { ModTime time.Time `json:"modified"` Mode os.FileMode `json:"mode"` IsDir bool `json:"isDir"` + IsSymlink bool `json:"isSymlink"` + Link string `json:"link"` Type string `json:"type"` Subtitles []string `json:"subtitles,omitempty"` Content string `json:"content,omitempty"` @@ -254,13 +256,23 @@ func (i *FileInfo) readListing(checker rules.Checker, readHeader bool) error { continue } - if IsSymlink(f.Mode()) { + isSymlink := IsSymlink(f.Mode()) + symLink := "" + if isSymlink { // It's a symbolic link. We try to follow it. If it doesn't work, // we stay with the link information instead of the target's. info, err := i.Fs.Stat(fPath) if err == nil { f = info } + + // Try to read the link's target + if lsf, ok := i.Fs.(afero.LinkReader); ok { + link, err := lsf.ReadlinkIfPossible(fPath) + if err == nil { + symLink = link + } + } } file := &FileInfo{ @@ -270,6 +282,8 @@ func (i *FileInfo) readListing(checker rules.Checker, readHeader bool) error { ModTime: f.ModTime(), Mode: f.Mode(), IsDir: f.IsDir(), + IsSymlink: isSymlink, + Link: symLink, Extension: filepath.Ext(name), Path: fPath, } diff --git a/frontend/public/themes/dark.css b/frontend/public/themes/dark.css index 98353831..5e73e6b0 100644 --- a/frontend/public/themes/dark.css +++ b/frontend/public/themes/dark.css @@ -104,6 +104,9 @@ nav > div { #listing.list .item.header { background: var(--background); } +#listing .item .symlink-icon { + color: var(--surfacePrimary); +} .message { color: var(--textPrimary); diff --git a/frontend/src/components/files/ListingItem.vue b/frontend/src/components/files/ListingItem.vue index 337a2d55..89fc61e9 100644 --- a/frontend/src/components/files/ListingItem.vue +++ b/frontend/src/components/files/ListingItem.vue @@ -17,11 +17,23 @@ v-if="readOnly == undefined && type === 'image' && isThumbsEnabled" v-lazy="thumbnailUrl" /> - {{ icon }} +
-

{{ name }}

+

+ {{ name }} → {{ link }} +

+

{{ name }}

{{ humanSize() }}

@@ -50,6 +62,8 @@ export default { }, props: [ "name", + "link", + "isSymlink", "isDir", "url", "type", diff --git a/frontend/src/components/prompts/Archive.vue b/frontend/src/components/prompts/Archive.vue index 9a875520..ec170f71 100644 --- a/frontend/src/components/prompts/Archive.vue +++ b/frontend/src/components/prompts/Archive.vue @@ -76,14 +76,14 @@ export default { uri = uri.replace("//", "/"); try { - this.loading = true + this.loading = true; await api.archive(uri, this.name, format, ...items); this.$store.commit("setReload", true); } catch (e) { this.$showError(e); } finally { - this.loading = false + this.loading = false; } this.$store.commit("closeHovers"); diff --git a/frontend/src/css/listing.css b/frontend/src/css/listing.css index 8506df7a..d0a2c717 100644 --- a/frontend/src/css/listing.css +++ b/frontend/src/css/listing.css @@ -100,6 +100,7 @@ #listing.mosaic .item div:first-of-type { width: 5em; + position: inherit; } #listing.mosaic .item div:last-of-type { @@ -240,3 +241,32 @@ #listing #multiple-selection i { color: #fff; } + +#listing .item .symlink-icon { + color: #fff; + position: absolute; +} + +#listing.mosaic .item .symlink-icon.dir { + font-size: 1.5em; + left: .45em; + bottom: .45em; +} + +#listing.mosaic .item .symlink-icon.file { + font-size: 1.5em; + left: .65em; + bottom: .2em; +} + +#listing.list .item .symlink-icon.dir { + font-size: 1.2em; + left: 1em; + bottom: 1em; +} + +#listing.list .item .symlink-icon.file { + font-size: 1.2em; + left: 1.14em; + bottom: .85em; +} \ No newline at end of file diff --git a/frontend/src/views/files/Listing.vue b/frontend/src/views/files/Listing.vue index cb1145c0..dd69e03b 100644 --- a/frontend/src/views/files/Listing.vue +++ b/frontend/src/views/files/Listing.vue @@ -213,6 +213,8 @@ :key="base64(item.name)" v-bind:index="item.index" v-bind:name="item.name" + v-bind:isSymlink="item.isSymlink" + v-bind:link="item.link" v-bind:isDir="item.isDir" v-bind:url="item.url" v-bind:modified="item.modified" @@ -229,6 +231,8 @@ :key="base64(item.name)" v-bind:index="item.index" v-bind:name="item.name" + v-bind:isSymlink="item.isSymlink" + v-bind:link="item.link" v-bind:isDir="item.isDir" v-bind:url="item.url" v-bind:modified="item.modified" diff --git a/go.mod b/go.mod index 6ba09628..727ed492 100644 --- a/go.mod +++ b/go.mod @@ -21,7 +21,7 @@ require ( github.com/nwaples/rardecode v1.0.0 // indirect github.com/pelletier/go-toml v1.6.0 github.com/pierrec/lz4 v0.0.0-20190131084431-473cd7ce01a1 // indirect - github.com/spf13/afero v1.2.2 + github.com/spf13/afero v1.3.0 github.com/spf13/cobra v0.0.5 github.com/spf13/jwalterweatherman v1.1.0 // indirect github.com/spf13/pflag v1.0.5 diff --git a/go.sum b/go.sum index e104a73b..150799db 100644 --- a/go.sum +++ b/go.sum @@ -114,6 +114,7 @@ github.com/klauspost/compress v1.4.1/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0 github.com/klauspost/cpuid v1.2.0 h1:NMpwD2G9JSFOE1/TJjGSo5zG7Yb2bTe7eq1jH+irmeE= github.com/klauspost/cpuid v1.2.0/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= +github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg= github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= @@ -159,7 +160,9 @@ github.com/pelletier/go-toml v1.6.0/go.mod h1:5N711Q9dKgbdkxHL+MEfF31hpT7l0S0s/t github.com/pierrec/lz4 v0.0.0-20190131084431-473cd7ce01a1 h1:0utzB5Mn6QyMzIeOn+oD7pjKQLjJwfM9bz6TkPPdxcw= github.com/pierrec/lz4 v0.0.0-20190131084431-473cd7ce01a1/go.mod h1:3/3N9NVKO0jef7pBehbT1qWhCMrIgbYNnFAZCqQ5LRc= github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/profile v1.2.1/go.mod h1:hJw3o1OdXxsrSjjVksARp5W95eeEaEfptyVZyv6JUPA= +github.com/pkg/sftp v1.10.1/go.mod h1:lYOWFsE0bwd1+KfKJaKeuokY15vzFx25BLbzYYoAxZI= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= @@ -184,6 +187,8 @@ github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasO github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ= github.com/spf13/afero v1.2.2 h1:5jhuqJyZCZf2JRofRvN/nIFgIWNzPa3/Vz8mYylgbWc= github.com/spf13/afero v1.2.2/go.mod h1:9ZxEEn6pIJ8Rxe320qSDBk6AsU0r9pR7Q4OcevTdifk= +github.com/spf13/afero v1.3.0 h1:Ysnmjh1Di8EaWaBv40CYR4IdaIsBc5996Gh1oZzCBKk= +github.com/spf13/afero v1.3.0/go.mod h1:5KUK8ByomD5Ti5Artl0RtHeI5pTF7MIDuXL3yY520V4= github.com/spf13/cast v1.3.0 h1:oget//CVOEoFewqQxwr0Ej5yjygnqGkvggSE/gB35Q8= github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= github.com/spf13/cobra v0.0.5 h1:f0B+LkLX6DtmRH1isoNA9VTtNUK9K8xYd28JNNfOv/s= @@ -201,6 +206,7 @@ github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+ github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= +github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= github.com/stretchr/testify v1.6.1 h1:hDPOHmpOpP40lSULcqw7IrRb/u7w6RpDC9399XyoNd0= github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/subosito/gotenv v1.2.0 h1:Slr1R9HxAlEKefgq5jn9U+DnETlIUa6HfgEzj0g5d7s= @@ -229,6 +235,7 @@ golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9/go.mod h1:6SG95UA2DQfeDnf golang.org/x/crypto v0.0.0-20190123085648-057139ce5d2b/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190228161510-8dd112bcdc25/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20190820162420-60c769a6c586/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20200510223506-06a226fb4e37 h1:cg5LA/zNPRzIXIWSCxQW10Rvpy94aQh3LT/ShoCpkHw= golang.org/x/crypto v0.0.0-20200510223506-06a226fb4e37/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/image v0.0.0-20191009234506-e7c1f5e7dbb8 h1:hVwzHzIUGRjiF7EcUjqNxk3NCfkPxbDKRdnNE1Rpg0U=